diff --git a/modules/abstract-utxo/package.json b/modules/abstract-utxo/package.json index feb5b18dbb..d5622d72c8 100644 --- a/modules/abstract-utxo/package.json +++ b/modules/abstract-utxo/package.json @@ -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", diff --git a/modules/utxo-bin/package.json b/modules/utxo-bin/package.json index 1cee7ebdbe..bd92ff73b3 100644 --- a/modules/utxo-bin/package.json +++ b/modules/utxo-bin/package.json @@ -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/bitcoinjs-lib@7.1.0-master.2", diff --git a/modules/utxo-core/package.json b/modules/utxo-core/package.json index 48c7663c6d..2d8b3a295c 100644 --- a/modules/utxo-core/package.json +++ b/modules/utxo-core/package.json @@ -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/bip174@3.1.0-master.4" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/utxo-core/src/testutil/descriptor/descriptors.ts b/modules/utxo-core/src/testutil/descriptor/descriptors.ts index 19cf816284..035490b83c 100644 --- a/modules/utxo-core/src/testutil/descriptor/descriptors.ts +++ b/modules/utxo-core/src/testutil/descriptor/descriptors.ts @@ -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'; @@ -47,20 +49,14 @@ 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`); } @@ -68,15 +64,7 @@ function multi( 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 { @@ -90,21 +78,34 @@ export function getPsbtParams(t: DescriptorTemplate): Partial { } } -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}`); } @@ -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( diff --git a/yarn.lock b/yarn.lock index e160ed97fb..995cdbfdf1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"