From 437eb7e14e3aacebd17ae99948f0acbe706dd526 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Mon, 27 Jan 2025 15:30:30 +0100 Subject: [PATCH 1/2] feat(abstract-utxo): extend Tr2Of3 test for findDescriptors The previous test was incomplete as we used Tr2Of3 only for the external output Issue: BTC-1786 --- .../test/core/descriptor/psbt/findDescriptors.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/abstract-utxo/test/core/descriptor/psbt/findDescriptors.ts b/modules/abstract-utxo/test/core/descriptor/psbt/findDescriptors.ts index 1bc434b02a..8cffd8f762 100644 --- a/modules/abstract-utxo/test/core/descriptor/psbt/findDescriptors.ts +++ b/modules/abstract-utxo/test/core/descriptor/psbt/findDescriptors.ts @@ -5,10 +5,10 @@ import { findDescriptorForInput, findDescriptorForOutput } from '../../../../src import { mockPsbt } from './mock.utils'; -function describeWithTemplates(tA: DescriptorTemplate, tB: DescriptorTemplate) { - describe(`parsePsbt [${tA},${tB}]`, function () { - const descriptorA = getDescriptor(tA, getDefaultXPubs('a')); - const descriptorB = getDescriptor(tB, getDefaultXPubs('b')); +function describeWithTemplates(templateSelf: DescriptorTemplate, templateOther: DescriptorTemplate) { + describe(`parsePsbt [${templateSelf},${templateOther}]`, function () { + const descriptorA = getDescriptor(templateSelf, getDefaultXPubs('a')); + const descriptorB = getDescriptor(templateOther, getDefaultXPubs('b')); const descriptorMap = new Map([ ['a', descriptorA], ['b', descriptorB], @@ -41,3 +41,4 @@ function describeWithTemplates(tA: DescriptorTemplate, tB: DescriptorTemplate) { describeWithTemplates('Wsh2Of3', 'Wsh2Of3'); describeWithTemplates('Wsh2Of3', 'Tr2Of3-NoKeyPath'); +describeWithTemplates('Tr2Of3-NoKeyPath', 'Tr2Of3-NoKeyPath'); From 758777c94dbcc6d1008ecc36c11c2d45b2457d1b Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Mon, 27 Jan 2025 15:31:41 +0100 Subject: [PATCH 2/2] fix(abstract-utxo): fix findDescriptorForOutput for taproot outputs Issue: BTC-1786 --- .../core/descriptor/psbt/findDescriptors.ts | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/modules/abstract-utxo/src/core/descriptor/psbt/findDescriptors.ts b/modules/abstract-utxo/src/core/descriptor/psbt/findDescriptors.ts index bdd843cf1b..567a98232c 100644 --- a/modules/abstract-utxo/src/core/descriptor/psbt/findDescriptors.ts +++ b/modules/abstract-utxo/src/core/descriptor/psbt/findDescriptors.ts @@ -71,6 +71,19 @@ function findDescriptorForAnyDerivationPath( return undefined; } +type WithBip32Derivation = { bip32Derivation?: { path: string }[] }; +type WithTapBip32Derivation = { tapBip32Derivation?: { path: string }[] }; + +function getDerivationPaths(v: WithBip32Derivation | WithTapBip32Derivation): string[] | undefined { + if ('bip32Derivation' in v && v.bip32Derivation) { + return v.bip32Derivation.map((v) => v.path); + } + if ('tapBip32Derivation' in v && v.tapBip32Derivation) { + return v.tapBip32Derivation.map((v) => v.path).filter((v) => v !== '' && v !== 'm'); + } + return undefined; +} + /** * @param input * @param descriptorMap @@ -84,21 +97,11 @@ export function findDescriptorForInput( if (!script) { throw new Error('Missing script'); } - if (input.bip32Derivation !== undefined) { - return findDescriptorForAnyDerivationPath( - script, - input.bip32Derivation.map((v) => v.path), - descriptorMap - ); - } - if (input.tapBip32Derivation !== undefined) { - return findDescriptorForAnyDerivationPath( - script, - input.tapBip32Derivation.filter((v) => v.path !== '' && v.path !== 'm').map((v) => v.path), - descriptorMap - ); + const derivationPaths = getDerivationPaths(input); + if (!derivationPaths) { + throw new Error('Missing derivation paths'); } - throw new Error('Missing derivation path'); + return findDescriptorForAnyDerivationPath(script, derivationPaths, descriptorMap); } /** @@ -112,12 +115,9 @@ export function findDescriptorForOutput( output: PsbtOutput, descriptorMap: DescriptorMap ): DescriptorWithIndex | undefined { - if (!output.bip32Derivation) { + const derivationPaths = getDerivationPaths(output); + if (!derivationPaths) { return undefined; } - return findDescriptorForAnyDerivationPath( - script, - output.bip32Derivation.map((d) => d.path), - descriptorMap - ); + return findDescriptorForAnyDerivationPath(script, derivationPaths, descriptorMap); }