-
Notifications
You must be signed in to change notification settings - Fork 10
Support output descriptors for wallet analysis (singlesig, multisig, miniscript) #49
Description
Context
Currently the tool accepts xpub, zpub and ypub to analyze wallet privacy. Since we already support extended public keys, the natural next step is supporting output descriptors — the modern, self-describing standard for defining how a wallet derives addresses.
This would also solve the ambiguity described in #48 (xpub not encoding script type), since descriptors explicitly define everything: script type, keys, derivation paths and spending conditions.
What are output descriptors?
Output descriptors (BIP-380 and family) are a standard way to describe exactly how a wallet generates addresses. They encode the full recipe: which keys, which derivation path, which script type, and even complex spending conditions.
Singlesig examples
# Legacy (P2PKH)
pkh([d34db33f/44h/0h/0h]xpub6ERa.../0/*)
# Nested SegWit (P2SH-P2WPKH)
sh(wpkh([d34db33f/49h/0h/0h]xpub6ERa.../0/*))
# Native SegWit (P2WPKH)
wpkh([d34db33f/84h/0h/0h]xpub6ERa.../0/*)
# Taproot (P2TR)
tr([d34db33f/86h/0h/0h]xpub6ERa.../0/*)
Note how the descriptor makes the script type explicit — no more guessing if an xpub is Legacy or SegWit.
Multisig examples
# 2-of-3 Native SegWit multisig
wsh(sortedmulti(2,[aabbccdd/48h/0h/0h/2h]xpub6A.../0/*,[11223344/48h/0h/0h/2h]xpub6B.../0/*,[55667788/48h/0h/0h/2h]xpub6C.../0/*))
# 2-of-3 Nested SegWit multisig
sh(wsh(sortedmulti(2,[aabbccdd/48h/0h/0h/1h]xpub6A.../0/*,[11223344/48h/0h/0h/1h]xpub6B.../0/*,[55667788/48h/0h/0h/1h]xpub6C.../0/*)))
Miniscript examples
# Vault: spend immediately with 2-of-3, or after 90 days with 1 recovery key
wsh(or_d(multi(2,xpubA,xpubB,xpubC),and_v(v:pkh(xpubRecovery),older(12960))))
# Inheritance: owner can spend anytime, heir can spend after 1 year
wsh(or_d(pk(xpubOwner),and_v(v:pk(xpubHeir),older(52560))))
Why this matters for privacy analysis
-
Singlesig: Eliminates the xpub/zpub ambiguity entirely. The descriptor tells the tool exactly which addresses to derive — no guessing.
-
Multisig: Currently there's no way to analyze multisig wallet privacy. Multisig users have specific privacy considerations:
- All cosigner xpubs are embedded in the redeem script, potentially linking participants
- P2SH/P2WSH multisig scripts are visible on-chain when spent, revealing the m-of-n structure
- Multisig transactions have a distinct fingerprint compared to singlesig
-
Miniscript: Complex spending policies (timelocks, vaults, inheritance) create unique on-chain fingerprints that can be detected and analyzed. Users with these setups would benefit from knowing how their spending conditions affect their privacy.
What wallets export descriptors?
Most modern wallets already export descriptors:
- Bitcoin Core — native descriptor wallet since v0.21
- Sparrow — Settings > Script Type > copy descriptor
- Nunchuk — exports descriptors for multisig
- Liana — miniscript-native, exports descriptors
- Electrum — supports descriptor export
- Coldcard — exports descriptors via MicroSD
Proposed implementation
Input: Accept a descriptor string in the wallet analysis input field. Detect descriptor format by looking for known prefixes: pkh(, wpkh(, sh(, wsh(, tr(, sortedmulti(, etc.
Derivation: Parse the descriptor, derive the corresponding addresses (both receive and change paths: /0/* and /1/*), and run the existing privacy analysis on the discovered transactions.
Additional findings for multisig/miniscript:
- Flag the m-of-n structure visibility when spent
- Detect if the multisig script reveals cosigner count on-chain
- Identify unique spending policy fingerprints (timelocks, hash locks)
- Warn about address reuse across different cosigner combinations
Priority
This could be implemented incrementally:
- Phase 1: Singlesig descriptors (solves xpub input should ask for address type (Legacy/SegWit/Taproot) to avoid wrong derivation #48 completely)
- Phase 2: Multisig descriptors
- Phase 3: Miniscript descriptors