PHP WebShell
Текущая директория: /opt/BitGoJS/modules/utxo-core/src/descriptor/psbt
Просмотр файла: findDescriptors.ts
/*
Utilities for mapping back from PSBT inputs to descriptors.
This is a somewhat brute-force attempt that relies on the `bip32Derivation` field to be set.
It will probably only work correctly if all xpubs in the descriptor are derivable.
We should take a look at a more robust and standard approach like this: https://github.com/bitcoin/bips/pull/1548
*/
import { PsbtInput, PsbtOutput } from 'bip174/src/lib/interfaces';
import { Descriptor } from '@bitgo/wasm-miniscript';
import { DescriptorMap } from '../DescriptorMap';
type DescriptorWithoutIndex = { descriptor: Descriptor; index: undefined };
/**
* Find a definite descriptor in the descriptor map that matches the given script.
* @param script
* @param descriptorMap
*/
function findDescriptorWithoutDerivation(
script: Buffer,
descriptorMap: DescriptorMap
): DescriptorWithoutIndex | undefined {
for (const descriptor of descriptorMap.values()) {
if (!descriptor.hasWildcard()) {
if (Buffer.from(descriptor.scriptPubkey()).equals(script)) {
return { descriptor, index: undefined };
}
}
}
return undefined;
}
type DescriptorWithIndex = { descriptor: Descriptor; index: number };
/**
* Find a descriptor in the descriptor map that matches the given script and derivation index.
* @param script
* @param index
* @param descriptorMap
* @returns DescriptorWithIndex if found, undefined otherwise
*/
function findDescriptorForDerivationIndex(
script: Buffer,
index: number,
descriptorMap: DescriptorMap
): DescriptorWithIndex | undefined {
for (const descriptor of descriptorMap.values()) {
if (descriptor.hasWildcard() && Buffer.from(descriptor.atDerivationIndex(index).scriptPubkey()).equals(script)) {
return { descriptor, index };
}
}
return undefined;
}
function getDerivationIndexFromPath(path: string): number {
const indexStr = path.split('/').pop();
if (!indexStr) {
throw new Error(`Invalid derivation path ${path}`);
}
const index = parseInt(indexStr, 10);
if (index.toString() !== indexStr) {
throw new Error(`Invalid derivation path ${path}`);
}
return index;
}
/**
* Wrapper around findDescriptorForDerivationPath that tries multiple derivation paths.
* @param script
* @param derivationPaths
* @param descriptorMap
*/
function findDescriptorForAnyDerivationPath(
script: Buffer,
derivationPaths: string[],
descriptorMap: DescriptorMap
): DescriptorWithIndex | undefined {
const derivationIndexSet = new Set(derivationPaths.map((p) => getDerivationIndexFromPath(p)));
for (const index of [...derivationIndexSet]) {
const desc = findDescriptorForDerivationIndex(script, index, descriptorMap);
if (desc) {
return desc;
}
}
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
* @returns DescriptorWithIndex for the input if found, undefined otherwise
*/
export function findDescriptorForInput(
input: PsbtInput,
descriptorMap: DescriptorMap
): DescriptorWithIndex | DescriptorWithoutIndex | undefined {
const script = input.witnessUtxo?.script;
if (!script) {
throw new Error('Missing script');
}
const derivationPaths = getDerivationPaths(input) ?? [];
return (
findDescriptorWithoutDerivation(script, descriptorMap) ??
findDescriptorForAnyDerivationPath(script, derivationPaths, descriptorMap)
);
}
/**
* @param script - the output script
* @param output - the PSBT output
* @param descriptorMap
* @returns DescriptorWithIndex for the output if found, undefined otherwise
*/
export function findDescriptorForOutput(
script: Buffer,
output: PsbtOutput,
descriptorMap: DescriptorMap
): DescriptorWithIndex | DescriptorWithoutIndex | undefined {
const derivationPaths = getDerivationPaths(output);
return (
findDescriptorWithoutDerivation(script, descriptorMap) ??
(derivationPaths === undefined
? undefined
: findDescriptorForAnyDerivationPath(script, derivationPaths, descriptorMap))
);
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!