Skip to content

Descriptors API Reference

Resources:

wpkh()

Constructs a P2WPKH Descriptor with the given public key.

For example:

  • wpkh($alice_pk)
  • wpkh(xpub661MyMwAqRbcGRXD6bfSCyz6kHu1rKqhLSz69rgSSagqfpLVwgibwu916Z2X6e5u3uj8P64HyjJrwhmpVWRAwWxneMTCanVevFyrMJAVqfy/0/9)
  • wpkh(03b2123025f45648c3f31fd4b7d3e1ec3344769ab3f53dec5af9b8a9a95385cbd5)

wsh()

wsh(Policy|Miniscript<Segwitv0Ctx>|SortedMulti) -> Descriptor<Wsh>

When called with a Policy, [Miniscript][Miniscript] or SortedMulti, constructs a P2WSH Descriptor.

For example: wsh(pk($alice) && older(5))

wsh(Script) -> WshInfo

When called with a raw Script, constructs a WshInfo representation.

For example: wsh(`$alice OP_CHECKSIGVERIFY 5 OP_CSV`)

Descriptors can only represent scripts expressed as Miniscript. For raw Script, the WshInfo structure is used instead. See the raw Scripting guide for more details.

tr()

tr(internal_key: PubKey) -> Descriptor<Tr>
tr(internal_key: PubKey, tree: Policy|Array<Policy>) -> Descriptor<Tr>
tr(tree: Policy|Array<Policy>) -> Descriptor<Tr>
tr(internal_key: PubKey, tree: Script|Array<Script>) -> TapInfo
tr(tree: Script|Array<Script>) -> TapInfo
tr(internal_key: PubKey, merkle_root: Hash) -> TapInfo

When called with a Miniscript Policy script tree or no tree (keypath-only), constructs a P2TR Descriptor.

When called with a raw Script tree or merkle_root hash, constructs a TapInfo.

→ See the full tr() documentation under the Taproot reference.

Descriptors can only represent Taproot trees expressed as Miniscript. To represent trees with raw Script or trees known only by their merkle root hash, the TapInfo structure is used instead.

sh()

sh(Policy|Miniscript<LegacyCtx>|SortedMulti) -> Descriptor<Sh>

Constructs a legacy P2SH Descriptor with the given Policy|[Miniscript][Miniscript]|SortedMulti as the redeemScript.

For example: sh(pk($alice) && older(5))

Wrap a Segwitv0 P2WPKH/P2WSH descriptor with a legacy P2SH descriptor, producing a P2SH-P2WPKH/P2SH-P2WSH descriptor.

For example: sh(wpkh($alice)), sh(wsh(pk($alice) && older(5)))

pkh()

Constructs a legacy P2PKH Descriptor with the given public key.

bare()

bare(Policy|Miniscript<BareCtx>) -> Descriptor<Bare>

Constructs a bare descriptor, with the Policy used directly as the output's scriptPubKey.

Typically used for legacy P2PK: bare(pk($alice)), or just bare($alice)

Or for bare multi-sig: bare(multi(1, $alice, $bob)), bare(1 of [ $alice, $bob ])

multi()

multi(threshold_k: Int, pks: Array<PubKey>|...PubKey) -> Miniscript

Require a signature by threshold_k of the public keys specified in pks.

The pks in the compiled Script will retain their original ordering.

Can be called with variadic arguments as multi(2, $alice, $bob, $charlie), or with an array as multi(2, [ $alice, $bob, $charlie ]).

Also see: BIP 383

sortedmulti()

sortedmulti(threshold_k: Int, pks: Array<PubKey>|...PubKey) -> SortedMulti

Like multi(), expect that the pks in the compiled Script are sorted lexicographically.

Returns: The virtual SortedMulti type, represented as a tagged Array

Also see: BIP 383

Note that sortedmulti() must be used with wsh() or sh(). Using it under bare() or tr() descriptors is currently unsupported (by the underlying rust-miniscript library).

Descriptor

Construction Examples:

  • wpkh(xpub661MyMwAqRbcFvXwqbgwi…cBX2nPX9KYVTz3cotpLmSkMxrp99L)
  • wsh(pk($alice) && older(2 days))
  • tr($alice, pk($bob) && older(3))
  • pkh(xpub661MyMwAqRbcFvXwqbgwi…cBX2nPX9KYVTz3cotpLmSkMxrp99L/<0;1>/*)
  • descriptor("wsh(and_v(v:pk(xpub661MyMwAqRbcFvXwqbgwi…cBX2nPX9KYVTz3cotpLmSkMxrp99L),older(1)))")

→ See the descriptors guide.

Variations:

Underlying type: miniscript::Descriptor

descriptor()

descriptor(String|Descriptor) -> Descriptor

descriptor_type String

One of "Tr", "Wpkh", "Wsh", "Pkh", "Sh", "ShWsh", "ShWpkh", "Bare", "WshSortedMulti", "ShSortedMulti" or "ShWshSortedMulti"

address_type String opt

One of "p2tr", "p2wpkh", "p2wsh", "p2pkh" or "p2sh"

Not available for Bare descriptors.

max_weight Int

singles Array<Descriptor<SinglePath>>

is_safe Bool

is_multipath Bool

is_wildcard Bool

is_definite Bool

Definite-only

The script_pubkey, explicit_script and witness_program fields are only available for definite descriptors - non-multi-path and with no underived /* wildcards.

script_pubkey Script opt

Also see: scriptPubKey()

explicit_script Script opt

Only available for definite non-taproot descriptors

witness_program Int:Bytes opt

Only available for definite segwit descriptors

Taproot-only

The rest of the fields are only only available for Taproot tr() descriptors.

Similar fields are mirrored on TapInfo, with the exception of miniscripts and miniscript_tree.

internal_key PubKey opt

Also available for non-definite descriptors, returning the wildcard/multi-path PubKey used by the descriptor.

miniscripts Array<Miniscript> opt

Only available for taproot descriptors. Returns an empty array when there are no script paths.

miniscript_tree TapNode opt

Only available for taproot descriptors with script paths.

Taproot+Definite-only

The fields below are only only available for Taproot descriptors that are also definite.

output_key PubKey<SingleKey> opt

The tweaked Taproot output key, for use in the scriptPubKey.

Only available for definite taproot descriptors.

output_key_parity Int opt

The parity of the output key (0 for even, 1 for odd).

Only available for definite taproot descriptors.

merkle_root Hash opt

Only available for definite taproot descriptors with script paths.

scripts Array<Script> opt

Only available for definite taproot descriptors. Returns an empty array when there are no script paths.

script_tree TapNode opt

Only available for definite taproot descriptors with script paths.

WshInfo

A descriptor-like structure used to represent Wsh over raw witness Script.

WshInfo are constructed using wsh(Script).

When working with Wsh over Miniscript, a wsh() Descriptor should be used instead.

This is not actually a descriptor and only provides a limited subset of functionality:

Using WshInfo with PSBT does not:

Also see: TapInfo, the equivalent for Taproot tress with raw Script

Underlying type: minsc::WshInfo

Show example use
// Script requiring two numbers that add up to 5,
// plus a signature by $alice's child key at m/0/15
$wsh = wsh(`OP_ADD 5 OP_EQUALVERIFY {$alice/0/15} OP_CHECKSIG`);

$address = address($wsh);
$spk = scriptPubKey($wsh); // or $wsh->script_pubkey
$explicit = explicitScript($wsh); // or $wsh->explicit_script

// Can be used in transaction outputs
$funding_tx = tx[
  "input": 0afe19ebf28ebfc296318ad00e9e122e458857e1c20305060dfb2c0d3e20c386:0,
  "output": $wsh:1 BTC,
];

// Can be used as the PSBT input UTXO
$psbt = psbt[
  "input": [
    "prevout": c0a85ea5a8ed744d085b497f8b41e5d5ec770d4750a2555c7c4fa8cfb5655be4:1,
    "utxo": $wsh:1 BTC,
    // Needs to be set explicitly to enable signing:
    "bip32_derivation": [ $alice/0/15 ],
  ],
  "outputs": [
    tb1quewn3qlyg3ugpj8rc5m8zn27z0270y2ppt5m6n:0.9 BTC,
    wpkh($bob):0.05 BTC,
  ]
];

// `witness_script` is populated automatically
assert::eq($psbt->inputs.0->witness_script, $wsh->explicit_script);

// Can compute sighashes
$sighash = psbt::sighash($psbt, 0);

// Can sign because `bip32_derivation` was set
$signed = psbt::sign($psbt, $alice_sk);

// Finalization must be performed manually
$input = $signed->inputs.0;
$finalized_tx = psbt::finalize_witness($psbt, [
  0: [ $input->partial_sigs.0.1, 2, 3, $input->witness_script ]
]);

// Script execution debug
$trace = tx::ptrace($finalized_tx, 0, [ $wsh:1 BTC ]);
$wsh = wsh(`OP_ADD <5> OP_EQUALVERIFY <0x0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18> OP_CHECKSIG`) // wshinfo

$address = tb1qveh4d4q2u9q06889h7plzwgr2hhl3zxjp5rrwd4a2tufkwk3t0cqs53gcm // address

$spk = `<0> <0x666f56d40ae140fd1ce5bf83f1390355eff888d20d063736bd52f89b3ad15bf0>` // script

$explicit = `OP_ADD <5> OP_EQUALVERIFY <0x0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18> OP_CHECKSIG` // script

$funding_tx = tx[
  "version": 2,
  "inputs": [
    0afe19ebf28ebfc296318ad00e9e122e458857e1c20305060dfb2c0d3e20c386:0
  ],
  "outputs": [
    `<0> <0x666f56d40ae140fd1ce5bf83f1390355eff888d20d063736bd52f89b3ad15bf0>`:1 BTC
  ]
] // transaction

$psbt = psbt[
  "unsigned_tx": tx[
    "version": 2,
    "inputs": [
      c0a85ea5a8ed744d085b497f8b41e5d5ec770d4750a2555c7c4fa8cfb5655be4:1
    ],
    "outputs": [
      `<0> <0xe65d3883e4447880c8e3c536714d5e13d5e79141>`:0.9 BTC,
      `<0> <0x6e598f8e8ffc8bf8c7597706366bdfaba68bd133>`:0.05 BTC
    ]
  ],
  "version": 0,
  "inputs": [
    [
      "utxo": `<0> <0x666f56d40ae140fd1ce5bf83f1390355eff888d20d063736bd52f89b3ad15bf0>`:1 BTC,
      "witness_script": `OP_ADD <5> OP_EQUALVERIFY <0x0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18> OP_CHECKSIG`,
      "bip32_derivation": [
        [df786318/0/15]0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18
      ]
    ]
  ],
  "outputs": [
    [ ],
    [ "bip32_derivation": [ [6e598f8e]034d14a48fa6c307d9c79e8a7c3164c6cb6279d2369cae32b4e1deebbb3c0b971c ] ]
  ]
] // psbt

$sighash = 0x70e622660a0877b6ba68396172d783f782498af111ea79e985980b4be8430e52 // bytes

$signed = psbt[
  "unsigned_tx": tx[
    "version": 2,
    "inputs": [
      c0a85ea5a8ed744d085b497f8b41e5d5ec770d4750a2555c7c4fa8cfb5655be4:1
    ],
    "outputs": [
      `<0> <0xe65d3883e4447880c8e3c536714d5e13d5e79141>`:0.9 BTC,
      `<0> <0x6e598f8e8ffc8bf8c7597706366bdfaba68bd133>`:0.05 BTC
    ]
  ],
  "version": 0,
  "inputs": [
    [
      "utxo": `<0> <0x666f56d40ae140fd1ce5bf83f1390355eff888d20d063736bd52f89b3ad15bf0>`:1 BTC,
      "partial_sigs": [
        0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18: 0x304402202e29b6a69f3cbc4a45aa1c893a307499d02d3d5568d62ca2ef94d00afec85fe7022045a0251cc01d8cc5edee61cf4eae93169d5c99bf4054e960f1b8c4cddc1a5c5401
      ],
      "witness_script": `OP_ADD <5> OP_EQUALVERIFY <0x0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18> OP_CHECKSIG`,
      "bip32_derivation": [
        [df786318/0/15]0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18
      ]
    ]
  ],
  "outputs": [
    [ ],
    [ "bip32_derivation": [ [6e598f8e]034d14a48fa6c307d9c79e8a7c3164c6cb6279d2369cae32b4e1deebbb3c0b971c ] ]
  ]
] // psbt

$input = [
  "witness_script": `OP_ADD <5> OP_EQUALVERIFY <0x0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18> OP_CHECKSIG`,
  "utxo": [ "script_pubkey": `<0> <0x666f56d40ae140fd1ce5bf83f1390355eff888d20d063736bd52f89b3ad15bf0>`, "amount": 100000000 ],
  "partial_sigs": [
    pubkey(0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18): 0x304402202e29b6a69f3cbc4a45aa1c893a307499d02d3d5568d62ca2ef94d00afec85fe7022045a0251cc01d8cc5edee61cf4eae93169d5c99bf4054e960f1b8c4cddc1a5c5401
  ],
  "tap_scripts": [ ],
  "tap_script_sigs": [ ],
  "tap_key_origins": [ ],
  "ripemd160_preimages": [ ],
  "sha256_preimages": [ ],
  "hash160_preimages": [ ],
  "hash256_preimages": [ ],
  "bip32_derivation": [ pubkey(0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18): 0xdf786318: [ 0, 15 ] ],
  "unknown": [ ],
  "proprietary": [ ]
] // array

$finalized_tx = tx[
  "version": 2,
  "inputs": [
    [
      "prevout": c0a85ea5a8ed744d085b497f8b41e5d5ec770d4750a2555c7c4fa8cfb5655be4:1,
      "witness": [ 0x304402202e29b6a69f3cbc4a45aa1c893a307499d02d3d5568d62ca2ef94d00afec85fe7022045a0251cc01d8cc5edee61cf4eae93169d5c99bf4054e960f1b8c4cddc1a5c5401, 0x02, 0x03, 0x935588210211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18ac ]
    ]
  ],
  "outputs": [
    `<0> <0xe65d3883e4447880c8e3c536714d5e13d5e79141>`:0.9 BTC,
    `<0> <0x6e598f8e8ffc8bf8c7597706366bdfaba68bd133>`:0.05 BTC
  ]
] // transaction

$trace = [
  "init_stack": [
    0x304402202e29b6a69f3cbc4a45aa1c893a307499d02d3d5568d62ca2ef94d00afec85fe7022045a0251cc01d8cc5edee61cf4eae93169d5c99bf4054e960f1b8c4cddc1a5c5401,
    2,
    3
  ],
  OP_ADD: 0x304402202e29b6a69f3cbc4a45aa1c893a307499d02d3d5568d62ca2ef94d00afec85fe7022045a0251cc01d8cc5edee61cf4eae93169d5c99bf4054e960f1b8c4cddc1a5c5401:5,
  OP_PUSHNUM_5: [
    0x304402202e29b6a69f3cbc4a45aa1c893a307499d02d3d5568d62ca2ef94d00afec85fe7022045a0251cc01d8cc5edee61cf4eae93169d5c99bf4054e960f1b8c4cddc1a5c5401,
    5,
    5
  ],
  OP_EQUALVERIFY: [
    0x304402202e29b6a69f3cbc4a45aa1c893a307499d02d3d5568d62ca2ef94d00afec85fe7022045a0251cc01d8cc5edee61cf4eae93169d5c99bf4054e960f1b8c4cddc1a5c5401
  ],
  OP_PUSHBYTES_33: 0x0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18: [
    0x304402202e29b6a69f3cbc4a45aa1c893a307499d02d3d5568d62ca2ef94d00afec85fe7022045a0251cc01d8cc5edee61cf4eae93169d5c99bf4054e960f1b8c4cddc1a5c5401,
    0x0211fff5af35167762f616224aaa6a426d420784ae99b618304de5b45fae12fd18
  ],
  OP_CHECKSIG: [ 1 ],
  "success": true
] // array

script_pubkey Script

explicit_script Script

witness_program Int:Bytes

address_type String

Always "p2wsh"

is_definite Bool

Always true

SortedMulti