Skip to content

Commit e65fabb

Browse files
OttoAllmendingerllm-git
andcommitted
feat(abstract-utxo): support RootWalletKeys in fixedScript address generation
Support passing RootWalletKeys directly to generateAddressWithChainAndIndex for more efficient key derivation without recreating HD nodes for each address. Also allows passing custom derivation prefixes which can be set inside RootWalletKeys (defaults to /0/0/). Issue: BTC-2668 Co-authored-by: llm-git <[email protected]>
1 parent cb6df0f commit e65fabb

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

modules/abstract-utxo/src/address/fixedScript.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
P2trUnsupportedError,
1010
P2wshUnsupportedError,
1111
UnsupportedAddressTypeError,
12-
sanitizeLegacyPath,
12+
isTriple,
13+
Triple,
1314
} from '@bitgo/sdk-core';
1415
import * as utxolib from '@bitgo/utxo-lib';
1516
import { bitgo } from '@bitgo/utxo-lib';
@@ -52,7 +53,7 @@ function supportsAddressType(network: utxolib.Network, addressType: ScriptType2O
5253

5354
export function generateAddressWithChainAndIndex(
5455
network: utxolib.Network,
55-
keychains: { pub: string }[],
56+
keychains: bitgo.RootWalletKeys | Triple<string>,
5657
chain: bitgo.ChainCode,
5758
index: number,
5859
format: CreateAddressFormat | undefined
@@ -61,24 +62,19 @@ export function generateAddressWithChainAndIndex(
6162
// Convert CreateAddressFormat to AddressFormat for wasm-utxo
6263
// 'base58' -> 'default', 'cashaddr' -> 'cashaddr'
6364
const wasmFormat = format === 'base58' ? 'default' : format;
64-
return wasmUtxo.fixedScriptWallet.address(
65-
keychains.map((k) => k.pub) as [string, string, string],
66-
chain,
67-
index,
68-
network,
69-
wasmFormat
70-
);
65+
return wasmUtxo.fixedScriptWallet.address(keychains, chain, index, network, wasmFormat);
66+
}
67+
68+
if (!(keychains instanceof bitgo.RootWalletKeys)) {
69+
const hdNodes = keychains.map((pub) => bip32.fromBase58(pub));
70+
keychains = new bitgo.RootWalletKeys(hdNodes as Triple<utxolib.BIP32Interface>);
7171
}
7272

73-
const path = '0/0/' + chain + '/' + index;
74-
const hdNodes = keychains.map(({ pub }) => bip32.fromBase58(pub));
75-
const derivedKeys = hdNodes.map((hdNode) => hdNode.derivePath(sanitizeLegacyPath(path)).publicKey);
7673
const addressType = bitgo.scriptTypeForChain(chain);
7774

75+
const derivedKeys = keychains.deriveForChainAndIndex(chain, index).publicKeys;
7876
const { scriptPubKey: outputScript } = utxolib.bitgo.outputScripts.createOutputScript2of3(derivedKeys, addressType);
79-
8077
const address = utxolib.address.fromOutputScript(outputScript, network);
81-
8278
return canonicalAddress(network, address, format);
8379
}
8480

@@ -143,7 +139,17 @@ export function generateAddress(network: utxolib.Network, params: GenerateFixedS
143139
}
144140
}
145141

146-
return generateAddressWithChainAndIndex(network, keychains, derivationChain, derivationIndex, params.format);
142+
if (!isTriple(keychains)) {
143+
throw new Error('keychains must be a triple');
144+
}
145+
146+
return generateAddressWithChainAndIndex(
147+
network,
148+
keychains.map((k) => k.pub) as Triple<string>,
149+
derivationChain,
150+
derivationIndex,
151+
params.format
152+
);
147153
}
148154

149155
type Keychain = {

0 commit comments

Comments
 (0)