@swapkit/wallet-hardware 4.11.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-n05bv2n5.js → chunk-1jpcb30j.js} +3 -3
- package/dist/{chunk-n05bv2n5.js.map → chunk-1jpcb30j.js.map} +1 -1
- package/dist/{chunk-9gy0xve4.js → chunk-20wx60bn.js} +3 -3
- package/dist/{chunk-9gy0xve4.js.map → chunk-20wx60bn.js.map} +1 -1
- package/dist/chunk-4tbtxdxa.js +5 -0
- package/dist/chunk-4tbtxdxa.js.map +10 -0
- package/dist/chunk-7v7cgm69.js +4 -0
- package/dist/chunk-7v7cgm69.js.map +10 -0
- package/dist/{chunk-3yr76n9s.js → chunk-83g13ck6.js} +3 -3
- package/dist/{chunk-3yr76n9s.js.map → chunk-83g13ck6.js.map} +1 -1
- package/dist/{chunk-bwf31zxr.js → chunk-h2r568rz.js} +3 -3
- package/dist/{chunk-bwf31zxr.js.map → chunk-h2r568rz.js.map} +1 -1
- package/dist/{chunk-vwv6z2mk.js → chunk-xkh15edk.js} +2 -2
- package/dist/keepkey/index.cjs +2 -2
- package/dist/keepkey/index.cjs.map +3 -3
- package/dist/keepkey/index.js +2 -2
- package/dist/keepkey/index.js.map +3 -3
- package/dist/ledger/index.cjs +2 -2
- package/dist/ledger/index.cjs.map +6 -5
- package/dist/ledger/index.js +2 -2
- package/dist/ledger/index.js.map +3 -3
- package/dist/trezor/index.cjs +2 -2
- package/dist/trezor/index.cjs.map +5 -4
- package/dist/trezor/index.js +2 -2
- package/dist/trezor/index.js.map +3 -3
- package/dist/types/helpers/psbt.d.ts +9 -0
- package/dist/types/helpers/psbt.d.ts.map +1 -0
- package/dist/types/keepkey/chains/utxo.d.ts.map +1 -1
- package/dist/types/ledger/clients/utxo-psbt.d.ts +2 -0
- package/dist/types/ledger/clients/utxo-psbt.d.ts.map +1 -1
- package/dist/types/ledger/index.d.ts.map +1 -1
- package/dist/types/trezor/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/helpers/psbt.ts +26 -0
- package/src/keepkey/chains/utxo.ts +5 -2
- package/src/ledger/clients/utxo-psbt.ts +34 -1
- package/src/ledger/index.ts +14 -4
- package/src/trezor/index.ts +13 -6
- package/dist/chunk-gwx23jdp.js +0 -4
- package/dist/chunk-gwx23jdp.js.map +0 -10
- /package/dist/{chunk-vwv6z2mk.js.map → chunk-xkh15edk.js.map} +0 -0
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import type Transport from "@ledgerhq/hw-transport";
|
|
2
2
|
import { base64 } from "@scure/base";
|
|
3
3
|
import { HDKey } from "@scure/bip32";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Chain,
|
|
6
|
+
type DerivationPathArray,
|
|
7
|
+
derivationPathToString,
|
|
8
|
+
getWalletFormatFor,
|
|
9
|
+
SwapKitError,
|
|
10
|
+
type UTXOChain,
|
|
11
|
+
} from "@swapkit/helpers";
|
|
5
12
|
import type { Transaction } from "@swapkit/utxo-signer";
|
|
6
13
|
|
|
14
|
+
import { applyMissingSpendingMetadata } from "../../helpers/psbt";
|
|
7
15
|
import { getLedgerTransport } from "../helpers/getLedgerTransport";
|
|
8
16
|
|
|
9
17
|
type SupportedCoin = "bitcoin" | "litecoin";
|
|
10
18
|
|
|
19
|
+
const UTXO_CHAIN_FOR_COIN: Record<SupportedCoin, UTXOChain> = { bitcoin: Chain.Bitcoin, litecoin: Chain.Litecoin };
|
|
20
|
+
|
|
11
21
|
type DefaultDescriptorTemplate = "wpkh(@0/**)" | "tr(@0/**)" | "sh(wpkh(@0/**))" | "pkh(@0/**)";
|
|
12
22
|
|
|
13
23
|
function templateForFormat(format: ReturnType<typeof getWalletFormatFor>): DefaultDescriptorTemplate {
|
|
@@ -43,6 +53,16 @@ function pathToNumberArray(path: string): number[] {
|
|
|
43
53
|
});
|
|
44
54
|
}
|
|
45
55
|
|
|
56
|
+
function dropWitnessUtxoFromLegacyInputs(tx: Transaction) {
|
|
57
|
+
for (let inputIndex = 0; inputIndex < tx.inputsLength; inputIndex++) {
|
|
58
|
+
const input = tx.getInput(inputIndex);
|
|
59
|
+
|
|
60
|
+
if (input.nonWitnessUtxo && input.witnessUtxo) {
|
|
61
|
+
tx.updateInput(inputIndex, { witnessUtxo: undefined });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
46
66
|
function hasBip32Derivation(tx: Transaction, inputIndex: number) {
|
|
47
67
|
const input = tx.getInput(inputIndex) as { bip32Derivation?: Array<unknown> };
|
|
48
68
|
|
|
@@ -135,6 +155,7 @@ const BaseLedgerPsbtUTXO = ({ chain }: { chain: SupportedCoin }) => {
|
|
|
135
155
|
const app = await getAppClient();
|
|
136
156
|
return app.getExtendedPubkey(`m/${normalizeLedgerPath(path)}`);
|
|
137
157
|
},
|
|
158
|
+
getPublicKey: getLeafPubkey,
|
|
138
159
|
signTransaction: async (tx: Transaction): Promise<Transaction> => {
|
|
139
160
|
const { app, policy, fpr } = await buildPolicy();
|
|
140
161
|
const fingerprintBE = Number.parseInt(fpr, 16) >>> 0;
|
|
@@ -154,6 +175,18 @@ const BaseLedgerPsbtUTXO = ({ chain }: { chain: SupportedCoin }) => {
|
|
|
154
175
|
}
|
|
155
176
|
}
|
|
156
177
|
|
|
178
|
+
if (format === "legacy") {
|
|
179
|
+
dropWitnessUtxoFromLegacyInputs(tx);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (format === "p2sh") {
|
|
183
|
+
await applyMissingSpendingMetadata({
|
|
184
|
+
chain: UTXO_CHAIN_FOR_COIN[chain],
|
|
185
|
+
publicKey: await getLeafPubkey(),
|
|
186
|
+
tx,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
157
190
|
const psbtB64 = base64.encode(tx.toPSBT(0));
|
|
158
191
|
const sigs = await app.signPsbt(psbtB64, policy, null);
|
|
159
192
|
|
package/src/ledger/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
NetworkDerivationPath,
|
|
12
12
|
SwapKitError,
|
|
13
13
|
type UTXOChain,
|
|
14
|
+
UTXOScriptType,
|
|
14
15
|
WalletOption,
|
|
15
16
|
} from "@swapkit/helpers";
|
|
16
17
|
import {
|
|
@@ -19,6 +20,7 @@ import {
|
|
|
19
20
|
compileMemo,
|
|
20
21
|
createHDWalletHelpers,
|
|
21
22
|
getNetworkForChain,
|
|
23
|
+
getScriptTypeForAddress,
|
|
22
24
|
getUTXOAccountIndexFromPath,
|
|
23
25
|
getUTXOAccountPath,
|
|
24
26
|
getUTXOAddressPath,
|
|
@@ -172,6 +174,7 @@ async function getWalletMethods({
|
|
|
172
174
|
const signer = await getLedgerClient({ chain, derivationPath, transport });
|
|
173
175
|
|
|
174
176
|
const address = providedAddress ?? (await getLedgerAddress({ chain, ledgerClient: signer }));
|
|
177
|
+
const scriptType = getScriptTypeForAddress(address, utxoChain);
|
|
175
178
|
|
|
176
179
|
// V3 toolbox signer:
|
|
177
180
|
// - BTC uses the modern `ledger-bitcoin` AppClient with native PSBT signing.
|
|
@@ -181,13 +184,19 @@ async function getWalletMethods({
|
|
|
181
184
|
// policy APDUs and returns CLA_NOT_SUPPORTED.
|
|
182
185
|
// - ZEC stays on the bespoke `signPCZT` flow for now.
|
|
183
186
|
let toolboxSigner:
|
|
184
|
-
| {
|
|
187
|
+
| {
|
|
188
|
+
getAddress: () => Promise<string>;
|
|
189
|
+
publicKey?: Uint8Array;
|
|
190
|
+
signTransaction: (tx: Transaction) => Promise<Transaction>;
|
|
191
|
+
}
|
|
185
192
|
| undefined;
|
|
193
|
+
let publicKey: Uint8Array | undefined;
|
|
186
194
|
let signAndBroadcastLegacyPsbtTransaction: ((tx: Transaction) => Promise<string>) | undefined;
|
|
187
195
|
if (chain === Chain.Bitcoin) {
|
|
188
196
|
const { BitcoinPsbtLedger } = await import("./clients/utxo-psbt");
|
|
189
197
|
const psbtClient = BitcoinPsbtLedger(derivationPath, transport);
|
|
190
|
-
|
|
198
|
+
publicKey = scriptType === UTXOScriptType.P2SH_P2WPKH ? await psbtClient.getPublicKey() : undefined;
|
|
199
|
+
toolboxSigner = { getAddress: psbtClient.getAddress, publicKey, signTransaction: psbtClient.signTransaction };
|
|
191
200
|
} else if (
|
|
192
201
|
chain === Chain.BitcoinCash ||
|
|
193
202
|
chain === Chain.Dogecoin ||
|
|
@@ -203,8 +212,8 @@ async function getWalletMethods({
|
|
|
203
212
|
}
|
|
204
213
|
|
|
205
214
|
const toolbox = toolboxSigner
|
|
206
|
-
? await getUtxoToolbox(utxoChain, { signer: toolboxSigner })
|
|
207
|
-
: getUtxoToolbox(utxoChain);
|
|
215
|
+
? await getUtxoToolbox(utxoChain, { scriptType, signer: toolboxSigner })
|
|
216
|
+
: getUtxoToolbox(utxoChain, { scriptType });
|
|
208
217
|
const signAndBroadcastTransaction = signAndBroadcastLegacyPsbtTransaction ?? toolbox.signAndBroadcastTransaction;
|
|
209
218
|
|
|
210
219
|
const transfer = async (params: UTXOBuildTxParams) => {
|
|
@@ -216,6 +225,7 @@ async function getWalletMethods({
|
|
|
216
225
|
feeRate,
|
|
217
226
|
fetchTxHex: true,
|
|
218
227
|
memo,
|
|
228
|
+
publicKey: params.publicKey ?? publicKey,
|
|
219
229
|
sender: address,
|
|
220
230
|
});
|
|
221
231
|
|
package/src/trezor/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
SKConfig,
|
|
11
11
|
SwapKitError,
|
|
12
12
|
type UTXOChain,
|
|
13
|
+
UTXOScriptType,
|
|
13
14
|
WalletOption,
|
|
14
15
|
} from "@swapkit/helpers";
|
|
15
16
|
import {
|
|
@@ -26,6 +27,8 @@ import type { BTCNetwork, PCZT, Transaction, ZcashPSBT, ZcashTransaction } from
|
|
|
26
27
|
import { BCHSigHash, NETWORKS, ZcashVersionGroupId } from "@swapkit/utxo-signer";
|
|
27
28
|
import { createWallet, getWalletSupportedChains, type HardwareExtendedPublicKeyInfo } from "@swapkit/wallet-core";
|
|
28
29
|
|
|
30
|
+
import { applyMissingSpendingMetadata } from "../helpers/psbt";
|
|
31
|
+
|
|
29
32
|
type TrezorBip32Derivation = [Uint8Array, { fingerprint: number; path: number[] }];
|
|
30
33
|
type TrezorCoreMode = "auto" | "iframe" | "popup" | "suite-desktop" | "suite-web";
|
|
31
34
|
type TrezorTransport = "BridgeTransport" | "WebUsbTransport" | "NodeUsbTransport";
|
|
@@ -208,11 +211,11 @@ function decodeOpReturnData(script: Uint8Array): string | null {
|
|
|
208
211
|
function getScriptType(derivationPath: DerivationPathArray) {
|
|
209
212
|
switch (derivationPath[0]) {
|
|
210
213
|
case 84:
|
|
211
|
-
return { input: "SPENDWITNESS", output: "PAYTOWITNESS" } as const;
|
|
214
|
+
return { input: "SPENDWITNESS", output: "PAYTOWITNESS", utxo: UTXOScriptType.P2WPKH } as const;
|
|
212
215
|
case 49:
|
|
213
|
-
return { input: "SPENDP2SHWITNESS", output: "PAYTOP2SHWITNESS" } as const;
|
|
216
|
+
return { input: "SPENDP2SHWITNESS", output: "PAYTOP2SHWITNESS", utxo: UTXOScriptType.P2SH_P2WPKH } as const;
|
|
214
217
|
case 44:
|
|
215
|
-
return { input: "SPENDADDRESS", output: "PAYTOADDRESS" } as const;
|
|
218
|
+
return { input: "SPENDADDRESS", output: "PAYTOADDRESS", utxo: UTXOScriptType.P2PKH } as const;
|
|
216
219
|
default:
|
|
217
220
|
return null;
|
|
218
221
|
}
|
|
@@ -690,6 +693,7 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
690
693
|
}
|
|
691
694
|
|
|
692
695
|
const resolvedScriptType = scriptType;
|
|
696
|
+
const toolboxParams = { scriptType: scriptType.utxo };
|
|
693
697
|
const coin = chain.toLowerCase();
|
|
694
698
|
|
|
695
699
|
const getAddress = async (path: DerivationPathArray = derivationPath) => {
|
|
@@ -717,7 +721,7 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
717
721
|
};
|
|
718
722
|
|
|
719
723
|
const address = providedAddress ?? (await getAddress());
|
|
720
|
-
const baseToolbox = getUtxoToolbox(chain);
|
|
724
|
+
const baseToolbox = getUtxoToolbox(chain, toolboxParams);
|
|
721
725
|
|
|
722
726
|
const signTransaction = async (tx: Transaction, inputs: UTXOType[], memo = "") => {
|
|
723
727
|
const TrezorConnect = (await import("@trezor/connect-web")).default;
|
|
@@ -810,6 +814,8 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
810
814
|
tx.updateInput(inputIndex, { bip32Derivation: [derivation] });
|
|
811
815
|
}
|
|
812
816
|
|
|
817
|
+
await applyMissingSpendingMetadata({ chain: utxoChain, indexes: [inputIndex], publicKey: derivation[0], tx });
|
|
818
|
+
|
|
813
819
|
trezorInputs.push({
|
|
814
820
|
address_n: derivation[1].path,
|
|
815
821
|
amount,
|
|
@@ -998,7 +1004,7 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
998
1004
|
feeRate?: number;
|
|
999
1005
|
feeOptionKey?: (typeof FeeOption)[keyof typeof FeeOption];
|
|
1000
1006
|
}) => {
|
|
1001
|
-
const toolbox = getUtxoToolbox(chain);
|
|
1007
|
+
const toolbox = getUtxoToolbox(chain, toolboxParams);
|
|
1002
1008
|
const txFeeRate = feeRate || (await toolbox.getFeeRates())[feeOptionKey || FeeOption.Fast];
|
|
1003
1009
|
|
|
1004
1010
|
const { tx, inputs: selectedInputs } = await toolbox.createTransaction({
|
|
@@ -1038,7 +1044,7 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
1038
1044
|
});
|
|
1039
1045
|
}
|
|
1040
1046
|
|
|
1041
|
-
const toolbox = getUtxoToolbox(chain);
|
|
1047
|
+
const toolbox = getUtxoToolbox(chain, toolboxParams);
|
|
1042
1048
|
|
|
1043
1049
|
const feeRate = paramFeeRate || (await toolbox.getFeeRates())[feeOptionKey || FeeOption.Fast];
|
|
1044
1050
|
|
|
@@ -1061,6 +1067,7 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
1061
1067
|
|
|
1062
1068
|
const toolbox = shouldUseTrezorPsbtSigner(chain)
|
|
1063
1069
|
? await getUtxoToolbox(utxoChain, {
|
|
1070
|
+
...toolboxParams,
|
|
1064
1071
|
signer: { getAddress: async () => address, signTransaction: signPsbtTransaction },
|
|
1065
1072
|
})
|
|
1066
1073
|
: baseToolbox;
|
package/dist/chunk-gwx23jdp.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{c as C}from"./chunk-3yr76n9s.js";import{d as D}from"./chunk-n05bv2n5.js";import{base64 as m}from"@scure/base";import{HDKey as b}from"@scure/bip32";import{derivationPathToString as P,getWalletFormatFor as x,SwapKitError as X}from"@swapkit/helpers";function g(G){switch(G){case"bech32":return"wpkh(@0/**)";case"p2sh":return"sh(wpkh(@0/**))";case"legacy":return"pkh(@0/**)";default:return"wpkh(@0/**)"}}function u(G){return typeof G==="string"?G:P(G)}function k(G){return G.replace(/^m\//,"").replace(/^\/+/,"")}function l(G){return G.replace(/^m\//,"").split("/").filter(Boolean).map((Q)=>{let R=Q.endsWith("'"),V=Number.parseInt(R?Q.slice(0,-1):Q,10);return R?(V|2147483648)>>>0:V})}function s(G,Q){let R=G.getInput(Q);return Boolean(R.bip32Derivation?.length)}var F=({chain:G})=>{return(Q,R)=>{let V,z;async function _(){if(!V){let q=R??await C(),{AppClient:J}=await import("ledger-bitcoin");V=new J(q)}return V}async function S(){if(!z)z=await(await _()).getMasterFingerprint();return z}let $=k(Q?u(Q):"84'/0'/0'/0/0"),W=$.split("/").filter(Boolean),H=W.slice(0,3).join("/"),w=W.slice(3),E=Number(w[0]??0),K=Number(w[1]??0),L=x(`m/${$}`),T=g(L),j,N;async function O(){let q=await _(),J=await S();if(!j)j=await q.getExtendedPubkey(`m/${H}`);let{DefaultWalletPolicy:M}=await import("ledger-bitcoin"),U=new M(T,`[${J}/${H}]${j}`);return{app:q,fpr:J,policy:U,xpub:j}}async function I(){if(!N){let{xpub:q}=await O(),M=b.fromExtendedKey(q).derive(`m/${E}/${K}`);if(!M.publicKey)throw new X("wallet_ledger_get_address_error",{message:`Cannot derive leaf pubkey for ${G}`});N=M.publicKey}return N}return{connect:async()=>{await _()},getAddress:async()=>{let{app:q,policy:J}=await O(),M=await q.getWalletAddress(J,null,E,K,!1);if(!M)throw new X("wallet_ledger_get_address_error",{message:`Cannot get ${G} address from ledger derivation path: ${$}`});return M},getExtendedPublicKey:async(q=`m/${H}`)=>{return(await _()).getExtendedPubkey(`m/${k(q)}`)},signTransaction:async(q)=>{let{app:J,policy:M,fpr:U}=await O(),v=Number.parseInt(U,16)>>>0,A=l($),B=Array.from({length:q.inputsLength},(Y,Z)=>Z).filter((Y)=>!s(q,Y));if(B.length>0){let Y=await I();for(let Z of B)q.updateInput(Z,{bip32Derivation:[[Y,{fingerprint:v,path:A}]]})}let f=m.encode(q.toPSBT(0)),y=await J.signPsbt(f,M,null);for(let[Y,Z]of y)q.updateInput(Y,{partialSig:[[new Uint8Array(Z.pubkey),new Uint8Array(Z.signature)]]});return q}}}},n=F({chain:"bitcoin"}),p=F({chain:"litecoin"});export{p as LitecoinPsbtLedger,n as BitcoinPsbtLedger};
|
|
2
|
-
|
|
3
|
-
//# debugId=ACED2AE00D3D0A0F64756E2164756E21
|
|
4
|
-
//# sourceMappingURL=chunk-gwx23jdp.js.map
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/ledger/clients/utxo-psbt.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import type Transport from \"@ledgerhq/hw-transport\";\nimport { base64 } from \"@scure/base\";\nimport { HDKey } from \"@scure/bip32\";\nimport { type DerivationPathArray, derivationPathToString, getWalletFormatFor, SwapKitError } from \"@swapkit/helpers\";\nimport type { Transaction } from \"@swapkit/utxo-signer\";\n\nimport { getLedgerTransport } from \"../helpers/getLedgerTransport\";\n\ntype SupportedCoin = \"bitcoin\" | \"litecoin\";\n\ntype DefaultDescriptorTemplate = \"wpkh(@0/**)\" | \"tr(@0/**)\" | \"sh(wpkh(@0/**))\" | \"pkh(@0/**)\";\n\nfunction templateForFormat(format: ReturnType<typeof getWalletFormatFor>): DefaultDescriptorTemplate {\n switch (format) {\n case \"bech32\":\n return \"wpkh(@0/**)\";\n case \"p2sh\":\n return \"sh(wpkh(@0/**))\";\n case \"legacy\":\n return \"pkh(@0/**)\";\n default:\n return \"wpkh(@0/**)\";\n }\n}\n\nfunction pathToString(path: DerivationPathArray | string): string {\n return typeof path === \"string\" ? path : derivationPathToString(path);\n}\n\nfunction normalizeLedgerPath(path: string): string {\n return path.replace(/^m\\//, \"\").replace(/^\\/+/, \"\");\n}\n\nfunction pathToNumberArray(path: string): number[] {\n return path\n .replace(/^m\\//, \"\")\n .split(\"/\")\n .filter(Boolean)\n .map((p) => {\n const hardened = p.endsWith(\"'\");\n const num = Number.parseInt(hardened ? p.slice(0, -1) : p, 10);\n return hardened ? (num | 0x80000000) >>> 0 : num;\n });\n}\n\nfunction hasBip32Derivation(tx: Transaction, inputIndex: number) {\n const input = tx.getInput(inputIndex) as { bip32Derivation?: Array<unknown> };\n\n return Boolean(input.bip32Derivation?.length);\n}\n\nconst BaseLedgerPsbtUTXO = ({ chain }: { chain: SupportedCoin }) => {\n return (derivationPathArray?: DerivationPathArray | string, injectedTransport?: Transport) => {\n // Per-call state — each BitcoinPsbtLedger/LitecoinPsbtLedger invocation has its own\n // AppClient and master fingerprint so different consumers (e.g. concurrent MCP\n // sessions on different devices) cannot inherit each other's ledger bindings or xpub.\n let appClient: import(\"ledger-bitcoin\").AppClient | undefined;\n let masterFingerprint: string | undefined;\n\n async function getAppClient() {\n if (!appClient) {\n const transport = injectedTransport ?? (await getLedgerTransport());\n const { AppClient } = await import(\"ledger-bitcoin\");\n appClient = new AppClient(transport);\n }\n return appClient;\n }\n\n async function getFingerprint() {\n if (!masterFingerprint) {\n const app = await getAppClient();\n masterFingerprint = await app.getMasterFingerprint();\n }\n return masterFingerprint;\n }\n\n // Single-address account: change == index == 0 by default.\n const derivationPath = normalizeLedgerPath(\n derivationPathArray ? pathToString(derivationPathArray) : \"84'/0'/0'/0/0\",\n );\n const pathSegments = derivationPath.split(\"/\").filter(Boolean);\n const accountPath = pathSegments.slice(0, 3).join(\"/\");\n const leafSegments = pathSegments.slice(3);\n const change = Number(leafSegments[0] ?? 0);\n const addressIndex = Number(leafSegments[1] ?? 0);\n // getWalletFormatFor expects an m/-prefixed path (it reads the purpose\n // from the second segment); derivationPath is normalized without it.\n const format = getWalletFormatFor(`m/${derivationPath}`);\n const template = templateForFormat(format);\n\n let cachedAccountXpub: string | undefined;\n let cachedLeafPubkey: Uint8Array | undefined;\n\n async function buildPolicy() {\n const app = await getAppClient();\n const fpr = await getFingerprint();\n if (!cachedAccountXpub) {\n cachedAccountXpub = await app.getExtendedPubkey(`m/${accountPath}`);\n }\n const { DefaultWalletPolicy } = await import(\"ledger-bitcoin\");\n const policy = new DefaultWalletPolicy(template, `[${fpr}/${accountPath}]${cachedAccountXpub}`);\n return { app, fpr, policy, xpub: cachedAccountXpub };\n }\n\n async function getLeafPubkey() {\n if (!cachedLeafPubkey) {\n const { xpub } = await buildPolicy();\n const accountKey = HDKey.fromExtendedKey(xpub);\n const leaf = accountKey.derive(`m/${change}/${addressIndex}`);\n if (!leaf.publicKey) {\n throw new SwapKitError(\"wallet_ledger_get_address_error\", {\n message: `Cannot derive leaf pubkey for ${chain}`,\n });\n }\n cachedLeafPubkey = leaf.publicKey;\n }\n return cachedLeafPubkey;\n }\n\n return {\n connect: async () => {\n await getAppClient();\n },\n getAddress: async () => {\n const { app, policy } = await buildPolicy();\n const address = await app.getWalletAddress(policy, null, change, addressIndex, false);\n if (!address) {\n throw new SwapKitError(\"wallet_ledger_get_address_error\", {\n message: `Cannot get ${chain} address from ledger derivation path: ${derivationPath}`,\n });\n }\n return address;\n },\n getExtendedPublicKey: async (path = `m/${accountPath}`) => {\n const app = await getAppClient();\n return app.getExtendedPubkey(`m/${normalizeLedgerPath(path)}`);\n },\n signTransaction: async (tx: Transaction): Promise<Transaction> => {\n const { app, policy, fpr } = await buildPolicy();\n const fingerprintBE = Number.parseInt(fpr, 16) >>> 0;\n const pathNumbers = pathToNumberArray(derivationPath);\n const missingDerivationIndexes = Array.from({ length: tx.inputsLength }, (_, inputIndex) => inputIndex).filter(\n (inputIndex) => !hasBip32Derivation(tx, inputIndex),\n );\n\n if (missingDerivationIndexes.length > 0) {\n const leafPubkey = await getLeafPubkey();\n\n // Fallback for PSBTs that do not include per-input HD key origins.\n for (const inputIndex of missingDerivationIndexes) {\n tx.updateInput(inputIndex, {\n bip32Derivation: [[leafPubkey, { fingerprint: fingerprintBE, path: pathNumbers }]],\n });\n }\n }\n\n const psbtB64 = base64.encode(tx.toPSBT(0));\n const sigs = await app.signPsbt(psbtB64, policy, null);\n\n for (const [idx, partial] of sigs) {\n tx.updateInput(idx, { partialSig: [[new Uint8Array(partial.pubkey), new Uint8Array(partial.signature)]] });\n }\n\n return tx;\n },\n };\n };\n};\n\nexport const BitcoinPsbtLedger = BaseLedgerPsbtUTXO({ chain: \"bitcoin\" });\nexport const LitecoinPsbtLedger = BaseLedgerPsbtUTXO({ chain: \"litecoin\" });\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "ACED2AE00D3D0A0F64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
File without changes
|