Skip to content

Commit

Permalink
feat(utxo-core): update descriptor test util to use AST types
Browse files Browse the repository at this point in the history
Refactor test descriptor builder to use AST nodes and types instead of
string manipulation.

Issue: BTC-1829
  • Loading branch information
OttoAllmendinger committed Feb 14, 2025
1 parent 79f9c5c commit d29e0dc
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 34 deletions.
2 changes: 1 addition & 1 deletion modules/abstract-utxo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"@bitgo/unspents": "^0.47.17",
"@bitgo/utxo-core": "^1.1.0",
"@bitgo/utxo-lib": "^11.2.1",
"@bitgo/wasm-miniscript": "^2.0.0-beta.3",
"@bitgo/wasm-miniscript": "^2.0.0-beta.4",
"@types/bluebird": "^3.5.25",
"@types/lodash": "^4.14.121",
"@types/superagent": "4.1.15",
Expand Down
2 changes: 1 addition & 1 deletion modules/utxo-bin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@bitgo/statics": "^50.24.0",
"@bitgo/unspents": "^0.47.17",
"@bitgo/utxo-lib": "^11.2.1",
"@bitgo/wasm-miniscript": "^2.0.0-beta.3",
"@bitgo/wasm-miniscript": "^2.0.0-beta.4",
"archy": "^1.0.0",
"bech32": "^2.0.0",
"bitcoinjs-lib": "npm:@bitgo-forks/[email protected]",
Expand Down
2 changes: 1 addition & 1 deletion modules/utxo-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"dependencies": {
"@bitgo/unspents": "^0.47.17",
"@bitgo/utxo-lib": "^11.2.1",
"@bitgo/wasm-miniscript": "^2.0.0-beta.3",
"@bitgo/wasm-miniscript": "^2.0.0-beta.4",
"bip174": "npm:@bitgo-forks/[email protected]"
},
"gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c"
Expand Down
55 changes: 28 additions & 27 deletions modules/utxo-core/src/testutil/descriptor/descriptors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Descriptor } from '@bitgo/wasm-miniscript';
import assert from 'assert';

import { Descriptor, ast } from '@bitgo/wasm-miniscript';
import { BIP32Interface } from '@bitgo/utxo-lib';

import { DescriptorMap, PsbtParams } from '../../descriptor';
Expand Down Expand Up @@ -47,36 +49,22 @@ export type DescriptorTemplate =
*/
| 'ShWsh2Of3CltvDrop';

function toXPub(k: BIP32Interface | string): string {
function toXPub(k: BIP32Interface | string, path: string): string {
if (typeof k === 'string') {
return k;
return k + '/' + path;
}
return k.neutered().toBase58();
return k.neutered().toBase58() + '/' + path;
}

function multi(
prefix: 'multi' | 'multi_a',
m: number,
n: number,
keys: BIP32Interface[] | string[],
path: string
): string {
function multiArgs(m: number, n: number, keys: BIP32Interface[] | string[], path: string): [number, ...string[]] {
if (n < m) {
throw new Error(`Cannot create ${m} of ${n} multisig`);
}
if (keys.length < n) {
throw new Error(`Not enough keys for ${m} of ${n} multisig: keys.length=${keys.length}`);
}
keys = keys.slice(0, n);
return prefix + `(${m},${keys.map((k) => `${toXPub(k)}/${path}`).join(',')})`;
}

function multiWsh(m: number, n: number, keys: BIP32Interface[] | string[], path: string): string {
return multi('multi', m, n, keys, path);
}

function multiTap(m: number, n: number, keys: BIP32Interface[] | string[], path: string): string {
return multi('multi_a', m, n, keys, path);
return [m, ...keys.map((k) => toXPub(k, path))];
}

export function getPsbtParams(t: DescriptorTemplate): Partial<PsbtParams> {
Expand All @@ -90,21 +78,34 @@ export function getPsbtParams(t: DescriptorTemplate): Partial<PsbtParams> {
}
}

export function getDescriptorString(
function getDescriptorNode(
template: DescriptorTemplate,
keys: KeyTriple | string[] = getDefaultXPubs(),
path = '0/*'
): string {
): ast.DescriptorNode {
switch (template) {
case 'Wsh2Of3':
return `wsh(${multiWsh(2, 3, keys, path)})`;
return {
wsh: { multi: multiArgs(2, 3, keys, path) },
};
case 'ShWsh2Of3CltvDrop':
const { locktime } = getPsbtParams(template);
return `sh(wsh(and_v(r:after(${locktime}),${multiWsh(2, 3, keys, path)})))`;
assert(locktime);
return {
sh: {
wsh: {
and_v: [{ 'r:after': locktime }, { multi: multiArgs(2, 3, keys, path) }],
},
},
};
case 'Wsh2Of2':
return `wsh(${multiWsh(2, 2, keys, path)})`;
return {
wsh: { multi: multiArgs(2, 2, keys, path) },
};
case 'Tr2Of3-NoKeyPath':
return `tr(${getUnspendableKey()},${multiTap(2, 3, keys, path)})`;
return {
tr: [getUnspendableKey(), { multi_a: multiArgs(2, 3, keys, path) }],
};
}
throw new Error(`Unknown descriptor template: ${template}`);
}
Expand All @@ -114,7 +115,7 @@ export function getDescriptor(
keys: KeyTriple | string[] = getDefaultXPubs(),
path = '0/*'
): Descriptor {
return Descriptor.fromString(getDescriptorString(template, keys, path), 'derivable');
return Descriptor.fromString(ast.formatNode(getDescriptorNode(template, keys, path)), 'derivable');
}

export function getDescriptorMap(
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -886,10 +886,10 @@
monocle-ts "^2.3.13"
newtype-ts "^0.3.5"

"@bitgo/wasm-miniscript@^2.0.0-beta.3":
version "2.0.0-beta.3"
resolved "https://registry.npmjs.org/@bitgo/wasm-miniscript/-/wasm-miniscript-2.0.0-beta.3.tgz#f52f9fa411f4f13527c960842f81729133aa6810"
integrity sha512-9JWfizfdpSExQ5qDkMlZAR0UbonKILPwDXM+iqiBKIRGwlYak071lX9sfGPWoRuo7g72gU//s7AiZc6kZqgetw==
"@bitgo/wasm-miniscript@^2.0.0-beta.4":
version "2.0.0-beta.4"
resolved "https://registry.npmjs.org/@bitgo/wasm-miniscript/-/wasm-miniscript-2.0.0-beta.4.tgz#6897327a0e6007cfa02081a02cba8b442e318dc5"
integrity sha512-lZCSo3NY/vb1hagU3J7fIdv7GhCGYb/INCdAi6ogDXBzWDl3tloviCZ9DXCNPXc7lbj8mVr3GR8zAFkPTQ0xEw==

"@brandonblack/musig@^0.0.1-alpha.0":
version "0.0.1-alpha.1"
Expand Down

0 comments on commit d29e0dc

Please sign in to comment.