Overview
TheSparkReadonlyClient lets you query wallet data without creating a full SparkWallet. It exposes read-only methods for balances, transfers, deposits, invoices, and token transactions.
Three use cases:
Installation
The wallet viewer ships with the standard SDK package.Create a Public Client
No authentication. Queries public (non-private) wallet data.Public clients can query any wallet that hasn’t enabled privacy mode. Bitcoin balance and wallet-history queries return empty results when read access is denied. This does not suppress authentication or network errors.
Create with Viewer Key
Authenticates with an identity key derived from a mnemonic or seed. For a separate service identity, the wallet owner must first grant that key access withsetViewerIdentityPublicKey(). Follow the grant and revoke flow. Keep the viewer mnemonic separate from the owner’s wallet mnemonic.
Create with Custom Signer
For integrations where a partner provides aSparkSigner implementation instead of a mnemonic.
Query Examples
Balances
Transfers
Deposits and UTXOs
Invoices and Token Transactions
Privacy Model
New wallets are public by default. With privacy enabled, Bitcoin balance and wallet-history queries require the owner’s identity or the single viewer identity authorized by the owner. An unrelated authenticated client has no more access than a public client. Denied reads return zero balances or empty lists, so the response cannot tell you whether the wallet is empty or access is missing. Token activity remains public. See Privacy Mode for the scope of the setting and transfer-ID lookup considerations.Events and client boundaries
SparkReadonlyClient queries data. It does not claim transfers, optimize wallet outputs, or expose a public event-stream subscription method in SDK 0.12.1. Use polling for a viewer, SparkWallet events for an active wallet, or webhooks for request outcomes.
The protected connectionManager is not a supported subscription API. Public-client credentials cannot authenticate an operator event stream; a low-level attempt can fail with UNAUTHENTICATED, including an invalid-token-encoding message. Do not use that path to test whether a user granted read access.
Transfer objects differ from the wallet API
Do not pass viewer results directly to code expecting
WalletTransfer. For raw transfers, use senders[], receivers[], and the relevant leaf values. Import enum definitions from @buildonspark/spark-sdk/proto/spark instead of hard-coding numeric values.
Token history also has a different result shape: the viewer returns transactions, while queryTokenTransactionsWithFilters() returns tokenTransactionsWithStatus. Both use cursors. The viewer does not expose the wallet’s queryTokenTransactionsByTxHashes() method. To determine send versus receive, inspect the transaction’s inputs and outputs relative to the wallet; appearing in its history does not establish direction.