Recently, Wallet of Satoshi announced they were releasing a self-custodial wallet. And then yesterday, Lightspark announced WoS would be launching on Spark.
I didn't really know much about Spark, so I thought a brief explainer would be nice.
Spark is a statechain
So, you start by deciding to deposit onchain funds into a Spark Entity. This is a statechain. A statechain is a way of sharing utxos.
If there was a single 1btc utxo and you and 9 other people all had a presigned transaction that sent a portion of the 1 btc to your personal address, you could say you were sharing the utxo. But that isn't very useful.
If, however, you could safely change the amounts on your pre-signed transactions so that it changed the relative portions owned by each person, you could transfer bitcoin from one person's ownership to another's without changing anything onchain. This is what statechains do: with the help of a coordinator or group of coordinator's they distribute pre-signed exit transactions updated to reflect any transfers of bitcoin between the people using the Spark.
Before you deposit, you have to work with the operators of the Spark Entity (there are currently only two) to create an aggregated public key. You and however many operators are in the Spark Entity create this public key using a version of FROST.
This public key is used to create a taproot deposit address, which will receive your deposit into the statechain.1
Before you send funds to this address, you and the operators in the Spark Entity collaboratively sign two transactions that together serve as your unilateral exit to the chain.
You hopefully will not have to broadcast these pre-signed transactions, but they are your security assurance: if you feel people are cheating you, you broadcast and get your money back.
Once both these transactions are signed by you and the Spark operators, you can deposit funds to your deposit address.
Transferring funds via Spark
Transfer of funds in Spark (and other statechains) is achieved by tweaking the Spark Entity's key and signing a new exit transaction for the receiver of the funds.
The sender of funds on Spark could still try to broadcast their old presigned transaction, but it includes a timelock that is designed to be slightly longer than a timelock on your presigned transaction -- so you have an opportunity to publish your exit transaction before them.
However, if all the Spark operators fail to delete the old key they were using, the user who sent you funds could ask them to participate in signing a new exit transaction which includes the funds supposedly received by you.
So you have to trust the Spark operators to delete their keys -- which is what they say they will do.
From the Spark "Trust Model" page:
If an operator follows this protocol, the transferred funds are secure, even against future coercion or hacking. Spark strengthens this model by using multiple operators, ensuring that as long as one (or the required threshold) deletes their key, users remain secure and have perfect forward security. (emphasis added)
This is trust assumption no. 1 in Spark: operators must delete old keys.
Why people might use something like Spark
Spark allows users to send funds to each other by changing their respective share of ownership of a single utxo without changing the onchain spending conditions of the utxo.
So 4 people could send funds back and forth between each other without ever needing to publish a transaction onchain (as long as the Spark operators are doing what they say and deleting old tweaked keys with every transfer).
This is pretty cool because transfers can be instant and low fee, and you could have a whole lot of people sharing one single utxo.
"No, the new Wallet of Satoshi is not 'self-custodial'"
@bluematt posted a very helpful clarification about what self-custody is and what it is not.
Spark is, of course, much better than a classic custodial wallet - it allows for unilateral exit if the operator shuts down and deletes their keys (once they finish implementing it) - but it still requires fully trusting the operator. If the operator changes the code running on their server and swap coins with folks, they can steal coins going forward.
I've already discussed the first trust assumption (operator must delete their key), but bluematt's second point is also important: you don't know what kind of code the Spark operators are running.
I suppose there is a world where if the wallet app you are using is open source and if you trust that a lot of people are reviewing the code on it, it could make sure that the cryptography the operators are using is real and correct -- although perhaps I am wrong. I'm not a cryptographer.
While Spark says they are open source, I couldn't find out if Wallet of Satoshi is. So as far as I can tell, running WoS, you don't have any assurances that your Spark operators are running the code they say they are.
So trust assumption no. 2 is that you trust Wallet of Satoshi because you don't have anyway of seeing what the Spark operator's are doing.
It's fair to question whether this counts as self-custody (in the same way it's fair to question whether ecash is self custody2). I think it is better than custodial WoS. But it's probably not great to call it a self-custodial bitcoin wallet.
Want to learn more about statechains?
Shinobi recently wrote an article about statechains for Bitcoin Magazine, but I didn't find it too helpful in understanding what is going on here.
But Shinobi also has an older article about Mercury Layer that I found a little better (even though it's solely focused on Mercury's version of statechains).
The Mercury Layer AMA from 2024 was somewhat helpful, particularly @tptrevethan's response here.
<insert project getting hyped on the tweeter>