Skip to content

Bitcoin accepted at checkout  |  Ships from Montreal, QC, Canada  |  Expert support since 2016

Bitcoin Output Script Descriptors Reference (BIP-380 to BIP-392)

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 →

Script expressions

pk(KEY)BIP381 · Deployed

ProducesP2PK — <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 · Deployed

ProducesP2PKH — 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 · Deployed

ProducesP2SH — 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 · Deployed

ProducesP2WPKH — 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 · Deployed

ProducesP2WSH — 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 · Deployed

ProducesMultisig — 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 · Deployed

ProducesSame 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 · Deployed

Produces2 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 · Deployed

ProducesThe literal script encoded by HEX

Encapsulates an arbitrary raw output script, given as hex, as a descriptor.

NestingTop level ONLY.

addr(ADDR)BIP385 · Deployed

ProducesThe output script produced by the address ADDR

Encapsulates any Bitcoin address as a descriptor.

NestingTop level ONLY.

tr(KEY) / tr(KEY,TREE)BIP386 · Deployed

ProducesP2TR — 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 · Deployed

ProducesTapscript 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 · Deployed

ProducesSame 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 · Draft

ProducesP2TR 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.

Key expressions

musig(KEY,...,KEY)BIP390 · Draft

ProducesNot 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 · Draft

ProducesNot 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.

Checksum & key forms (BIP-380)

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.