Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions packages/wasm-utxo/js/descriptorWallet/psbt/findDescriptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ function findDescriptorForDerivationIndex(
return undefined;
}

function getDerivationIndexFromPath(path: string): number {
function getDerivationIndexFromPath(path: string): number | undefined {
const indexStr = path.split("/").pop();
if (!indexStr) {
throw new Error(`Invalid derivation path ${path}`);
return undefined;
}
const index = parseInt(indexStr, 10);
if (index.toString() !== indexStr) {
throw new Error(`Invalid derivation path ${path}`);
const index = Number(indexStr);
if (!Number.isSafeInteger(index) || index < 0 || index.toString() !== indexStr) {
return undefined;
}
return index;
}
Expand All @@ -108,7 +108,13 @@ function findDescriptorForAnyDerivationPath(
derivationPaths: string[],
descriptorMap: DescriptorMap,
): DescriptorWithIndex | undefined {
const derivationIndexSet = new Set(derivationPaths.map((p) => getDerivationIndexFromPath(p)));
const derivationIndexSet = new Set<number>();
for (const path of derivationPaths) {
const index = getDerivationIndexFromPath(path);
if (index !== undefined) {
derivationIndexSet.add(index);
}
}
for (const index of [...derivationIndexSet]) {
const desc = findDescriptorForDerivationIndex(script, index, descriptorMap);
if (desc) {
Expand All @@ -122,14 +128,12 @@ function findDescriptorForAnyDerivationPath(
type WithBip32Derivation = { bip32Derivation?: { path: string }[] };
type WithTapBip32Derivation = { tapBip32Derivation?: { path: string }[] };

function getDerivationPaths(v: WithBip32Derivation | WithTapBip32Derivation): string[] | undefined {
if ("bip32Derivation" in v && v.bip32Derivation && v.bip32Derivation.length > 0) {
return v.bip32Derivation.map((v) => v.path);
}
if ("tapBip32Derivation" in v && v.tapBip32Derivation && v.tapBip32Derivation.length > 0) {
return v.tapBip32Derivation.map((v) => v.path).filter((v) => v !== "" && v !== "m");
}
return undefined;
function getDerivationPaths(v: WithBip32Derivation & WithTapBip32Derivation): string[] | undefined {
const paths = [
...(v.bip32Derivation ?? []).map((derivation) => derivation.path),
...(v.tapBip32Derivation ?? []).map((derivation) => derivation.path),
].filter((path) => path !== "" && path !== "m");
return paths.length > 0 ? paths : undefined;
}

/**
Expand Down
19 changes: 19 additions & 0 deletions packages/wasm-utxo/js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,24 @@ declare module "./wasm/wasm_utxo.js" {
tapBip32Derivation: PsbtBip32Derivation[];
}

/** A serialized input-map record with a standard PSBT key type. */
interface PsbtKnownInputKeyValue {
type: "known";
key: string;
keyData: Uint8Array;
value: Uint8Array;
}

/** A serialized input-map record whose key type is unrecognized. */
interface PsbtUnknownInputKeyValue {
type: "unknown";
keyType: bigint;
keyData: Uint8Array;
value: Uint8Array;
}

type PsbtInputKeyValue = PsbtKnownInputKeyValue | PsbtUnknownInputKeyValue;

/** Raw PSBT output data returned by getOutputs() */
interface PsbtOutputData {
script: Uint8Array;
Expand Down Expand Up @@ -172,3 +190,4 @@ export {
type ITransactionCommon,
} from "./transaction.js";
export { hasPsbtMagic, type IPsbt, type IPsbtWithAddress } from "./psbt.js";
export type { PsbtInputKeyValue } from "./wasm/wasm_utxo.js";
8 changes: 7 additions & 1 deletion packages/wasm-utxo/js/psbt.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import type { PsbtInputData, PsbtOutputData, PsbtOutputDataWithAddress } from "./wasm/wasm_utxo.js";
import type {
PsbtInputData,
PsbtInputKeyValue,
PsbtOutputData,
PsbtOutputDataWithAddress,
} from "./wasm/wasm_utxo.js";
import type { BIP32 } from "./bip32.js";
import type { ITransactionCommon } from "./transaction.js";
import type { PsbtKvKey } from "./fixedScriptWallet/BitGoKeySubtype.js";

/** Common interface for PSBT types */
export interface IPsbt extends ITransactionCommon<PsbtInputData, PsbtOutputData> {
getGlobalXpubs(): BIP32[];
getInputKeyValues(index: number): PsbtInputKeyValue[];
unsignedTxId(): string;
addInputAtIndex(
index: number,
Expand Down
11 changes: 10 additions & 1 deletion packages/wasm-utxo/js/psbtBase.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import type { PsbtInputData, PsbtOutputData, WasmBIP32 } from "./wasm/wasm_utxo.js";
import type {
PsbtInputData,
PsbtInputKeyValue,
PsbtOutputData,
WasmBIP32,
} from "./wasm/wasm_utxo.js";
import { BIP32 } from "./bip32.js";
import type { PsbtKvKey } from "./fixedScriptWallet/BitGoKeySubtype.js";

Expand All @@ -10,6 +15,7 @@ interface WasmPsbtBase {
unsigned_tx_id(): string;
serialize(): Uint8Array;
get_inputs(): unknown;
get_input_key_values(index: number): unknown;
get_outputs(): unknown;
get_global_xpubs(): unknown;
remove_input(index: number): void;
Expand Down Expand Up @@ -53,6 +59,9 @@ export abstract class PsbtBase<W extends WasmPsbtBase> {
getInputs(): PsbtInputData[] {
return this._wasm.get_inputs() as PsbtInputData[];
}
getInputKeyValues(index: number): PsbtInputKeyValue[] {
return this._wasm.get_input_key_values(index) as PsbtInputKeyValue[];
}
getOutputs(): PsbtOutputData[] {
return this._wasm.get_outputs() as PsbtOutputData[];
}
Expand Down
Loading
Loading