Multisig
Hand this device's key to the coordinator, then agree to the quorum that comes back.
Agreeing is the dangerous part. A descriptor with your key quietly swapped out makes a wallet that accepts deposits and can never be spent from, and every later screen looks normal. The device refuses a descriptor it holds no key in. Other cosigners' fingerprints are labelled unverified: they are four bytes chosen by whoever wrote the descriptor.
- Quorum addresses is read across devices. Two devices showing the same address at the same index is the cheap proof they registered the same descriptor. If they differ, do not send anything.
- Quorums lists each quorum this device cosigns, with your position, the checksum to compare across devices, and each cosigner by the name you gave it.
Forgetting a quorum there means typing its checksum. It loses no money, since a registration is not a key, but that quorum's change then reads as a payment to a stranger on the signing screen until you register the descriptor again, so keep it. Forgetting lasts for the session only and asks for no passphrase, so a quorum saved with the wallet returns at the next unlock, as the list says.
It ends by saying what the device cannot tell you: whether the other cosigners registered the same descriptor, and whether your coordinator imported it. An unfinished quorum receives money like a finished one, so confirm both yourself.
Which quorums this device handles
- It builds
wsh(sortedmulti(...)), native segwit, which is what Build a quorum produces. - It accepts a taproot quorum,
tr(NUMS, sortedmulti_a(...)), from a coordinator. Registering, deriving addresses, recognising change and signing the script path all work, and the recovery drill proves it against a real Bitcoin Core: identical addresses, one signature that does not finalise, two devices that do. - It does not build taproot quorums: your coordinator writes that descriptor and every device registers it.
Setting up a quorum
Guide me walks you through this as "Set up a wallet across devices" and ends by listing what it has not finished. The procedure:
-
On each device, create or import a wallet. Name them to tell apart on sight:
Cosigner A,Cosigner B,Cosigner C. Write each mnemonic down separately: three devices, three backups. -
On each device, export its multisig key, the BIP-48 account xpub. It is a different branch from the single-signature one, so using a seed alone and in a quorum does not link the two on chain.
-
Assemble the descriptor. Building is not registering: the result still goes through the review in step 4.
- On a device, with no other computer: Multisig, then I have the other keys, build it here. Collect the other keys by camera or paste and choose the threshold; the device adds its own. Order does not matter: the same keys give a byte-identical descriptor, so the checksum in step 5 differs only when the KEYS differ.
- With a coordinator: any software that speaks descriptors. The device
also reads Coldcard setup files (including Electrum's, with a Derivation
line per cosigner), BSMS round-two files, Specter Desktop JSON (which
Sparrow also writes), Bitcoin Core's
listdescriptorsoutput andimportdescriptorsarrays, and one-descriptor-per-line files such as Jade's and Keystone's exports and Sparrow's Output Descriptor export. All but Sparrow's descriptor export are tested against real files from the other program, kept in spec/interop. Caravan and Electrum wallet files are refused: neither holds a descriptor. Choose this when other cosigners are other vendors' hardware, or you want a watching wallet anyway.
-
Register the descriptor on every device. People skip this step. It is how a device knows which outputs are change: without it, an attacker's address in the change position is indistinguishable from money coming back to you. A quorum this device holds no key in is refused.
With a saved wallet open, tap Agree to it after the review and type the wallet's passphrase. The quorum is sealed into the wallet file and survives locking. A wrong passphrase is refused, registers nothing, and does not count toward the attempts that erase the wallet. An unsaved wallet has nowhere to store the quorum, so it lasts until the device locks; the review says so, and the finished screen says which happened.
-
Compare the checksum on all three screens: the eight characters after the
#, covering the whole descriptor. If they differ, one device has a different wallet, and the addresses will differ in ways nothing else on screen reveals.
Spending
A PSBT walks from device to device; they never need to be in one room.
- A coordinator builds an unsigned PSBT.
- Device A reviews and signs. It shows the signatures present and needed, and whether its signature was the last; for a 2-of-3 it says the transaction is not finished.
- The partly-signed PSBT goes to device B, by QR.
- Device B's review shows one signature already present, so you know before signing whether you are the last cosigner.
- Device B signs, adding to A's signature rather than replacing it. The screen says the transaction is complete and offers the finished raw transaction as well as the PSBT.
- Broadcast it with whatever you use for that.
A third signature is unnecessary but harmless: the transaction stays valid, and the device says so.
What each screen tells you, and why it matters
Believing you are finished when you are not is the costly mistake, so a requirement the device cannot read is reported as unknown and unmet, never assumed satisfied.
Knowing which device to walk to next
After signing, the device names the cosigners still needed, by the names you gave them. It traces each signature to a master fingerprint through the transaction's derivation records and matches it against your registered descriptor.
A fingerprint is four bytes and is not proof. It is the start of a public key hash, written by whoever assembled the descriptor, and two keys can collide in it: enough to tell three devices apart, not to identify a key. This device's own position comes from re-deriving its key, and is proof.
The names decide nothing: completion is decided by counting signatures against the script's threshold. An untraceable signature is reported separately, not counted. That is expected for a taproot key-path signature, which names no key; anywhere else, ask who made it. A device that has not registered the quorum says it cannot tell, rather than showing an empty list.
Receiving to the quorum, not to one device
With a registered quorum, "what is my address" has two answers, and they are not interchangeable. The quorum's address needs your threshold of devices to spend; this device's own address needs only this device. Both are ordinary bech32 strings and look alike.
So Receive asks which you want, defaulting to the quorum. You can pick this device alone; the screen then says one key, not the quorum, would protect the money. The quorums offered are the open wallet's own, read each time a wallet opens, and until that list is read Receive shows no address. Money sent to the single-signature address is not lost (this device can spend it, and your mnemonic recovers it), but one key protects it instead of two.
Check the address against the thing that produced it. A quorum address is re-derived from the registered descriptor. It does not derive from one device's keys, so checking it that way answers no about a correct address.
Back up the descriptor, not just the words
Your mnemonics are not enough to rebuild a quorum. Even with all three seed phrases of a 2-of-3, you also need the other keys, how many must sign, and the script type, which no seed phrase records. The descriptor does.
It is under Export on a wallet screen, labelled as the thing to keep, above the single-signature descriptor, which covers only this device's key and does not back up the quorum. Keep it with the words. It is not a secret: it holds no private key and cannot spend.
Telling the devices apart
Three devices in one 2-of-3 hold different seeds for the same funds, but before unlock they show only the wallet name and colour you chose, which may be the same on all three. What distinguishes them:
- A device name, set from the wallet picker or More then Name this device. It is in the header of every screen, the lock screen included, so you see it before any passphrase. It is not verified and never will be: it sits in a plain file beside the wallets, editable by anyone holding the card, and nothing decides anything from it. It is not a "profile": each wallet stays sealed under its own passphrase.
- The cosigner number on the wallet screen once a quorum is registered:
2 of 3, you are cosigner 2. It is recomputed from the seed each time, not stored; a device that cannot place itself in a registered quorum says so. It works only inside a quorum: a device with no registrations is anonymous, and one in two quorums has two positions. - The wallet name you chose, which is per-device and should differ:
Cosigner A, notFamily Vaulton all three. - The fingerprint after unlock, derived from the loaded keys: the one value that editing a file cannot fake.
- A physical label on the case. The device cannot help here; a sticker can.
Name the other cosigners too, with the Name it button beside each key on the quorum review screen: "the attic Pi", "Dad's Coldcard". A name confirmed with the wallet's passphrase is sealed with the wallet; without it, the name is held for the session only and gone at the next lock. The screen says which. Names are yours, never checked, and say nothing about who controls a key. This device gets no nickname: re-deriving its key identifies it. Names are sealed rather than kept beside the file, because a plaintext list would tell someone holding the card who your cosigners are.
What the devices do NOT do for each other
- They do not attest to each other. Device A cannot tell you device B runs verified code. Each shows its own manifest root hash at unlock; comparing them is up to you. There is no protocol for this and no plan for one.
- They do not share a passphrase or a store. Each encrypts its own wallet under its own passphrase, so one compromised passphrase does not expose the others, at the intended cost of three passphrases to remember.
- They do not agree on labels. Labels are per-device until you move a BIP-329 file between them. Nothing synchronises.
- They do not know how many cosigners are on nullroute. The descriptor names keys, not devices.
Known gaps
- Multi-wallet PSBTs are not supported. One PSBT is signed against one open wallet; inputs from two wallets on one device is phase 7.
- Batch signing is not supported. Signing several individually reviewed PSBTs in one go is phase 7.
- PSBT version 2 is refused. The device reads version 0 (BIP-174) only and says so when handed version 2 (BIP-370). Export it again as version 0.
- Taproot multisig can be registered and its addresses derived, but a message
cannot be signed for any multisig address. That needs BIP-322's full
variant, which the device refuses by name; single-key addresses, taproot
included, sign messages. See
docs/THREAT-MODEL.mdfor the full list of what is and is not built. - A BSMS file's first address is checked, and a wrong one refuses the file. This device derives the first address from the first path restriction and refuses the file, naming both, if it differs from the one the coordinator wrote (BIP-129). The import screen then shows the address as this device's own: confirm with the other signers that every device shows the same one. A file with no first address is read; confirm instead the first receive address shown once the quorum is registered.
- A descriptor is read exactly as written. Sparrow reads
multi()assortedmulti(), and an extended key with no/0/*after it as a whole account. This device does neither, so an old Specter export relying on either derives different addresses here than in Sparrow. Compare a first address on both before sending to a quorum. - There is no device-to-device transport. Everything goes through a coordinator, a card you carry, or a camera: a deliberate consequence of the air gap.
Rendered from docs/USING.md, the same bytes that ship with the code. SHA-256 b735aa55a6ae5cc7682c2b90fe2c551b3a396a02240f45936d50e6540d65a989