Skip to Content
Packages@tuwaio/pulsar-solana@tuwaio/pulsar-solana

@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 (devnet, solana:devnet and the genesis-hash chain ID solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 are the same cluster) and throws SolanaChainMismatchError otherwise; it does not switch clusters. The transaction is saved with the genesis-hash chain ID of its cluster as chainId (CAIP-2, as CAIP-30 defines it for Solana). It also builds Solana Explorer links and retries failed transactions for UI kits such as Nova Transactions.
  • Signature tracker: polls getSignatureStatuses every second and writes the commitment to confirmationStatus as it goes (processed, then confirmed, usually about a second after sending, so a UI can show the transaction as confirmed), until the transaction is finalized (Success) or fails (Failed, as soon as the status carries an on-chain error). It fetches the fee, blockhash and instructions once with getTransaction (commitment confirmed; legacy, version 0 and version 1 transactions) and searches the transaction history, so transactions that finished while the page was closed are found after a reload. The details are optional: a getTransaction error never hides the status or fails the transaction, and a finalized transaction whose details are still missing after 10 checks is marked Success without them.
  • Expired transactions: a transaction whose signature is still unknown when the chain passes the last valid block height of its blockhash can no longer land; the tracker checks it once more and marks it Failed with an “expired” error, within seconds. signAndSendSolanaTx saves that height as lastValidBlockHeight; for transactions sent otherwise, set it with updateTxParams, or the tracker gives up one hour after sending. Errors of getSignatureStatuses and getBlockHeight are retried.
  • Signing helper: signAndSendSolanaTx builds a version 0 transaction from one or more instructions (for example generated by Codama ), sets the latest blockhash, and has a TransactionSendingSigner sign and send it. Create the signer for a Wallet Standard account with createSolanaTransactionSendingSigner of @tuwaio/orbit-solana (0.5 and later), without React.
  • Standalone use: solanaFetcher works with initializePollingTracker from @tuwaio/pulsar-core without 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; the store’s onTxFinished and subscribeTxFinished run for every finished transaction, also after a reload. An RPC outage says nothing about the transaction, so in the store errors of the RPC never end tracking: it asks every minute after 30 errors in a row. 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.12), @tuwaio/orbit-core (>=0.4), @tuwaio/orbit-solana (>=0.4), @solana/kit (>=8.2) and dayjs (1.x) are peer dependencies and must be installed alongside @tuwaio/pulsar-solana. The @wallet-standard packages are the peer dependencies of @tuwaio/orbit-solana, and zustand and immer those of @tuwaio/pulsar-core.


🚀 Usage

import type { Instruction } from '@solana/kit'; import { OrbitAdapter } from '@tuwaio/orbit-core'; import { createSolanaClientWithCache, createSolanaTransactionSendingSigner } from '@tuwaio/orbit-solana'; import { createPulsarStore, type SolanaTransaction } from '@tuwaio/pulsar-core'; import { pulsarSolanaAdapter, signAndSendSolanaTx } from '@tuwaio/pulsar-solana'; import type { UiWalletAccount } from '@wallet-standard/ui-core'; const rpcUrls = { devnet: 'https://api.devnet.solana.com' }; export const pulsarStore = createPulsarStore<SolanaTransaction>({ name: 'pulsar-transactions', adapter: pulsarSolanaAdapter({ rpcUrls }), }); // `account`: the Wallet Standard account, for example `connectedAccount` of the Satellite Connect connection export async function send(account: UiWalletAccount, instruction: Instruction) { const client = createSolanaClientWithCache({ rpcUrlOrMoniker: 'devnet', rpcUrls }); const signer = createSolanaTransactionSendingSigner(account, 'devnet'); await pulsarStore.getState().executeTxAction({ actionFunction: () => signAndSendSolanaTx({ client, signer, instruction }), params: { adapter: OrbitAdapter.SOLANA, desiredChainID: 'devnet', // the cluster of the connected wallet; saved as chainId 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1' type: 'transfer', title: 'Transfer', }, }); }

The step-by-step React setup, with Nova Connect and a Codama-generated program client, is in the React transaction tracking guide , and tracking without the store on Solana Trackers Standalone .


🌐 External Services

HelperHostPurpose
Signature trackerThe URL of its cluster in rpcUrls, else the public endpoint of the cluster (api.<cluster>.solana.com)getSignatureStatuses and getTransaction for the signature
retryTxActionThe URL of its cluster in rpcUrls, else the public endpoint of the clusterThe RPC client passed to your actionFunction
signAndSendSolanaTxThe client you passgetLatestBlockhash; 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.

Classes

Interfaces

Type Aliases

Functions

Last updated on