Research/Spark

Building on Spark: How the SDK Lets Wallet Developers Ship Bitcoin Payments in Days

Spark's developer SDK abstracts statechain and FROST complexity, letting wallet builders integrate self-custodial Bitcoin payments quickly.

bcMaoSep 28, 2026

Wallet developers building Bitcoin payment features have traditionally faced months of integration work. Lightning implementations require channel management, liquidity provisioning, and peer-to-peer networking. On-chain wallets demand UTXO tracking, fee estimation, and coin selection. The Spark SDK takes a different approach: it abstracts statechain transfers, FROST threshold signing, and key management behind a simple API, letting developers ship self-custodial Bitcoin and stablecoin payments in days rather than months.

This article walks through the SDK architecture, the integration path from installation to first payment, and how it compares to other Bitcoin payment SDKs like LDK, Breez SDK, and Greenlight.

What the Spark SDK Abstracts

The core of Spark is a statechain protocol enhanced with FROST threshold signatures. Transfers work by rotating key shares between sender and receiver while the underlying Bitcoin remains in the same on-chain address. The Spark Entity (a set of independent operators) participates in a 2-of-2 multisig with the user, where the operator side is itself a FROST threshold key split across multiple parties.

None of this complexity is visible to SDK consumers. The SparkWallet class exposes methods like transfer(), getBalance(), and createLightningInvoice(). Under the hood, each call coordinates FROST signing rounds, manages virtual transaction outputs (VTXOs), handles key derivation from the user's seed phrase, and communicates with Spark Operators over an authenticated channel.

Statechain transfer coordination

When a developer calls wallet.transfer(), the SDK performs a multi-step process invisibly: it contacts the Spark Entity to initiate a key rotation, participates in a FROST signing round to produce the new shared key, verifies that the old key share has been invalidated, and delivers the transfer notification to the receiver. The developer sees a single async function call that resolves when the transfer is complete.

FROST signing abstraction

FROST (Flexible Round-Optimized Schnorr Threshold) signatures require coordinated multi-round protocols between signers. Implementing FROST from scratch involves nonce commitment schemes, Schnorr signature aggregation, and share verification. The SDK handles all of this internally, including retry logic for operator communication and key share validation. Developers never interact with raw cryptographic primitives.

Key management

Users generate a standard BIP-39 mnemonic locally. The SDK derives all necessary key material from this mnemonic, including the user's half of each 2-of-2 signing pair. Key storage, derivation paths, and backup are handled by the SDK's initialization flow. The self-custody guarantee is preserved: the user's mnemonic never leaves the device, and operators never see the user's private key material.

Self-custody by default: Unlike custodial APIs where a backend holds keys, the Spark SDK generates and stores keys on the client side. Users can always exit to Bitcoin L1 using pre-signed exit transactions, even if Spark operators go offline. This is true self-custody, not a custodial service wrapped in an SDK.

What the SDK Exposes

The API surface is deliberately minimal. The SparkWallet class covers six categories: wallet lifecycle, balance queries, Spark transfers, Lightning operations, L1 deposits and withdrawals, and token operations.

CategoryKey MethodsWhat It Does
Wallet lifecycleSparkWallet.initialize()Create new wallet or restore from mnemonic
BalancegetBalance()Returns BTC balance (sats) and token balances
Spark transferstransfer(), getSparkAddress()Send/receive BTC on Spark with instant settlement
LightningpayLightningInvoice(), createLightningInvoice()Send and receive Lightning payments natively
L1 bridgegetSingleUseDepositAddress(), withdraw()Move Bitcoin between L1 and Spark
TokenstransferTokens(), createTokensInvoice()Send/receive USDB and other Spark-native tokens

Event listeners (wallet.on("transfer:claimed", callback)) let apps react to incoming payments in real time. This is sufficient to build a complete payment wallet without touching any lower-level protocol details.

From Installation to First Payment

The integration path for the Spark SDK is designed for speed. A developer with Node.js experience can go from zero to a working Bitcoin payment in under an hour.

Step 1: Install the SDK

The TypeScript SDK is available on npm. For teams starting a new project, the scaffolding tool sets up a complete project structure:

npm install @buildonspark/spark-sdk

# Or scaffold a complete project:
npx @buildonspark/create-spark-app my-wallet

Step 2: Initialize a wallet

Wallet creation generates a new HD wallet with a BIP-39 mnemonic. The SDK handles key derivation and operator registration:

import { SparkWallet } from "@buildonspark/spark-sdk";

// Create a new wallet
const { wallet, mnemonic } = await SparkWallet.initialize({
  options: { network: "MAINNET" }
});

// Or restore from existing mnemonic
const { wallet: restored } = await SparkWallet.initialize({
  mnemonicOrSeed: existingMnemonic,
  accountNumber: 0,
  options: { network: "MAINNET" }
});

Step 3: Send a payment

Sending Bitcoin on Spark is a single method call. The SDK resolves the recipient's Spark address, coordinates the statechain transfer, and returns when settlement is complete:

// Spark-to-Spark transfer (instant, near-zero fee)
await wallet.transfer({
  receiverSparkAddress: recipientAddress,
  amountSats: 50000
});

// Pay a Lightning invoice
await wallet.payLightningInvoice({
  invoice: bolt11Invoice,
  maxFeeSats: 100
});

Step 4: Receive payments

Receiving is equally straightforward. The SDK supports both Spark-native invoices and Lightning invoices from the same wallet:

// Create a Spark invoice
const sparkInvoice = await wallet.createSatsInvoice({
  amount: 25000,
  memo: "Coffee payment"
});

// Create a Lightning invoice
const lnInvoice = await wallet.createLightningInvoice({
  amountSats: 25000,
  memo: "Coffee payment"
});

// Listen for incoming payments
wallet.on("transfer:claimed", (transfer) => {
  console.log("Received:", transfer.amountSats, "sats");
});
Zero-conf deposits: The Spark SDK credits on-chain Bitcoin deposits instantly by validating the transaction at broadcast time. The protocol handles confirmation risk, so users do not wait for block confirmations. Developers call getSingleUseDepositAddress() to generate a deposit address and claimDeposit() to finalize.

Stablecoin Support: Bitcoin and Dollars from One SDK

A distinctive feature of the Spark SDK is native stablecoin support. USDB, a USD-backed stablecoin issued by Brale (a FinCEN-registered MSB), is a first-class citizen in the SDK. It uses the BTKN token standard native to Spark, not a bridge from another chain.

The same SparkWallet instance handles both BTC and token operations. Developers do not need a separate stablecoin SDK, a bridge integration, or an EVM-compatible layer:

// Check token balances
const { balance, tokenBalances } = await wallet.getBalance();
// balance: BTC in sats
// tokenBalances: array of { tokenIdentifier, amount }

// Send USDB
await wallet.transferTokens({
  tokenIdentifier: "usdb",
  tokenAmount: 1000, // $10.00
  receiverSparkAddress: recipientAddress
});

// Create a USDB invoice
const invoice = await wallet.createTokensInvoice({
  tokenIdentifier: "usdb",
  amount: 5000,
  memo: "Invoice #1234"
});

This dual-asset capability is particularly relevant for fintech applications that need dollar-denominated payments without leaving the Bitcoin ecosystem. A single SDK integration gives users access to both volatile BTC and stable USD transfers.

How Spark SDK Compares to Lightning SDKs

The most direct comparisons are with LDK (Lightning Dev Kit), Breez SDK, and Greenlight by Blockstream. Each targets a different point on the control-vs-complexity spectrum.

LDK: maximum control, maximum effort

LDK is a Rust library that gives developers full control over every aspect of a Lightning node. It is modular by design: you provide your own on-chain wallet (often BDK), your own persistence layer, your own fee estimator, and your own chain data source. A minimal LDK wallet requires implementing roughly 10 trait interfaces covering chain monitoring, key management, transaction broadcasting, event persistence, and logging.

The result is maximum flexibility for teams building differentiated Lightning products, but the integration timeline is measured in months. Post-launch maintenance includes channel rebalancing, peer management, and watchtower operation.

Breez SDK: managed Lightning with LSP abstraction

Breez SDK wraps Lightning complexity behind a higher-level API and connects to Breez's Lightning Service Provider infrastructure for automated channel management and liquidity provisioning. Integration is substantially faster than raw LDK: configuration plus connection takes roughly 10 lines of code, and sending a payment takes 3. Breez SDK is built in Rust with bindings for Swift, Kotlin, Python, Flutter, Go, C#, and React Native.

The tradeoff is dependency on Breez infrastructure for LSP services and a fee structure that includes LSP channel-open fees for inbound liquidity. Breez now also offers a Spark integration alongside its Lightning offering.

Greenlight: cloud-hosted CLN nodes

Blockstream's Greenlight runs Core Lightning nodes in the cloud on behalf of developers. The user holds keys locally while the node runs on Blockstream's infrastructure. This provides the full CLN feature set without server management, but developers still need to handle channel liquidity, routing configuration, and the operational complexity that comes with running a Lightning node.

Spark SDK: protocol complexity removed

The Spark SDK eliminates entire categories of infrastructure that Lightning-based solutions require. There are no channels to open, no liquidity to manage, no routing to configure, and no watchtowers to run. The tradeoff is the 1-of-n trust model: users trust that at least one Spark operator behaves honestly during each transfer. For many consumer wallet use cases, this is an acceptable tradeoff given the dramatic reduction in integration complexity and ongoing maintenance.

DimensionLDKBreez SDKGreenlightSpark SDK
Core languageRustRustC (CLN)TypeScript
Wallet init complexity~100+ lines, 10 trait impls~10 lines~20 lines + cloud setup~5 lines
Send payment~20 lines~3 lines~5 lines~3 lines
Channel managementManual (developer handles)Automated via LSPSemi-automatedNot applicable
Liquidity planningRequiredLSP handles inboundRequiredNot applicable
Infrastructure requiredFull node, Electrum, gossip dataBreez API keyBlockstream cloud accessNone (public operators)
Offline receivingNoNoNoYes (SSP holds conditionally)
Native stablecoin supportNoNoNoYes (USDB, BTKN tokens)
Trust modelFully trustlessTrustless (non-custodial LSP)Blockstream hosts node1-of-n operators
Ongoing maintenanceChannel rebalancing, peer mgmt, watchtowersSDK updates, LSP fee monitoringChannel mgmt, routing configSDK updates only
Platform bindingsRust, Swift, Kotlin, Node.jsRust, Swift, Kotlin, Flutter, RN, Go, C#CLN plugins, Breez wraps itTypeScript, Kotlin, Swift, RN

Platform Support and Language Bindings

The Spark SDK is available natively for the platforms where most wallet development happens:

  • TypeScript (npm): @buildonspark/spark-sdk for Node.js, browser, and React Native environments
  • Kotlin: spark-kotlin-sdk for native Android applications
  • Swift: spark-swift-sdk for native iOS applications

For additional language support, the Breez Spark SDK extends reach to Rust, Python, Go, Flutter, and C# through FFI bindings. This means developers working in virtually any major mobile or server-side language can integrate Spark without writing TypeScript.

The scaffolding tool (npx @buildonspark/create-spark-app) generates a complete project skeleton with wallet initialization, environment configuration, and example payment flows. This is particularly useful for hackathon prototypes and proof-of-concept builds where time to first demo is critical.

Developer Experience: What Makes It Different

Several design decisions in the Spark SDK reflect lessons learned from the Lightning SDK ecosystem.

No infrastructure to provision

LDK and Greenlight require developers to run or connect to Bitcoin full nodes, Electrum servers, or cloud infrastructure. The Spark SDK connects to the existing Spark operator network directly. There is no server to deploy, no RPC endpoint to configure, and no gossip data to sync. This removes an entire deployment category from the launch checklist.

No state management burden

Lightning wallets must persist channel state reliably. Losing channel state can result in funds loss through outdated commitment transactions. The Spark SDK stores wallet state locally but the protocol is not vulnerable to stale state attacks: if local data is lost, the wallet can be fully restored from the mnemonic because the operators maintain the current state of each VTXO.

Unified payment interface

A Spark wallet can send and receive via three rails from the same instance: Spark-to-Spark transfers (instant, near-zero fee), Lightning payments (via Spark Service Providers performing atomic swaps), and L1 Bitcoin (deposits and withdrawals). Developers do not need to integrate multiple SDKs or maintain separate codepaths for different payment types.

Event-driven architecture

The SDK uses an event emitter pattern for incoming payments. Instead of polling, developers register callbacks that fire when transfers are claimed, deposits confirm, or token payments arrive. This integrates cleanly with modern frontend frameworks and mobile app architectures.

Production Integrations

The SDK's design has been validated by production deployments across wallet categories. Over 20 applications have integrated Spark, including consumer wallets like Wallet of Satoshi, Xverse, Blitz, and Breez; neobanks like Deblock; infrastructure providers like Privy and Dynamic; and trading platforms like Flashnet.

The breadth of integrations demonstrates that the SDK surface is general enough for different product architectures while remaining specific enough to be useful without extensive customization. Teams building embedded wallets, standalone payment apps, and Telegram bots have all shipped using the same API surface.

Documentation and Developer Resources

The Spark developer documentation covers the complete SDK surface with quickstart guides, API references, and integration examples for TypeScript and React Native. Key resources include:

  • Quickstart guide: wallet creation to first payment in a single tutorial
  • API reference: complete method signatures with parameter types and return values
  • Token issuance guide: creating and managing custom tokens using the BTKN standard
  • GitHub repository: buildonspark/spark (Apache 2.0 license)

For developers evaluating the SDK against alternatives, the Bitcoin wallet SDK comparison provides a detailed feature-by-feature breakdown across BDK, LDK, Breez SDK, and Spark SDK. The payment app development guide covers the full decision tree from architecture to deployment.

Tradeoffs Developers Should Understand

The Spark SDK is not a universal solution. Several tradeoffs are worth evaluating before committing to the integration.

Trust model

Spark relies on a 1-of-n trust assumption: at least one operator must behave honestly during each transfer. This is weaker than Lightning's fully trustless model but stronger than custodial solutions. For applications where absolute trustlessness is a product requirement (institutional custody, high-value settlement), a Lightning-based SDK may be more appropriate.

Operator dependency

If all Spark operators go offline, new transfers cannot be processed. Users can still exit to Bitcoin L1 via pre-signed exit transactions, so funds are never at risk, but the liveness of the payment layer depends on operator availability. Currently, Lightspark and Flashnet operate as operators with plans to expand to additional independent parties.

Privacy considerations

Spark operators can observe transfer metadata including amounts and participant addresses. This is similar to the visibility that Lightning routing nodes have, but the centralized operator model concentrates this information. Developers building privacy-focused applications should evaluate whether this visibility model meets their requirements.

L1 exit costs

Exiting from Spark to Bitcoin L1 requires an on-chain transaction with associated fees. Small balances may become uneconomical to exit during high-fee periods. This is a limitation shared by all Bitcoin Layer 2 solutions.

Getting Started

For developers ready to integrate, the fastest path is the scaffolding tool: npx @buildonspark/create-spark-app generates a working project with wallet initialization and example payment flows. The Spark developer documentation provides step-by-step quickstart guides, and the GitHub repository is open source under the Apache 2.0 license. For a concrete example of what a production Spark wallet looks like for end users, General Bread demonstrates the self-custodial Bitcoin and stablecoin payment experience that the SDK enables.

This article is for educational purposes only. It does not constitute financial or investment advice. Bitcoin and Layer 2 protocols involve technical and financial risk. Always do your own research and understand the tradeoffs before using any protocol.