انضم إلى نوستر
2026-08-31 14:20:54 UTC

Federico Rivi on Nostr: Spark presents itself as self-custodial: instant payments, offline receiving, no ...

Spark presents itself as self-custodial: instant payments, offline receiving, no Lightning channels to open, and keys held by the user.

However, the mainnet configuration published in the SDKs lists three operators - Lightspark, Breez, and Flashnet - and only two of them are needed to produce the aggregate signature controlling each deposit.

Every Spark deposit funds a Taproot output. The key combines two components: one held by the user and one held by the operators. The operators cannot spend on their own. But the user cannot transact without interacting with them.

Spark repeatedly uses the phrase “only one honest operator is needed.” Yet the published configuration is 2-of-3: two old shares being retained are enough to reconstruct the aggregate component and sign a conflicting spend together with a former owner. The third operator can refuse to participate without preventing anything. Bitcoin Layers classifies this as the protocol’s primary finality risk.

A unilateral exit formally exists in the protocol. But many popular wallets still depend on the operators to obtain the data required to construct it.

Meanwhile, Spark is scaling: Wallet of Satoshi, Primal, Blink, Blitz, Cake Wallet. Freedomia, a no-KYC Visa card, also uses it for Lightning deposits following the suspension of Boltz services.
Spark’s self-custody is therefore heavily conditional: the unilateral exit exists on paper, provided the operators cooperate in giving you the data you need.

Last Saturday I got my assessment of the Glow wallet wrong.

I had listed it alongside Blockstream Swaps and Arkade Intents among the projects reducing wallets' dependence on a single operator. After a week spent on the documentation, that sentence deserves a correction.

Glow is the demo application of the new Breez SDK, built on the Spark protocol. The same protocol is already used by Wallet of Satoshi, Primal, Blink, Blitz, Cake Wallet and Xverse. The latter two respectively claim over one million and 1.6 million users.

Since Tuesday, Spark has also been used for the Lightning deposits of Freedomia, a popular no-KYC Visa card many of you know (if you'd like to support me, you can try it via this link). After Boltz suspended its services, Freedomia rebuilt the flow with Breez: the payment is routed via Spark and Orchestra, converted into USDC on Polygon and credited to the card balance.

https://x.com/freedomiacard/status/2089814738695803139

Spark's value proposition is clear: instant payments, offline receiving, no Lightning channels to open, no liquidity to manage and user control of the keys. Wallets and services present it as a self-custodial solution.

The question to verify is equally precise: can a user bring their bitcoin back on-chain when the Spark operators stop cooperating or become unreachable?

The answer has two levels. The protocol provides for a genuine unilateral exit, but many popular wallets still depend on the operators to obtain the data needed to build it.

How bitcoin is controlled on Spark

A Spark deposit funds a Taproot output on the Bitcoin blockchain. The key controlling that output derives from the combination of two components: one belongs to the user, the other to the group of Spark operators.

The mainnet configuration published in the SDKs lists three operators: Lightspark, Breez and Flashnet. Each holds a share of the collective component and two are enough to produce the signature. When the user and the operators sign together, a normal Schnorr signature appears on the blockchain.

The operators do not possess the user's component and cannot spend the deposit on their own. To perform normal Spark operations, however, the user must interact with them.

When Alice transfers bitcoin to Bob, the on-chain output remains unchanged. Spark modifies the key components off-chain: Bob obtains a new personal component and the operators update their shares so that the overall public key continues to match that of the original output.

The operators must then delete the previous shares, those compatible with Alice's key. The official documentation describes this assumption as “trust at a specific point in time”: if the deletion happens correctly during the transfer, a subsequent compromise of the operators cannot reconstruct the previous state.

The deletion of a piece of data remains impossible to prove cryptographically. Alice and a sufficient number of operators who had retained the old shares could sign a competing spend. Bitcoin Layers considers this eventuality Spark's main finality risk.

The scenario remains theoretical and without documented precedent. It would require a previous owner willing to steal, collusion among the operators and the retention of shares relating to the same state.

Spark often presents its security with the formula “one honest operator is enough”. The published configuration, however, is 2-of-3: two old shares are sufficient to form the collective component of the signature. The third operator can refuse to participate without preventing the other two from proceeding.

How trees and leaves work

The first statechains only allowed an entire UTXO to be transferred off-chain. Spark added the ability to split that value through a hierarchical structure of pre-signed transactions.

The first transaction in the structure, called the root transaction, spends the deposit output. The intermediate transactions spend the outputs of the previous level and split them into smaller amounts. The terminal nodes are called leaves and represent the individual portions of balance controlled by users.

These transactions remain off the blockchain during ordinary operation. The operators store their structure, state and signatures in their own databases. The wallet sums the value of the leaves assigned to the user's identity and displays a single balance.

To make a payment, the wallet selects a combination of leaves that covers the requested amount. When the available denominations cannot make up the figure, the Spark Service Provider - SSP - performs an atomic swap: it receives a group of leaves and returns another group of the same value with different denominations.

Payments sent and received, swaps, renewals and optimizations therefore change the set of leaves owned and their position in the structure. Each leaf has a specific path made up of the root and all the intermediate transactions preceding it.

A seed imported into another wallet recreates the user's identity and keys. The new wallet then queries the operators to learn the leaves assigned to that identity, their state and the transactions preceding them.

The balance recovered via the seed therefore depends on the availability of the Spark databases.

How the unilateral exit really works

When a leaf is created or transferred, the user and operators sign in advance the transactions needed to bring it on-chain as well. The user can publish them in the future without requesting new signatures.

Each new owner receives a transaction with a shorter timelock than the previous owner's. If Alice publishes an old version, Bob has a window during which he can publish his own and enforce the most recent state. The operators keep copies of these transactions and act as watchtowers. Spark acknowledges that failure to intervene within the expected window would allow the previous owner to complete the spend.

The cooperative exit requires the user, the operators and the SSP. The parties sign a new transaction directed to the Bitcoin address chosen by the user. The process produces a single on-chain transaction.

The unilateral exit instead uses the previously signed transactions. The wallet must retrieve the current leaf and all the transactions connecting it to the root. It then publishes them in order, from root to leaf. Each level must confirm before the next can enter the mempool.

The pre-signed transactions have zero fees, because the future cost of block space is unknown. Each contains an ephemeral anchor that allows a second transaction with sufficient fees for both to be added. The mechanism is called CPFP and requires the user to separately own at least one Bitcoin UTXO with which to fund the fees.

After the intermediate transactions confirm, the user must wait for the leaf's timelock to expire, publish the refund transaction and finally spend the relevant output to the desired Bitcoin address.

Blink executed this process with a 100,000 sat wallet on mainnet. The 22 leaves required a total of 253 packages. The first attempt to send them together resulted in 252 being rejected, because the mempool only allowed one unconfirmed level per path.

At 1 sat/vB, 18 leaves containing a total of 9,888 sats had an exit cost higher than their own value. The four economically recoverable ones contained 90,112 sats. The process required dozens of confirmations, timelocks of up to 1,400 blocks and the subsequent publication by a watchtower of already-signed alternative transactions.

The four leaves eventually arrived in outputs controlled by the user's seed without new authorizations from the operators. After the final sweeps, the expected recovery was around 82,000 sats.

The test shows that Spark's unilateral exit works up to a point. It shows, in particular, that it requires up-to-date state, external funds for fees, tools capable of handling package relay, numerous confirmations and timeframes that can exceed a week. Above all, for the smaller leaves it can prove uneconomical.

Why the seed is not enough

Before the test, Blink had prepared a recovery bundle containing all the current leaves, the pre-signed transactions and their ancestors.

The seed allows the cryptographic keys to be derived. The recovery bundle contains the dynamic state needed to establish which signed transactions belong to the user today and in what order they must be published.

A seed created months earlier does not record subsequent transfers, swaps and reorganizations. During a complete operator blackout it can generate the user's keys, while the current leaves and the transactions needed for the exit remain unknown.

The documentation for Breez release 0.22, published on August 13, states this explicitly: the operators must be reachable when the exit is prepared, because the SDK retrieves the pre-signed transactions from them.

Last Thursday Breez merged support into the code for storing the full structure locally, automatically collecting ancestors, exporting the state and building the exit offline. The change has yet to reach a public release and then the wallets using the SDK.

The public code of Blink and Glow uses version 0.22. Primal uses 0.17.1 and Cake 0.14. In these versions the full operator-offline path remains outside the app.

Blitz stores leaves and ancestors in its own database and allows a recovery bundle to be exported. Completing the exit still requires the external tool developed by Blink to prepare fees, build and publish the packages, wait for the timelocks and complete the sweeps.

Wallet of Satoshi is closed source. Its guide states that the seed or the Google Drive backup allow the wallet to be restored on another phone. The restore queries the Spark infrastructure. There is no public procedure for completing it during a total blackout.

An independent review completed in July examined eight consumer wallets without finding a complete implementation of the operator-offline exit inside the applications. Blitz subsequently added the export, while execution remains entrusted to external tools.

Lightspark's operational control

Lightspark runs one of the three operators, is the fixed coordinator to which the SDKs send their main requests and controls the only SSP configured by default. Breez and Flashnet can jointly meet the signing threshold, but applications do not automatically switch to them when the Lightspark coordinator stops responding.

The code is open source and another group can launch its own Spark Entity with different operators. The network used by the most popular wallets nevertheless remains permissioned: the list of operators is written into the SDK configuration and every change must be distributed to the applications.

The code also contains a control called a wallet kill switch. Each operator can use it to block operations that modify the state of a specific identity, while leaving reads available. The wallet receives the same message as for a normal authentication error and therefore cannot distinguish between the two situations.

The public repository documents only the code and there is no evidence of its use against real users. The existence of the control nevertheless shows that the operators have a tool for selectively blocking a wallet.

David Marcus, CEO of Lightspark, previously worked at PayPal, Facebook Messenger and Libra/Diem. In 2019, he defended before the US Congress Facebook's attempt to create a permissioned global monetary network governed by an association of companies. The project was scaled back and eventually abandoned after years of political and regulatory opposition.

Marcus's career provides context. It shows continuity between two goals: building global infrastructure for money and making it simple enough to be integrated into products used by millions of people.

The point is that Bitcoin requires skepticism by default, as events in recent weeks have once again shown: it requires us to evaluate the system under the worst-case scenario, regardless of the intentions of those who build it.

A five-year-old bug caused Coldcard to generate weak seeds. Malice was unnecessary. The lesson from Stop #311 applies to Spark as well: bugs, compromises and political pressure must be treated as conditions anticipated by the design.

Lightspark also sells Grid, global accounts and regulated infrastructure for fiat and stablecoins. Its terms of service provide for KYC and sanctions screening, and allow transactions to be refused, delayed, reversed or frozen. Grid is separate from Spark, and these terms demonstrate only the company's commercial and regulatory orientation.

A hypothetical scenario remains possible. In the future, a regulator could require identification to access the cooperative exit or the operators' APIs. The SSP could enforce it on the cheaper exit and the servers when distributing state. A user with a complete recovery bundle could continue to use the unilateral exit. A user with only the seed would depend on the infrastructure subject to the new rule.

That technical possibility alone is enough to apply the right standard: every wallet must retain and provide the user with all the data needed for the exit before that risk materializes.

The test to demand from Spark wallets is concrete: operators offline, SSP offline, the application still able to build the exit, broadcast it and reach a Bitcoin UTXO using a backup that the user knows must be protected.

Until this test is passed, calling those wallets self-custodial means bowing to Lightspark's marketing.