@tuwaio/pulsar-solana
@tuwaio/pulsar-solana is the Solana Layer 4 (L4) package of Pulsar, the transaction tracking project of TUWA Stage 2 (“State & Connection”, next to Satellite Connect). Built on @solana/kit and @tuwaio/orbit-solana (Wallet Standard discovery and cached RPC clients), it provides the Solana adapter for @tuwaio/pulsar-core, a signature tracker and a helper to sign and send transactions. It does not use the legacy @solana/web3.js or gill.
🏛️ Core Capabilities
- Adapter:
pulsarSolanaAdapter({ rpcUrls })reads the connected wallet from the last connection saved by@tuwaio/orbit-core(Satellite Connect writes it) and finds it among the installed Wallet Standard wallets. Before signing it checks that the wallet is on the cluster of the transaction (devnetandsolana:devnetare the same cluster) and throwsSolanaChainMismatchErrorotherwise; it does not switch clusters. It also builds Solana Explorer links and retries failed transactions for UI kits such as Nova Transactions. - Signature tracker: polls
getSignatureStatusesevery 2.5 s until the transaction isfinalized(Success) or fails on-chain (Failed), and fetches its fee, blockhash and instructions once withgetTransaction. It searches the transaction history, so transactions that finished while the page was closed are found after a reload. RPC errors are retried; tracking gives up after 10 consecutive errors, or when the transaction is still not finalized (or not found) one hour after it was sent. - Signing helper:
signAndSendSolanaTxbuilds a version 0 transaction from one or more instructions (for example generated by Codama ), sets the latest blockhash, and has aTransactionSendingSignersign and send it. - Standalone use:
solanaFetcherworks withinitializePollingTrackerfrom@tuwaio/pulsar-corewithout the store. See Solana Trackers Standalone .
The tracker writes its results to the store with updateTxParams, and the onSuccess and onError callbacks of executeTxAction receive the updated transaction. When it gives up, it marks the transaction Failed and keeps it in the pool.
💾 Installation
pnpm add @tuwaio/pulsar-solana @tuwaio/pulsar-core @tuwaio/orbit-core @tuwaio/orbit-solana @solana/kit @wallet-standard/app @wallet-standard/ui-core @wallet-standard/ui-registry zustand immer dayjs[!IMPORTANT]
@tuwaio/pulsar-core(>=0.8),@tuwaio/orbit-core(>=0.3),@tuwaio/orbit-solana(>=0.3),@solana/kit(>=8.2) anddayjs(1.x) are peer dependencies and must be installed alongside@tuwaio/pulsar-solana. The@wallet-standardpackages are the peer dependencies of@tuwaio/orbit-solana, andzustandandimmerthose of@tuwaio/pulsar-core.
🚀 Usage
import type { Instruction, TransactionSendingSigner } from '@solana/kit';
import { OrbitAdapter } from '@tuwaio/orbit-core';
import { createSolanaClientWithCache } from '@tuwaio/orbit-solana';
import { createPulsarStore, type SolanaTransaction } from '@tuwaio/pulsar-core';
import { pulsarSolanaAdapter, signAndSendSolanaTx } from '@tuwaio/pulsar-solana';
const rpcUrls = { devnet: 'https://api.devnet.solana.com' };
export const pulsarStore = createPulsarStore<SolanaTransaction>({
name: 'pulsar-transactions',
adapter: pulsarSolanaAdapter({ rpcUrls }),
});
export async function send(signer: TransactionSendingSigner, instruction: Instruction) {
const client = createSolanaClientWithCache({ rpcUrlOrMoniker: 'devnet', rpcUrls });
await pulsarStore.getState().executeTxAction({
actionFunction: () => signAndSendSolanaTx({ client, signer, instruction }),
params: {
adapter: OrbitAdapter.SOLANA,
desiredChainID: 'devnet', // the cluster of the connected wallet ('solana:devnet' works too)
rpcUrl: rpcUrls.devnet, // saved with the transaction, so tracking resumes on the same RPC after a reload
type: 'transfer',
title: 'Transfer',
},
});
}The step-by-step React setup, with Nova Connect and a Codama-generated program client, is on the Getting Started page, and tracking without the store on Solana Trackers Standalone .
🌐 External Services
| Helper | Host | Purpose |
|---|---|---|
| Signature tracker | The transaction’s rpcUrl, else the public endpoint of its cluster (api.<cluster>.solana.com) | getSignatureStatuses and getTransaction for the signature |
retryTxAction | The transaction’s rpcUrl, else the URL of its cluster in rpcUrls, else api.mainnet-beta.solana.com | The RPC client passed to your actionFunction |
signAndSendSolanaTx | The client you pass | getLatestBlockhash; the signer sends the transaction |
The public api.*.solana.com endpoints are rate-limited; pass your own RPC URLs in production. Explorer links point to explorer.solana.com and are not requested by the package.
📚 API Reference
Every export, with signatures and types generated from the source, is documented at pulsar.docs.tuwa.io/packages/pulsar-solana .
📄 License
Licensed under the Apache-2.0 License. See the LICENSE file for details.