Descriptors API Reference¶
Resources:
wpkh()
¶
wpkh(PubKey) -> Descriptor<Wpkh>
Constructs a P2WPKH Descriptor with the given public key.
For example:
Rust source code: src/stdlib/descriptors.rs:36
wsh()
¶
wsh(Policy|Miniscript<Segwitv0Ctx>|SortedMulti) -> Descriptor<Wsh>
When called with a Policy, [Miniscript][Miniscript] or SortedMulti, constructs a P2WSH Descriptor.
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
WshInfostructure is used instead. See the raw Scripting guide for more details.
Rust source code: src/stdlib/descriptors.rs:43
tr()
¶
tr(internal_key: PubKey) -> Descriptor<Tr>
tr(tree: Policy|Array<Policy>) -> Descriptor<Tr>
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
TapInfostructure is used instead.
Rust source code: src/stdlib/taproot.rs:56
sh()
¶
sh(Policy|Miniscript<LegacyCtx>|SortedMulti) -> Descriptor<Sh>
Constructs a legacy P2SH Descriptor with the given Policy|[Miniscript][Miniscript]|SortedMulti as the redeemScript.
sh(Descriptor<Wpkh|Wsh>) -> Descriptor<ShWpkh|ShWsh>
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)))
Rust source code: src/stdlib/descriptors.rs:62
pkh()
¶
pkh(PubKey) -> Descriptor<Pkh>
Constructs a legacy P2PKH Descriptor with the given public key.
Rust source code: src/stdlib/descriptors.rs:80
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 ])
Rust source code: src/stdlib/descriptors.rs:85
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
Rust source code: src/stdlib/miniscript.rs:161
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 withwsh()orsh(). Using it underbare()ortr()descriptors is currently unsupported (by the underlyingrust-miniscriptlibrary).
Rust source code: src/stdlib/descriptors.rs:93
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:
Descriptor<Tr>|Descriptor<Wpkh>|Descriptor<Wsh>|Descriptor<Pkh>|Descriptor<Sh>|Descriptor<ShWpkh>|Descriptor<ShWsh>|Descriptor<Bare>Descriptor<SinglePath>|Descriptor<MultiPath>Descriptor<Definite>|Descriptor<Indefinite>
Underlying type: miniscript::Descriptor
descriptor()
¶
descriptor(String|Descriptor) -> Descriptor
Rust source code: src/stdlib/descriptors.rs:107
One of "Tr", "Wpkh", "Wsh", "Pkh", "Sh", "ShWsh", "ShWpkh", "Bare", "WshSortedMulti", "ShSortedMulti" or "ShWshSortedMulti"
One of "p2tr", "p2wpkh", "p2wsh", "p2pkh" or "p2sh"
Not available for Bare descriptors.
Descriptor->singles
Array<Descriptor<SinglePath>>
¶
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.
Also see: scriptPubKey()
Only available for definite non-taproot descriptors
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.
Also available for non-definite descriptors, returning the wildcard/multi-path PubKey used by the descriptor.
Only available for taproot descriptors. Returns an empty array when there are no script paths.
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.
The tweaked Taproot output key, for use in the scriptPubKey.
Only available for definite taproot descriptors.
The parity of the output key (0 for even, 1 for odd).
Only available for definite taproot descriptors.
Only available for definite taproot descriptors with script paths.
Only available for definite taproot descriptors. Returns an empty array when there are no script paths.
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:
- Can be used in transaction outputs
- Can be used with
address(),scriptPubKey()andexplicitScript() - Can be used as the
PsbtInput->utxoto automatically populate thePsbtInput->witness_script - Can be used as the
PsbtOutputto automatically populate thePsbtOutput->witness_script - Can be used as the
utxoto compute sighashes withtx::sighash()andpsbt::sighash() - Signing transactions with
tx::sign()andpsbt::sign()is possible, but requires manually setting thebip32_derivationfield (see below)
Using WshInfo with PSBT does not:
-
Work with Miniscript's automatic
psbt::finalize(). Manual finalization must be performed instead usingpsbt::finalize_witness(). -
Populate the
bip32_derivationfield with the public keys used in the Script. The keys and their origins must be set explicitly to enable signing.
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
Always "p2wsh"
Always true