@babylonlabs-io/ts-sdk 0.68.0 → 0.69.0
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/PeginManager-DSFecw-w.js +1503 -0
- package/dist/PeginManager-DSFecw-w.js.map +1 -0
- package/dist/PeginManager-VM-jifLt.cjs +2 -0
- package/dist/PeginManager-VM-jifLt.cjs.map +1 -0
- package/dist/{batchPoll-Cjj1du0i.js → batchPoll-Bc_UKaTz.js} +2 -2
- package/dist/{batchPoll-Cjj1du0i.js.map → batchPoll-Bc_UKaTz.js.map} +1 -1
- package/dist/{batchPoll-REVZiE-M.cjs → batchPoll-C9cZ5usJ.cjs} +2 -2
- package/dist/{batchPoll-REVZiE-M.cjs.map → batchPoll-C9cZ5usJ.cjs.map} +1 -1
- package/dist/buildAndBroadcastRefund-CPPGvzXb.cjs +2 -0
- package/dist/buildAndBroadcastRefund-CPPGvzXb.cjs.map +1 -0
- package/dist/{buildAndBroadcastRefund-CpMDJ8up.js → buildAndBroadcastRefund-DY4ZZcFL.js} +3 -3
- package/dist/buildAndBroadcastRefund-DY4ZZcFL.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +7 -7
- package/dist/{mempoolApi-_D-jvtj_.js → mempoolApi-71R_CNZa.js} +71 -69
- package/dist/mempoolApi-71R_CNZa.js.map +1 -0
- package/dist/mempoolApi-BJN9fGEd.cjs +2 -0
- package/dist/mempoolApi-BJN9fGEd.cjs.map +1 -0
- package/dist/signPsbtsWithFallback-C5cVgYhh.cjs +2 -0
- package/dist/signPsbtsWithFallback-C5cVgYhh.cjs.map +1 -0
- package/dist/{signPsbtsWithFallback-Bv79gLFe.js → signPsbtsWithFallback-DCZO2h6i.js} +84 -81
- package/dist/signPsbtsWithFallback-DCZO2h6i.js.map +1 -0
- package/dist/tbv/core/clients/index.cjs +1 -1
- package/dist/tbv/core/clients/index.js +2 -2
- package/dist/tbv/core/clients/vault-provider/auth/bip322Verify.d.ts +9 -0
- package/dist/tbv/core/clients/vault-provider/auth/bip322Verify.d.ts.map +1 -1
- package/dist/tbv/core/deposit-terms/depositTerms.d.ts +13 -0
- package/dist/tbv/core/deposit-terms/depositTerms.d.ts.map +1 -1
- package/dist/tbv/core/deposit-terms/prePeginApproval.d.ts +1 -0
- package/dist/tbv/core/deposit-terms/prePeginApproval.d.ts.map +1 -1
- package/dist/tbv/core/index.cjs +1 -1
- package/dist/tbv/core/index.js +7 -7
- package/dist/tbv/core/managers/PeginManager.d.ts +6 -0
- package/dist/tbv/core/managers/PeginManager.d.ts.map +1 -1
- package/dist/tbv/core/managers/index.cjs +1 -1
- package/dist/tbv/core/managers/index.js +2 -2
- package/dist/tbv/core/managers/pegin/verifyPopWitness.d.ts.map +1 -1
- package/dist/tbv/core/primitives/index.cjs +1 -1
- package/dist/tbv/core/primitives/index.js +1 -1
- package/dist/tbv/core/primitives/psbt/verifyKeyPathSchnorrSignature.d.ts +6 -5
- package/dist/tbv/core/primitives/psbt/verifyKeyPathSchnorrSignature.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/runDepositorPresignFlow.d.ts.map +1 -1
- package/dist/tbv/core/services/index.cjs +1 -1
- package/dist/tbv/core/services/index.js +2 -2
- package/dist/tbv/index.cjs +1 -1
- package/dist/tbv/index.js +7 -7
- package/dist/testing/MockBitcoinWallet.d.ts +1 -1
- package/dist/testing/MockBitcoinWallet.d.ts.map +1 -1
- package/dist/testing/index.cjs +1 -1
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.js +66 -62
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/signBip322P2wpkhWitness.d.ts +5 -0
- package/dist/testing/signBip322P2wpkhWitness.d.ts.map +1 -1
- package/dist/{toRefundInputs-9hv_6k0E.js → toRefundInputs-C012ZXcp.js} +3 -3
- package/dist/{toRefundInputs-9hv_6k0E.js.map → toRefundInputs-C012ZXcp.js.map} +1 -1
- package/dist/{toRefundInputs-D8sFs44p.cjs → toRefundInputs-DaxiTty9.cjs} +2 -2
- package/dist/{toRefundInputs-D8sFs44p.cjs.map → toRefundInputs-DaxiTty9.cjs.map} +1 -1
- package/dist/{verifyKeyPathSchnorrSignature-oGCUbjjZ.js → verifyKeyPathSchnorrSignature-C6Cmk0R1.js} +137 -128
- package/dist/verifyKeyPathSchnorrSignature-C6Cmk0R1.js.map +1 -0
- package/dist/verifyKeyPathSchnorrSignature-Cr5T4Aym.cjs +2 -0
- package/dist/verifyKeyPathSchnorrSignature-Cr5T4Aym.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/PeginManager--2R3T2S8.js +0 -1458
- package/dist/PeginManager--2R3T2S8.js.map +0 -1
- package/dist/PeginManager-CKWq8ouZ.cjs +0 -2
- package/dist/PeginManager-CKWq8ouZ.cjs.map +0 -1
- package/dist/buildAndBroadcastRefund-CpMDJ8up.js.map +0 -1
- package/dist/buildAndBroadcastRefund-DrXwxrW1.cjs +0 -2
- package/dist/buildAndBroadcastRefund-DrXwxrW1.cjs.map +0 -1
- package/dist/mempoolApi-EU1La9wk.cjs +0 -2
- package/dist/mempoolApi-EU1La9wk.cjs.map +0 -1
- package/dist/mempoolApi-_D-jvtj_.js.map +0 -1
- package/dist/signPsbtsWithFallback-Bv79gLFe.js.map +0 -1
- package/dist/signPsbtsWithFallback-DJ4kE9UI.cjs +0 -2
- package/dist/signPsbtsWithFallback-DJ4kE9UI.cjs.map +0 -1
- package/dist/verifyKeyPathSchnorrSignature-DCOzQkDf.cjs +0 -2
- package/dist/verifyKeyPathSchnorrSignature-DCOzQkDf.cjs.map +0 -1
- package/dist/verifyKeyPathSchnorrSignature-oGCUbjjZ.js.map +0 -1
package/dist/tbv/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { P as s, f as t, g as r, d as i, b as o, a as n, c as P, h as p, e as u } from "../verifyScriptPathSchnorrSignature-Dy9gF5RF.js";
|
|
2
2
|
import { a as c } from "../constants-GjWXdaqV.js";
|
|
3
3
|
import { computeMinClaimValue as E, computeMinPeginFee as g, deriveVaultId as A, expandAuthAnchor as T, expandHashlockSecret as S, expandWotsSeed as R, peginP2aAnchorOutput as m, supportedTxGraphVersions as _, validatePeginP2aAnchor as f } from "@babylonlabs-io/babylon-tbv-rust-wasm";
|
|
4
|
-
import { a as x, c as h, b as O, e as b, f as I } from "../verifyKeyPathSchnorrSignature-
|
|
4
|
+
import { a as x, c as h, b as O, e as b, f as I } from "../verifyKeyPathSchnorrSignature-C6Cmk0R1.js";
|
|
5
5
|
import { a as V, b as y } from "../noPayout-CXn-geIS.js";
|
|
6
6
|
import { b as F } from "../challengeAssert-BNQ8sToz.js";
|
|
7
7
|
import { c as N, d as B, a as U, b as H, e as K, f as L, k, g as X, h as w, i as W, j as G, p as j, s as J, t as z, u as Y, v as Z } from "../bitcoin-Ch_jxnDa.js";
|
|
8
8
|
import { B as Q, H as $, K as aa, M as ea, T as sa, c as ta } from "../validation-Dj3dqYtl.js";
|
|
9
9
|
import { c as ia } from "../signing-DaLvGwQe.js";
|
|
10
|
-
import { C as na, M as Pa, P as pa, b as ua, a as da, c as ca, d as la, f as Ea, e as ga } from "../PeginManager
|
|
11
|
-
import { P as Ta, c as Sa, f as Ra, r as ma, s as _a, v as fa } from "../signPsbtsWithFallback-
|
|
10
|
+
import { C as na, M as Pa, P as pa, b as ua, a as da, c as ca, d as la, f as Ea, e as ga } from "../PeginManager-DSFecw-w.js";
|
|
11
|
+
import { P as Ta, c as Sa, f as Ra, r as ma, s as _a, v as fa } from "../signPsbtsWithFallback-DCZO2h6i.js";
|
|
12
12
|
import { A as xa, P as ha } from "../ProtocolParams.abi-C0TSRaHV.js";
|
|
13
13
|
import { B as ba } from "../BTCVaultRegistry.abi-CJwWI2EO.js";
|
|
14
14
|
import { B as va } from "../BTCVaultRegistryKeyEpochs.abi-CXjhRZbm.js";
|
|
@@ -17,12 +17,12 @@ import { V as Ua, b as Ha, a as Ka, d as La, f as ka, p as Xa } from "../parseFu
|
|
|
17
17
|
import { B as Wa, a as Ga, f as ja, c as Ja, b as za, d as Ya, g as Za, i as qa, h as Qa, s as $a, e as ae, w as ee } from "../waitForTransactionReceiptSmartAware-lobLm0q0.js";
|
|
18
18
|
import { B as te, D as re, L as ie, M as oe, c as ne, P as Pe, b as pe, a as ue, S as de, T as ce, W as le, f as Ee, d as ge, p as Ae, r as Te } from "../fundPeginTransaction-B2wyjqp0.js";
|
|
19
19
|
import { U as Re, a as me, e as _e, f as fe, v as Ce } from "../reservation-CBAvoF3U.js";
|
|
20
|
-
import { M as he, V as Oe, g as be, a as Ie, b as ve, c as Ve, d as ye, e as De, f as Fe, h as Me, i as Ne, p as Be, v as Ue, j as He, k as Ke } from "../mempoolApi-
|
|
21
|
-
import { O as ke, S as Xe, V as we, g as We, h as Ge, i as je, j as Je, a as ze, d as Ye, b as Ze, f as qe, p as Qe, r as $e, v as as, c as es, e as ss } from "../batchPoll-
|
|
20
|
+
import { M as he, V as Oe, g as be, a as Ie, b as ve, c as Ve, d as ye, e as De, f as Fe, h as Me, i as Ne, p as Be, v as Ue, j as He, k as Ke } from "../mempoolApi-71R_CNZa.js";
|
|
21
|
+
import { O as ke, S as Xe, V as we, g as We, h as Ge, i as je, j as Je, a as ze, d as Ye, b as Ze, f as qe, p as Qe, r as $e, v as as, c as es, e as ss } from "../batchPoll-Bc_UKaTz.js";
|
|
22
22
|
import { A as rs, D as is, J as os, a as ns, b as Ps, d as ps, P as us, R as ds, e as cs, c as ls, V as Es, i as gs } from "../json-rpc-client-DuUARJvV.js";
|
|
23
23
|
import { a as Ts } from "../onChainBtcPubkey-BAHZyKQL.js";
|
|
24
|
-
import { D as Rs, a as ms, h as _s, j as fs, P as Cs, k as xs, U as hs, V as Os, c as bs, d as Is, f as vs, e as Vs, b as ys, i as Ds, r as Fs, g as Ms, t as Ns } from "../toRefundInputs-
|
|
25
|
-
import { H as Us, E as Hs, P as Ks, o as Ls, c as ks, d as Xs, K as ws, L as Ws, M as Gs, N as js, R as Js, a as zs, b as Ys, y as Zs, I as qs, J as Qs, g as $s, z as at, p as et, i as st, e as tt, G as rt, F as it, t as ot, A as nt, B as Pt, C as pt, D as ut, r as dt, s as ct, f as lt, h as Et, j as gt, v as At, k as Tt, l as St, m as Rt, n as mt, q as _t, u as ft, w as Ct, x as xt } from "../buildAndBroadcastRefund-
|
|
24
|
+
import { D as Rs, a as ms, h as _s, j as fs, P as Cs, k as xs, U as hs, V as Os, c as bs, d as Is, f as vs, e as Vs, b as ys, i as Ds, r as Fs, g as Ms, t as Ns } from "../toRefundInputs-C012ZXcp.js";
|
|
25
|
+
import { H as Us, E as Hs, P as Ks, o as Ls, c as ks, d as Xs, K as ws, L as Ws, M as Gs, N as js, R as Js, a as zs, b as Ys, y as Zs, I as qs, J as Qs, g as $s, z as at, p as et, i as st, e as tt, G as rt, F as it, t as ot, A as nt, B as Pt, C as pt, D as ut, r as dt, s as ct, f as lt, h as Et, j as gt, v as At, k as Tt, l as St, m as Rt, n as mt, q as _t, u as ft, w as Ct, x as xt } from "../buildAndBroadcastRefund-DY4ZZcFL.js";
|
|
26
26
|
import { C as Ot, P as bt, c as It, g as vt, i as Vt } from "../peginState-CxDiaKuk.js";
|
|
27
27
|
export {
|
|
28
28
|
rs as AUTH_REJECTED_RPC_CODE,
|
|
@@ -34,7 +34,7 @@ export declare class MockBitcoinWallet implements BitcoinWallet {
|
|
|
34
34
|
getAddress(): Promise<string>;
|
|
35
35
|
signPsbt(psbtHex: string, _options?: SignPsbtOptions): Promise<string>;
|
|
36
36
|
signPsbts(psbtsHexes: string[], _options?: SignPsbtOptions[]): Promise<string[]>;
|
|
37
|
-
signMessage(message: string,
|
|
37
|
+
signMessage(message: string, type: "bip322-simple" | "ecdsa"): Promise<string>;
|
|
38
38
|
getNetwork(): Promise<BitcoinNetwork>;
|
|
39
39
|
deriveContextHash(appName: string, context: string): Promise<string>;
|
|
40
40
|
/** Updates configuration for testing different scenarios. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MockBitcoinWallet.d.ts","sourceRoot":"","sources":["../../src/testing/MockBitcoinWallet.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAChB,MAAM,4CAA4C,CAAC;AAOpD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3E;AAkDD,uCAAuC;AACvC,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,MAAM,CAAoC;gBAEtC,MAAM,GAAE,uBAA4B;IAqB1C,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAIlC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IActE,SAAS,CACb,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC;IASd,WAAW,CACf,OAAO,EAAE,MAAM,EACf,
|
|
1
|
+
{"version":3,"file":"MockBitcoinWallet.d.ts","sourceRoot":"","sources":["../../src/testing/MockBitcoinWallet.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAChB,MAAM,4CAA4C,CAAC;AAOpD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3E;AAkDD,uCAAuC;AACvC,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,MAAM,CAAoC;gBAEtC,MAAM,GAAE,uBAA4B;IAqB1C,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAIlC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IActE,SAAS,CACb,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC;IASd,WAAW,CACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,GAAG,OAAO,GAC9B,OAAO,CAAC,MAAM,CAAC;IA2CZ,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC;IAIrC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1E,6DAA6D;IAC7D,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,IAAI;IAY7D,uCAAuC;IACvC,KAAK,IAAI,IAAI;CAGd"}
|
package/dist/testing/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var S=Object.defineProperty;var O=(i,e,t)=>e in i?S(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var c=(i,e,t)=>O(i,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("@bitcoin-js/tiny-secp256k1-asmjs"),y=require("../sha2-DsrLC4NM.cjs"),o=require("buffer"),u=require("../bitcoin-m84N5a8o.cjs"),l=require("bitcoinjs-lib"),k=require("../shared/index.cjs");function B(i){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(i){for(const t in i)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(i,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>i[t]})}}return e.default=i,Object.freeze(e)}const b=B(v),I="BIP0322-signed-message",E=1,g=0,K=71,D=100,H=0,T=0,_=0,N=32,F=4294967295,M=0,U=0,A=32,C=106,W=2,R=32,$=0;function G(i,e){const t=b.pointFromScalar(e,!0);if(!t)throw new Error("signBip322P2wpkhWitness: invalid private key");const n=y.sha256(new TextEncoder().encode(I)),s=y.sha256(o.Buffer.concat([n,n,o.Buffer.from(i)])),r=l.payments.p2wpkh({pubkey:o.Buffer.from(t)});if(!r.output||!r.hash)throw new Error("signBip322P2wpkhWitness: could not derive P2WPKH script");const a=new l.Transaction;a.version=H,a.locktime=T,a.addInput(o.Buffer.alloc(N,0),F,_,o.Buffer.concat([o.Buffer.from([U,A]),o.Buffer.from(s)])),a.addOutput(r.output,g);const h=new l.Transaction;h.version=H,h.locktime=T,h.addInput(a.getHash(),M,_),h.addOutput(o.Buffer.from([C]),g);const q=l.payments.p2pkh({hash:r.hash}).output;if(!q)throw new Error("signBip322P2wpkhWitness: could not build scriptCode");const P=h.hashForWitnessV0(0,q,g,E);let d;for(let f=0;f<D;f++){const w=o.Buffer.alloc(R,0);w.writeUInt32LE(f,$);const x=l.script.signature.encode(o.Buffer.from(b.sign(P,e,w)),E);if(x.length>=K){d=x;break}}if(!d)throw new Error("signBip322P2wpkhWitness: could not grind a 71/72-byte signature");return Uint8Array.from([W,d.length,...d,t.length,...t])}const X=async(i,e)=>{const t=new TextEncoder,n=t.encode(i),s=t.encode(e),r=new Uint8Array(4+n.length+4+s.length),a=new DataView(r.buffer);return a.setUint32(0,n.length),r.set(n,4),a.setUint32(4+n.length,s.length),r.set(s,4+n.length+4),u.uint8ArrayToHex(y.sha256(r))},j=`${"00".repeat(31)}01`;function p(i){return u.uint8ArrayToHex(b.xOnlyPointFromScalar(Uint8Array.from(o.Buffer.from(i,"hex"))))}const m={publicKeyHex:"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",address:"tb1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkx6jks",network:k.BitcoinNetworks.SIGNET,shouldFailSigning:!1,privateKeyHex:j,deriveContextHash:X};class L{constructor(e={}){c(this,"config");this.config={...m,...e.publicKeyHex?{publicKeyHex:e.publicKeyHex}:{},...e.address?{address:e.address}:{},...e.network!==void 0?{network:e.network}:{},...e.shouldFailSigning!==void 0?{shouldFailSigning:e.shouldFailSigning}:{},...e.privateKeyHex?{privateKeyHex:e.privateKeyHex}:{},...e.deriveContextHash?{deriveContextHash:e.deriveContextHash}:{}},e.privateKeyHex&&!e.publicKeyHex&&(this.config.publicKeyHex=p(e.privateKeyHex))}async getPublicKeyHex(){return this.config.publicKeyHex}async getAddress(){return this.config.address}async signPsbt(e,t){if(this.config.shouldFailSigning)throw new Error("Mock signing failed");if(!e||e.length===0)throw new Error("Invalid PSBT: empty hex string");return e+"deadbeef"}async signPsbts(e,t){const n=[];for(const s of e){const r=await this.signPsbt(s);n.push(r)}return n}async signMessage(e,t){if(t!=="bip322-simple")throw new Error("MockBitcoinWallet.signMessage: only bip322-simple is implemented");if(this.config.shouldFailSigning)throw new Error("Mock signing failed");if(!e||e.length===0)throw new Error("Invalid message: empty string");const n=p(this.config.privateKeyHex);let s;try{s=u.canonicalizeBtcPubkey(this.config.publicKeyHex)}catch{s=void 0}if(s!==n)throw new Error(`MockBitcoinWallet.signMessage: privateKeyHex signs as x-only pubkey ${n}, but publicKeyHex is ${this.config.publicKeyHex}. Pass a matching publicKeyHex/privateKeyHex pair.`);const r=G(new TextEncoder().encode(e),Uint8Array.from(o.Buffer.from(this.config.privateKeyHex,"hex")));return`0x${u.uint8ArrayToHex(r)}`}async getNetwork(){return this.config.network}async deriveContextHash(e,t){return this.config.deriveContextHash(e,t)}updateConfig(e){this.config={...this.config,...e},e.privateKeyHex&&!e.publicKeyHex&&(this.config.publicKeyHex=p(e.privateKeyHex))}reset(){this.config={...m}}}class V{constructor(e={}){c(this,"account");c(this,"chain");c(this,"shouldFailOperations");c(this,"transactionDelay");c(this,"nonce",0);this.account={address:e.address||"0x742d35cc6634c0532925a3b844bc9e7595f0beb0"},this.chain={id:e.chainId??11155111},this.shouldFailOperations=e.shouldFailOperations??!1,this.transactionDelay=e.transactionDelay??0,this.signMessage=this.signMessage.bind(this),this.sendTransaction=this.sendTransaction.bind(this)}async signMessage(e){const t=e.message,n=e.account||this.account.address;if(this.shouldFailOperations)throw new Error("Mock signing failed");if(!t||t.length===0)throw new Error("Invalid message: empty string");const s=`personal_sign:${t}-${n}-${this.chain.id}`;return`0x${o.Buffer.from(s).toString("hex").slice(0,130).padEnd(130,"0")}`}async sendTransaction(e){var s;if(this.shouldFailOperations)throw new Error("Mock transaction failed");if(!e.to)throw new Error("Invalid transaction: missing 'to' address");this.transactionDelay>0&&await new Promise(r=>setTimeout(r,this.transactionDelay)),this.nonce++;const t=JSON.stringify({from:this.account.address,to:e.to,value:((s=e.value)==null?void 0:s.toString())||"0",nonce:this.nonce,chainId:this.chain.id});return`0x${o.Buffer.from(t).toString("hex").slice(0,64).padEnd(64,"0")}`}updateConfig(e){e.address!==void 0&&(this.account.address=e.address),e.chainId!==void 0&&(this.chain.id=e.chainId),e.shouldFailOperations!==void 0&&(this.shouldFailOperations=e.shouldFailOperations),e.transactionDelay!==void 0&&(this.transactionDelay=e.transactionDelay)}reset(){this.account.address="0x742d35cc6634c0532925a3b844bc9e7595f0beb0",this.chain.id=11155111,this.shouldFailOperations=!1,this.transactionDelay=0,this.nonce=0}getCurrentNonce(){return this.nonce}}exports.MockBitcoinWallet=L;exports.MockEthereumWallet=V;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/testing/signBip322P2wpkhWitness.ts","../../src/testing/MockBitcoinWallet.ts","../../src/testing/MockEthereumWallet.ts"],"sourcesContent":["/**\n * Test-support BIP-322 \"simple\" P2WPKH signer.\n *\n * Produces the consensus-encoded two-item witness `[DER sig ‖ 0x01,\n * compressed pubkey]` that a Native SegWit software wallet returns for\n * `signMessage(..., \"bip322-simple\")`. The virtual to_spend/to_sign\n * construction follows the `bip322` crate 0.0.10 (`util.rs:18-85`) — the\n * same reference the production verifier\n * (`tbv/core/clients/vault-provider/auth/bip322Verify.ts`) mirrors, and\n * the BIP-322 official vectors pin.\n *\n * Test-only: never feed real key material to this module.\n */\n\nimport * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { script as bscript, payments, Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\n/** BIP-322 message tag (BIP-340 tagged-hash style). */\nconst BIP322_TAG = \"BIP0322-signed-message\";\nconst SIGHASH_ALL = 0x01;\nconst ZERO_SATS = 0;\n/**\n * vaultd accepts only 71/72-byte encoded signatures (`bip322` crate 0.0.10\n * `verify.rs:141-153`); a short-DER signature (~0.8% of draws) is ground\n * away by re-signing with fresh entropy. 100 attempts bounds the failure\n * probability around 0.008^100.\n */\nconst MIN_ENCODED_SIG_BYTES = 71;\nconst MAX_SIGN_GRIND_ATTEMPTS = 100;\n\n// Wire fields of the virtual to_spend/to_sign transactions (`bip322`\n// crate 0.0.10 `util.rs:18-85`).\nconst BIP322_TX_VERSION = 0;\nconst BIP322_TX_LOCKTIME = 0;\nconst BIP322_INPUT_SEQUENCE = 0;\n/** to_spend prevout: all-zero 32-byte txid at index 0xFFFFFFFF (`util.rs:18-85`). */\nconst TO_SPEND_PREVOUT_TXID_BYTES = 32;\nconst TO_SPEND_PREVOUT_INDEX = 0xffffffff;\n/** to_sign spends to_spend's only output (`util.rs:18-85`). */\nconst TO_SPEND_OUTPUT_INDEX = 0;\nconst OP_0 = 0x00;\n/** Direct push of the 32-byte tagged message hash. */\nconst OP_PUSHBYTES_32 = 0x20;\nconst OP_RETURN = 0x6a;\n/** Consensus P2WPKH witness: exactly [signature, pubkey]. */\nconst P2WPKH_WITNESS_ITEMS = 2;\n/** Grinding: 32-byte extra-entropy buffer, attempt counter at offset 0. */\nconst GRIND_ENTROPY_BYTES = 32;\nconst GRIND_COUNTER_OFFSET = 0;\n\n/**\n * Sign `messageBytes` as a BIP-322 \"simple\" P2WPKH proof with `privateKey`\n * and return the consensus-encoded two-item witness\n * (`0x02 ‖ len ‖ sig ‖ 0x21 ‖ pubkey`).\n */\nexport function signBip322P2wpkhWitness(\n messageBytes: Uint8Array,\n privateKey: Uint8Array,\n): Uint8Array {\n const pubkey = ecc.pointFromScalar(privateKey, true);\n if (!pubkey) {\n throw new Error(\"signBip322P2wpkhWitness: invalid private key\");\n }\n\n // m_hash = SHA256( SHA256(tag) ‖ SHA256(tag) ‖ message )\n const tagHash = sha256(new TextEncoder().encode(BIP322_TAG));\n const messageHash = sha256(\n Buffer.concat([tagHash, tagHash, Buffer.from(messageBytes)]),\n );\n\n const p2wpkh = payments.p2wpkh({ pubkey: Buffer.from(pubkey) });\n if (!p2wpkh.output || !p2wpkh.hash) {\n throw new Error(\"signBip322P2wpkhWitness: could not derive P2WPKH script\");\n }\n\n // to_spend / to_sign per bip322 crate util.rs:18-85.\n const toSpend = new Transaction();\n toSpend.version = BIP322_TX_VERSION;\n toSpend.locktime = BIP322_TX_LOCKTIME;\n toSpend.addInput(\n Buffer.alloc(TO_SPEND_PREVOUT_TXID_BYTES, 0),\n TO_SPEND_PREVOUT_INDEX,\n BIP322_INPUT_SEQUENCE,\n Buffer.concat([\n Buffer.from([OP_0, OP_PUSHBYTES_32]),\n Buffer.from(messageHash),\n ]),\n );\n toSpend.addOutput(p2wpkh.output, ZERO_SATS);\n const toSign = new Transaction();\n toSign.version = BIP322_TX_VERSION;\n toSign.locktime = BIP322_TX_LOCKTIME;\n toSign.addInput(\n toSpend.getHash(),\n TO_SPEND_OUTPUT_INDEX,\n BIP322_INPUT_SEQUENCE,\n );\n toSign.addOutput(Buffer.from([OP_RETURN]), ZERO_SATS);\n\n // BIP-143 sighash with the standard P2WPKH scriptCode, value 0\n // (bip322 crate verify.rs:163-173).\n const scriptCode = payments.p2pkh({ hash: p2wpkh.hash }).output;\n if (!scriptCode) {\n throw new Error(\"signBip322P2wpkhWitness: could not build scriptCode\");\n }\n const sighash = toSign.hashForWitnessV0(\n 0,\n scriptCode,\n ZERO_SATS,\n SIGHASH_ALL,\n );\n\n let encodedSignature: Buffer | undefined;\n for (let attempt = 0; attempt < MAX_SIGN_GRIND_ATTEMPTS; attempt++) {\n const entropy = Buffer.alloc(GRIND_ENTROPY_BYTES, 0);\n entropy.writeUInt32LE(attempt, GRIND_COUNTER_OFFSET);\n // ecc.sign emits low-S (libsecp256k1), so 73-byte encodings can't occur.\n const candidate = bscript.signature.encode(\n Buffer.from(ecc.sign(sighash, privateKey, entropy)),\n SIGHASH_ALL,\n );\n if (candidate.length >= MIN_ENCODED_SIG_BYTES) {\n encodedSignature = candidate;\n break;\n }\n }\n if (!encodedSignature) {\n throw new Error(\n \"signBip322P2wpkhWitness: could not grind a 71/72-byte signature\",\n );\n }\n\n return Uint8Array.from([\n P2WPKH_WITNESS_ITEMS,\n encodedSignature.length,\n ...encodedSignature,\n pubkey.length,\n ...pubkey,\n ]);\n}\n","import * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { Buffer } from \"buffer\";\n\nimport {\n BitcoinNetworks,\n type BitcoinNetwork,\n} from \"../shared/wallets/interfaces\";\nimport type {\n BitcoinWallet,\n SignPsbtOptions,\n} from \"../shared/wallets/interfaces/BitcoinWallet\";\nimport {\n canonicalizeBtcPubkey,\n uint8ArrayToHex,\n} from \"../tbv/core/primitives/utils/bitcoin\";\nimport { signBip322P2wpkhWitness } from \"./signBip322P2wpkhWitness\";\n\n/**\n * Configuration for MockBitcoinWallet.\n */\nexport interface MockBitcoinWalletConfig {\n publicKeyHex?: string;\n address?: string;\n network?: BitcoinNetwork;\n shouldFailSigning?: boolean;\n /**\n * 32-byte hex key `signMessage` signs BIP-322 proofs with. Defaults to\n * the privkey-1 test key, whose x-only pubkey is the default\n * `publicKeyHex` (the secp256k1 generator's x coordinate). PoP flows\n * verify the witness against `publicKeyHex`: overriding only this key\n * derives the matching `publicKeyHex`, and a divergent pair throws at\n * sign time. Test material only — never a real key.\n */\n privateKeyHex?: string;\n /**\n * Optional override for `deriveContextHash`. When omitted the mock\n * returns a deterministic 64-char lowercase hex string derived from\n * `(appName, context)` so tests can assert pass-through wiring\n * without pinning a specific value. Override to inject spec test\n * vectors or to simulate failure modes.\n */\n deriveContextHash?: (appName: string, context: string) => Promise<string>;\n}\n\n/**\n * Default `deriveContextHash` implementation: deterministic and\n * collision-resistant via SHA-256, so tests that assert pass-through\n * wiring (different `(appName, context)` → different output) hold\n * without flakes. Domain-separates the two inputs by length-prefixing\n * each as `len(name) || name || len(ctx) || ctx`, preventing\n * `(\"ab\", \"cd\")` from colliding with `(\"abc\", \"d\")`.\n */\nconst defaultDeriveContextHash = async (\n appName: string,\n context: string,\n): Promise<string> => {\n const enc = new TextEncoder();\n const nameBytes = enc.encode(appName);\n const ctxBytes = enc.encode(context);\n const buf = new Uint8Array(4 + nameBytes.length + 4 + ctxBytes.length);\n const view = new DataView(buf.buffer);\n view.setUint32(0, nameBytes.length);\n buf.set(nameBytes, 4);\n view.setUint32(4 + nameBytes.length, ctxBytes.length);\n buf.set(ctxBytes, 4 + nameBytes.length + 4);\n return uint8ArrayToHex(sha256(buf));\n};\n\n/** Privkey 1 — the test key `signMessage` signs with by default. */\nconst DEFAULT_PRIVATE_KEY_HEX = `${\"00\".repeat(31)}01`;\n\n/** Lowercase x-only pubkey of a 32-byte private key. */\nfunction xOnlyPubkeyHexOf(privateKeyHex: string): string {\n return uint8ArrayToHex(\n ecc.xOnlyPointFromScalar(\n Uint8Array.from(Buffer.from(privateKeyHex, \"hex\")),\n ),\n );\n}\n\nconst DEFAULT_CONFIG: Required<MockBitcoinWalletConfig> = {\n // x-only pubkey of DEFAULT_PRIVATE_KEY_HEX (the secp256k1 generator's x\n // coordinate), so the default wallet's PoP witnesses verify against it.\n publicKeyHex:\n \"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\n address: \"tb1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkx6jks\",\n network: BitcoinNetworks.SIGNET,\n shouldFailSigning: false,\n privateKeyHex: DEFAULT_PRIVATE_KEY_HEX,\n deriveContextHash: defaultDeriveContextHash,\n};\n\n/** Mock Bitcoin wallet for testing. */\nexport class MockBitcoinWallet implements BitcoinWallet {\n private config: Required<MockBitcoinWalletConfig>;\n\n constructor(config: MockBitcoinWalletConfig = {}) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...(config.publicKeyHex ? { publicKeyHex: config.publicKeyHex } : {}),\n ...(config.address ? { address: config.address } : {}),\n ...(config.network !== undefined ? { network: config.network } : {}),\n ...(config.shouldFailSigning !== undefined\n ? { shouldFailSigning: config.shouldFailSigning }\n : {}),\n ...(config.privateKeyHex ? { privateKeyHex: config.privateKeyHex } : {}),\n ...(config.deriveContextHash\n ? { deriveContextHash: config.deriveContextHash }\n : {}),\n };\n // A private-key override without a public key would otherwise sign\n // against the DEFAULT pubkey — derive the matching one instead.\n if (config.privateKeyHex && !config.publicKeyHex) {\n this.config.publicKeyHex = xOnlyPubkeyHexOf(config.privateKeyHex);\n }\n }\n\n async getPublicKeyHex(): Promise<string> {\n return this.config.publicKeyHex;\n }\n\n async getAddress(): Promise<string> {\n return this.config.address;\n }\n\n async signPsbt(psbtHex: string, _options?: SignPsbtOptions): Promise<string> {\n if (this.config.shouldFailSigning) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!psbtHex || psbtHex.length === 0) {\n throw new Error(\"Invalid PSBT: empty hex string\");\n }\n\n // In a real implementation, this would actually sign the PSBT\n // For the mock, we just return the input with a mock signature appended\n return psbtHex + \"deadbeef\";\n }\n\n async signPsbts(\n psbtsHexes: string[],\n _options?: SignPsbtOptions[],\n ): Promise<string[]> {\n const signedPsbts: string[] = [];\n for (const psbtHex of psbtsHexes) {\n const signedPsbt = await this.signPsbt(psbtHex);\n signedPsbts.push(signedPsbt);\n }\n return signedPsbts;\n }\n\n async signMessage(\n message: string,\n _type: \"bip322-simple\" | \"ecdsa\",\n ): Promise<string> {\n if (this.config.shouldFailSigning) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!message || message.length === 0) {\n throw new Error(\"Invalid message: empty string\");\n }\n\n // PoP flows verify the witness against `publicKeyHex`, so a divergent\n // key pair must fail loudly here, not as a confusing verify mismatch.\n const signingXOnlyHex = xOnlyPubkeyHexOf(this.config.privateKeyHex);\n let configuredXOnlyHex: string | undefined;\n try {\n configuredXOnlyHex = canonicalizeBtcPubkey(this.config.publicKeyHex);\n } catch {\n configuredXOnlyHex = undefined; // an unparseable key cannot match\n }\n if (configuredXOnlyHex !== signingXOnlyHex) {\n throw new Error(\n `MockBitcoinWallet.signMessage: privateKeyHex signs as x-only pubkey ` +\n `${signingXOnlyHex}, but publicKeyHex is ${this.config.publicKeyHex}. ` +\n `Pass a matching publicKeyHex/privateKeyHex pair.`,\n );\n }\n\n // The SDK cryptographically verifies what a wallet returns\n // (`verifyPopWitness`), so the mock signs a REAL BIP-322 P2WPKH witness\n // with its private key. The type is not consulted: PoP flows only ever\n // request \"bip322-simple\", and the interface tests assert shape only.\n const witness = signBip322P2wpkhWitness(\n new TextEncoder().encode(message),\n Uint8Array.from(Buffer.from(this.config.privateKeyHex, \"hex\")),\n );\n return `0x${uint8ArrayToHex(witness)}`;\n }\n\n async getNetwork(): Promise<BitcoinNetwork> {\n return this.config.network;\n }\n\n async deriveContextHash(appName: string, context: string): Promise<string> {\n return this.config.deriveContextHash(appName, context);\n }\n\n /** Updates configuration for testing different scenarios. */\n updateConfig(updates: Partial<MockBitcoinWalletConfig>): void {\n this.config = {\n ...this.config,\n ...updates,\n };\n }\n\n /** Resets to default configuration. */\n reset(): void {\n this.config = { ...DEFAULT_CONFIG };\n }\n}\n","import { Buffer } from \"buffer\";\nimport type { Address, Hex } from \"viem\";\n\n/**\n * Configuration for MockEthereumWallet.\n */\nexport interface MockEthereumWalletConfig {\n address?: Address;\n chainId?: number;\n shouldFailOperations?: boolean;\n transactionDelay?: number;\n}\n\n/**\n * Mock Ethereum wallet for testing.\n *\n * Provides the subset of viem's WalletClient methods used by the SDK.\n * Can be passed to functions expecting a WalletClient for testing purposes.\n */\nexport class MockEthereumWallet {\n // Public properties matching viem's WalletClient structure\n account: { address: Address };\n chain: { id: number };\n\n private shouldFailOperations: boolean;\n private transactionDelay: number;\n private nonce: number = 0;\n\n constructor(config: MockEthereumWalletConfig = {}) {\n // Use lowercase addresses to avoid EIP-55 checksum validation issues\n this.account = {\n address:\n config.address ||\n (\"0x742d35cc6634c0532925a3b844bc9e7595f0beb0\" as Address),\n };\n\n this.chain = {\n id: config.chainId ?? 11155111, // Sepolia by default\n };\n\n this.shouldFailOperations = config.shouldFailOperations ?? false;\n this.transactionDelay = config.transactionDelay ?? 0;\n\n // Bind methods to preserve 'this' context when called\n this.signMessage = this.signMessage.bind(this);\n this.sendTransaction = this.sendTransaction.bind(this);\n }\n\n async signMessage(args: { message: string; account?: Address }): Promise<Hex> {\n const message = args.message;\n const account = args.account || this.account.address;\n\n if (this.shouldFailOperations) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!message || message.length === 0) {\n throw new Error(\"Invalid message: empty string\");\n }\n\n // Generate a deterministic mock signature\n const signatureData = `personal_sign:${message}-${account}-${this.chain.id}`;\n const signature = `0x${Buffer.from(signatureData)\n .toString(\"hex\")\n .slice(0, 130)\n .padEnd(130, \"0\")}` as Hex;\n return signature;\n }\n\n async sendTransaction(tx: {\n to: Address;\n data?: Hex;\n value?: bigint;\n gas?: bigint;\n account?: { address: Address };\n chain?: { id: number };\n }): Promise<Hex> {\n if (this.shouldFailOperations) {\n throw new Error(\"Mock transaction failed\");\n }\n\n if (!tx.to) {\n throw new Error(\"Invalid transaction: missing 'to' address\");\n }\n\n // Simulate network delay if configured\n if (this.transactionDelay > 0) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.transactionDelay),\n );\n }\n\n // Generate a deterministic mock transaction hash\n this.nonce++;\n const txData = JSON.stringify({\n from: this.account.address,\n to: tx.to,\n value: tx.value?.toString() || \"0\",\n nonce: this.nonce,\n chainId: this.chain.id,\n });\n\n const hash = `0x${Buffer.from(txData)\n .toString(\"hex\")\n .slice(0, 64)\n .padEnd(64, \"0\")}` as Hex;\n return hash;\n }\n\n /** Updates configuration for testing different scenarios. */\n updateConfig(updates: Partial<MockEthereumWalletConfig>): void {\n if (updates.address !== undefined) {\n this.account.address = updates.address;\n }\n if (updates.chainId !== undefined) {\n this.chain.id = updates.chainId;\n }\n if (updates.shouldFailOperations !== undefined) {\n this.shouldFailOperations = updates.shouldFailOperations;\n }\n if (updates.transactionDelay !== undefined) {\n this.transactionDelay = updates.transactionDelay;\n }\n }\n\n /** Resets to default configuration and nonce. */\n reset(): void {\n this.account.address =\n \"0x742d35cc6634c0532925a3b844bc9e7595f0beb0\" as Address;\n this.chain.id = 11155111;\n this.shouldFailOperations = false;\n this.transactionDelay = 0;\n this.nonce = 0;\n }\n\n /** Returns current nonce for testing. */\n getCurrentNonce(): number {\n return this.nonce;\n }\n}\n"],"names":["BIP322_TAG","SIGHASH_ALL","ZERO_SATS","MIN_ENCODED_SIG_BYTES","MAX_SIGN_GRIND_ATTEMPTS","BIP322_TX_VERSION","BIP322_TX_LOCKTIME","BIP322_INPUT_SEQUENCE","TO_SPEND_PREVOUT_TXID_BYTES","TO_SPEND_PREVOUT_INDEX","TO_SPEND_OUTPUT_INDEX","OP_0","OP_PUSHBYTES_32","OP_RETURN","P2WPKH_WITNESS_ITEMS","GRIND_ENTROPY_BYTES","GRIND_COUNTER_OFFSET","signBip322P2wpkhWitness","messageBytes","privateKey","pubkey","ecc","tagHash","sha256","messageHash","Buffer","p2wpkh","payments","toSpend","Transaction","toSign","scriptCode","sighash","encodedSignature","attempt","entropy","candidate","bscript","defaultDeriveContextHash","appName","context","enc","nameBytes","ctxBytes","buf","view","uint8ArrayToHex","DEFAULT_PRIVATE_KEY_HEX","xOnlyPubkeyHexOf","privateKeyHex","DEFAULT_CONFIG","BitcoinNetworks","MockBitcoinWallet","config","__publicField","psbtHex","_options","psbtsHexes","signedPsbts","signedPsbt","message","_type","signingXOnlyHex","configuredXOnlyHex","canonicalizeBtcPubkey","witness","updates","MockEthereumWallet","args","account","signatureData","tx","resolve","txData","_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/testing/signBip322P2wpkhWitness.ts","../../src/testing/MockBitcoinWallet.ts","../../src/testing/MockEthereumWallet.ts"],"sourcesContent":["/**\n * Test-support BIP-322 \"simple\" P2WPKH signer.\n *\n * Produces the consensus-encoded two-item witness `[DER sig ‖ 0x01,\n * compressed pubkey]` that a Native SegWit software wallet returns for\n * `signMessage(..., \"bip322-simple\")`. The virtual to_spend/to_sign\n * construction follows the `bip322` crate 0.0.10 (`util.rs:18-85`) — the\n * same reference the production verifier\n * (`tbv/core/clients/vault-provider/auth/bip322Verify.ts`) mirrors, and\n * the BIP-322 official vectors pin.\n *\n * Conscious call: `./testing` deliberately depends on the Bitcoin stack\n * (bitcoinjs-lib was already in this entry's graph via MockBitcoinWallet;\n * tiny-secp256k1-asmjs is new here) — out of scope for the CLAUDE.md §9\n * optional-BTC split.\n *\n * Test-only: never feed real key material to this module.\n */\n\nimport * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { script as bscript, payments, Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\n/** BIP-322 message tag (BIP-340 tagged-hash style). */\nconst BIP322_TAG = \"BIP0322-signed-message\";\nconst SIGHASH_ALL = 0x01;\nconst ZERO_SATS = 0;\n/**\n * vaultd accepts only 71/72-byte encoded signatures (`bip322` crate 0.0.10\n * `verify.rs:141-153`); a short-DER signature (~0.4% of draws) is ground\n * away by re-signing with fresh entropy. 100 attempts bounds the failure\n * probability around 0.004^100.\n */\nconst MIN_ENCODED_SIG_BYTES = 71;\nconst MAX_SIGN_GRIND_ATTEMPTS = 100;\n\n// Wire fields of the virtual to_spend/to_sign transactions (`bip322`\n// crate 0.0.10 `util.rs:18-85`).\nconst BIP322_TX_VERSION = 0;\nconst BIP322_TX_LOCKTIME = 0;\nconst BIP322_INPUT_SEQUENCE = 0;\n/** to_spend prevout: all-zero 32-byte txid at index 0xFFFFFFFF (`util.rs:18-85`). */\nconst TO_SPEND_PREVOUT_TXID_BYTES = 32;\nconst TO_SPEND_PREVOUT_INDEX = 0xffffffff;\n/** to_sign spends to_spend's only output (`util.rs:18-85`). */\nconst TO_SPEND_OUTPUT_INDEX = 0;\nconst OP_0 = 0x00;\n/** Direct push of the 32-byte tagged message hash. */\nconst OP_PUSHBYTES_32 = 0x20;\nconst OP_RETURN = 0x6a;\n/** Consensus P2WPKH witness: exactly [signature, pubkey]. */\nconst P2WPKH_WITNESS_ITEMS = 2;\n/** Grinding: 32-byte extra-entropy buffer, attempt counter at offset 0. */\nconst GRIND_ENTROPY_BYTES = 32;\nconst GRIND_COUNTER_OFFSET = 0;\n\n/**\n * Sign `messageBytes` as a BIP-322 \"simple\" P2WPKH proof with `privateKey`\n * and return the consensus-encoded two-item witness\n * (`0x02 ‖ len ‖ sig ‖ 0x21 ‖ pubkey`).\n */\nexport function signBip322P2wpkhWitness(\n messageBytes: Uint8Array,\n privateKey: Uint8Array,\n): Uint8Array {\n const pubkey = ecc.pointFromScalar(privateKey, true);\n if (!pubkey) {\n throw new Error(\"signBip322P2wpkhWitness: invalid private key\");\n }\n\n // m_hash = SHA256( SHA256(tag) ‖ SHA256(tag) ‖ message )\n const tagHash = sha256(new TextEncoder().encode(BIP322_TAG));\n const messageHash = sha256(\n Buffer.concat([tagHash, tagHash, Buffer.from(messageBytes)]),\n );\n\n const p2wpkh = payments.p2wpkh({ pubkey: Buffer.from(pubkey) });\n if (!p2wpkh.output || !p2wpkh.hash) {\n throw new Error(\"signBip322P2wpkhWitness: could not derive P2WPKH script\");\n }\n\n // to_spend / to_sign per bip322 crate util.rs:18-85.\n const toSpend = new Transaction();\n toSpend.version = BIP322_TX_VERSION;\n toSpend.locktime = BIP322_TX_LOCKTIME;\n toSpend.addInput(\n Buffer.alloc(TO_SPEND_PREVOUT_TXID_BYTES, 0),\n TO_SPEND_PREVOUT_INDEX,\n BIP322_INPUT_SEQUENCE,\n Buffer.concat([\n Buffer.from([OP_0, OP_PUSHBYTES_32]),\n Buffer.from(messageHash),\n ]),\n );\n toSpend.addOutput(p2wpkh.output, ZERO_SATS);\n const toSign = new Transaction();\n toSign.version = BIP322_TX_VERSION;\n toSign.locktime = BIP322_TX_LOCKTIME;\n toSign.addInput(\n toSpend.getHash(),\n TO_SPEND_OUTPUT_INDEX,\n BIP322_INPUT_SEQUENCE,\n );\n toSign.addOutput(Buffer.from([OP_RETURN]), ZERO_SATS);\n\n // BIP-143 sighash with the standard P2WPKH scriptCode, value 0\n // (bip322 crate verify.rs:163-173).\n const scriptCode = payments.p2pkh({ hash: p2wpkh.hash }).output;\n if (!scriptCode) {\n throw new Error(\"signBip322P2wpkhWitness: could not build scriptCode\");\n }\n const sighash = toSign.hashForWitnessV0(\n 0,\n scriptCode,\n ZERO_SATS,\n SIGHASH_ALL,\n );\n\n let encodedSignature: Buffer | undefined;\n for (let attempt = 0; attempt < MAX_SIGN_GRIND_ATTEMPTS; attempt++) {\n const entropy = Buffer.alloc(GRIND_ENTROPY_BYTES, 0);\n entropy.writeUInt32LE(attempt, GRIND_COUNTER_OFFSET);\n // ecc.sign emits low-S (libsecp256k1), so 73-byte encodings can't occur.\n const candidate = bscript.signature.encode(\n Buffer.from(ecc.sign(sighash, privateKey, entropy)),\n SIGHASH_ALL,\n );\n if (candidate.length >= MIN_ENCODED_SIG_BYTES) {\n encodedSignature = candidate;\n break;\n }\n }\n if (!encodedSignature) {\n throw new Error(\n \"signBip322P2wpkhWitness: could not grind a 71/72-byte signature\",\n );\n }\n\n return Uint8Array.from([\n P2WPKH_WITNESS_ITEMS,\n encodedSignature.length,\n ...encodedSignature,\n pubkey.length,\n ...pubkey,\n ]);\n}\n","import * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { Buffer } from \"buffer\";\n\nimport {\n BitcoinNetworks,\n type BitcoinNetwork,\n} from \"../shared/wallets/interfaces\";\nimport type {\n BitcoinWallet,\n SignPsbtOptions,\n} from \"../shared/wallets/interfaces/BitcoinWallet\";\nimport {\n canonicalizeBtcPubkey,\n uint8ArrayToHex,\n} from \"../tbv/core/primitives/utils/bitcoin\";\nimport { signBip322P2wpkhWitness } from \"./signBip322P2wpkhWitness\";\n\n/**\n * Configuration for MockBitcoinWallet.\n */\nexport interface MockBitcoinWalletConfig {\n publicKeyHex?: string;\n address?: string;\n network?: BitcoinNetwork;\n shouldFailSigning?: boolean;\n /**\n * 32-byte hex key `signMessage` signs BIP-322 proofs with. Defaults to\n * the privkey-1 test key, whose x-only pubkey is the default\n * `publicKeyHex` (the secp256k1 generator's x coordinate). PoP flows\n * verify the witness against `publicKeyHex`: overriding only this key\n * derives the matching `publicKeyHex`, and a divergent pair throws at\n * sign time. Test material only — never a real key.\n */\n privateKeyHex?: string;\n /**\n * Optional override for `deriveContextHash`. When omitted the mock\n * returns a deterministic 64-char lowercase hex string derived from\n * `(appName, context)` so tests can assert pass-through wiring\n * without pinning a specific value. Override to inject spec test\n * vectors or to simulate failure modes.\n */\n deriveContextHash?: (appName: string, context: string) => Promise<string>;\n}\n\n/**\n * Default `deriveContextHash` implementation: deterministic and\n * collision-resistant via SHA-256, so tests that assert pass-through\n * wiring (different `(appName, context)` → different output) hold\n * without flakes. Domain-separates the two inputs by length-prefixing\n * each as `len(name) || name || len(ctx) || ctx`, preventing\n * `(\"ab\", \"cd\")` from colliding with `(\"abc\", \"d\")`.\n */\nconst defaultDeriveContextHash = async (\n appName: string,\n context: string,\n): Promise<string> => {\n const enc = new TextEncoder();\n const nameBytes = enc.encode(appName);\n const ctxBytes = enc.encode(context);\n const buf = new Uint8Array(4 + nameBytes.length + 4 + ctxBytes.length);\n const view = new DataView(buf.buffer);\n view.setUint32(0, nameBytes.length);\n buf.set(nameBytes, 4);\n view.setUint32(4 + nameBytes.length, ctxBytes.length);\n buf.set(ctxBytes, 4 + nameBytes.length + 4);\n return uint8ArrayToHex(sha256(buf));\n};\n\n/** Privkey 1 — the test key `signMessage` signs with by default. */\nconst DEFAULT_PRIVATE_KEY_HEX = `${\"00\".repeat(31)}01`;\n\n/** Lowercase x-only pubkey of a 32-byte private key. */\nfunction xOnlyPubkeyHexOf(privateKeyHex: string): string {\n return uint8ArrayToHex(\n ecc.xOnlyPointFromScalar(\n Uint8Array.from(Buffer.from(privateKeyHex, \"hex\")),\n ),\n );\n}\n\nconst DEFAULT_CONFIG: Required<MockBitcoinWalletConfig> = {\n // x-only pubkey of DEFAULT_PRIVATE_KEY_HEX (the secp256k1 generator's x\n // coordinate), so the default wallet's PoP witnesses verify against it.\n publicKeyHex:\n \"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\n address: \"tb1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkx6jks\",\n network: BitcoinNetworks.SIGNET,\n shouldFailSigning: false,\n privateKeyHex: DEFAULT_PRIVATE_KEY_HEX,\n deriveContextHash: defaultDeriveContextHash,\n};\n\n/** Mock Bitcoin wallet for testing. */\nexport class MockBitcoinWallet implements BitcoinWallet {\n private config: Required<MockBitcoinWalletConfig>;\n\n constructor(config: MockBitcoinWalletConfig = {}) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...(config.publicKeyHex ? { publicKeyHex: config.publicKeyHex } : {}),\n ...(config.address ? { address: config.address } : {}),\n ...(config.network !== undefined ? { network: config.network } : {}),\n ...(config.shouldFailSigning !== undefined\n ? { shouldFailSigning: config.shouldFailSigning }\n : {}),\n ...(config.privateKeyHex ? { privateKeyHex: config.privateKeyHex } : {}),\n ...(config.deriveContextHash\n ? { deriveContextHash: config.deriveContextHash }\n : {}),\n };\n // A private-key override without a public key would otherwise sign\n // against the DEFAULT pubkey — derive the matching one instead.\n if (config.privateKeyHex && !config.publicKeyHex) {\n this.config.publicKeyHex = xOnlyPubkeyHexOf(config.privateKeyHex);\n }\n }\n\n async getPublicKeyHex(): Promise<string> {\n return this.config.publicKeyHex;\n }\n\n async getAddress(): Promise<string> {\n return this.config.address;\n }\n\n async signPsbt(psbtHex: string, _options?: SignPsbtOptions): Promise<string> {\n if (this.config.shouldFailSigning) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!psbtHex || psbtHex.length === 0) {\n throw new Error(\"Invalid PSBT: empty hex string\");\n }\n\n // In a real implementation, this would actually sign the PSBT\n // For the mock, we just return the input with a mock signature appended\n return psbtHex + \"deadbeef\";\n }\n\n async signPsbts(\n psbtsHexes: string[],\n _options?: SignPsbtOptions[],\n ): Promise<string[]> {\n const signedPsbts: string[] = [];\n for (const psbtHex of psbtsHexes) {\n const signedPsbt = await this.signPsbt(psbtHex);\n signedPsbts.push(signedPsbt);\n }\n return signedPsbts;\n }\n\n async signMessage(\n message: string,\n type: \"bip322-simple\" | \"ecdsa\",\n ): Promise<string> {\n // Only BIP-322 witnesses are implemented; returning one for \"ecdsa\"\n // would hand a future ECDSA-flow test the wrong artifact silently.\n if (type !== \"bip322-simple\") {\n throw new Error(\n \"MockBitcoinWallet.signMessage: only bip322-simple is implemented\",\n );\n }\n if (this.config.shouldFailSigning) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!message || message.length === 0) {\n throw new Error(\"Invalid message: empty string\");\n }\n\n // PoP flows verify the witness against `publicKeyHex`, so a divergent\n // key pair must fail loudly here, not as a confusing verify mismatch.\n const signingXOnlyHex = xOnlyPubkeyHexOf(this.config.privateKeyHex);\n let configuredXOnlyHex: string | undefined;\n try {\n configuredXOnlyHex = canonicalizeBtcPubkey(this.config.publicKeyHex);\n } catch {\n configuredXOnlyHex = undefined; // an unparseable key cannot match\n }\n if (configuredXOnlyHex !== signingXOnlyHex) {\n throw new Error(\n `MockBitcoinWallet.signMessage: privateKeyHex signs as x-only pubkey ` +\n `${signingXOnlyHex}, but publicKeyHex is ${this.config.publicKeyHex}. ` +\n `Pass a matching publicKeyHex/privateKeyHex pair.`,\n );\n }\n\n // The SDK cryptographically verifies what a wallet returns\n // (`verifyPopWitness`), so the mock signs a REAL BIP-322 P2WPKH witness\n // with its private key.\n const witness = signBip322P2wpkhWitness(\n new TextEncoder().encode(message),\n Uint8Array.from(Buffer.from(this.config.privateKeyHex, \"hex\")),\n );\n return `0x${uint8ArrayToHex(witness)}`;\n }\n\n async getNetwork(): Promise<BitcoinNetwork> {\n return this.config.network;\n }\n\n async deriveContextHash(appName: string, context: string): Promise<string> {\n return this.config.deriveContextHash(appName, context);\n }\n\n /** Updates configuration for testing different scenarios. */\n updateConfig(updates: Partial<MockBitcoinWalletConfig>): void {\n this.config = {\n ...this.config,\n ...updates,\n };\n // Mirror the constructor: a private-key-only update re-derives the\n // matching pubkey; an explicit publicKeyHex still wins.\n if (updates.privateKeyHex && !updates.publicKeyHex) {\n this.config.publicKeyHex = xOnlyPubkeyHexOf(updates.privateKeyHex);\n }\n }\n\n /** Resets to default configuration. */\n reset(): void {\n this.config = { ...DEFAULT_CONFIG };\n }\n}\n","import { Buffer } from \"buffer\";\nimport type { Address, Hex } from \"viem\";\n\n/**\n * Configuration for MockEthereumWallet.\n */\nexport interface MockEthereumWalletConfig {\n address?: Address;\n chainId?: number;\n shouldFailOperations?: boolean;\n transactionDelay?: number;\n}\n\n/**\n * Mock Ethereum wallet for testing.\n *\n * Provides the subset of viem's WalletClient methods used by the SDK.\n * Can be passed to functions expecting a WalletClient for testing purposes.\n */\nexport class MockEthereumWallet {\n // Public properties matching viem's WalletClient structure\n account: { address: Address };\n chain: { id: number };\n\n private shouldFailOperations: boolean;\n private transactionDelay: number;\n private nonce: number = 0;\n\n constructor(config: MockEthereumWalletConfig = {}) {\n // Use lowercase addresses to avoid EIP-55 checksum validation issues\n this.account = {\n address:\n config.address ||\n (\"0x742d35cc6634c0532925a3b844bc9e7595f0beb0\" as Address),\n };\n\n this.chain = {\n id: config.chainId ?? 11155111, // Sepolia by default\n };\n\n this.shouldFailOperations = config.shouldFailOperations ?? false;\n this.transactionDelay = config.transactionDelay ?? 0;\n\n // Bind methods to preserve 'this' context when called\n this.signMessage = this.signMessage.bind(this);\n this.sendTransaction = this.sendTransaction.bind(this);\n }\n\n async signMessage(args: { message: string; account?: Address }): Promise<Hex> {\n const message = args.message;\n const account = args.account || this.account.address;\n\n if (this.shouldFailOperations) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!message || message.length === 0) {\n throw new Error(\"Invalid message: empty string\");\n }\n\n // Generate a deterministic mock signature\n const signatureData = `personal_sign:${message}-${account}-${this.chain.id}`;\n const signature = `0x${Buffer.from(signatureData)\n .toString(\"hex\")\n .slice(0, 130)\n .padEnd(130, \"0\")}` as Hex;\n return signature;\n }\n\n async sendTransaction(tx: {\n to: Address;\n data?: Hex;\n value?: bigint;\n gas?: bigint;\n account?: { address: Address };\n chain?: { id: number };\n }): Promise<Hex> {\n if (this.shouldFailOperations) {\n throw new Error(\"Mock transaction failed\");\n }\n\n if (!tx.to) {\n throw new Error(\"Invalid transaction: missing 'to' address\");\n }\n\n // Simulate network delay if configured\n if (this.transactionDelay > 0) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.transactionDelay),\n );\n }\n\n // Generate a deterministic mock transaction hash\n this.nonce++;\n const txData = JSON.stringify({\n from: this.account.address,\n to: tx.to,\n value: tx.value?.toString() || \"0\",\n nonce: this.nonce,\n chainId: this.chain.id,\n });\n\n const hash = `0x${Buffer.from(txData)\n .toString(\"hex\")\n .slice(0, 64)\n .padEnd(64, \"0\")}` as Hex;\n return hash;\n }\n\n /** Updates configuration for testing different scenarios. */\n updateConfig(updates: Partial<MockEthereumWalletConfig>): void {\n if (updates.address !== undefined) {\n this.account.address = updates.address;\n }\n if (updates.chainId !== undefined) {\n this.chain.id = updates.chainId;\n }\n if (updates.shouldFailOperations !== undefined) {\n this.shouldFailOperations = updates.shouldFailOperations;\n }\n if (updates.transactionDelay !== undefined) {\n this.transactionDelay = updates.transactionDelay;\n }\n }\n\n /** Resets to default configuration and nonce. */\n reset(): void {\n this.account.address =\n \"0x742d35cc6634c0532925a3b844bc9e7595f0beb0\" as Address;\n this.chain.id = 11155111;\n this.shouldFailOperations = false;\n this.transactionDelay = 0;\n this.nonce = 0;\n }\n\n /** Returns current nonce for testing. */\n getCurrentNonce(): number {\n return this.nonce;\n }\n}\n"],"names":["BIP322_TAG","SIGHASH_ALL","ZERO_SATS","MIN_ENCODED_SIG_BYTES","MAX_SIGN_GRIND_ATTEMPTS","BIP322_TX_VERSION","BIP322_TX_LOCKTIME","BIP322_INPUT_SEQUENCE","TO_SPEND_PREVOUT_TXID_BYTES","TO_SPEND_PREVOUT_INDEX","TO_SPEND_OUTPUT_INDEX","OP_0","OP_PUSHBYTES_32","OP_RETURN","P2WPKH_WITNESS_ITEMS","GRIND_ENTROPY_BYTES","GRIND_COUNTER_OFFSET","signBip322P2wpkhWitness","messageBytes","privateKey","pubkey","ecc","tagHash","sha256","messageHash","Buffer","p2wpkh","payments","toSpend","Transaction","toSign","scriptCode","sighash","encodedSignature","attempt","entropy","candidate","bscript","defaultDeriveContextHash","appName","context","enc","nameBytes","ctxBytes","buf","view","uint8ArrayToHex","DEFAULT_PRIVATE_KEY_HEX","xOnlyPubkeyHexOf","privateKeyHex","DEFAULT_CONFIG","BitcoinNetworks","MockBitcoinWallet","config","__publicField","psbtHex","_options","psbtsHexes","signedPsbts","signedPsbt","message","type","signingXOnlyHex","configuredXOnlyHex","canonicalizeBtcPubkey","witness","updates","MockEthereumWallet","args","account","signatureData","tx","resolve","txData","_a"],"mappings":"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"}
|
package/dist/testing/index.js
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
1
|
var v = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var c = (r, t, e) =>
|
|
4
|
-
import * as
|
|
5
|
-
import { s as
|
|
2
|
+
var k = (r, t, e) => t in r ? v(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
|
|
3
|
+
var c = (r, t, e) => k(r, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import * as p from "@bitcoin-js/tiny-secp256k1-asmjs";
|
|
5
|
+
import { s as f } from "../sha2-BYVxyZzX.js";
|
|
6
6
|
import { Buffer as o } from "buffer";
|
|
7
|
-
import { c as
|
|
8
|
-
import { payments as
|
|
9
|
-
import { BitcoinNetworks as
|
|
10
|
-
const
|
|
7
|
+
import { c as I, u as y } from "../bitcoin-Ch_jxnDa.js";
|
|
8
|
+
import { payments as q, Transaction as b, script as O } from "bitcoinjs-lib";
|
|
9
|
+
import { BitcoinNetworks as K } from "../shared/index.js";
|
|
10
|
+
const D = "BIP0322-signed-message", m = 1, g = 0, N = 71, B = 100, H = 0, _ = 0, T = 0, F = 32, M = 4294967295, U = 0, C = 0, A = 32, W = 106, R = 2, G = 32, X = 0;
|
|
11
11
|
function $(r, t) {
|
|
12
|
-
const e =
|
|
12
|
+
const e = p.pointFromScalar(t, !0);
|
|
13
13
|
if (!e)
|
|
14
14
|
throw new Error("signBip322P2wpkhWitness: invalid private key");
|
|
15
|
-
const n =
|
|
15
|
+
const n = f(new TextEncoder().encode(D)), i = f(
|
|
16
16
|
o.concat([n, n, o.from(r)])
|
|
17
|
-
),
|
|
18
|
-
if (!
|
|
17
|
+
), s = q.p2wpkh({ pubkey: o.from(e) });
|
|
18
|
+
if (!s.output || !s.hash)
|
|
19
19
|
throw new Error("signBip322P2wpkhWitness: could not derive P2WPKH script");
|
|
20
|
-
const a = new
|
|
21
|
-
a.version =
|
|
22
|
-
o.alloc(
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const a = new b();
|
|
21
|
+
a.version = H, a.locktime = _, a.addInput(
|
|
22
|
+
o.alloc(F, 0),
|
|
23
|
+
M,
|
|
24
|
+
T,
|
|
25
25
|
o.concat([
|
|
26
|
-
o.from([
|
|
27
|
-
o.from(
|
|
26
|
+
o.from([C, A]),
|
|
27
|
+
o.from(i)
|
|
28
28
|
])
|
|
29
|
-
), a.addOutput(
|
|
30
|
-
const h = new
|
|
31
|
-
h.version =
|
|
29
|
+
), a.addOutput(s.output, g);
|
|
30
|
+
const h = new b();
|
|
31
|
+
h.version = H, h.locktime = _, h.addInput(
|
|
32
32
|
a.getHash(),
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
), h.addOutput(o.from([
|
|
36
|
-
const
|
|
37
|
-
if (!
|
|
33
|
+
U,
|
|
34
|
+
T
|
|
35
|
+
), h.addOutput(o.from([W]), g);
|
|
36
|
+
const w = q.p2pkh({ hash: s.hash }).output;
|
|
37
|
+
if (!w)
|
|
38
38
|
throw new Error("signBip322P2wpkhWitness: could not build scriptCode");
|
|
39
39
|
const S = h.hashForWitnessV0(
|
|
40
40
|
0,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
w,
|
|
42
|
+
g,
|
|
43
|
+
m
|
|
44
44
|
);
|
|
45
45
|
let d;
|
|
46
|
-
for (let l = 0; l <
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
o.from(
|
|
51
|
-
|
|
46
|
+
for (let l = 0; l < B; l++) {
|
|
47
|
+
const x = o.alloc(G, 0);
|
|
48
|
+
x.writeUInt32LE(l, X);
|
|
49
|
+
const E = O.signature.encode(
|
|
50
|
+
o.from(p.sign(S, t, x)),
|
|
51
|
+
m
|
|
52
52
|
);
|
|
53
|
-
if (
|
|
54
|
-
d =
|
|
53
|
+
if (E.length >= N) {
|
|
54
|
+
d = E;
|
|
55
55
|
break;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -60,7 +60,7 @@ function $(r, t) {
|
|
|
60
60
|
"signBip322P2wpkhWitness: could not grind a 71/72-byte signature"
|
|
61
61
|
);
|
|
62
62
|
return Uint8Array.from([
|
|
63
|
-
|
|
63
|
+
R,
|
|
64
64
|
d.length,
|
|
65
65
|
...d,
|
|
66
66
|
e.length,
|
|
@@ -68,12 +68,12 @@ function $(r, t) {
|
|
|
68
68
|
]);
|
|
69
69
|
}
|
|
70
70
|
const L = async (r, t) => {
|
|
71
|
-
const e = new TextEncoder(), n = e.encode(r),
|
|
72
|
-
return a.setUint32(0, n.length),
|
|
71
|
+
const e = new TextEncoder(), n = e.encode(r), i = e.encode(t), s = new Uint8Array(4 + n.length + 4 + i.length), a = new DataView(s.buffer);
|
|
72
|
+
return a.setUint32(0, n.length), s.set(n, 4), a.setUint32(4 + n.length, i.length), s.set(i, 4 + n.length + 4), y(f(s));
|
|
73
73
|
}, V = `${"00".repeat(31)}01`;
|
|
74
|
-
function
|
|
75
|
-
return
|
|
76
|
-
|
|
74
|
+
function u(r) {
|
|
75
|
+
return y(
|
|
76
|
+
p.xOnlyPointFromScalar(
|
|
77
77
|
Uint8Array.from(o.from(r, "hex"))
|
|
78
78
|
)
|
|
79
79
|
);
|
|
@@ -83,7 +83,7 @@ const P = {
|
|
|
83
83
|
// coordinate), so the default wallet's PoP witnesses verify against it.
|
|
84
84
|
publicKeyHex: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
|
85
85
|
address: "tb1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkx6jks",
|
|
86
|
-
network:
|
|
86
|
+
network: K.SIGNET,
|
|
87
87
|
shouldFailSigning: !1,
|
|
88
88
|
privateKeyHex: V,
|
|
89
89
|
deriveContextHash: L
|
|
@@ -99,7 +99,7 @@ class tt {
|
|
|
99
99
|
...t.shouldFailSigning !== void 0 ? { shouldFailSigning: t.shouldFailSigning } : {},
|
|
100
100
|
...t.privateKeyHex ? { privateKeyHex: t.privateKeyHex } : {},
|
|
101
101
|
...t.deriveContextHash ? { deriveContextHash: t.deriveContextHash } : {}
|
|
102
|
-
}, t.privateKeyHex && !t.publicKeyHex && (this.config.publicKeyHex =
|
|
102
|
+
}, t.privateKeyHex && !t.publicKeyHex && (this.config.publicKeyHex = u(t.privateKeyHex));
|
|
103
103
|
}
|
|
104
104
|
async getPublicKeyHex() {
|
|
105
105
|
return this.config.publicKeyHex;
|
|
@@ -116,33 +116,37 @@ class tt {
|
|
|
116
116
|
}
|
|
117
117
|
async signPsbts(t, e) {
|
|
118
118
|
const n = [];
|
|
119
|
-
for (const
|
|
120
|
-
const
|
|
121
|
-
n.push(
|
|
119
|
+
for (const i of t) {
|
|
120
|
+
const s = await this.signPsbt(i);
|
|
121
|
+
n.push(s);
|
|
122
122
|
}
|
|
123
123
|
return n;
|
|
124
124
|
}
|
|
125
125
|
async signMessage(t, e) {
|
|
126
|
+
if (e !== "bip322-simple")
|
|
127
|
+
throw new Error(
|
|
128
|
+
"MockBitcoinWallet.signMessage: only bip322-simple is implemented"
|
|
129
|
+
);
|
|
126
130
|
if (this.config.shouldFailSigning)
|
|
127
131
|
throw new Error("Mock signing failed");
|
|
128
132
|
if (!t || t.length === 0)
|
|
129
133
|
throw new Error("Invalid message: empty string");
|
|
130
|
-
const n =
|
|
131
|
-
let
|
|
134
|
+
const n = u(this.config.privateKeyHex);
|
|
135
|
+
let i;
|
|
132
136
|
try {
|
|
133
|
-
|
|
137
|
+
i = I(this.config.publicKeyHex);
|
|
134
138
|
} catch {
|
|
135
|
-
|
|
139
|
+
i = void 0;
|
|
136
140
|
}
|
|
137
|
-
if (
|
|
141
|
+
if (i !== n)
|
|
138
142
|
throw new Error(
|
|
139
143
|
`MockBitcoinWallet.signMessage: privateKeyHex signs as x-only pubkey ${n}, but publicKeyHex is ${this.config.publicKeyHex}. Pass a matching publicKeyHex/privateKeyHex pair.`
|
|
140
144
|
);
|
|
141
|
-
const
|
|
145
|
+
const s = $(
|
|
142
146
|
new TextEncoder().encode(t),
|
|
143
147
|
Uint8Array.from(o.from(this.config.privateKeyHex, "hex"))
|
|
144
148
|
);
|
|
145
|
-
return `0x${
|
|
149
|
+
return `0x${y(s)}`;
|
|
146
150
|
}
|
|
147
151
|
async getNetwork() {
|
|
148
152
|
return this.config.network;
|
|
@@ -155,7 +159,7 @@ class tt {
|
|
|
155
159
|
this.config = {
|
|
156
160
|
...this.config,
|
|
157
161
|
...t
|
|
158
|
-
};
|
|
162
|
+
}, t.privateKeyHex && !t.publicKeyHex && (this.config.publicKeyHex = u(t.privateKeyHex));
|
|
159
163
|
}
|
|
160
164
|
/** Resets to default configuration. */
|
|
161
165
|
reset() {
|
|
@@ -183,22 +187,22 @@ class et {
|
|
|
183
187
|
throw new Error("Mock signing failed");
|
|
184
188
|
if (!e || e.length === 0)
|
|
185
189
|
throw new Error("Invalid message: empty string");
|
|
186
|
-
const
|
|
187
|
-
return `0x${o.from(
|
|
190
|
+
const i = `personal_sign:${e}-${n}-${this.chain.id}`;
|
|
191
|
+
return `0x${o.from(i).toString("hex").slice(0, 130).padEnd(130, "0")}`;
|
|
188
192
|
}
|
|
189
193
|
async sendTransaction(t) {
|
|
190
|
-
var
|
|
194
|
+
var i;
|
|
191
195
|
if (this.shouldFailOperations)
|
|
192
196
|
throw new Error("Mock transaction failed");
|
|
193
197
|
if (!t.to)
|
|
194
198
|
throw new Error("Invalid transaction: missing 'to' address");
|
|
195
199
|
this.transactionDelay > 0 && await new Promise(
|
|
196
|
-
(
|
|
200
|
+
(s) => setTimeout(s, this.transactionDelay)
|
|
197
201
|
), this.nonce++;
|
|
198
202
|
const e = JSON.stringify({
|
|
199
203
|
from: this.account.address,
|
|
200
204
|
to: t.to,
|
|
201
|
-
value: ((
|
|
205
|
+
value: ((i = t.value) == null ? void 0 : i.toString()) || "0",
|
|
202
206
|
nonce: this.nonce,
|
|
203
207
|
chainId: this.chain.id
|
|
204
208
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/testing/signBip322P2wpkhWitness.ts","../../src/testing/MockBitcoinWallet.ts","../../src/testing/MockEthereumWallet.ts"],"sourcesContent":["/**\n * Test-support BIP-322 \"simple\" P2WPKH signer.\n *\n * Produces the consensus-encoded two-item witness `[DER sig ‖ 0x01,\n * compressed pubkey]` that a Native SegWit software wallet returns for\n * `signMessage(..., \"bip322-simple\")`. The virtual to_spend/to_sign\n * construction follows the `bip322` crate 0.0.10 (`util.rs:18-85`) — the\n * same reference the production verifier\n * (`tbv/core/clients/vault-provider/auth/bip322Verify.ts`) mirrors, and\n * the BIP-322 official vectors pin.\n *\n * Test-only: never feed real key material to this module.\n */\n\nimport * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { script as bscript, payments, Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\n/** BIP-322 message tag (BIP-340 tagged-hash style). */\nconst BIP322_TAG = \"BIP0322-signed-message\";\nconst SIGHASH_ALL = 0x01;\nconst ZERO_SATS = 0;\n/**\n * vaultd accepts only 71/72-byte encoded signatures (`bip322` crate 0.0.10\n * `verify.rs:141-153`); a short-DER signature (~0.8% of draws) is ground\n * away by re-signing with fresh entropy. 100 attempts bounds the failure\n * probability around 0.008^100.\n */\nconst MIN_ENCODED_SIG_BYTES = 71;\nconst MAX_SIGN_GRIND_ATTEMPTS = 100;\n\n// Wire fields of the virtual to_spend/to_sign transactions (`bip322`\n// crate 0.0.10 `util.rs:18-85`).\nconst BIP322_TX_VERSION = 0;\nconst BIP322_TX_LOCKTIME = 0;\nconst BIP322_INPUT_SEQUENCE = 0;\n/** to_spend prevout: all-zero 32-byte txid at index 0xFFFFFFFF (`util.rs:18-85`). */\nconst TO_SPEND_PREVOUT_TXID_BYTES = 32;\nconst TO_SPEND_PREVOUT_INDEX = 0xffffffff;\n/** to_sign spends to_spend's only output (`util.rs:18-85`). */\nconst TO_SPEND_OUTPUT_INDEX = 0;\nconst OP_0 = 0x00;\n/** Direct push of the 32-byte tagged message hash. */\nconst OP_PUSHBYTES_32 = 0x20;\nconst OP_RETURN = 0x6a;\n/** Consensus P2WPKH witness: exactly [signature, pubkey]. */\nconst P2WPKH_WITNESS_ITEMS = 2;\n/** Grinding: 32-byte extra-entropy buffer, attempt counter at offset 0. */\nconst GRIND_ENTROPY_BYTES = 32;\nconst GRIND_COUNTER_OFFSET = 0;\n\n/**\n * Sign `messageBytes` as a BIP-322 \"simple\" P2WPKH proof with `privateKey`\n * and return the consensus-encoded two-item witness\n * (`0x02 ‖ len ‖ sig ‖ 0x21 ‖ pubkey`).\n */\nexport function signBip322P2wpkhWitness(\n messageBytes: Uint8Array,\n privateKey: Uint8Array,\n): Uint8Array {\n const pubkey = ecc.pointFromScalar(privateKey, true);\n if (!pubkey) {\n throw new Error(\"signBip322P2wpkhWitness: invalid private key\");\n }\n\n // m_hash = SHA256( SHA256(tag) ‖ SHA256(tag) ‖ message )\n const tagHash = sha256(new TextEncoder().encode(BIP322_TAG));\n const messageHash = sha256(\n Buffer.concat([tagHash, tagHash, Buffer.from(messageBytes)]),\n );\n\n const p2wpkh = payments.p2wpkh({ pubkey: Buffer.from(pubkey) });\n if (!p2wpkh.output || !p2wpkh.hash) {\n throw new Error(\"signBip322P2wpkhWitness: could not derive P2WPKH script\");\n }\n\n // to_spend / to_sign per bip322 crate util.rs:18-85.\n const toSpend = new Transaction();\n toSpend.version = BIP322_TX_VERSION;\n toSpend.locktime = BIP322_TX_LOCKTIME;\n toSpend.addInput(\n Buffer.alloc(TO_SPEND_PREVOUT_TXID_BYTES, 0),\n TO_SPEND_PREVOUT_INDEX,\n BIP322_INPUT_SEQUENCE,\n Buffer.concat([\n Buffer.from([OP_0, OP_PUSHBYTES_32]),\n Buffer.from(messageHash),\n ]),\n );\n toSpend.addOutput(p2wpkh.output, ZERO_SATS);\n const toSign = new Transaction();\n toSign.version = BIP322_TX_VERSION;\n toSign.locktime = BIP322_TX_LOCKTIME;\n toSign.addInput(\n toSpend.getHash(),\n TO_SPEND_OUTPUT_INDEX,\n BIP322_INPUT_SEQUENCE,\n );\n toSign.addOutput(Buffer.from([OP_RETURN]), ZERO_SATS);\n\n // BIP-143 sighash with the standard P2WPKH scriptCode, value 0\n // (bip322 crate verify.rs:163-173).\n const scriptCode = payments.p2pkh({ hash: p2wpkh.hash }).output;\n if (!scriptCode) {\n throw new Error(\"signBip322P2wpkhWitness: could not build scriptCode\");\n }\n const sighash = toSign.hashForWitnessV0(\n 0,\n scriptCode,\n ZERO_SATS,\n SIGHASH_ALL,\n );\n\n let encodedSignature: Buffer | undefined;\n for (let attempt = 0; attempt < MAX_SIGN_GRIND_ATTEMPTS; attempt++) {\n const entropy = Buffer.alloc(GRIND_ENTROPY_BYTES, 0);\n entropy.writeUInt32LE(attempt, GRIND_COUNTER_OFFSET);\n // ecc.sign emits low-S (libsecp256k1), so 73-byte encodings can't occur.\n const candidate = bscript.signature.encode(\n Buffer.from(ecc.sign(sighash, privateKey, entropy)),\n SIGHASH_ALL,\n );\n if (candidate.length >= MIN_ENCODED_SIG_BYTES) {\n encodedSignature = candidate;\n break;\n }\n }\n if (!encodedSignature) {\n throw new Error(\n \"signBip322P2wpkhWitness: could not grind a 71/72-byte signature\",\n );\n }\n\n return Uint8Array.from([\n P2WPKH_WITNESS_ITEMS,\n encodedSignature.length,\n ...encodedSignature,\n pubkey.length,\n ...pubkey,\n ]);\n}\n","import * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { Buffer } from \"buffer\";\n\nimport {\n BitcoinNetworks,\n type BitcoinNetwork,\n} from \"../shared/wallets/interfaces\";\nimport type {\n BitcoinWallet,\n SignPsbtOptions,\n} from \"../shared/wallets/interfaces/BitcoinWallet\";\nimport {\n canonicalizeBtcPubkey,\n uint8ArrayToHex,\n} from \"../tbv/core/primitives/utils/bitcoin\";\nimport { signBip322P2wpkhWitness } from \"./signBip322P2wpkhWitness\";\n\n/**\n * Configuration for MockBitcoinWallet.\n */\nexport interface MockBitcoinWalletConfig {\n publicKeyHex?: string;\n address?: string;\n network?: BitcoinNetwork;\n shouldFailSigning?: boolean;\n /**\n * 32-byte hex key `signMessage` signs BIP-322 proofs with. Defaults to\n * the privkey-1 test key, whose x-only pubkey is the default\n * `publicKeyHex` (the secp256k1 generator's x coordinate). PoP flows\n * verify the witness against `publicKeyHex`: overriding only this key\n * derives the matching `publicKeyHex`, and a divergent pair throws at\n * sign time. Test material only — never a real key.\n */\n privateKeyHex?: string;\n /**\n * Optional override for `deriveContextHash`. When omitted the mock\n * returns a deterministic 64-char lowercase hex string derived from\n * `(appName, context)` so tests can assert pass-through wiring\n * without pinning a specific value. Override to inject spec test\n * vectors or to simulate failure modes.\n */\n deriveContextHash?: (appName: string, context: string) => Promise<string>;\n}\n\n/**\n * Default `deriveContextHash` implementation: deterministic and\n * collision-resistant via SHA-256, so tests that assert pass-through\n * wiring (different `(appName, context)` → different output) hold\n * without flakes. Domain-separates the two inputs by length-prefixing\n * each as `len(name) || name || len(ctx) || ctx`, preventing\n * `(\"ab\", \"cd\")` from colliding with `(\"abc\", \"d\")`.\n */\nconst defaultDeriveContextHash = async (\n appName: string,\n context: string,\n): Promise<string> => {\n const enc = new TextEncoder();\n const nameBytes = enc.encode(appName);\n const ctxBytes = enc.encode(context);\n const buf = new Uint8Array(4 + nameBytes.length + 4 + ctxBytes.length);\n const view = new DataView(buf.buffer);\n view.setUint32(0, nameBytes.length);\n buf.set(nameBytes, 4);\n view.setUint32(4 + nameBytes.length, ctxBytes.length);\n buf.set(ctxBytes, 4 + nameBytes.length + 4);\n return uint8ArrayToHex(sha256(buf));\n};\n\n/** Privkey 1 — the test key `signMessage` signs with by default. */\nconst DEFAULT_PRIVATE_KEY_HEX = `${\"00\".repeat(31)}01`;\n\n/** Lowercase x-only pubkey of a 32-byte private key. */\nfunction xOnlyPubkeyHexOf(privateKeyHex: string): string {\n return uint8ArrayToHex(\n ecc.xOnlyPointFromScalar(\n Uint8Array.from(Buffer.from(privateKeyHex, \"hex\")),\n ),\n );\n}\n\nconst DEFAULT_CONFIG: Required<MockBitcoinWalletConfig> = {\n // x-only pubkey of DEFAULT_PRIVATE_KEY_HEX (the secp256k1 generator's x\n // coordinate), so the default wallet's PoP witnesses verify against it.\n publicKeyHex:\n \"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\n address: \"tb1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkx6jks\",\n network: BitcoinNetworks.SIGNET,\n shouldFailSigning: false,\n privateKeyHex: DEFAULT_PRIVATE_KEY_HEX,\n deriveContextHash: defaultDeriveContextHash,\n};\n\n/** Mock Bitcoin wallet for testing. */\nexport class MockBitcoinWallet implements BitcoinWallet {\n private config: Required<MockBitcoinWalletConfig>;\n\n constructor(config: MockBitcoinWalletConfig = {}) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...(config.publicKeyHex ? { publicKeyHex: config.publicKeyHex } : {}),\n ...(config.address ? { address: config.address } : {}),\n ...(config.network !== undefined ? { network: config.network } : {}),\n ...(config.shouldFailSigning !== undefined\n ? { shouldFailSigning: config.shouldFailSigning }\n : {}),\n ...(config.privateKeyHex ? { privateKeyHex: config.privateKeyHex } : {}),\n ...(config.deriveContextHash\n ? { deriveContextHash: config.deriveContextHash }\n : {}),\n };\n // A private-key override without a public key would otherwise sign\n // against the DEFAULT pubkey — derive the matching one instead.\n if (config.privateKeyHex && !config.publicKeyHex) {\n this.config.publicKeyHex = xOnlyPubkeyHexOf(config.privateKeyHex);\n }\n }\n\n async getPublicKeyHex(): Promise<string> {\n return this.config.publicKeyHex;\n }\n\n async getAddress(): Promise<string> {\n return this.config.address;\n }\n\n async signPsbt(psbtHex: string, _options?: SignPsbtOptions): Promise<string> {\n if (this.config.shouldFailSigning) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!psbtHex || psbtHex.length === 0) {\n throw new Error(\"Invalid PSBT: empty hex string\");\n }\n\n // In a real implementation, this would actually sign the PSBT\n // For the mock, we just return the input with a mock signature appended\n return psbtHex + \"deadbeef\";\n }\n\n async signPsbts(\n psbtsHexes: string[],\n _options?: SignPsbtOptions[],\n ): Promise<string[]> {\n const signedPsbts: string[] = [];\n for (const psbtHex of psbtsHexes) {\n const signedPsbt = await this.signPsbt(psbtHex);\n signedPsbts.push(signedPsbt);\n }\n return signedPsbts;\n }\n\n async signMessage(\n message: string,\n _type: \"bip322-simple\" | \"ecdsa\",\n ): Promise<string> {\n if (this.config.shouldFailSigning) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!message || message.length === 0) {\n throw new Error(\"Invalid message: empty string\");\n }\n\n // PoP flows verify the witness against `publicKeyHex`, so a divergent\n // key pair must fail loudly here, not as a confusing verify mismatch.\n const signingXOnlyHex = xOnlyPubkeyHexOf(this.config.privateKeyHex);\n let configuredXOnlyHex: string | undefined;\n try {\n configuredXOnlyHex = canonicalizeBtcPubkey(this.config.publicKeyHex);\n } catch {\n configuredXOnlyHex = undefined; // an unparseable key cannot match\n }\n if (configuredXOnlyHex !== signingXOnlyHex) {\n throw new Error(\n `MockBitcoinWallet.signMessage: privateKeyHex signs as x-only pubkey ` +\n `${signingXOnlyHex}, but publicKeyHex is ${this.config.publicKeyHex}. ` +\n `Pass a matching publicKeyHex/privateKeyHex pair.`,\n );\n }\n\n // The SDK cryptographically verifies what a wallet returns\n // (`verifyPopWitness`), so the mock signs a REAL BIP-322 P2WPKH witness\n // with its private key. The type is not consulted: PoP flows only ever\n // request \"bip322-simple\", and the interface tests assert shape only.\n const witness = signBip322P2wpkhWitness(\n new TextEncoder().encode(message),\n Uint8Array.from(Buffer.from(this.config.privateKeyHex, \"hex\")),\n );\n return `0x${uint8ArrayToHex(witness)}`;\n }\n\n async getNetwork(): Promise<BitcoinNetwork> {\n return this.config.network;\n }\n\n async deriveContextHash(appName: string, context: string): Promise<string> {\n return this.config.deriveContextHash(appName, context);\n }\n\n /** Updates configuration for testing different scenarios. */\n updateConfig(updates: Partial<MockBitcoinWalletConfig>): void {\n this.config = {\n ...this.config,\n ...updates,\n };\n }\n\n /** Resets to default configuration. */\n reset(): void {\n this.config = { ...DEFAULT_CONFIG };\n }\n}\n","import { Buffer } from \"buffer\";\nimport type { Address, Hex } from \"viem\";\n\n/**\n * Configuration for MockEthereumWallet.\n */\nexport interface MockEthereumWalletConfig {\n address?: Address;\n chainId?: number;\n shouldFailOperations?: boolean;\n transactionDelay?: number;\n}\n\n/**\n * Mock Ethereum wallet for testing.\n *\n * Provides the subset of viem's WalletClient methods used by the SDK.\n * Can be passed to functions expecting a WalletClient for testing purposes.\n */\nexport class MockEthereumWallet {\n // Public properties matching viem's WalletClient structure\n account: { address: Address };\n chain: { id: number };\n\n private shouldFailOperations: boolean;\n private transactionDelay: number;\n private nonce: number = 0;\n\n constructor(config: MockEthereumWalletConfig = {}) {\n // Use lowercase addresses to avoid EIP-55 checksum validation issues\n this.account = {\n address:\n config.address ||\n (\"0x742d35cc6634c0532925a3b844bc9e7595f0beb0\" as Address),\n };\n\n this.chain = {\n id: config.chainId ?? 11155111, // Sepolia by default\n };\n\n this.shouldFailOperations = config.shouldFailOperations ?? false;\n this.transactionDelay = config.transactionDelay ?? 0;\n\n // Bind methods to preserve 'this' context when called\n this.signMessage = this.signMessage.bind(this);\n this.sendTransaction = this.sendTransaction.bind(this);\n }\n\n async signMessage(args: { message: string; account?: Address }): Promise<Hex> {\n const message = args.message;\n const account = args.account || this.account.address;\n\n if (this.shouldFailOperations) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!message || message.length === 0) {\n throw new Error(\"Invalid message: empty string\");\n }\n\n // Generate a deterministic mock signature\n const signatureData = `personal_sign:${message}-${account}-${this.chain.id}`;\n const signature = `0x${Buffer.from(signatureData)\n .toString(\"hex\")\n .slice(0, 130)\n .padEnd(130, \"0\")}` as Hex;\n return signature;\n }\n\n async sendTransaction(tx: {\n to: Address;\n data?: Hex;\n value?: bigint;\n gas?: bigint;\n account?: { address: Address };\n chain?: { id: number };\n }): Promise<Hex> {\n if (this.shouldFailOperations) {\n throw new Error(\"Mock transaction failed\");\n }\n\n if (!tx.to) {\n throw new Error(\"Invalid transaction: missing 'to' address\");\n }\n\n // Simulate network delay if configured\n if (this.transactionDelay > 0) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.transactionDelay),\n );\n }\n\n // Generate a deterministic mock transaction hash\n this.nonce++;\n const txData = JSON.stringify({\n from: this.account.address,\n to: tx.to,\n value: tx.value?.toString() || \"0\",\n nonce: this.nonce,\n chainId: this.chain.id,\n });\n\n const hash = `0x${Buffer.from(txData)\n .toString(\"hex\")\n .slice(0, 64)\n .padEnd(64, \"0\")}` as Hex;\n return hash;\n }\n\n /** Updates configuration for testing different scenarios. */\n updateConfig(updates: Partial<MockEthereumWalletConfig>): void {\n if (updates.address !== undefined) {\n this.account.address = updates.address;\n }\n if (updates.chainId !== undefined) {\n this.chain.id = updates.chainId;\n }\n if (updates.shouldFailOperations !== undefined) {\n this.shouldFailOperations = updates.shouldFailOperations;\n }\n if (updates.transactionDelay !== undefined) {\n this.transactionDelay = updates.transactionDelay;\n }\n }\n\n /** Resets to default configuration and nonce. */\n reset(): void {\n this.account.address =\n \"0x742d35cc6634c0532925a3b844bc9e7595f0beb0\" as Address;\n this.chain.id = 11155111;\n this.shouldFailOperations = false;\n this.transactionDelay = 0;\n this.nonce = 0;\n }\n\n /** Returns current nonce for testing. */\n getCurrentNonce(): number {\n return this.nonce;\n }\n}\n"],"names":["BIP322_TAG","SIGHASH_ALL","ZERO_SATS","MIN_ENCODED_SIG_BYTES","MAX_SIGN_GRIND_ATTEMPTS","BIP322_TX_VERSION","BIP322_TX_LOCKTIME","BIP322_INPUT_SEQUENCE","TO_SPEND_PREVOUT_TXID_BYTES","TO_SPEND_PREVOUT_INDEX","TO_SPEND_OUTPUT_INDEX","OP_0","OP_PUSHBYTES_32","OP_RETURN","P2WPKH_WITNESS_ITEMS","GRIND_ENTROPY_BYTES","GRIND_COUNTER_OFFSET","signBip322P2wpkhWitness","messageBytes","privateKey","pubkey","ecc","tagHash","sha256","messageHash","Buffer","p2wpkh","payments","toSpend","Transaction","toSign","scriptCode","sighash","encodedSignature","attempt","entropy","candidate","bscript","defaultDeriveContextHash","appName","context","enc","nameBytes","ctxBytes","buf","view","uint8ArrayToHex","DEFAULT_PRIVATE_KEY_HEX","xOnlyPubkeyHexOf","privateKeyHex","DEFAULT_CONFIG","BitcoinNetworks","MockBitcoinWallet","config","__publicField","psbtHex","_options","psbtsHexes","signedPsbts","signedPsbt","message","_type","signingXOnlyHex","configuredXOnlyHex","canonicalizeBtcPubkey","witness","updates","MockEthereumWallet","args","account","signatureData","tx","resolve","txData","_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/testing/signBip322P2wpkhWitness.ts","../../src/testing/MockBitcoinWallet.ts","../../src/testing/MockEthereumWallet.ts"],"sourcesContent":["/**\n * Test-support BIP-322 \"simple\" P2WPKH signer.\n *\n * Produces the consensus-encoded two-item witness `[DER sig ‖ 0x01,\n * compressed pubkey]` that a Native SegWit software wallet returns for\n * `signMessage(..., \"bip322-simple\")`. The virtual to_spend/to_sign\n * construction follows the `bip322` crate 0.0.10 (`util.rs:18-85`) — the\n * same reference the production verifier\n * (`tbv/core/clients/vault-provider/auth/bip322Verify.ts`) mirrors, and\n * the BIP-322 official vectors pin.\n *\n * Conscious call: `./testing` deliberately depends on the Bitcoin stack\n * (bitcoinjs-lib was already in this entry's graph via MockBitcoinWallet;\n * tiny-secp256k1-asmjs is new here) — out of scope for the CLAUDE.md §9\n * optional-BTC split.\n *\n * Test-only: never feed real key material to this module.\n */\n\nimport * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { script as bscript, payments, Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\n/** BIP-322 message tag (BIP-340 tagged-hash style). */\nconst BIP322_TAG = \"BIP0322-signed-message\";\nconst SIGHASH_ALL = 0x01;\nconst ZERO_SATS = 0;\n/**\n * vaultd accepts only 71/72-byte encoded signatures (`bip322` crate 0.0.10\n * `verify.rs:141-153`); a short-DER signature (~0.4% of draws) is ground\n * away by re-signing with fresh entropy. 100 attempts bounds the failure\n * probability around 0.004^100.\n */\nconst MIN_ENCODED_SIG_BYTES = 71;\nconst MAX_SIGN_GRIND_ATTEMPTS = 100;\n\n// Wire fields of the virtual to_spend/to_sign transactions (`bip322`\n// crate 0.0.10 `util.rs:18-85`).\nconst BIP322_TX_VERSION = 0;\nconst BIP322_TX_LOCKTIME = 0;\nconst BIP322_INPUT_SEQUENCE = 0;\n/** to_spend prevout: all-zero 32-byte txid at index 0xFFFFFFFF (`util.rs:18-85`). */\nconst TO_SPEND_PREVOUT_TXID_BYTES = 32;\nconst TO_SPEND_PREVOUT_INDEX = 0xffffffff;\n/** to_sign spends to_spend's only output (`util.rs:18-85`). */\nconst TO_SPEND_OUTPUT_INDEX = 0;\nconst OP_0 = 0x00;\n/** Direct push of the 32-byte tagged message hash. */\nconst OP_PUSHBYTES_32 = 0x20;\nconst OP_RETURN = 0x6a;\n/** Consensus P2WPKH witness: exactly [signature, pubkey]. */\nconst P2WPKH_WITNESS_ITEMS = 2;\n/** Grinding: 32-byte extra-entropy buffer, attempt counter at offset 0. */\nconst GRIND_ENTROPY_BYTES = 32;\nconst GRIND_COUNTER_OFFSET = 0;\n\n/**\n * Sign `messageBytes` as a BIP-322 \"simple\" P2WPKH proof with `privateKey`\n * and return the consensus-encoded two-item witness\n * (`0x02 ‖ len ‖ sig ‖ 0x21 ‖ pubkey`).\n */\nexport function signBip322P2wpkhWitness(\n messageBytes: Uint8Array,\n privateKey: Uint8Array,\n): Uint8Array {\n const pubkey = ecc.pointFromScalar(privateKey, true);\n if (!pubkey) {\n throw new Error(\"signBip322P2wpkhWitness: invalid private key\");\n }\n\n // m_hash = SHA256( SHA256(tag) ‖ SHA256(tag) ‖ message )\n const tagHash = sha256(new TextEncoder().encode(BIP322_TAG));\n const messageHash = sha256(\n Buffer.concat([tagHash, tagHash, Buffer.from(messageBytes)]),\n );\n\n const p2wpkh = payments.p2wpkh({ pubkey: Buffer.from(pubkey) });\n if (!p2wpkh.output || !p2wpkh.hash) {\n throw new Error(\"signBip322P2wpkhWitness: could not derive P2WPKH script\");\n }\n\n // to_spend / to_sign per bip322 crate util.rs:18-85.\n const toSpend = new Transaction();\n toSpend.version = BIP322_TX_VERSION;\n toSpend.locktime = BIP322_TX_LOCKTIME;\n toSpend.addInput(\n Buffer.alloc(TO_SPEND_PREVOUT_TXID_BYTES, 0),\n TO_SPEND_PREVOUT_INDEX,\n BIP322_INPUT_SEQUENCE,\n Buffer.concat([\n Buffer.from([OP_0, OP_PUSHBYTES_32]),\n Buffer.from(messageHash),\n ]),\n );\n toSpend.addOutput(p2wpkh.output, ZERO_SATS);\n const toSign = new Transaction();\n toSign.version = BIP322_TX_VERSION;\n toSign.locktime = BIP322_TX_LOCKTIME;\n toSign.addInput(\n toSpend.getHash(),\n TO_SPEND_OUTPUT_INDEX,\n BIP322_INPUT_SEQUENCE,\n );\n toSign.addOutput(Buffer.from([OP_RETURN]), ZERO_SATS);\n\n // BIP-143 sighash with the standard P2WPKH scriptCode, value 0\n // (bip322 crate verify.rs:163-173).\n const scriptCode = payments.p2pkh({ hash: p2wpkh.hash }).output;\n if (!scriptCode) {\n throw new Error(\"signBip322P2wpkhWitness: could not build scriptCode\");\n }\n const sighash = toSign.hashForWitnessV0(\n 0,\n scriptCode,\n ZERO_SATS,\n SIGHASH_ALL,\n );\n\n let encodedSignature: Buffer | undefined;\n for (let attempt = 0; attempt < MAX_SIGN_GRIND_ATTEMPTS; attempt++) {\n const entropy = Buffer.alloc(GRIND_ENTROPY_BYTES, 0);\n entropy.writeUInt32LE(attempt, GRIND_COUNTER_OFFSET);\n // ecc.sign emits low-S (libsecp256k1), so 73-byte encodings can't occur.\n const candidate = bscript.signature.encode(\n Buffer.from(ecc.sign(sighash, privateKey, entropy)),\n SIGHASH_ALL,\n );\n if (candidate.length >= MIN_ENCODED_SIG_BYTES) {\n encodedSignature = candidate;\n break;\n }\n }\n if (!encodedSignature) {\n throw new Error(\n \"signBip322P2wpkhWitness: could not grind a 71/72-byte signature\",\n );\n }\n\n return Uint8Array.from([\n P2WPKH_WITNESS_ITEMS,\n encodedSignature.length,\n ...encodedSignature,\n pubkey.length,\n ...pubkey,\n ]);\n}\n","import * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { Buffer } from \"buffer\";\n\nimport {\n BitcoinNetworks,\n type BitcoinNetwork,\n} from \"../shared/wallets/interfaces\";\nimport type {\n BitcoinWallet,\n SignPsbtOptions,\n} from \"../shared/wallets/interfaces/BitcoinWallet\";\nimport {\n canonicalizeBtcPubkey,\n uint8ArrayToHex,\n} from \"../tbv/core/primitives/utils/bitcoin\";\nimport { signBip322P2wpkhWitness } from \"./signBip322P2wpkhWitness\";\n\n/**\n * Configuration for MockBitcoinWallet.\n */\nexport interface MockBitcoinWalletConfig {\n publicKeyHex?: string;\n address?: string;\n network?: BitcoinNetwork;\n shouldFailSigning?: boolean;\n /**\n * 32-byte hex key `signMessage` signs BIP-322 proofs with. Defaults to\n * the privkey-1 test key, whose x-only pubkey is the default\n * `publicKeyHex` (the secp256k1 generator's x coordinate). PoP flows\n * verify the witness against `publicKeyHex`: overriding only this key\n * derives the matching `publicKeyHex`, and a divergent pair throws at\n * sign time. Test material only — never a real key.\n */\n privateKeyHex?: string;\n /**\n * Optional override for `deriveContextHash`. When omitted the mock\n * returns a deterministic 64-char lowercase hex string derived from\n * `(appName, context)` so tests can assert pass-through wiring\n * without pinning a specific value. Override to inject spec test\n * vectors or to simulate failure modes.\n */\n deriveContextHash?: (appName: string, context: string) => Promise<string>;\n}\n\n/**\n * Default `deriveContextHash` implementation: deterministic and\n * collision-resistant via SHA-256, so tests that assert pass-through\n * wiring (different `(appName, context)` → different output) hold\n * without flakes. Domain-separates the two inputs by length-prefixing\n * each as `len(name) || name || len(ctx) || ctx`, preventing\n * `(\"ab\", \"cd\")` from colliding with `(\"abc\", \"d\")`.\n */\nconst defaultDeriveContextHash = async (\n appName: string,\n context: string,\n): Promise<string> => {\n const enc = new TextEncoder();\n const nameBytes = enc.encode(appName);\n const ctxBytes = enc.encode(context);\n const buf = new Uint8Array(4 + nameBytes.length + 4 + ctxBytes.length);\n const view = new DataView(buf.buffer);\n view.setUint32(0, nameBytes.length);\n buf.set(nameBytes, 4);\n view.setUint32(4 + nameBytes.length, ctxBytes.length);\n buf.set(ctxBytes, 4 + nameBytes.length + 4);\n return uint8ArrayToHex(sha256(buf));\n};\n\n/** Privkey 1 — the test key `signMessage` signs with by default. */\nconst DEFAULT_PRIVATE_KEY_HEX = `${\"00\".repeat(31)}01`;\n\n/** Lowercase x-only pubkey of a 32-byte private key. */\nfunction xOnlyPubkeyHexOf(privateKeyHex: string): string {\n return uint8ArrayToHex(\n ecc.xOnlyPointFromScalar(\n Uint8Array.from(Buffer.from(privateKeyHex, \"hex\")),\n ),\n );\n}\n\nconst DEFAULT_CONFIG: Required<MockBitcoinWalletConfig> = {\n // x-only pubkey of DEFAULT_PRIVATE_KEY_HEX (the secp256k1 generator's x\n // coordinate), so the default wallet's PoP witnesses verify against it.\n publicKeyHex:\n \"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\n address: \"tb1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkx6jks\",\n network: BitcoinNetworks.SIGNET,\n shouldFailSigning: false,\n privateKeyHex: DEFAULT_PRIVATE_KEY_HEX,\n deriveContextHash: defaultDeriveContextHash,\n};\n\n/** Mock Bitcoin wallet for testing. */\nexport class MockBitcoinWallet implements BitcoinWallet {\n private config: Required<MockBitcoinWalletConfig>;\n\n constructor(config: MockBitcoinWalletConfig = {}) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...(config.publicKeyHex ? { publicKeyHex: config.publicKeyHex } : {}),\n ...(config.address ? { address: config.address } : {}),\n ...(config.network !== undefined ? { network: config.network } : {}),\n ...(config.shouldFailSigning !== undefined\n ? { shouldFailSigning: config.shouldFailSigning }\n : {}),\n ...(config.privateKeyHex ? { privateKeyHex: config.privateKeyHex } : {}),\n ...(config.deriveContextHash\n ? { deriveContextHash: config.deriveContextHash }\n : {}),\n };\n // A private-key override without a public key would otherwise sign\n // against the DEFAULT pubkey — derive the matching one instead.\n if (config.privateKeyHex && !config.publicKeyHex) {\n this.config.publicKeyHex = xOnlyPubkeyHexOf(config.privateKeyHex);\n }\n }\n\n async getPublicKeyHex(): Promise<string> {\n return this.config.publicKeyHex;\n }\n\n async getAddress(): Promise<string> {\n return this.config.address;\n }\n\n async signPsbt(psbtHex: string, _options?: SignPsbtOptions): Promise<string> {\n if (this.config.shouldFailSigning) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!psbtHex || psbtHex.length === 0) {\n throw new Error(\"Invalid PSBT: empty hex string\");\n }\n\n // In a real implementation, this would actually sign the PSBT\n // For the mock, we just return the input with a mock signature appended\n return psbtHex + \"deadbeef\";\n }\n\n async signPsbts(\n psbtsHexes: string[],\n _options?: SignPsbtOptions[],\n ): Promise<string[]> {\n const signedPsbts: string[] = [];\n for (const psbtHex of psbtsHexes) {\n const signedPsbt = await this.signPsbt(psbtHex);\n signedPsbts.push(signedPsbt);\n }\n return signedPsbts;\n }\n\n async signMessage(\n message: string,\n type: \"bip322-simple\" | \"ecdsa\",\n ): Promise<string> {\n // Only BIP-322 witnesses are implemented; returning one for \"ecdsa\"\n // would hand a future ECDSA-flow test the wrong artifact silently.\n if (type !== \"bip322-simple\") {\n throw new Error(\n \"MockBitcoinWallet.signMessage: only bip322-simple is implemented\",\n );\n }\n if (this.config.shouldFailSigning) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!message || message.length === 0) {\n throw new Error(\"Invalid message: empty string\");\n }\n\n // PoP flows verify the witness against `publicKeyHex`, so a divergent\n // key pair must fail loudly here, not as a confusing verify mismatch.\n const signingXOnlyHex = xOnlyPubkeyHexOf(this.config.privateKeyHex);\n let configuredXOnlyHex: string | undefined;\n try {\n configuredXOnlyHex = canonicalizeBtcPubkey(this.config.publicKeyHex);\n } catch {\n configuredXOnlyHex = undefined; // an unparseable key cannot match\n }\n if (configuredXOnlyHex !== signingXOnlyHex) {\n throw new Error(\n `MockBitcoinWallet.signMessage: privateKeyHex signs as x-only pubkey ` +\n `${signingXOnlyHex}, but publicKeyHex is ${this.config.publicKeyHex}. ` +\n `Pass a matching publicKeyHex/privateKeyHex pair.`,\n );\n }\n\n // The SDK cryptographically verifies what a wallet returns\n // (`verifyPopWitness`), so the mock signs a REAL BIP-322 P2WPKH witness\n // with its private key.\n const witness = signBip322P2wpkhWitness(\n new TextEncoder().encode(message),\n Uint8Array.from(Buffer.from(this.config.privateKeyHex, \"hex\")),\n );\n return `0x${uint8ArrayToHex(witness)}`;\n }\n\n async getNetwork(): Promise<BitcoinNetwork> {\n return this.config.network;\n }\n\n async deriveContextHash(appName: string, context: string): Promise<string> {\n return this.config.deriveContextHash(appName, context);\n }\n\n /** Updates configuration for testing different scenarios. */\n updateConfig(updates: Partial<MockBitcoinWalletConfig>): void {\n this.config = {\n ...this.config,\n ...updates,\n };\n // Mirror the constructor: a private-key-only update re-derives the\n // matching pubkey; an explicit publicKeyHex still wins.\n if (updates.privateKeyHex && !updates.publicKeyHex) {\n this.config.publicKeyHex = xOnlyPubkeyHexOf(updates.privateKeyHex);\n }\n }\n\n /** Resets to default configuration. */\n reset(): void {\n this.config = { ...DEFAULT_CONFIG };\n }\n}\n","import { Buffer } from \"buffer\";\nimport type { Address, Hex } from \"viem\";\n\n/**\n * Configuration for MockEthereumWallet.\n */\nexport interface MockEthereumWalletConfig {\n address?: Address;\n chainId?: number;\n shouldFailOperations?: boolean;\n transactionDelay?: number;\n}\n\n/**\n * Mock Ethereum wallet for testing.\n *\n * Provides the subset of viem's WalletClient methods used by the SDK.\n * Can be passed to functions expecting a WalletClient for testing purposes.\n */\nexport class MockEthereumWallet {\n // Public properties matching viem's WalletClient structure\n account: { address: Address };\n chain: { id: number };\n\n private shouldFailOperations: boolean;\n private transactionDelay: number;\n private nonce: number = 0;\n\n constructor(config: MockEthereumWalletConfig = {}) {\n // Use lowercase addresses to avoid EIP-55 checksum validation issues\n this.account = {\n address:\n config.address ||\n (\"0x742d35cc6634c0532925a3b844bc9e7595f0beb0\" as Address),\n };\n\n this.chain = {\n id: config.chainId ?? 11155111, // Sepolia by default\n };\n\n this.shouldFailOperations = config.shouldFailOperations ?? false;\n this.transactionDelay = config.transactionDelay ?? 0;\n\n // Bind methods to preserve 'this' context when called\n this.signMessage = this.signMessage.bind(this);\n this.sendTransaction = this.sendTransaction.bind(this);\n }\n\n async signMessage(args: { message: string; account?: Address }): Promise<Hex> {\n const message = args.message;\n const account = args.account || this.account.address;\n\n if (this.shouldFailOperations) {\n throw new Error(\"Mock signing failed\");\n }\n\n if (!message || message.length === 0) {\n throw new Error(\"Invalid message: empty string\");\n }\n\n // Generate a deterministic mock signature\n const signatureData = `personal_sign:${message}-${account}-${this.chain.id}`;\n const signature = `0x${Buffer.from(signatureData)\n .toString(\"hex\")\n .slice(0, 130)\n .padEnd(130, \"0\")}` as Hex;\n return signature;\n }\n\n async sendTransaction(tx: {\n to: Address;\n data?: Hex;\n value?: bigint;\n gas?: bigint;\n account?: { address: Address };\n chain?: { id: number };\n }): Promise<Hex> {\n if (this.shouldFailOperations) {\n throw new Error(\"Mock transaction failed\");\n }\n\n if (!tx.to) {\n throw new Error(\"Invalid transaction: missing 'to' address\");\n }\n\n // Simulate network delay if configured\n if (this.transactionDelay > 0) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.transactionDelay),\n );\n }\n\n // Generate a deterministic mock transaction hash\n this.nonce++;\n const txData = JSON.stringify({\n from: this.account.address,\n to: tx.to,\n value: tx.value?.toString() || \"0\",\n nonce: this.nonce,\n chainId: this.chain.id,\n });\n\n const hash = `0x${Buffer.from(txData)\n .toString(\"hex\")\n .slice(0, 64)\n .padEnd(64, \"0\")}` as Hex;\n return hash;\n }\n\n /** Updates configuration for testing different scenarios. */\n updateConfig(updates: Partial<MockEthereumWalletConfig>): void {\n if (updates.address !== undefined) {\n this.account.address = updates.address;\n }\n if (updates.chainId !== undefined) {\n this.chain.id = updates.chainId;\n }\n if (updates.shouldFailOperations !== undefined) {\n this.shouldFailOperations = updates.shouldFailOperations;\n }\n if (updates.transactionDelay !== undefined) {\n this.transactionDelay = updates.transactionDelay;\n }\n }\n\n /** Resets to default configuration and nonce. */\n reset(): void {\n this.account.address =\n \"0x742d35cc6634c0532925a3b844bc9e7595f0beb0\" as Address;\n this.chain.id = 11155111;\n this.shouldFailOperations = false;\n this.transactionDelay = 0;\n this.nonce = 0;\n }\n\n /** Returns current nonce for testing. */\n getCurrentNonce(): number {\n return this.nonce;\n }\n}\n"],"names":["BIP322_TAG","SIGHASH_ALL","ZERO_SATS","MIN_ENCODED_SIG_BYTES","MAX_SIGN_GRIND_ATTEMPTS","BIP322_TX_VERSION","BIP322_TX_LOCKTIME","BIP322_INPUT_SEQUENCE","TO_SPEND_PREVOUT_TXID_BYTES","TO_SPEND_PREVOUT_INDEX","TO_SPEND_OUTPUT_INDEX","OP_0","OP_PUSHBYTES_32","OP_RETURN","P2WPKH_WITNESS_ITEMS","GRIND_ENTROPY_BYTES","GRIND_COUNTER_OFFSET","signBip322P2wpkhWitness","messageBytes","privateKey","pubkey","ecc","tagHash","sha256","messageHash","Buffer","p2wpkh","payments","toSpend","Transaction","toSign","scriptCode","sighash","encodedSignature","attempt","entropy","candidate","bscript","defaultDeriveContextHash","appName","context","enc","nameBytes","ctxBytes","buf","view","uint8ArrayToHex","DEFAULT_PRIVATE_KEY_HEX","xOnlyPubkeyHexOf","privateKeyHex","DEFAULT_CONFIG","BitcoinNetworks","MockBitcoinWallet","config","__publicField","psbtHex","_options","psbtsHexes","signedPsbts","signedPsbt","message","type","signingXOnlyHex","configuredXOnlyHex","canonicalizeBtcPubkey","witness","updates","MockEthereumWallet","args","account","signatureData","tx","resolve","txData","_a"],"mappings":"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"}
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
* (`tbv/core/clients/vault-provider/auth/bip322Verify.ts`) mirrors, and
|
|
10
10
|
* the BIP-322 official vectors pin.
|
|
11
11
|
*
|
|
12
|
+
* Conscious call: `./testing` deliberately depends on the Bitcoin stack
|
|
13
|
+
* (bitcoinjs-lib was already in this entry's graph via MockBitcoinWallet;
|
|
14
|
+
* tiny-secp256k1-asmjs is new here) — out of scope for the CLAUDE.md §9
|
|
15
|
+
* optional-BTC split.
|
|
16
|
+
*
|
|
12
17
|
* Test-only: never feed real key material to this module.
|
|
13
18
|
*/
|
|
14
19
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signBip322P2wpkhWitness.d.ts","sourceRoot":"","sources":["../../src/testing/signBip322P2wpkhWitness.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"signBip322P2wpkhWitness.d.ts","sourceRoot":"","sources":["../../src/testing/signBip322P2wpkhWitness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAwCH;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,UAAU,EACxB,UAAU,EAAE,UAAU,GACrB,UAAU,CAiFZ"}
|
|
@@ -2,8 +2,8 @@ var J = Object.defineProperty;
|
|
|
2
2
|
var X = (e, t, r) => t in e ? J(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
|
|
3
3
|
var I = (e, t, r) => X(e, typeof t != "symbol" ? t + "" : t, r);
|
|
4
4
|
import { s as G } from "./sha2-BYVxyZzX.js";
|
|
5
|
-
import { a as F } from "./signPsbtsWithFallback-
|
|
6
|
-
import { b as Y, g as Z } from "./PeginManager
|
|
5
|
+
import { a as F } from "./signPsbtsWithFallback-DCZO2h6i.js";
|
|
6
|
+
import { b as Y, g as Z } from "./PeginManager-DSFecw-w.js";
|
|
7
7
|
import { s as P, h as ee, p as z, u as te, e as re } from "./bitcoin-Ch_jxnDa.js";
|
|
8
8
|
import { computeMinClaimValue as N, computeMinPeginFee as D, peginP2aAnchorOutput as U, getPrePeginHtlcConnectorInfo as ne, expandAuthAnchor as oe } from "@babylonlabs-io/babylon-tbv-rust-wasm";
|
|
9
9
|
import { p as se, d as ae } from "./parseFundingOutpoints-CO-f6IHK.js";
|
|
@@ -453,4 +453,4 @@ export {
|
|
|
453
453
|
ue as r,
|
|
454
454
|
Me as t
|
|
455
455
|
};
|
|
456
|
-
//# sourceMappingURL=toRefundInputs-
|
|
456
|
+
//# sourceMappingURL=toRefundInputs-C012ZXcp.js.map
|