Leaf optimization pre-arranges your wallet’s internal structure to enable faster transfers. Without optimization, transfers may require a swap with the SSP (Spark Service Provider), adding latency. With optimization, transfers complete in ~5 seconds.
Spark creates power-of-2 denomination leaves (1, 2, 4, 8, 16… sats). With one leaf of each denomination, you can transfer any amount without needing an SSP swap. With multiple leaves of each denomination, you can make multiple transfers without swapping.
Higher multiplicity = faster transfers, but smaller individual leaves. Leaves under 16,348 sats cannot be unilaterally exited (fees would exceed value). If unilateral exit capability is critical for your users, use a lower multiplicity or larger balances.
For most consumer wallets, fast transfer speeds for 100% of users outweighs unilateral exit costs for a small fraction of users.
// Default behavior - auto optimization with multiplicity 1const { wallet } = await SparkWallet.initialize({ options: { network: "MAINNET" }});// Fast transfers for consumer walletconst { wallet } = await SparkWallet.initialize({ options: { network: "MAINNET", optimizationOptions: { auto: true, multiplicity: 5 } }});// Manual control for maximum optimizationconst { wallet } = await SparkWallet.initialize({ options: { network: "MAINNET", optimizationOptions: { auto: false, multiplicity: 5 } }});// Then call wallet.optimizeLeaves() explicitly when needed
Safe to pass on every init. Pass optimizationOptions every time you initialize (e.g., on app reopen). The SDK only runs optimization if needed and does nothing on wallets with no balance.
When running multiple wallet instances (e.g., service worker + popup in a browser extension):
Multiple instances are safe but may cause temporary claim failures. The SDK handles this automatically—failed claims retry and succeed on subsequent attempts.
Best practices:
Avoid calling getStaticDepositAddress() concurrently—this can create duplicate addresses
Let one instance handle background claiming if possible
Failed claims due to concurrent access are automatically recoverable
The SDK uses your device’s system time for expiry calculations.
Your device clock must be within 2 minutes of actual time, or operations will fail with “invalid expiry_time” errors. If users report this error, ask them to sync their device clock.