pk(KEY)BIP381 · DeployedProducesP2PK — <KEY> OP_CHECKSIG
Takes a single key expression and produces a pay-to-pubkey output script.
NestingAny context: top level, inside sh() or wsh(), and the original script expression allowed inside tr() TREEs.
Descriptors are how modern Bitcoin wallets describe themselves: a compact text expression that names the exact script type, keys and derivation a wallet watches. They are also the piece most backups are missing. This reference covers every descriptor expression standardized in BIP-380 through BIP-392 — what each produces, where it may nest, and how mature its BIP is — plus the checksum and key-expression grammar underneath them all. It slots into our self-custody set beside the wallet recovery matrix and the address-types reference.
Quick answer
An output script descriptor is the modern, standardized way to tell Bitcoin software exactly which outputs a wallet can see and spend — a small text function like wpkh(xpub.../0/*) that replaces the old guesswork about script types. This reference covers every expression defined across BIP-380 through BIP-392 (17 entries): the output script each produces, its nesting rules, the defining BIP and that BIP's status — from the universally deployed pk()/wpkh()/tr() to the draft musig() (MuSig2) and sp() (silent payments) expressions. rawtr() is included and flagged for what it is: a Bitcoin Core extension no BIP defines.
The quick test: if your wallet backup does not contain its descriptors (or the information to reconstruct them), it is incomplete — a seed alone does not tell restoring software which scripts to look for. Export descriptors alongside the seed. Free CSV/JSON under CC BY 4.0; BIP statuses as of 2026-07-26.
Download CSV Download JSON REST API →
pk(KEY)BIP381 · DeployedProducesP2PK — <KEY> OP_CHECKSIG
Takes a single key expression and produces a pay-to-pubkey output script.
NestingAny context: top level, inside sh() or wsh(), and the original script expression allowed inside tr() TREEs.
pkh(KEY)BIP381 · DeployedProducesP2PKH — OP_DUP OP_HASH160 <KEY_hash160> OP_EQUALVERIFY OP_CHECKSIG
Takes a single key expression and produces a pay-to-pubkey-hash output script.
NestingTop level, or inside sh() or wsh(). Not allowed inside tr() trees.
sh(SCRIPT)BIP381 · DeployedProducesP2SH — OP_HASH160 <SCRIPT_hash160> OP_EQUAL
Takes a script expression and produces a P2SH output script; its argument's output script is the redeemScript needed to spend.
NestingTop level ONLY.
wpkh(KEY)BIP382 · DeployedProducesP2WPKH — OP_0 <KEY_hash160>
Takes a single key expression and produces a P2WPKH output script. Only compressed public keys are allowed.
NestingTop level, or inside sh() (P2SH-P2WPKH). Not allowed inside wsh().
wsh(SCRIPT)BIP382 · DeployedProducesP2WSH — OP_0 <SCRIPT_sha256>
Takes a script expression and produces a P2WSH output script; its argument's output script is the witnessScript. All keys under it must be compressed.
NestingTop level, or inside sh() (P2SH-P2WSH). Cannot nest inside another wsh().
multi(k,KEY_1,...,KEY_n)BIP383 · DeployedProducesMultisig — k KEY_1 ... KEY_n n OP_CHECKMULTISIG
Threshold multisig: k of n keys must sign, keys in the order given. Extended keys derive in lockstep (same child index).
NestingTop level (max 3 keys), inside sh() (max 15 compressed keys), or inside wsh() (max 20 keys).
sortedmulti(k,KEY_1,...,KEY_n)BIP383 · DeployedProducesSame multisig template as multi()
Identical to multi() except public keys are sorted lexicographically before script creation (after derivation).
NestingSame as multi(): top level, inside sh(), or inside wsh().
combo(KEY)BIP384 · DeployedProduces2 or 4 scripts: P2PK + P2PKH always; plus P2WPKH + P2SH-P2WPKH if the key is compressed
Compatibility descriptor producing every script traditionally generated by key-based wallets for one key.
NestingTop level ONLY.
raw(HEX)BIP385 · DeployedProducesThe literal script encoded by HEX
Encapsulates an arbitrary raw output script, given as hex, as a descriptor.
NestingTop level ONLY.
addr(ADDR)BIP385 · DeployedProducesThe output script produced by the address ADDR
Encapsulates any Bitcoin address as a descriptor.
NestingTop level ONLY.
tr(KEY) / tr(KEY,TREE)BIP386 · DeployedProducesP2TR — OP_1 <32_byte_output_key>
Produces a taproot output. tr(KEY) uses KEY as the BIP-341 internal key with an unspendable script path; tr(KEY,TREE) additionally commits to a taproot script tree whose merkle root tweaks the internal key. All keys must produce x-only keys; uncompressed keys are forbidden.
NestingTop level ONLY. TREE is either an allowed script expression or {TREE,TREE} pairs.
multi_a(k,KEY_1,...,KEY_n)BIP387 · DeployedProducesTapscript multisig — KEY_1 OP_CHECKSIG KEY_2 OP_CHECKSIGADD ... k OP_NUMEQUAL
Threshold multisig for tapscript using OP_CHECKSIGADD. Max 999 keys; extended keys derive in lockstep.
NestingONLY inside a tr() descriptor; invalid at top level, in sh(), or in wsh().
sortedmulti_a(k,KEY_1,...,KEY_n)BIP387 · DeployedProducesSame tapscript multisig template as multi_a()
Identical to multi_a() except x-only keys are sorted lexicographically before script creation (after derivation).
NestingONLY inside tr().
sp(KEY) / sp(KEY,KEY)BIP392 · DraftProducesP2TR outputs as computed for silent payments (BIP-352)
Descriptor for BIP-352 silent payments. sp(KEY) takes a Bech32m-encoded spscan (watch-only) or spspend key; sp(KEY,KEY) takes a private scan key plus any single-key spend expression (musig() allowed). Uncompressed keys forbidden.
NestingTop level ONLY.
rawtr(KEY)— (no BIP) · Bitcoin Core extension (since v24.0)ProducesP2TR — OP_1 <KEY as the output key directly>
Uses KEY directly as the taproot output key with no tweaking — no BIP defines it, but BIP-390 references it as a valid musig() context and Bitcoin Core supports it.
NestingTop level ONLY.
musig(KEY,...,KEY)BIP390 · DraftProducesNot a script — a key expression producing a BIP-327 MuSig2 aggregate public key
Aggregates the listed participant keys with BIP-327 KeyAgg after derivation, with mandatory KeySort before aggregation. A /NUM/.../* suffix does further unhardened BIP-328 derivation on the aggregate key (participants must then be xpubs without their own /* or multipath).
NestingKey-expression position only, inside tr(), rawtr(), or sp(); cannot nest inside another musig().
KEY/<NUM;NUM;...> (multipath)BIP389 · DraftProducesNot a script — expands one descriptor into N descriptors (one per tuple value)
One derivation step in an extended-key path may be a tuple; the descriptor is treated as multiple descriptors, commonly /<0;1> for receive/change. All multipath expressions in one descriptor must have equal tuple lengths; duplicates forbidden; one multipath specifier per key expression; not allowed in key origins.
NestingA modification of BIP-380 key expressions — usable wherever ranged extended keys are.
A top-level descriptor may end in # plus an 8-character checksum drawn from the bech32 charset — a BCH code that always detects 1 error, and up to 3 errors on descriptors as long as 49,154 characters. It is optional when parsing, but applications may reject checksumless descriptors. Key expressions accept: a compressed public key (66 hex, 02/03), uncompressed (130 hex, 04), a WIF private key, or an xpub/xprv with /NUM derivation steps (hardened: h or '), optionally ending /* (ranged: one script per child index) — all optionally preceded by a [fingerprint/path] key origin. tr() adds the 64-hex x-only form; BIP-389 adds multipath tuples; BIP-390 adds musig(); BIP-392 adds the Bech32m spscan/spspend encodings.
Source: the raw BIP texts (bitcoin/bips, bip-0380 through bip-0392, fetched 2026-07-26); statuses transcribed from the BIP headers. BIP-388 (wallet policies) defines no descriptor functions and BIP-391 is Closed — both deliberately excluded. Pairs with the wallet recovery matrix, the address-types reference and the P2P message reference.
A descriptor wraps a spending policy, and that policy is written in Miniscript. See the Miniscript reference for every fragment and the Script it compiles to.
Last reviewed July 26, 2026.