Skip to content

Open a wallet ​

A wallet owns a local database and a worker. Supply an endpoint and choose where to store its data:

ts
import { createWalletClient } from '@zcashlabs/zcash.js';

const wallet = await createWalletClient('https://testnet.zec.rocks:443', {
  network: 'testnet',
  storage: { kind: 'node-filesystem', path: './my-wallet' },
});

try {
  const accounts = await wallet.accounts.list();
  console.log(accounts);
} finally {
  await wallet.close();
}

The SDK configures the light client, submission route, runtime, proving assets, and transaction policy. Opening a wallet does not generate a recovery phrase, attach a signer, scan the chain, or send a payment. See Accounts and signers to import or create an account.

Defaults ​

OptionDefault
NetworkMainnet; use network: 'testnet' for testnet
ConnectionThe supplied endpoint, used for scanning and explicit submission
Runtime and provingBundled engine, workers, and on-demand proving files
Confirmations3 trusted and 3 untrusted; no zero-confirmation shielding
ObservationPoll every 5 seconds; buffer up to 16 updates
Spending and changeIronwood only; transparent inputs disallowed
Fee ruleZIP-317 standard
Transaction expiry80 blocks after the proposal's target height
Proposal lock expiry20 blocks
Shielding threshold10,000 zatoshis
FreshnessRequire a synced wallet, with no allowed block lag
Startup recoveryLocal/offline reconciliation; no automatic rebroadcast

The network preset supplies genesis and activation rules. The endpoint must match that network; the SDK does not auto-detect or silently switch chains. Ironwood-only defaults require Ironwood-capable funds and recipients. Other pools or transparent shielding require an explicit transaction policy.

Call wallet.sync() before proposing a payment. Submission still requires a valid account, spending authority, and an explicit send/broadcast call.

Choose storage ​

Storage is required: the SDK never silently chooses a temporary wallet.

EnvironmentStorage
Node{ kind: 'node-filesystem', path: './my-wallet' }
Browser{ kind: 'browser-opfs', name: 'my-wallet' }
Disposable session{ kind: 'memory' }

Memory storage loses local wallet state and operation records after close. Back up recovery material separately. Only one owner should open a database at a time; conflicting ownership can fail with STORAGE_BUSY. Browser endpoints must support gRPC-Web and CORS. See platforms.

Override configuration ​

Pass a preset name, a registered Network, or a full NetworkDefinition as network. Configure the endpoint through transportOptions:

ts
import { createWalletClient } from '@zcashlabs/zcash.js';

export async function openWallet(endpoint: string) {
  return createWalletClient(endpoint, {
    network: 'testnet',
    storage: { kind: 'node-filesystem', path: './my-wallet' },
    transportOptions: { timeoutMs: 15000, sourceId: 'my-node' },
    confirmations: { trusted: 5, untrusted: 5, allowZeroConfirmationShielding: false },
    observation: { pollIntervalMs: 3000, maxBufferedUpdates: 16 },
  });
}

runtime accepts individual budget overrides. confirmations, observation, recovery, proving, and transactionPolicy accept their complete option objects. A supplied transaction policy also supplies the query confirmations unless confirmations is explicit; if both are provided, they must match. See proposals for transaction policy and operations and recovery for recovery options.

An explicit runtime.baseline selects a compatible authenticated runtime. Custom proving supplies reviewed asset requirements and a byte-loading callback; lengths and digests are checked. No remote proving service is supplied.

Supply your own clients ​

For separate scanning and submission routes, offline wallets, or a custom transport, supply the components directly:

ts
import { createWalletClient } from '@zcashlabs/zcash.js';
import type { LightClient, WalletStorage } from '@zcashlabs/zcash.js';

export function openReadOnly(light: LightClient, storage: WalletStorage) {
  return createWalletClient({
    network: light.network,
    light,
    storage,
    confirmations: { trusted: 3, untrusted: 3, allowZeroConfirmationShielding: false },
    observation: { pollIntervalMs: 5000, maxBufferedUpdates: 16 },
    recovery: { mode: 'offline' },
  });
}

In this component form, broadcaster and transactionPolicy are explicit: omitting them leaves submission and planning unconfigured. Providing only light enables scanning, not broadcasting.

Always await wallet.close(). Returned signers remain caller-owned and need their own dispose(). See the walkthrough for cleanup.