Note
A Seed Phrase Is Not a Wallet Definition: BIP 380 Output Descriptors
A mnemonic backs up entropy, not wallet definition. BIP 380 output descriptors name scripts, keys, paths, and checksums so watch-only and air-gapped sides agree on the same address set.
2026-10-09 · self-custody, bip-380, output-descriptors, bitcoin, wallet-backup, watch-only, air-gapped, protocol, descriptors

A Seed Phrase Is Not a Wallet Definition: BIP 380 Output Descriptors
A mnemonic backup answers one question well: which entropy can regenerate a tree of private keys. It does not answer the next questions that decide whether you can find or spend coins after you leave a single-key default: which scripts those keys wrap, which BIP 32 paths produce receive versus change, which cosigners belong in a threshold, and which address forms a restored wallet must watch. SegWit and Taproot made the gap concrete — given only private keys, restored wallets cannot reliably know which output scripts to produce. That mismatch is how “I have the words” turns into “I cannot see the coins.”
BIP 380 — Output Script Descriptors General Operation — is the machine-readable answer. A descriptor is an engineer-readable string that names the script template, the keys (or extended keys), the derivation steps, and optionally an error-correcting checksum. Export it beside the mnemonic and you back up policy, not only entropy. Import it into a watch-only wallet or an air-gapped signer and both sides agree on the same address set — without guessing which BIP 44 / 49 / 84 / 86 path a vendor preferred.
This note is educational protocol literacy. It sits beside — and does not rewrite — verify-before-trust and PSBT air-gapped signing. Verification catches a hostile binary; PSBT keeps signing offline; descriptors tell both sides which scripts they mean.
What a descriptor actually is
BIP 380 defines descriptors as nested script expressions and key expressions. The top level is a SCRIPT, optionally followed by #CHECKSUM — eight alphanumeric characters from the bech32 alphabet. Checksums are optional for parsing, but serious tooling rejects descriptors that lack one: Bitcoin Core’s deriveaddresses and importdescriptors require them; getdescriptorinfo computes the checksum for a bare string.
Script expressions look like functions — identifier plus parentheses. Common forms:
pk(KEY)/pkh(KEY)— P2PK / P2PKH (BIP 381)sh(SCRIPT)— P2SH wrap (BIP 381)wpkh(KEY)/wsh(SCRIPT)— native P2WPKH / P2WSH (BIP 382)multi(k,…)/sortedmulti(k,…)— threshold multisig; sorted keys for order-independence (BIP 383)tr(KEY)/tr(KEY, TREE)— P2TR key path, optionally with a script tree (BIP 386)
Nesting is intentional: sh(wpkh(KEY)) is nested SegWit; wsh(sortedmulti(2,KEY1,KEY2,KEY3)) is native SegWit 2-of-3; tr(KEY) is Taproot key-path. Script type is explicit — not inferred from a version byte bolted onto an xpub.
Key expressions fill those templates: a hex pubkey, a WIF private key, or a BIP 32 xpub / xprv, optionally prefixed with origin info [fingerprint/path] and trailed by /NUM or /NUMh steps. A final /* or /*h ranges over child indices so one string describes a whole receive or change chain. Hardened steps after an xpub need the private key — so watch-only exports normally stop at the last hardened step and push that path into the origin brackets.
A typical shape (illustrative, not live material):
wpkh([deadbeef/84h/0h/0h]xpub…/0/*)#checksum8
That string says: native SegWit v0 key-hash outputs; xpub origin fingerprint deadbeef at 84h/0h/0h; unhardened /0/* for the receive range; and an eight-character checksum so a wrong character fails closed. Change is usually a sibling with /1/*, or — under BIP 389 multipath — /<0;1>/* expanding into both.
Why the mnemonic alone is incomplete
BIP 380’s motivation is blunt. Traditional backups stored keys; after SegWit, the same keys can map to several standard scriptPubKey forms. BIPs 44, 49, and 84 standardised some paths, but not every wallet used them, and path data was rarely in the backup. Version bytes on extended keys tried to encode script type inside key serialisation — a layer violation BIP 380 rejects. Descriptors separate key derivation from script meaning so both travel as data.
That incompleteness shows up in three practical failures:
- Restore mismatch — App A watches
wpkh(…/84h/…); App B defaults to legacypkh(…/44h/…). Same words, empty balance view. - Watch-only without policy — An xpub without script and path context is under-specified; the watcher invents addresses the signer never intended.
- Multisig without a shared template — Cosigners who disagree on
multiversussortedmulti, or on receive/change branches, produce incompatible address sets. BIP 388 wallet policies compact this for hardware registration, but they compile to descriptors; they do not replace an explicit script.
Literacy here is not “memorise more BIP numbers.” It is: can you export the descriptor string(s) your wallet uses, verify the checksum, and import the same string into a second implementation you control?
Watch-only, air gaps, and the same string
A watch-only online wallet and an offline signer must agree on outputs before a PSBT is honest. Descriptors are that agreement. The online side imports a public descriptor (xpub, no private material), derives addresses, builds a funded PSBT, and embeds BIP 32 paths and scripts the signer needs. The offline side uses the matching descriptor (or BIP 388 policy registered from it) to recognise change, verify destinations against its own derivation, and refuse scripts it never approved.
Bitcoin Core has spoken this language since 0.17. Descriptor wallets store descriptors internally. Useful RPCs for literacy (not a setup tutorial): getdescriptorinfo returns canonical public form, checksum, and whether the string is ranged / solvable / contains private keys; listdescriptors shows what the wallet holds; importdescriptors / deriveaddresses import and expand ranged strings (checksum required on input).
Hardware-oriented flows often register a BIP 388 wallet policy (compact template plus key-info vector) so a limited-screen device can review an account once, then treat later spends as instances of that policy. The hinge is the same: seed alone is not the account definition; policy is.
None of this replaces verify-before-trust — a phishing-sourced descriptor is still hostile policy — or PSBT separation. Descriptors tell both sides what to watch and sign; PSBT carries this spend across the air gap.
What descriptors are not
Descriptors are not a privacy layer: publishing one (or an xpub inside it) reveals the address cluster a watcher can enumerate. They are not a substitute for seed hygiene, passphrase discipline, or multisig operational security. They are not Miniscript’s higher-level “policy” language (different word, different BIP family), though Miniscript fragments can appear inside wsh / tr. They are not product rankings — verify checksums and cross-check derived addresses across two independent tools when stakes are high.
The stakes are practical. When you may need to restore on unfamiliar hardware, hand a watch-only view to an auditor without signing keys, or keep an air-gapped signer honest against a compromised host, a portable, checkable string matters more than any one app. The string is the contract.
What this is not
This note is not a wallet shopping guide, brand ranking, or vendor setup walkthrough. No prices, yields, swaps, “where to buy,” personalised custody advice, recovery services, or trading signals. Descriptors do not make backups foolproof — wrong path, missing change descriptor, or a typo past a missing checksum still loses funds. It does not teach evasion of lawful process.
Educational takeaway: self-custody that backs up only twelve or twenty-four words is backing up entropy, not wallet definition. BIP 380 descriptors — with explicit script expressions, key origins, ranges, and checksums — are the portable description of how keys become spendable scripts. Learn to export, verify, and import them. That literacy travels between apps; slogans do not.
Related on CryptoDecentral
- Self-custody & wallets pillar
- Self-Custody Without Verify-Before-Trust Is a Slogan
- PSBT and Air-Gapped Signing: Keep Keys Offline While the Network Watches
Further reading (primary)
Sources
- https://raw.githubusercontent.com/bitcoin/bips/master/bip-0380.mediawiki
- https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki
- https://raw.githubusercontent.com/bitcoin/bips/master/bip-0381.mediawiki
- https://raw.githubusercontent.com/bitcoin/bips/master/bip-0382.mediawiki
- https://raw.githubusercontent.com/bitcoin/bips/master/bip-0383.mediawiki
- https://raw.githubusercontent.com/bitcoin/bips/master/bip-0386.mediawiki
- https://raw.githubusercontent.com/bitcoin/bips/master/bip-0388.mediawiki
- https://raw.githubusercontent.com/bitcoin/bitcoin/master/doc/descriptors.md
- https://bitcoincore.org/en/doc/31.0.0/rpc/util/getdescriptorinfo/
- https://bitcoincore.org/en/doc/30.0.0/rpc/wallet/listdescriptors/