bitcoin-wallets-hd

v2026.09.24

HD wallet implementation: BIP32 derivation, BIP39 mnemonic seed (with passphrase), BIP44/49/84/86 derivation paths, account structure, gap limit, watch-only via xpub, BIP352 silent payment scan/spend derivation and BIP392 sp() descriptors. USE WHEN: building/restoring an HD wallet, choosing derivation paths, debugging address generation, importing mnemonics.

GitHub
安装命令
npx skhub add claude-dev-suite/bitcoin-wallets-hd
Markdown
SKILL.md

HD Wallets

The standard architecture for Bitcoin wallets since 2014. One mnemonic

  • optional passphrase generates an unlimited tree of addresses.

Mnemonic seed (BIP39)

1. Generate 128/160/192/224/256 bits of entropy.
2. Append checksum: first ENT/32 bits of SHA256(entropy).
3. Split into 11-bit groups → indices into BIP39 wordlist.
4. Word count: 12 (128-bit), 15, 18, 21, 24 (256-bit).

Recommended: 12 words for general use, 24 words for high-value.

Passphrase

PBKDF2(password=mnemonic, salt="mnemonic" || passphrase,
       iter=2048, hash=SHA512, len=64) → 64-byte seed

Without passphrase, salt is just "mnemonic". The passphrase generates a completely different seed — even one character difference = different wallet.

Critical: passphrase has no on-chain or wallet-level marker. Lose it = funds gone. Recover only if you remember exact passphrase.

BIP32 master key

HMAC-SHA512(key="Bitcoin seed", msg=seed) → 64 bytes
  Left 32  → master private key
  Right 32 → master chain code

See ../../cryptography/bip32/SKILL.md.

Standard derivation paths

BIPPathOutputAddress prefix
BIP44m/44'/0'/account'/change/indexP2PKH1...
BIP49m/49'/0'/account'/change/indexP2SH-P2WPKH3...
BIP84m/84'/0'/account'/change/indexP2WPKHbc1q...
BIP86m/86'/0'/account'/change/indexP2TRbc1p...
BIP48m/48'/0'/account'/script_type'/change/indexmultisigbc1q.../bc1p...
BIP352m/352'/0'/account'/{0',1'}/0P2TR (silent payment)sp1q...

BIP352 is the odd one out: it derives two hardened branches (1' scan, 0' spend) instead of a change/index leaf, and sp1q... is a static address string, not an output script. See below.

Coin types: 0 = mainnet, 1 = testnet, 1776 = Liquid.

change=0 for receive, change=1 for change.

account' is hardened — separates wallets logically. account=0 for primary.

Gap limit

When recovering from mnemonic, scan addresses sequentially until you hit N consecutive empty addresses. Default N=20. Some wallets use 1000 for paranoid recovery.

Account structure

Modern wallets use descriptors for the watch-only metadata:

wpkh([d34db33f/84h/0h/0h]xpub.../<0;1>/*)#chk

This single descriptor produces:

  • Receive: wpkh(.../<0;1>/0), wpkh(.../<0;1>/1), ...
  • Change: wpkh(.../<0;1>/0) with index 1 instead of 0.

Or two separate descriptors with ;0/* and ;1/*.

Silent payments (BIP352 / BIP392)

Silent payments live in their own purpose tree. Two hardened branches, not one account xpub:

scan_private_key:  m/352'/coin_type'/account'/1'/0
spend_private_key: m/352'/coin_type'/account'/0'/0

BIP352 requires hardened derivation for both: that is what makes it safe to hand the scan private key to a scanning service without exposing the master key or the spend key. The address is bech32m with HRP sp (sp1q..., 116 chars on mainnet) or tsp on test networks, and never appears on-chain — the outputs paid to it are ordinary BIP341 P2TR.

BIP392 (Draft; merged to the BIPs repo 2026-03-05, authored by Sparrow's Craig Raw) puts this key material on the normal descriptor backup path with a new top-level sp() expression:

sp([d34db33f/352h/0h/0h]spscan1q...)   # watch-only: scan privkey + spend pubkey
sp([d34db33f/352h/0h/0h]spspend1q...)  # full wallet: both private keys
sp(<WIF or xprv scan key>,<BIP380 spend key>)  # two-key form
  • spscan and spspend are new bech32m key expressions (HRPs spscan / spspend, tspscan / tspspend on testnets), data part q for silent payments v0 followed by ser256(b_scan) || serP(B_spend) and ser256(b_scan) || ser256(b_spend) respectively.
  • sp() is top level only — sh(sp(...)) and wsh(sp(...)) are invalid.
  • Key origin on the single-key form points at the depth the two child paths (1h/0 scan, 0h/0 spend) are derived from.
  • In the two-key form the scan key must be private (scanning needs it); the spend key may be any BIP380 key expression resolving to a single key, including musig() from BIP390.
  • Uncompressed keys are rejected anywhere under sp() — BIP352 permits only compressed pubkeys.

Status as of September 2026: BIP392 is still Draft, with reference implementation and test vectors both marked TBD. Sparrow ships the protocol itself — sending in 2.3.0 (October 2025), BIP375 PSBT fields and DLEQ proof verification for hardware signers in 2.4.0 (February 2026), receiving wallets in 2.5.0 (May 2026). Bitcoin Core has no sp() descriptor: libsecp256k1 0.8.0 (August 2026) added an optional silentpayments module, but the wallet-level PRs (#35301, #35302, #32966) were all still open as of September 2026.

Multi-account wallets

Most users have one account. Multi-account wallets:

  • Each account has its own xpub.
  • Wallet UI lets user switch.
  • Useful for bookkeeping (personal vs business) or privacy (no chain-analysis link between accounts).

Watch-only via xpub

Export the account-level xpub (e.g., m/84'/0'/0'):

account_xpub = xpub6CV2... (with [d34db33f/84h/0h/0h] origin)

Import to a wallet that knows derivation paths but never holds the seed:

bitcoin-cli importdescriptors '[
  {"desc":"wpkh([d34db33f/84h/0h/0h]xpub6CV2.../<0;1>/*)#chk",
   "active":true,"range":[0,999],"timestamp":"now"}
]'

This wallet can:

  • Generate addresses, watch incoming.
  • Build PSBT for spending (Updater role).
  • Send PSBT to a hot/cold signer. Never sees private keys, can't accidentally sign.

Common bugs and pitfalls

  • BIP39 wordlist confusion — most wallets use English; some support multiple. The wordlist used must match the passphrase derivation salt language too.
  • Wrong derivation path — Ledger defaults to BIP44 even for segwit accounts; force BIP84/BIP86 explicitly.
  • Reusing the same seed across BIP44/49/84 — privacy bleed. Different addresses but observers can correlate via xpubs.
  • No passphrase backup — passphrase loss = funds lost.
  • Truncated entropy — using Math.random() or time-based RNG for entropy → catastrophic.
  • Address reuse — same address used multiple times: privacy loss + exposes the public key after first spend.

Compatibility matrix

WalletBIP44BIP49BIP84BIP86Multisig (BIP48)
Bitcoin Core (descriptor)yesyesyesyesyes
Sparrowyesyesyesyesyes
Specteryesyesyesyesyes
Electrumyesyesyespartialyes
BlueWalletyesyesyesyesyes
Trezor (Suite)yesyesyesyesyes
Ledger (Live)yesyesyesyesmanual
Coldcard (Mk4 / Q)yesyesyesyesyes

Silent payments (BIP352) are a separate tree rather than a column here, and support is uneven — check per wallet. Two fixed points as of September 2026: Sparrow does SP send and receive (2.5.x), Bitcoin Core implements neither the BIP392 sp() descriptor nor wallet-level silent payments.

See also

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

MIT

源路径

skills/bitcoin/wallets/hd

默认分支

main

最新提交

9496306

Tree SHA

fe4e2f1