> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spark.money/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet Viewer

> Query wallet data without signing keys using the SparkReadonlyClient

export const Method = ({children, className = ""}) => {
  return <code className={`spark-method not-prose inline-block px-2 py-1 mt-12 text-sm font-mono font-semibold rounded-md border ${className}`}>
      {children}
    </code>;
};

## Overview

The `SparkReadonlyClient` 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:

| Mode              | Auth                    | Use case                                                         |
| ----------------- | ----------------------- | ---------------------------------------------------------------- |
| **Public**        | None                    | Dashboards, explorers, analytics. Query any non-private wallet   |
| **Master Key**    | Identity key            | Query private wallets you own without full wallet initialization |
| **Custom Signer** | Identity key via signer | Partners (e.g., Privy) passing in a signer without a mnemonic    |

***

## Installation

The wallet viewer ships with the standard SDK package.

<CodeGroup>
  ```bash npm theme={null}
  npm install @buildonspark/spark-sdk
  ```

  ```bash yarn theme={null}
  yarn add @buildonspark/spark-sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @buildonspark/spark-sdk
  ```
</CodeGroup>

***

## Create a Public Client

No authentication. Queries public (non-private) wallet data.

```typescript theme={null}
import { SparkReadonlyClient } from "@buildonspark/spark-sdk";

const client = SparkReadonlyClient.createPublic({
  network: "MAINNET",
});

const balance = await client.getAvailableBalance("sp1...");
console.log("Balance:", balance, "sats");
```

<Info>
  Public clients can query any wallet that hasn't enabled [privacy mode](/wallets/privacy). Private wallets return empty results, not errors.
</Info>

***

## Create with Master Key

Authenticates with an identity key derived from a mnemonic or seed. Can query private wallets the key owns.

```typescript theme={null}
import { SparkReadonlyClient } from "@buildonspark/spark-sdk";

const client = await SparkReadonlyClient.createWithMasterKey(
  { network: "MAINNET" },
  "your twelve word mnemonic phrase here ...",
);

// Can see private wallet data
const balance = await client.getAvailableBalance("sp1...");
const tokens = await client.getTokenBalance("sp1...");
```

***

## Create with Custom Signer

For integrations where a partner provides a `SparkSigner` implementation instead of a mnemonic.

```typescript theme={null}
import { SparkReadonlyClient } from "@buildonspark/spark-sdk";

const client = SparkReadonlyClient.createWithSigner(
  { network: "MAINNET" },
  myCustomSigner,
);
```

***

## Query Examples

### Balances

```typescript theme={null}
// Bitcoin balance
const sats = await client.getAvailableBalance("sp1...");

// Token balances (all tokens)
const tokenBalances = await client.getTokenBalance("sp1...");
for (const [tokenId, info] of tokenBalances) {
  console.log(`${info.tokenMetadata.tokenTicker}: ${info.availableToSendBalance}`);
}

// Token balances (specific tokens)
const filtered = await client.getTokenBalance("sp1...", ["btkn1..."]);
```

### Transfers

```typescript theme={null}
// Paginated transfer history
const { transfers, offset } = await client.getTransfers({
  sparkAddress: "sp1...",
  limit: 25,
  offset: 0,
});

// Transfers from last 24 hours
const recent = await client.getTransfers({
  sparkAddress: "sp1...",
  createdAfter: new Date(Date.now() - 86_400_000),
});

// Specific transfers by ID
const specific = await client.getTransfersByIds(["transfer-id-1", "transfer-id-2"]);

// Pending inbound transfers
const pending = await client.getPendingTransfers("sp1...");
```

### Deposits and UTXOs

```typescript theme={null}
// Unused deposit addresses
const { depositAddresses } = await client.getUnusedDepositAddresses({
  sparkAddress: "sp1...",
});

// Static deposit addresses
const staticAddrs = await client.getStaticDepositAddresses("sp1...");

// UTXOs for a specific deposit address
const { utxos } = await client.getUtxosForDepositAddress({
  depositAddress: "bc1...",
});
```

### Invoices and Token Transactions

```typescript theme={null}
// Invoice statuses
const { invoiceStatuses } = await client.getSparkInvoices({
  invoices: ["spark1..."],
});

// Token transactions with cursor pagination
const page = await client.getTokenTransactions({
  sparkAddresses: ["sp1..."],
  pageSize: 25,
});

if (page.pageResponse?.nextCursor) {
  const next = await client.getTokenTransactions({
    sparkAddresses: ["sp1..."],
    cursor: page.pageResponse.nextCursor,
    direction: "NEXT",
  });
}
```

***

## Privacy Model

The wallet viewer respects [privacy mode](/wallets/privacy):

* **Privacy off** (default): Both public and authenticated clients see all data.
* **Privacy on**: Public clients get empty results. Authenticated clients (master key / signer) see everything.

The distinction is server-side. When a wallet has privacy enabled, unauthenticated requests return zero balances and empty arrays, not errors.

If you need visibility into private wallets without full wallet initialization, use `createWithMasterKey()`. For event-driven notifications (push notifications, payment alerts) without needing read access, see [webhooks](/wallets/privacy#webhooks).

***

## API Reference

See the full method reference at [Wallet Viewer API](/api-reference/readonly-overview).
