@babylonlabs-io/ts-sdk 0.27.1 → 0.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PeginManager-Da4uSHzl.cjs +2 -0
- package/dist/PeginManager-Da4uSHzl.cjs.map +1 -0
- package/dist/{context-ktqanzXE.js → PeginManager-DzMSIQ0I.js} +1100 -1058
- package/dist/PeginManager-DzMSIQ0I.js.map +1 -0
- package/dist/buildAndBroadcastRefund-DkEpTFkv.cjs +2 -0
- package/dist/buildAndBroadcastRefund-DkEpTFkv.cjs.map +1 -0
- package/dist/{buildAndBroadcastRefund-BzYJv-Fv.js → buildAndBroadcastRefund-xWS8frc6.js} +338 -348
- package/dist/buildAndBroadcastRefund-xWS8frc6.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +55 -55
- package/dist/sha2-6wN58S6R.js +280 -0
- package/dist/sha2-6wN58S6R.js.map +1 -0
- package/dist/sha2-CsTynrfJ.cjs +2 -0
- package/dist/sha2-CsTynrfJ.cjs.map +1 -0
- package/dist/shared/index.cjs.map +1 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/wallets/index.d.ts +2 -1
- package/dist/shared/wallets/index.d.ts.map +1 -1
- package/dist/shared/wallets/interfaces/BitcoinWallet.d.ts +8 -0
- package/dist/shared/wallets/interfaces/BitcoinWallet.d.ts.map +1 -1
- package/dist/signing-BZigafm0.js.map +1 -1
- package/dist/signing-DHSXjhLM.cjs.map +1 -1
- package/dist/tbv/core/clients/eth/vault-registry-reader.d.ts.map +1 -1
- package/dist/tbv/core/clients/index.cjs +1 -1
- package/dist/tbv/core/clients/index.js +2 -2
- package/dist/tbv/core/contracts/abis/BTCVaultRegistry.abi.d.ts +80 -70
- package/dist/tbv/core/contracts/abis/BTCVaultRegistry.abi.d.ts.map +1 -1
- package/dist/tbv/core/index.cjs +1 -1
- package/dist/tbv/core/index.js +52 -52
- package/dist/tbv/core/managers/PeginManager.d.ts +64 -27
- package/dist/tbv/core/managers/PeginManager.d.ts.map +1 -1
- package/dist/tbv/core/managers/index.d.ts +1 -1
- package/dist/tbv/core/managers/index.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/peginState.d.ts +1 -1
- package/dist/tbv/core/services/deposit/peginState.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/validation.d.ts +0 -4
- package/dist/tbv/core/services/deposit/validation.d.ts.map +1 -1
- package/dist/tbv/core/services/index.cjs +1 -1
- package/dist/tbv/core/services/index.js +1 -1
- package/dist/tbv/core/vault-secrets/__tests__/deriveVaultRoot.test.d.ts +13 -0
- package/dist/tbv/core/vault-secrets/__tests__/deriveVaultRoot.test.d.ts.map +1 -0
- package/dist/tbv/core/vault-secrets/context.d.ts +9 -0
- package/dist/tbv/core/vault-secrets/context.d.ts.map +1 -1
- package/dist/tbv/core/vault-secrets/deriveVaultRoot.d.ts +56 -0
- package/dist/tbv/core/vault-secrets/deriveVaultRoot.d.ts.map +1 -0
- package/dist/tbv/core/vault-secrets/expand.d.ts +18 -3
- package/dist/tbv/core/vault-secrets/expand.d.ts.map +1 -1
- package/dist/tbv/core/vault-secrets/index.d.ts +6 -3
- package/dist/tbv/core/vault-secrets/index.d.ts.map +1 -1
- package/dist/tbv/core/wots/blockDerivation.d.ts +20 -24
- package/dist/tbv/core/wots/blockDerivation.d.ts.map +1 -1
- package/dist/tbv/core/wots/errors.d.ts +3 -1
- package/dist/tbv/core/wots/errors.d.ts.map +1 -1
- package/dist/tbv/core/wots/index.d.ts +1 -2
- package/dist/tbv/core/wots/index.d.ts.map +1 -1
- package/dist/tbv/index.cjs +1 -1
- package/dist/tbv/index.js +52 -52
- package/dist/testing/MockBitcoinWallet.d.ts +10 -3
- 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 +67 -55
- package/dist/testing/index.js.map +1 -1
- package/dist/types-CnG3JsRs.js +680 -0
- package/dist/types-CnG3JsRs.js.map +1 -0
- package/dist/types-jmEyzzhY.cjs +2 -0
- package/dist/types-jmEyzzhY.cjs.map +1 -0
- package/dist/{vault-registry-reader-CpCOte7w.js → vault-registry-reader-BywZhqJL.js} +65 -64
- package/dist/{vault-registry-reader-CpCOte7w.js.map → vault-registry-reader-BywZhqJL.js.map} +1 -1
- package/dist/vault-registry-reader-DdruADqa.cjs +2 -0
- package/dist/{vault-registry-reader-BizmBSBV.cjs.map → vault-registry-reader-DdruADqa.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/buildAndBroadcastRefund-BEASMFsz.cjs +0 -2
- package/dist/buildAndBroadcastRefund-BEASMFsz.cjs.map +0 -1
- package/dist/buildAndBroadcastRefund-BzYJv-Fv.js.map +0 -1
- package/dist/context-B4fYDTxy.cjs +0 -2
- package/dist/context-B4fYDTxy.cjs.map +0 -1
- package/dist/context-ktqanzXE.js.map +0 -1
- package/dist/sha2-1XZuToHP.cjs +0 -2
- package/dist/sha2-1XZuToHP.cjs.map +0 -1
- package/dist/sha2-ZzfZqQSw.js +0 -1123
- package/dist/sha2-ZzfZqQSw.js.map +0 -1
- package/dist/tbv/core/wots/deriveWotsPkHash.d.ts +0 -9
- package/dist/tbv/core/wots/deriveWotsPkHash.d.ts.map +0 -1
- package/dist/vault-registry-reader-BizmBSBV.cjs +0 -2
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var b = (e, t, n) =>
|
|
4
|
-
import * as
|
|
5
|
-
import { Transaction as
|
|
6
|
-
import { Buffer as
|
|
7
|
-
import { isAddressEqual as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
1
|
+
var Jt = Object.defineProperty;
|
|
2
|
+
var te = (e, t, n) => t in e ? Jt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
|
+
var b = (e, t, n) => te(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
+
import * as ee from "bitcoinjs-lib";
|
|
5
|
+
import { Transaction as ne, Psbt as ft } from "bitcoinjs-lib";
|
|
6
|
+
import { Buffer as et } from "buffer";
|
|
7
|
+
import { isAddressEqual as gt, createPublicClient as j, http as z, encodeFunctionData as pt, zeroAddress as se } from "viem";
|
|
8
|
+
import { deriveVaultId as mt } from "@babylonlabs-io/babylon-tbv-rust-wasm";
|
|
9
|
+
import { b as bt, a as oe, d as re, e as ie, f as ae } from "./challengeAssert-j2Vwqo0-.js";
|
|
10
|
+
import { u as $t, h as nt, e as I, s as _, g as wt, i as ce, p as le } from "./bitcoin-B-Y0DlqR.js";
|
|
11
|
+
import { h as ue } from "./buildAndBroadcastRefund-xWS8frc6.js";
|
|
12
|
+
import { c as he } from "./signing-BZigafm0.js";
|
|
13
|
+
import { M as yt } from "./validation-CxqROCno.js";
|
|
14
|
+
import { a as Rt, b as U, c as A, d as F, e as st, s as L, f as Ut, H as de, r as V, u as fe, g as xt, h as ge } from "./sha2-6wN58S6R.js";
|
|
15
|
+
import { b as pe, f as q, i as me } from "./psbtInputFields-DeTFSJOq.js";
|
|
16
|
+
import { p as be, f as we } from "./fundPeginTransaction-oV-dNJOU.js";
|
|
17
|
+
import { p as ye, f as xe } from "./vault-registry-reader-BywZhqJL.js";
|
|
18
|
+
import { B as C } from "./types-CnG3JsRs.js";
|
|
19
|
+
const S = {
|
|
18
20
|
// VaultAlreadyExists()
|
|
19
21
|
"0x04aabf33": "Vault already exists: This Bitcoin transaction has already been registered. Please select different UTXOs or use a different amount to create a unique transaction.",
|
|
20
22
|
// ScriptPubKeyMismatch() - taproot output doesn't match expected script
|
|
@@ -48,7 +50,7 @@ const H = {
|
|
|
48
50
|
// PeginTransactionAlreadyUsed()
|
|
49
51
|
"0x7ed061c9": "This pegin transaction has already been used to activate another vault."
|
|
50
52
|
};
|
|
51
|
-
function
|
|
53
|
+
function at(e) {
|
|
52
54
|
if (!e || typeof e != "object") return;
|
|
53
55
|
const t = e;
|
|
54
56
|
if (typeof t.data == "string" && t.data.startsWith("0x"))
|
|
@@ -67,24 +69,24 @@ function dt(e) {
|
|
|
67
69
|
if (i)
|
|
68
70
|
return i[1];
|
|
69
71
|
}
|
|
70
|
-
function
|
|
71
|
-
const t =
|
|
72
|
+
function Ln(e) {
|
|
73
|
+
const t = at(e);
|
|
72
74
|
if (t) {
|
|
73
75
|
const n = t.substring(0, 10);
|
|
74
|
-
return
|
|
76
|
+
return S[t] ?? S[n];
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
|
-
function
|
|
78
|
-
const t =
|
|
79
|
+
function Vn(e) {
|
|
80
|
+
const t = at(e);
|
|
79
81
|
if (t === void 0) return !1;
|
|
80
82
|
const n = t.substring(0, 10);
|
|
81
|
-
return t in
|
|
83
|
+
return t in S || n in S;
|
|
82
84
|
}
|
|
83
|
-
function
|
|
85
|
+
function H(e) {
|
|
84
86
|
console.error("[Contract Error] Raw error:", e);
|
|
85
|
-
const t =
|
|
87
|
+
const t = at(e);
|
|
86
88
|
if (console.error("[Contract Error] Extracted error data:", t), t) {
|
|
87
|
-
const s = t.substring(0, 10), o =
|
|
89
|
+
const s = t.substring(0, 10), o = S[t] ?? S[s];
|
|
88
90
|
if (o)
|
|
89
91
|
throw console.error("[Contract Error] Known error:", o), new Error(o);
|
|
90
92
|
}
|
|
@@ -102,326 +104,944 @@ function A(e) {
|
|
|
102
104
|
}
|
|
103
105
|
throw e instanceof Error ? (console.error("[Contract Error] Unhandled error:", e.message), e) : new Error(`Contract call failed: ${String(e)}`);
|
|
104
106
|
}
|
|
105
|
-
const
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
throw new Error("BTC wallet returned empty public key");
|
|
109
|
-
return de(e).toLowerCase();
|
|
107
|
+
const W = /* @__PURE__ */ BigInt(2 ** 32 - 1), Pt = /* @__PURE__ */ BigInt(32);
|
|
108
|
+
function Pe(e, t = !1) {
|
|
109
|
+
return t ? { h: Number(e & W), l: Number(e >> Pt & W) } : { h: Number(e >> Pt & W) | 0, l: Number(e & W) | 0 };
|
|
110
110
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return e.toLowerCase();
|
|
111
|
+
function Ee(e, t = !1) {
|
|
112
|
+
const n = e.length;
|
|
113
|
+
let s = new Uint32Array(n), o = new Uint32Array(n);
|
|
114
|
+
for (let r = 0; r < n; r++) {
|
|
115
|
+
const { h: i, l: a } = Pe(e[r], t);
|
|
116
|
+
[s[r], o[r]] = [i, a];
|
|
118
117
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
return [s, o];
|
|
119
|
+
}
|
|
120
|
+
const ke = (e, t, n) => e << n | t >>> 32 - n, Te = (e, t, n) => t << n | e >>> 32 - n, _e = (e, t, n) => t << n - 32 | e >>> 64 - n, ve = (e, t, n) => e << n - 32 | t >>> 64 - n;
|
|
121
|
+
class Lt {
|
|
122
|
+
constructor(t, n) {
|
|
123
|
+
b(this, "oHash");
|
|
124
|
+
b(this, "iHash");
|
|
125
|
+
b(this, "blockLen");
|
|
126
|
+
b(this, "outputLen");
|
|
127
|
+
b(this, "finished", !1);
|
|
128
|
+
b(this, "destroyed", !1);
|
|
129
|
+
if (Rt(t), U(n, void 0, "key"), this.iHash = t.create(), typeof this.iHash.update != "function")
|
|
130
|
+
throw new Error("Expected instance of class which extends utils.Hash");
|
|
131
|
+
this.blockLen = this.iHash.blockLen, this.outputLen = this.iHash.outputLen;
|
|
132
|
+
const s = this.blockLen, o = new Uint8Array(s);
|
|
133
|
+
o.set(n.length > s ? t.create().update(n).digest() : n);
|
|
134
|
+
for (let r = 0; r < o.length; r++)
|
|
135
|
+
o[r] ^= 54;
|
|
136
|
+
this.iHash.update(o), this.oHash = t.create();
|
|
137
|
+
for (let r = 0; r < o.length; r++)
|
|
138
|
+
o[r] ^= 106;
|
|
139
|
+
this.oHash.update(o), A(o);
|
|
140
|
+
}
|
|
141
|
+
update(t) {
|
|
142
|
+
return F(this), this.iHash.update(t), this;
|
|
143
|
+
}
|
|
144
|
+
digestInto(t) {
|
|
145
|
+
F(this), U(t, this.outputLen, "output"), this.finished = !0, this.iHash.digestInto(t), this.oHash.update(t), this.oHash.digestInto(t), this.destroy();
|
|
146
|
+
}
|
|
147
|
+
digest() {
|
|
148
|
+
const t = new Uint8Array(this.oHash.outputLen);
|
|
149
|
+
return this.digestInto(t), t;
|
|
150
|
+
}
|
|
151
|
+
_cloneInto(t) {
|
|
152
|
+
t || (t = Object.create(Object.getPrototypeOf(this), {}));
|
|
153
|
+
const { oHash: n, iHash: s, finished: o, destroyed: r, blockLen: i, outputLen: a } = this;
|
|
154
|
+
return t = t, t.finished = o, t.destroyed = r, t.blockLen = i, t.outputLen = a, t.oHash = n._cloneInto(t.oHash), t.iHash = s._cloneInto(t.iHash), t;
|
|
155
|
+
}
|
|
156
|
+
clone() {
|
|
157
|
+
return this._cloneInto();
|
|
158
|
+
}
|
|
159
|
+
destroy() {
|
|
160
|
+
this.destroyed = !0, this.oHash.destroy(), this.iHash.destroy();
|
|
123
161
|
}
|
|
124
|
-
if (!He.test(e) || e.length % 4 !== 0)
|
|
125
|
-
throw new Error("BTC wallet returned malformed base64 BIP-322 signature");
|
|
126
|
-
const t = it.from(e, "base64");
|
|
127
|
-
if (t.length === 0 || t.toString("base64") !== e)
|
|
128
|
-
throw new Error("BTC wallet returned malformed base64 BIP-322 signature");
|
|
129
|
-
return `0x${t.toString("hex")}`;
|
|
130
162
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
163
|
+
const Vt = (e, t, n) => new Lt(e, t).update(n).digest();
|
|
164
|
+
Vt.create = (e, t) => new Lt(e, t);
|
|
165
|
+
const G = /* @__PURE__ */ Uint8Array.of(0), Et = /* @__PURE__ */ Uint8Array.of();
|
|
166
|
+
function ct(e, t, n, s = 32) {
|
|
167
|
+
Rt(e), st(s, "length");
|
|
168
|
+
const o = e.outputLen;
|
|
169
|
+
if (s > 255 * o)
|
|
170
|
+
throw new Error("Length must be <= 255*HashLen");
|
|
171
|
+
const r = Math.ceil(s / o);
|
|
172
|
+
n === void 0 ? n = Et : U(n, void 0, "info");
|
|
173
|
+
const i = new Uint8Array(r * o), a = Vt.create(e, t), l = a._cloneInto(), u = new Uint8Array(a.outputLen);
|
|
174
|
+
for (let c = 0; c < r; c++)
|
|
175
|
+
G[0] = c + 1, l.update(c === 0 ? Et : u).update(n).update(G).digestInto(u), i.set(u, o * c), a._cloneInto(l);
|
|
176
|
+
return a.destroy(), l.destroy(), A(u, G), i.slice(0, s);
|
|
139
177
|
}
|
|
140
|
-
const _t =
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
178
|
+
const Z = new TextEncoder().encode("babylonvault"), kt = 255, Tt = 65535, _t = 2, Ie = "hashlock", Be = "auth-anchor", He = "wots-seed";
|
|
179
|
+
function Wt(e) {
|
|
180
|
+
if (!Number.isInteger(e) || e < 0 || e > 4294967295)
|
|
181
|
+
throw new Error(`i2osp4: value must be a u32, got ${e}`);
|
|
182
|
+
const t = new Uint8Array(4);
|
|
183
|
+
return t[0] = e >>> 24 & 255, t[1] = e >>> 16 & 255, t[2] = e >>> 8 & 255, t[3] = e & 255, t;
|
|
184
|
+
}
|
|
185
|
+
function lt(e, t = new Uint8Array(0)) {
|
|
186
|
+
const n = new TextEncoder().encode(e);
|
|
187
|
+
if (n.length === 0 || n.length > kt)
|
|
188
|
+
throw new Error(
|
|
189
|
+
`info: label length must be in [1, ${kt}], got ${n.length}`
|
|
190
|
+
);
|
|
191
|
+
if (t.length > Tt)
|
|
192
|
+
throw new Error(
|
|
193
|
+
`info: ctx length must be in [0, ${Tt}], got ${t.length}`
|
|
194
|
+
);
|
|
195
|
+
const s = Z.length + 1 + n.length + _t + t.length, o = new Uint8Array(s);
|
|
196
|
+
let r = 0;
|
|
197
|
+
return o.set(Z, r), r += Z.length, o[r] = n.length, r += 1, o.set(n, r), r += n.length, o[r] = t.length >>> 8 & 255, o[r + 1] = t.length & 255, r += _t, o.set(t, r), o;
|
|
198
|
+
}
|
|
199
|
+
const vt = 32, Ae = 32, Se = 32, Ce = 64;
|
|
200
|
+
function ut(e) {
|
|
201
|
+
if (e.length !== vt)
|
|
202
|
+
throw new Error(
|
|
203
|
+
`vault-secrets: root must be exactly ${vt} bytes, got ${e.length}`
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
function Wn(e) {
|
|
207
|
+
return ut(e), ct(
|
|
208
|
+
L,
|
|
209
|
+
e,
|
|
210
|
+
lt(Be),
|
|
211
|
+
Ae
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
function Oe(e, t) {
|
|
215
|
+
return ut(e), ct(
|
|
216
|
+
L,
|
|
217
|
+
e,
|
|
218
|
+
lt(Ie, Wt(t)),
|
|
219
|
+
Se
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
function $e(e, t) {
|
|
223
|
+
return ut(e), ct(
|
|
224
|
+
L,
|
|
225
|
+
e,
|
|
226
|
+
lt(He, Wt(t)),
|
|
227
|
+
Ce
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
const R = 32, Y = 32, ot = 36, Nt = 32, X = 4, Re = X + R + X + Nt;
|
|
231
|
+
function rt(e, t, n) {
|
|
232
|
+
e[t] = n >>> 24 & 255, e[t + 1] = n >>> 16 & 255, e[t + 2] = n >>> 8 & 255, e[t + 3] = n & 255;
|
|
233
|
+
}
|
|
234
|
+
function Ue(e) {
|
|
235
|
+
if (e.txid.length !== Y)
|
|
236
|
+
throw new Error(
|
|
237
|
+
`outpoint.txid must be exactly ${Y} bytes, got ${e.txid.length}`
|
|
238
|
+
);
|
|
239
|
+
if (!Number.isInteger(e.vout) || e.vout < 0 || e.vout > 4294967295)
|
|
240
|
+
throw new Error(`outpoint.vout must be a u32, got ${e.vout}`);
|
|
241
|
+
const t = new Uint8Array(ot);
|
|
242
|
+
return t.set(e.txid, 0), rt(t, Y, e.vout), t;
|
|
243
|
+
}
|
|
244
|
+
function It(e, t) {
|
|
245
|
+
const n = Math.min(e.length, t.length);
|
|
246
|
+
for (let s = 0; s < n; s++)
|
|
247
|
+
if (e[s] !== t[s]) return e[s] - t[s];
|
|
248
|
+
return e.length - t.length;
|
|
249
|
+
}
|
|
250
|
+
function Le(e) {
|
|
251
|
+
if (e.length === 0)
|
|
252
|
+
throw new Error(
|
|
253
|
+
"buildFundingOutpointsCommitment: outpoints must be non-empty"
|
|
254
|
+
);
|
|
255
|
+
const t = e.map(Ue);
|
|
256
|
+
t.sort(It);
|
|
257
|
+
for (let s = 1; s < t.length; s++)
|
|
258
|
+
if (It(t[s - 1], t[s]) === 0)
|
|
174
259
|
throw new Error(
|
|
175
|
-
|
|
176
|
-
);
|
|
177
|
-
if (t.hashlocks.length === 0)
|
|
178
|
-
throw new Error("hashlocks must contain at least one entry");
|
|
179
|
-
const a = r.length, h = {
|
|
180
|
-
depositorPubkey: s,
|
|
181
|
-
vaultProviderPubkey: o,
|
|
182
|
-
vaultKeeperPubkeys: r,
|
|
183
|
-
universalChallengerPubkeys: i,
|
|
184
|
-
hashlocks: t.hashlocks,
|
|
185
|
-
timelockRefund: t.timelockRefund,
|
|
186
|
-
pegInAmounts: t.amounts,
|
|
187
|
-
feeRate: t.protocolFeeRate,
|
|
188
|
-
numLocalChallengers: a,
|
|
189
|
-
councilQuorum: t.councilQuorum,
|
|
190
|
-
councilSize: t.councilSize,
|
|
191
|
-
network: this.config.btcNetwork
|
|
192
|
-
}, u = await ie(h), c = fe(
|
|
193
|
-
[...t.availableUTXOs],
|
|
194
|
-
u.totalOutputValue,
|
|
195
|
-
t.mempoolFeeRate,
|
|
196
|
-
pe(
|
|
197
|
-
u.htlcValues.length,
|
|
198
|
-
h.authAnchorHash
|
|
199
|
-
)
|
|
200
|
-
), m = kt(this.config.btcNetwork), l = me({
|
|
201
|
-
unfundedTxHex: u.psbtHex,
|
|
202
|
-
selectedUTXOs: c.selectedUTXOs,
|
|
203
|
-
changeAddress: t.changeAddress,
|
|
204
|
-
changeAmount: c.changeAmount,
|
|
205
|
-
network: m
|
|
206
|
-
}), y = v(G(l)), f = [], x = [], P = [];
|
|
207
|
-
for (let g = 0; g < t.hashlocks.length; g++) {
|
|
208
|
-
const p = await ae({
|
|
209
|
-
prePeginParams: h,
|
|
210
|
-
timelockPegin: t.timelockPegin,
|
|
211
|
-
fundedPrePeginTxHex: l,
|
|
212
|
-
htlcVout: g
|
|
213
|
-
}), E = await ce({
|
|
214
|
-
peginTxHex: p.txHex,
|
|
215
|
-
fundedPrePeginTxHex: l,
|
|
216
|
-
depositorPubkey: s,
|
|
217
|
-
vaultProviderPubkey: o,
|
|
218
|
-
vaultKeeperPubkeys: r,
|
|
219
|
-
universalChallengerPubkeys: i,
|
|
220
|
-
hashlock: t.hashlocks[g],
|
|
221
|
-
timelockRefund: t.timelockRefund,
|
|
222
|
-
network: this.config.btcNetwork
|
|
223
|
-
});
|
|
224
|
-
f.push(p), x.push(E.psbtHex), P.push(
|
|
225
|
-
re(n, 1)
|
|
260
|
+
"buildFundingOutpointsCommitment: duplicate outpoint detected"
|
|
226
261
|
);
|
|
262
|
+
const n = new Uint8Array(t.length * ot);
|
|
263
|
+
for (let s = 0; s < t.length; s++)
|
|
264
|
+
n.set(t[s], s * ot);
|
|
265
|
+
return L(n);
|
|
266
|
+
}
|
|
267
|
+
function Ve(e) {
|
|
268
|
+
if (e.depositorBtcPubkey.length !== R)
|
|
269
|
+
throw new Error(
|
|
270
|
+
`vaultContext: depositorBtcPubkey must be exactly ${R} bytes, got ${e.depositorBtcPubkey.length}`
|
|
271
|
+
);
|
|
272
|
+
const t = Le(e.fundingOutpoints), n = new Uint8Array(Re);
|
|
273
|
+
let s = 0;
|
|
274
|
+
return rt(n, s, R), s += X, n.set(e.depositorBtcPubkey, s), s += R, rt(n, s, Nt), s += X, n.set(t, s), n;
|
|
275
|
+
}
|
|
276
|
+
const We = "babylon-vault", Mt = 32, Bt = Mt * 2, Ne = /^[0-9a-f]+$/;
|
|
277
|
+
async function Me(e, t) {
|
|
278
|
+
const n = Ve(t), s = $t(n), o = await e.deriveContextHash(We, s);
|
|
279
|
+
if (typeof o != "string")
|
|
280
|
+
throw new Error(
|
|
281
|
+
`deriveVaultRoot: wallet must return a string, got ${typeof o}`
|
|
282
|
+
);
|
|
283
|
+
if (o.length !== Bt)
|
|
284
|
+
throw new Error(
|
|
285
|
+
`deriveVaultRoot: wallet must return a ${Bt}-character hex string (${Mt} bytes), got length ${o.length}`
|
|
286
|
+
);
|
|
287
|
+
if (!Ne.test(o))
|
|
288
|
+
throw new Error(
|
|
289
|
+
"deriveVaultRoot: wallet must return lowercase hex per derive-context-hash.md §2.1; got value with non-lowercase or non-hex characters"
|
|
290
|
+
);
|
|
291
|
+
return nt(o);
|
|
292
|
+
}
|
|
293
|
+
const Fe = /* @__PURE__ */ Uint8Array.from([
|
|
294
|
+
7,
|
|
295
|
+
4,
|
|
296
|
+
13,
|
|
297
|
+
1,
|
|
298
|
+
10,
|
|
299
|
+
6,
|
|
300
|
+
15,
|
|
301
|
+
3,
|
|
302
|
+
12,
|
|
303
|
+
0,
|
|
304
|
+
9,
|
|
305
|
+
5,
|
|
306
|
+
2,
|
|
307
|
+
14,
|
|
308
|
+
11,
|
|
309
|
+
8
|
|
310
|
+
]), Ft = Uint8Array.from(new Array(16).fill(0).map((e, t) => t)), Xe = Ft.map((e) => (9 * e + 5) % 16), Xt = /* @__PURE__ */ (() => {
|
|
311
|
+
const n = [[Ft], [Xe]];
|
|
312
|
+
for (let s = 0; s < 4; s++)
|
|
313
|
+
for (let o of n)
|
|
314
|
+
o.push(o[s].map((r) => Fe[r]));
|
|
315
|
+
return n;
|
|
316
|
+
})(), Kt = Xt[0], Dt = Xt[1], jt = /* @__PURE__ */ [
|
|
317
|
+
[11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],
|
|
318
|
+
[12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],
|
|
319
|
+
[13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],
|
|
320
|
+
[14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],
|
|
321
|
+
[15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5]
|
|
322
|
+
].map((e) => Uint8Array.from(e)), Ke = /* @__PURE__ */ Kt.map((e, t) => e.map((n) => jt[t][n])), De = /* @__PURE__ */ Dt.map((e, t) => e.map((n) => jt[t][n])), je = /* @__PURE__ */ Uint32Array.from([
|
|
323
|
+
0,
|
|
324
|
+
1518500249,
|
|
325
|
+
1859775393,
|
|
326
|
+
2400959708,
|
|
327
|
+
2840853838
|
|
328
|
+
]), ze = /* @__PURE__ */ Uint32Array.from([
|
|
329
|
+
1352829926,
|
|
330
|
+
1548603684,
|
|
331
|
+
1836072691,
|
|
332
|
+
2053994217,
|
|
333
|
+
0
|
|
334
|
+
]);
|
|
335
|
+
function Ht(e, t, n, s) {
|
|
336
|
+
return e === 0 ? t ^ n ^ s : e === 1 ? t & n | ~t & s : e === 2 ? (t | ~n) ^ s : e === 3 ? t & s | n & ~s : t ^ (n | ~s);
|
|
337
|
+
}
|
|
338
|
+
const N = /* @__PURE__ */ new Uint32Array(16);
|
|
339
|
+
class qe extends de {
|
|
340
|
+
constructor() {
|
|
341
|
+
super(64, 20, 8, !0);
|
|
342
|
+
b(this, "h0", 1732584193);
|
|
343
|
+
b(this, "h1", -271733879);
|
|
344
|
+
b(this, "h2", -1732584194);
|
|
345
|
+
b(this, "h3", 271733878);
|
|
346
|
+
b(this, "h4", -1009589776);
|
|
347
|
+
}
|
|
348
|
+
get() {
|
|
349
|
+
const { h0: n, h1: s, h2: o, h3: r, h4: i } = this;
|
|
350
|
+
return [n, s, o, r, i];
|
|
351
|
+
}
|
|
352
|
+
set(n, s, o, r, i) {
|
|
353
|
+
this.h0 = n | 0, this.h1 = s | 0, this.h2 = o | 0, this.h3 = r | 0, this.h4 = i | 0;
|
|
354
|
+
}
|
|
355
|
+
process(n, s) {
|
|
356
|
+
for (let p = 0; p < 16; p++, s += 4)
|
|
357
|
+
N[p] = n.getUint32(s, !0);
|
|
358
|
+
let o = this.h0 | 0, r = o, i = this.h1 | 0, a = i, l = this.h2 | 0, u = l, c = this.h3 | 0, y = c, g = this.h4 | 0, h = g;
|
|
359
|
+
for (let p = 0; p < 5; p++) {
|
|
360
|
+
const T = 4 - p, P = je[p], v = ze[p], d = Kt[p], x = Dt[p], f = Ke[p], m = De[p];
|
|
361
|
+
for (let w = 0; w < 16; w++) {
|
|
362
|
+
const E = V(o + Ht(p, i, l, c) + N[d[w]] + P, f[w]) + g | 0;
|
|
363
|
+
o = g, g = c, c = V(l, 10) | 0, l = i, i = E;
|
|
364
|
+
}
|
|
365
|
+
for (let w = 0; w < 16; w++) {
|
|
366
|
+
const E = V(r + Ht(T, a, u, y) + N[x[w]] + v, m[w]) + h | 0;
|
|
367
|
+
r = h, h = y, y = V(u, 10) | 0, u = a, a = E;
|
|
368
|
+
}
|
|
227
369
|
}
|
|
228
|
-
|
|
229
|
-
x,
|
|
230
|
-
P
|
|
231
|
-
), d = [];
|
|
232
|
-
for (let g = 0; g < w.length; g++) {
|
|
233
|
-
const p = le(
|
|
234
|
-
w[g],
|
|
235
|
-
s
|
|
236
|
-
), E = ue(w[g]);
|
|
237
|
-
d.push({
|
|
238
|
-
htlcVout: g,
|
|
239
|
-
htlcValue: u.htlcValues[g],
|
|
240
|
-
peginTxHex: E,
|
|
241
|
-
peginTxid: f[g].txid,
|
|
242
|
-
peginInputSignature: p,
|
|
243
|
-
vaultScriptPubKey: f[g].vaultScriptPubKey
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
return {
|
|
247
|
-
fundedPrePeginTxHex: l,
|
|
248
|
-
prePeginTxid: y,
|
|
249
|
-
perVault: d,
|
|
250
|
-
selectedUTXOs: c.selectedUTXOs,
|
|
251
|
-
fee: c.fee,
|
|
252
|
-
changeAmount: c.changeAmount
|
|
253
|
-
};
|
|
370
|
+
this.set(this.h1 + l + y | 0, this.h2 + c + h | 0, this.h3 + g + r | 0, this.h4 + o + a | 0, this.h0 + i + u | 0);
|
|
254
371
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
372
|
+
roundClean() {
|
|
373
|
+
A(N);
|
|
374
|
+
}
|
|
375
|
+
destroy() {
|
|
376
|
+
this.destroyed = !0, A(this.buffer), this.set(0, 0, 0, 0, 0);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const Ge = /* @__PURE__ */ Ut(() => new qe()), Ze = BigInt(0), O = BigInt(1), Ye = BigInt(2), Qe = BigInt(7), Je = BigInt(256), tn = BigInt(113), zt = [], qt = [], Gt = [];
|
|
380
|
+
for (let e = 0, t = O, n = 1, s = 0; e < 24; e++) {
|
|
381
|
+
[n, s] = [s, (2 * n + 3 * s) % 5], zt.push(2 * (5 * s + n)), qt.push((e + 1) * (e + 2) / 2 % 64);
|
|
382
|
+
let o = Ze;
|
|
383
|
+
for (let r = 0; r < 7; r++)
|
|
384
|
+
t = (t << O ^ (t >> Qe) * tn) % Je, t & Ye && (o ^= O << (O << BigInt(r)) - O);
|
|
385
|
+
Gt.push(o);
|
|
386
|
+
}
|
|
387
|
+
const Zt = Ee(Gt, !0), en = Zt[0], nn = Zt[1], At = (e, t, n) => n > 32 ? _e(e, t, n) : ke(e, t, n), St = (e, t, n) => n > 32 ? ve(e, t, n) : Te(e, t, n);
|
|
388
|
+
function sn(e, t = 24) {
|
|
389
|
+
const n = new Uint32Array(10);
|
|
390
|
+
for (let s = 24 - t; s < 24; s++) {
|
|
391
|
+
for (let i = 0; i < 10; i++)
|
|
392
|
+
n[i] = e[i] ^ e[i + 10] ^ e[i + 20] ^ e[i + 30] ^ e[i + 40];
|
|
393
|
+
for (let i = 0; i < 10; i += 2) {
|
|
394
|
+
const a = (i + 8) % 10, l = (i + 2) % 10, u = n[l], c = n[l + 1], y = At(u, c, 1) ^ n[a], g = St(u, c, 1) ^ n[a + 1];
|
|
395
|
+
for (let h = 0; h < 50; h += 10)
|
|
396
|
+
e[i + h] ^= y, e[i + h + 1] ^= g;
|
|
273
397
|
}
|
|
274
|
-
|
|
275
|
-
for (let
|
|
276
|
-
const r =
|
|
277
|
-
|
|
278
|
-
n[o]
|
|
279
|
-
);
|
|
280
|
-
s.push(r);
|
|
398
|
+
let o = e[2], r = e[3];
|
|
399
|
+
for (let i = 0; i < 24; i++) {
|
|
400
|
+
const a = qt[i], l = At(o, r, a), u = St(o, r, a), c = zt[i];
|
|
401
|
+
o = e[c], r = e[c + 1], e[c] = l, e[c + 1] = u;
|
|
281
402
|
}
|
|
282
|
-
|
|
403
|
+
for (let i = 0; i < 50; i += 10) {
|
|
404
|
+
for (let a = 0; a < 10; a++)
|
|
405
|
+
n[a] = e[i + a];
|
|
406
|
+
for (let a = 0; a < 10; a++)
|
|
407
|
+
e[i + a] ^= ~n[(a + 2) % 10] & n[(a + 4) % 10];
|
|
408
|
+
}
|
|
409
|
+
e[0] ^= en[s], e[1] ^= nn[s];
|
|
283
410
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
),
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
(
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
411
|
+
A(n);
|
|
412
|
+
}
|
|
413
|
+
class ht {
|
|
414
|
+
// NOTE: we accept arguments in bytes instead of bits here.
|
|
415
|
+
constructor(t, n, s, o = !1, r = 24) {
|
|
416
|
+
b(this, "state");
|
|
417
|
+
b(this, "pos", 0);
|
|
418
|
+
b(this, "posOut", 0);
|
|
419
|
+
b(this, "finished", !1);
|
|
420
|
+
b(this, "state32");
|
|
421
|
+
b(this, "destroyed", !1);
|
|
422
|
+
b(this, "blockLen");
|
|
423
|
+
b(this, "suffix");
|
|
424
|
+
b(this, "outputLen");
|
|
425
|
+
b(this, "enableXOF", !1);
|
|
426
|
+
b(this, "rounds");
|
|
427
|
+
if (this.blockLen = t, this.suffix = n, this.outputLen = s, this.enableXOF = o, this.rounds = r, st(s, "outputLen"), !(0 < t && t < 200))
|
|
428
|
+
throw new Error("only keccak-f1600 function is supported");
|
|
429
|
+
this.state = new Uint8Array(200), this.state32 = fe(this.state);
|
|
430
|
+
}
|
|
431
|
+
clone() {
|
|
432
|
+
return this._cloneInto();
|
|
433
|
+
}
|
|
434
|
+
keccak() {
|
|
435
|
+
xt(this.state32), sn(this.state32, this.rounds), xt(this.state32), this.posOut = 0, this.pos = 0;
|
|
436
|
+
}
|
|
437
|
+
update(t) {
|
|
438
|
+
F(this), U(t);
|
|
439
|
+
const { blockLen: n, state: s } = this, o = t.length;
|
|
440
|
+
for (let r = 0; r < o; ) {
|
|
441
|
+
const i = Math.min(n - this.pos, o - r);
|
|
442
|
+
for (let a = 0; a < i; a++)
|
|
443
|
+
s[this.pos++] ^= t[r++];
|
|
444
|
+
this.pos === n && this.keccak();
|
|
445
|
+
}
|
|
446
|
+
return this;
|
|
447
|
+
}
|
|
448
|
+
finish() {
|
|
449
|
+
if (this.finished)
|
|
450
|
+
return;
|
|
451
|
+
this.finished = !0;
|
|
452
|
+
const { state: t, suffix: n, pos: s, blockLen: o } = this;
|
|
453
|
+
t[s] ^= n, (n & 128) !== 0 && s === o - 1 && this.keccak(), t[o - 1] ^= 128, this.keccak();
|
|
454
|
+
}
|
|
455
|
+
writeInto(t) {
|
|
456
|
+
F(this, !1), U(t), this.finish();
|
|
457
|
+
const n = this.state, { blockLen: s } = this;
|
|
458
|
+
for (let o = 0, r = t.length; o < r; ) {
|
|
459
|
+
this.posOut >= s && this.keccak();
|
|
460
|
+
const i = Math.min(s - this.posOut, r - o);
|
|
461
|
+
t.set(n.subarray(this.posOut, this.posOut + i), o), this.posOut += i, o += i;
|
|
462
|
+
}
|
|
463
|
+
return t;
|
|
464
|
+
}
|
|
465
|
+
xofInto(t) {
|
|
466
|
+
if (!this.enableXOF)
|
|
467
|
+
throw new Error("XOF is not possible for this instance");
|
|
468
|
+
return this.writeInto(t);
|
|
469
|
+
}
|
|
470
|
+
xof(t) {
|
|
471
|
+
return st(t), this.xofInto(new Uint8Array(t));
|
|
472
|
+
}
|
|
473
|
+
digestInto(t) {
|
|
474
|
+
if (ge(t, this), this.finished)
|
|
475
|
+
throw new Error("digest() was already called");
|
|
476
|
+
return this.writeInto(t), this.destroy(), t;
|
|
477
|
+
}
|
|
478
|
+
digest() {
|
|
479
|
+
return this.digestInto(new Uint8Array(this.outputLen));
|
|
480
|
+
}
|
|
481
|
+
destroy() {
|
|
482
|
+
this.destroyed = !0, A(this.state);
|
|
483
|
+
}
|
|
484
|
+
_cloneInto(t) {
|
|
485
|
+
const { blockLen: n, suffix: s, outputLen: o, rounds: r, enableXOF: i } = this;
|
|
486
|
+
return t || (t = new ht(n, s, o, i, r)), t.state32.set(this.state32), t.pos = this.pos, t.posOut = this.posOut, t.finished = this.finished, t.rounds = r, t.suffix = s, t.outputLen = o, t.enableXOF = i, t.destroyed = this.destroyed, t;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
const on = (e, t, n, s = {}) => Ut(() => new ht(t, e, n), s), rn = /* @__PURE__ */ on(1, 136, 32), Ct = 64, k = 20, it = 4, Yt = 2, an = 0, cn = 1, M = [64, 64], ln = (e) => Array.from(e).map((t) => t.toString(16).padStart(2, "0")).join("");
|
|
490
|
+
function dt(e) {
|
|
491
|
+
return Ge(L(e));
|
|
492
|
+
}
|
|
493
|
+
function Qt(e) {
|
|
494
|
+
return (1 << e) - 1;
|
|
495
|
+
}
|
|
496
|
+
function un(e) {
|
|
497
|
+
let t = 1;
|
|
498
|
+
for (; t * t < e + 1; ) t++;
|
|
499
|
+
return Math.max(t, 2);
|
|
500
|
+
}
|
|
501
|
+
function hn(e) {
|
|
502
|
+
const t = it, n = e * Qt(t);
|
|
503
|
+
return { d: t, n: e, checksum_radix: un(n) };
|
|
504
|
+
}
|
|
505
|
+
function Q(e, t) {
|
|
506
|
+
const n = [];
|
|
507
|
+
let s = t;
|
|
508
|
+
for (; s > 0; )
|
|
509
|
+
n.push(s & 255), s >>>= 8;
|
|
510
|
+
const o = new Uint8Array(e.length + n.length);
|
|
511
|
+
o.set(e);
|
|
512
|
+
for (let r = 0; r < n.length; r++)
|
|
513
|
+
o[e.length + r] = n[r];
|
|
514
|
+
return dt(o);
|
|
515
|
+
}
|
|
516
|
+
function J(e, t) {
|
|
517
|
+
let n = e;
|
|
518
|
+
for (let s = 0; s < t; s++)
|
|
519
|
+
n = dt(n);
|
|
520
|
+
return n;
|
|
521
|
+
}
|
|
522
|
+
function dn(e, t) {
|
|
523
|
+
const n = Qt(t.d), s = t.checksum_radix - 1, o = Math.floor(t.n * n / t.checksum_radix), r = [];
|
|
524
|
+
for (let c = 0; c < t.n; c++) {
|
|
525
|
+
const y = Q(e, c + Yt), g = J(y, n);
|
|
526
|
+
r.push(Array.from(g));
|
|
527
|
+
}
|
|
528
|
+
const i = Q(
|
|
529
|
+
e,
|
|
530
|
+
an
|
|
531
|
+
), a = J(
|
|
532
|
+
i,
|
|
533
|
+
s
|
|
534
|
+
), l = Q(
|
|
535
|
+
e,
|
|
536
|
+
cn
|
|
537
|
+
), u = J(
|
|
538
|
+
l,
|
|
539
|
+
o
|
|
540
|
+
);
|
|
541
|
+
return {
|
|
542
|
+
config: t,
|
|
543
|
+
message_terminals: r,
|
|
544
|
+
checksum_major_terminal: Array.from(u),
|
|
545
|
+
checksum_minor_terminal: Array.from(a)
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
async function fn(e) {
|
|
549
|
+
try {
|
|
550
|
+
if (e.length !== Ct)
|
|
321
551
|
throw new Error(
|
|
322
|
-
`
|
|
552
|
+
`WOTS seed must be exactly ${Ct} bytes, got ${e.length}`
|
|
323
553
|
);
|
|
324
|
-
const
|
|
325
|
-
|
|
554
|
+
const t = [];
|
|
555
|
+
for (let n = 0; n < M.length; n++) {
|
|
556
|
+
const s = M[n], o = hn(s), r = new Uint8Array(e.length + 1);
|
|
557
|
+
r.set(e), r[e.length] = n;
|
|
558
|
+
const i = dt(r);
|
|
559
|
+
try {
|
|
560
|
+
const a = dn(i, o);
|
|
561
|
+
if (a.config.d !== it)
|
|
562
|
+
throw new Error(
|
|
563
|
+
`Block ${n}: expected d=${it}, got d=${a.config.d}`
|
|
564
|
+
);
|
|
565
|
+
if (a.config.n !== s)
|
|
566
|
+
throw new Error(
|
|
567
|
+
`Block ${n}: expected n=${s}, got n=${a.config.n}`
|
|
568
|
+
);
|
|
569
|
+
if (a.message_terminals.length !== s)
|
|
570
|
+
throw new Error(
|
|
571
|
+
`Block ${n}: expected ${s} message terminals, got ${a.message_terminals.length}`
|
|
572
|
+
);
|
|
573
|
+
for (let l = 0; l < a.message_terminals.length; l++)
|
|
574
|
+
if (a.message_terminals[l].length !== k)
|
|
575
|
+
throw new Error(
|
|
576
|
+
`Block ${n} terminal ${l}: expected ${k} bytes, got ${a.message_terminals[l].length}`
|
|
577
|
+
);
|
|
578
|
+
if (a.checksum_minor_terminal.length !== k)
|
|
579
|
+
throw new Error(
|
|
580
|
+
`Block ${n} checksum_minor: expected ${k} bytes`
|
|
581
|
+
);
|
|
582
|
+
if (a.checksum_major_terminal.length !== k)
|
|
583
|
+
throw new Error(
|
|
584
|
+
`Block ${n} checksum_major: expected ${k} bytes`
|
|
585
|
+
);
|
|
586
|
+
t.push(a);
|
|
587
|
+
} finally {
|
|
588
|
+
r.fill(0), i.fill(0);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
if (t.length !== M.length)
|
|
326
592
|
throw new Error(
|
|
327
|
-
`
|
|
593
|
+
`Expected ${M.length} blocks, got ${t.length}`
|
|
328
594
|
);
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
595
|
+
return t;
|
|
596
|
+
} finally {
|
|
597
|
+
e.fill(0);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
function tt(e, t, n) {
|
|
601
|
+
if (e.length !== k)
|
|
602
|
+
throw new Error(
|
|
603
|
+
`Block ${t} ${n}: expected ${k} bytes, got ${e.length}`
|
|
604
|
+
);
|
|
605
|
+
for (let s = 0; s < e.length; s++) {
|
|
606
|
+
const o = e[s];
|
|
607
|
+
if (!Number.isInteger(o) || o < 0 || o > 255)
|
|
608
|
+
throw new Error(
|
|
609
|
+
`Block ${t} ${n}[${s}]: invalid byte value ${o}`
|
|
336
610
|
);
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
function gn(e) {
|
|
614
|
+
if (e.length === 0)
|
|
615
|
+
throw new Error("Public keys array must not be empty");
|
|
616
|
+
for (let r = 0; r < e.length; r++) {
|
|
617
|
+
const i = e[r];
|
|
618
|
+
tt(i.checksum_minor_terminal, r, "checksum_minor_terminal"), tt(i.checksum_major_terminal, r, "checksum_major_terminal");
|
|
619
|
+
for (let a = 0; a < i.message_terminals.length; a++)
|
|
620
|
+
tt(i.message_terminals[a], r, `message_terminal[${a}]`);
|
|
621
|
+
}
|
|
622
|
+
let t = 0;
|
|
623
|
+
for (const r of e)
|
|
624
|
+
t += Yt + r.message_terminals.length;
|
|
625
|
+
const n = new Uint8Array(t * k);
|
|
626
|
+
let s = 0;
|
|
627
|
+
for (const r of e) {
|
|
628
|
+
n.set(r.checksum_minor_terminal, s), s += k, n.set(r.checksum_major_terminal, s), s += k;
|
|
629
|
+
for (const i of r.message_terminals)
|
|
630
|
+
n.set(i, s), s += k;
|
|
631
|
+
}
|
|
632
|
+
const o = rn(n);
|
|
633
|
+
return `0x${ln(o)}`;
|
|
634
|
+
}
|
|
635
|
+
function Nn(e) {
|
|
636
|
+
const t = (e instanceof Error ? e.message : typeof e == "string" ? e : "").toLowerCase();
|
|
637
|
+
return t.includes("wots") && t.includes("hash") && t.includes("does not match");
|
|
638
|
+
}
|
|
639
|
+
const pn = 0, mn = /^0x[0-9a-f]+$/i, bn = /^[0-9a-f]+$/i, wn = /^[A-Za-z0-9+/]+={0,2}$/, yn = "00".repeat(32);
|
|
640
|
+
function $(e) {
|
|
641
|
+
if (typeof e != "string" || e.length === 0)
|
|
642
|
+
throw new Error("BTC wallet returned empty public key");
|
|
643
|
+
return le(e).toLowerCase();
|
|
644
|
+
}
|
|
645
|
+
function xn(e) {
|
|
646
|
+
if (typeof e != "string" || e.length === 0)
|
|
647
|
+
throw new Error("BTC wallet returned empty BIP-322 signature");
|
|
648
|
+
if (e.startsWith("0x") || e.startsWith("0X")) {
|
|
649
|
+
if (!mn.test(e) || e.length < 4 || e.length % 2 !== 0)
|
|
650
|
+
throw new Error("BTC wallet returned malformed hex BIP-322 signature");
|
|
651
|
+
return e.toLowerCase();
|
|
652
|
+
}
|
|
653
|
+
if (bn.test(e)) {
|
|
654
|
+
if (e.length % 2 !== 0)
|
|
655
|
+
throw new Error("BTC wallet returned malformed hex BIP-322 signature");
|
|
656
|
+
return `0x${e.toLowerCase()}`;
|
|
657
|
+
}
|
|
658
|
+
if (!wn.test(e) || e.length % 4 !== 0)
|
|
659
|
+
throw new Error("BTC wallet returned malformed base64 BIP-322 signature");
|
|
660
|
+
const t = et.from(e, "base64");
|
|
661
|
+
if (t.length === 0 || t.toString("base64") !== e)
|
|
662
|
+
throw new Error("BTC wallet returned malformed base64 BIP-322 signature");
|
|
663
|
+
return `0x${t.toString("hex")}`;
|
|
664
|
+
}
|
|
665
|
+
function Pn(e, t, n, s) {
|
|
666
|
+
const o = n == null ? void 0 : n[`${e}:${t}`];
|
|
667
|
+
return o ? Promise.resolve({
|
|
668
|
+
txid: e,
|
|
669
|
+
vout: t,
|
|
670
|
+
value: o.value,
|
|
671
|
+
scriptPubKey: o.scriptPubKey
|
|
672
|
+
}) : xe(e, t, s);
|
|
673
|
+
}
|
|
674
|
+
const Ot = 12e4;
|
|
675
|
+
class Mn {
|
|
676
|
+
/**
|
|
677
|
+
* Creates a new PeginManager instance.
|
|
678
|
+
*
|
|
679
|
+
* @param config - Manager configuration including wallets and contract addresses
|
|
680
|
+
*/
|
|
681
|
+
constructor(t) {
|
|
682
|
+
b(this, "config");
|
|
683
|
+
this.config = t;
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Prepare a peg-in: sizing pass → vault-root derivation (one wallet
|
|
687
|
+
* popup) → per-vault WOTS / hashlock derivation → commit pass with
|
|
688
|
+
* batch PSBT signing (one popup). Returns broadcast-ready txs, the
|
|
689
|
+
* pubkey snapshot, and the sensitive derived material.
|
|
690
|
+
*
|
|
691
|
+
* @throws If the wallet rejects, insufficient funds, or an internal
|
|
692
|
+
* invariant violation.
|
|
693
|
+
*/
|
|
694
|
+
async preparePegin(t) {
|
|
695
|
+
if (t.amounts.length === 0)
|
|
696
|
+
throw new Error("amounts must contain at least one entry");
|
|
697
|
+
const n = await this.config.btcWallet.getPublicKeyHex(), s = $(n), o = await this.prepareSizing(s, t), r = o.selectedUTXOs.map(
|
|
698
|
+
(h) => ({
|
|
699
|
+
txid: nt(h.txid),
|
|
700
|
+
vout: h.vout
|
|
701
|
+
})
|
|
702
|
+
), i = await Me(this.config.btcWallet, {
|
|
703
|
+
depositorBtcPubkey: nt(s),
|
|
704
|
+
fundingOutpoints: r
|
|
705
|
+
}), a = await this.expandPerVaultSecrets(i, t.amounts.length), { perVaultWotsKeys: l, wotsPkHashes: u, htlcSecretHexes: c, hashlocks: y } = a, g = await this.preparePeginCommit({
|
|
706
|
+
depositorBtcPubkeyRaw: n,
|
|
707
|
+
depositorBtcPubkey: s,
|
|
708
|
+
hashlocks: y,
|
|
709
|
+
sizing: o,
|
|
710
|
+
params: t
|
|
711
|
+
});
|
|
712
|
+
for (let h = 0; h < g.perVault.length; h++)
|
|
713
|
+
if (g.perVault[h].htlcVout !== h)
|
|
356
714
|
throw new Error(
|
|
357
|
-
`
|
|
715
|
+
`Internal invariant violation: htlcVout/index mismatch at vault ${h} (expected ${h}, got ${g.perVault[h].htlcVout})`
|
|
358
716
|
);
|
|
717
|
+
return {
|
|
718
|
+
transaction: {
|
|
719
|
+
...g,
|
|
720
|
+
selectedUTXOs: o.selectedUTXOs,
|
|
721
|
+
fee: o.fee,
|
|
722
|
+
changeAmount: o.changeAmount
|
|
723
|
+
},
|
|
724
|
+
depositorBtcPubkey: s,
|
|
725
|
+
derivedSecrets: {
|
|
726
|
+
perVaultWotsKeys: l,
|
|
727
|
+
wotsPkHashes: u,
|
|
728
|
+
htlcSecretHexes: c
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Derive per-vault WOTS keys + HTLC preimages from the wallet root.
|
|
734
|
+
* Takes ownership of `root`: zeros the buffer (and per-vault secret
|
|
735
|
+
* buffers) before returning, regardless of how the caller exits.
|
|
736
|
+
*/
|
|
737
|
+
async expandPerVaultSecrets(t, n) {
|
|
738
|
+
const s = [], o = [], r = [], i = [];
|
|
739
|
+
try {
|
|
740
|
+
for (let a = 0; a < n; a++) {
|
|
741
|
+
const l = $e(t, a);
|
|
742
|
+
try {
|
|
743
|
+
const c = await fn(l);
|
|
744
|
+
s.push(c), o.push(gn(c));
|
|
745
|
+
} finally {
|
|
746
|
+
l.fill(0);
|
|
747
|
+
}
|
|
748
|
+
const u = Oe(t, a);
|
|
749
|
+
try {
|
|
750
|
+
const c = $t(u);
|
|
751
|
+
r.push(c), i.push(
|
|
752
|
+
ue(I(c)).slice(2)
|
|
753
|
+
);
|
|
754
|
+
} finally {
|
|
755
|
+
u.fill(0);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
} finally {
|
|
759
|
+
t.fill(0);
|
|
359
760
|
}
|
|
360
|
-
|
|
361
|
-
return await we(P, h);
|
|
761
|
+
return { perVaultWotsKeys: s, wotsPkHashes: o, htlcSecretHexes: r, hashlocks: i };
|
|
362
762
|
}
|
|
363
763
|
/**
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
* This method:
|
|
367
|
-
* 1. Re-verifies the PopSignature against the currently connected ETH
|
|
368
|
-
* and BTC wallets — refuses to proceed if either has changed
|
|
369
|
-
* 2. Derives vault ID and checks if it already exists (pre-flight)
|
|
370
|
-
* 3. Encodes the contract call using viem
|
|
371
|
-
* 4. Estimates gas (catches contract errors early with proper revert
|
|
372
|
-
* reasons)
|
|
373
|
-
* 5. Sends transaction with pre-estimated gas via
|
|
374
|
-
* ethWallet.sendTransaction()
|
|
375
|
-
*
|
|
376
|
-
* The PopSignature must be obtained via
|
|
377
|
-
* {@link signProofOfPossession} before this call.
|
|
764
|
+
* Build unfunded Pre-PegIn + select UTXOs. No PSBT signing.
|
|
378
765
|
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
* unauthorized)
|
|
766
|
+
* Returns the full selection result (UTXOs, fee, changeAmount) so the
|
|
767
|
+
* commit pass funds the broadcast tx with the exact same set used to
|
|
768
|
+
* build the vault-context funding-outpoints commitment. Re-running
|
|
769
|
+
* `selectUtxosForPegin` in the commit pass would be deterministic given
|
|
770
|
+
* the same inputs, but threading the result through guarantees the
|
|
771
|
+
* domain separator structurally matches the funded tx inputs.
|
|
386
772
|
*/
|
|
387
|
-
async
|
|
773
|
+
async prepareSizing(t, n) {
|
|
774
|
+
const s = n.amounts.map(
|
|
775
|
+
() => yn
|
|
776
|
+
), o = n.vaultKeeperBtcPubkeys.length, r = await bt({
|
|
777
|
+
depositorPubkey: t,
|
|
778
|
+
vaultProviderPubkey: _(n.vaultProviderBtcPubkey),
|
|
779
|
+
vaultKeeperPubkeys: n.vaultKeeperBtcPubkeys.map(_),
|
|
780
|
+
universalChallengerPubkeys: n.universalChallengerBtcPubkeys.map(_),
|
|
781
|
+
hashlocks: s,
|
|
782
|
+
timelockRefund: n.timelockRefund,
|
|
783
|
+
pegInAmounts: n.amounts,
|
|
784
|
+
feeRate: n.protocolFeeRate,
|
|
785
|
+
numLocalChallengers: o,
|
|
786
|
+
councilQuorum: n.councilQuorum,
|
|
787
|
+
councilSize: n.councilSize,
|
|
788
|
+
network: this.config.btcNetwork
|
|
789
|
+
}), i = pe(
|
|
790
|
+
[...n.availableUTXOs],
|
|
791
|
+
r.totalOutputValue,
|
|
792
|
+
n.mempoolFeeRate,
|
|
793
|
+
// No auth-anchor OP_RETURN in this PR (deferred to PR5).
|
|
794
|
+
be(r.htlcValues.length)
|
|
795
|
+
);
|
|
796
|
+
return {
|
|
797
|
+
selectedUTXOs: i.selectedUTXOs,
|
|
798
|
+
fee: i.fee,
|
|
799
|
+
changeAmount: i.changeAmount
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
/** Build PegIn txs and batch-sign their inputs with real hashlocks. */
|
|
803
|
+
async preparePeginCommit(t) {
|
|
388
804
|
const {
|
|
389
|
-
|
|
390
|
-
|
|
805
|
+
depositorBtcPubkeyRaw: n,
|
|
806
|
+
depositorBtcPubkey: s,
|
|
807
|
+
hashlocks: o,
|
|
808
|
+
sizing: r,
|
|
809
|
+
params: i
|
|
810
|
+
} = t, a = _(i.vaultProviderBtcPubkey), l = i.vaultKeeperBtcPubkeys.map(_), u = i.universalChallengerBtcPubkeys.map(_), c = l.length, y = {
|
|
811
|
+
depositorPubkey: s,
|
|
812
|
+
vaultProviderPubkey: a,
|
|
813
|
+
vaultKeeperPubkeys: l,
|
|
814
|
+
universalChallengerPubkeys: u,
|
|
815
|
+
hashlocks: o,
|
|
816
|
+
timelockRefund: i.timelockRefund,
|
|
817
|
+
pegInAmounts: i.amounts,
|
|
818
|
+
feeRate: i.protocolFeeRate,
|
|
819
|
+
numLocalChallengers: c,
|
|
820
|
+
councilQuorum: i.councilQuorum,
|
|
821
|
+
councilSize: i.councilSize,
|
|
822
|
+
network: this.config.btcNetwork
|
|
823
|
+
}, g = await bt(y), h = wt(this.config.btcNetwork), p = we({
|
|
824
|
+
unfundedTxHex: g.psbtHex,
|
|
825
|
+
selectedUTXOs: r.selectedUTXOs,
|
|
826
|
+
changeAddress: i.changeAddress,
|
|
827
|
+
changeAmount: r.changeAmount,
|
|
828
|
+
network: h
|
|
829
|
+
}), T = _(q(p)), P = [], v = [], d = [];
|
|
830
|
+
for (let m = 0; m < o.length; m++) {
|
|
831
|
+
const w = await oe({
|
|
832
|
+
prePeginParams: y,
|
|
833
|
+
timelockPegin: i.timelockPegin,
|
|
834
|
+
fundedPrePeginTxHex: p,
|
|
835
|
+
htlcVout: m
|
|
836
|
+
}), E = await re({
|
|
837
|
+
peginTxHex: w.txHex,
|
|
838
|
+
fundedPrePeginTxHex: p,
|
|
839
|
+
depositorPubkey: s,
|
|
840
|
+
vaultProviderPubkey: a,
|
|
841
|
+
vaultKeeperPubkeys: l,
|
|
842
|
+
universalChallengerPubkeys: u,
|
|
843
|
+
hashlock: o[m],
|
|
844
|
+
timelockRefund: i.timelockRefund,
|
|
845
|
+
network: this.config.btcNetwork
|
|
846
|
+
});
|
|
847
|
+
P.push(w), v.push(E.psbtHex), d.push(
|
|
848
|
+
he(n, 1)
|
|
849
|
+
);
|
|
850
|
+
}
|
|
851
|
+
const x = await this.signPsbtsWithFallback(
|
|
852
|
+
v,
|
|
853
|
+
d
|
|
854
|
+
), f = [];
|
|
855
|
+
for (let m = 0; m < x.length; m++) {
|
|
856
|
+
const w = ie(
|
|
857
|
+
x[m],
|
|
858
|
+
s
|
|
859
|
+
), E = ae(x[m]);
|
|
860
|
+
f.push({
|
|
861
|
+
htlcVout: m,
|
|
862
|
+
htlcValue: g.htlcValues[m],
|
|
863
|
+
peginTxHex: E,
|
|
864
|
+
peginTxid: P[m].txid,
|
|
865
|
+
peginInputSignature: w,
|
|
866
|
+
vaultScriptPubKey: P[m].vaultScriptPubKey
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
return {
|
|
870
|
+
fundedPrePeginTxHex: p,
|
|
871
|
+
prePeginTxid: T,
|
|
872
|
+
perVault: f
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Signs multiple PSBTs using batch signing if available, falling back to sequential signing.
|
|
877
|
+
*
|
|
878
|
+
* Wallets that support native batch signing (e.g. UniSat) will sign all PSBTs
|
|
879
|
+
* in a single interaction. Others (e.g. Ledger, AppKit) implement signPsbts
|
|
880
|
+
* by looping signPsbt internally, so the UX depends on the wallet adapter.
|
|
881
|
+
*/
|
|
882
|
+
async signPsbtsWithFallback(t, n) {
|
|
883
|
+
if (typeof this.config.btcWallet.signPsbts == "function") {
|
|
884
|
+
const o = await this.config.btcWallet.signPsbts(
|
|
885
|
+
t,
|
|
886
|
+
n
|
|
887
|
+
);
|
|
888
|
+
if (o.length !== t.length)
|
|
889
|
+
throw new Error(
|
|
890
|
+
`Expected ${t.length} signed PSBTs but received ${o.length}`
|
|
891
|
+
);
|
|
892
|
+
return o;
|
|
893
|
+
}
|
|
894
|
+
const s = [];
|
|
895
|
+
for (let o = 0; o < t.length; o++) {
|
|
896
|
+
const r = await this.config.btcWallet.signPsbt(
|
|
897
|
+
t[o],
|
|
898
|
+
n[o]
|
|
899
|
+
);
|
|
900
|
+
s.push(r);
|
|
901
|
+
}
|
|
902
|
+
return s;
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Signs and broadcasts a funded peg-in transaction to the Bitcoin network.
|
|
906
|
+
*
|
|
907
|
+
* This method:
|
|
908
|
+
* 1. Parses the funded transaction hex
|
|
909
|
+
* 2. Fetches UTXO data from mempool for each input
|
|
910
|
+
* 3. Creates a PSBT with proper witnessUtxo/tapInternalKey
|
|
911
|
+
* 4. Signs via btcWallet.signPsbt()
|
|
912
|
+
* 5. Finalizes and extracts the transaction
|
|
913
|
+
* 6. Broadcasts via mempool API
|
|
914
|
+
*
|
|
915
|
+
* @param params - Transaction hex and depositor public key
|
|
916
|
+
* @returns The broadcasted Bitcoin transaction ID
|
|
917
|
+
* @throws Error if signing or broadcasting fails
|
|
918
|
+
*/
|
|
919
|
+
async signAndBroadcast(t) {
|
|
920
|
+
const { fundedPrePeginTxHex: n, depositorBtcPubkey: s } = t, o = n.startsWith("0x") ? n.slice(2) : n, r = ne.fromHex(o);
|
|
921
|
+
if (r.ins.length === 0)
|
|
922
|
+
throw new Error("Transaction has no inputs");
|
|
923
|
+
const i = new ft();
|
|
924
|
+
i.setVersion(r.version), i.setLocktime(r.locktime);
|
|
925
|
+
const a = et.from(
|
|
926
|
+
$(s),
|
|
927
|
+
"hex"
|
|
928
|
+
), l = this.config.mempoolApiUrl, u = r.ins.map((d) => {
|
|
929
|
+
const x = et.from(d.hash).reverse().toString("hex"), f = d.index;
|
|
930
|
+
return Pn(x, f, t.localPrevouts, l).then(
|
|
931
|
+
(m) => ({ input: d, utxoData: m, txid: x, vout: f })
|
|
932
|
+
);
|
|
933
|
+
}), c = await Promise.all(u), y = c.reduce(
|
|
934
|
+
(d, x) => d + BigInt(x.utxoData.value),
|
|
935
|
+
0n
|
|
936
|
+
), g = r.outs.reduce(
|
|
937
|
+
(d, x) => d + BigInt(x.value),
|
|
938
|
+
0n
|
|
939
|
+
);
|
|
940
|
+
if (y < g)
|
|
941
|
+
throw new Error(
|
|
942
|
+
`UTXO value mismatch: total input value (${y} sat) is less than total output value (${g} sat). This may indicate the mempool API returned manipulated UTXO data.`
|
|
943
|
+
);
|
|
944
|
+
const h = y - g;
|
|
945
|
+
if (h > yt)
|
|
946
|
+
throw new Error(
|
|
947
|
+
`Implied transaction fee (${h} sat) exceeds maximum reasonable fee (${yt} sat). This may indicate manipulated UTXO data.`
|
|
948
|
+
);
|
|
949
|
+
for (const { input: d, utxoData: x, txid: f, vout: m } of c) {
|
|
950
|
+
const w = me(
|
|
951
|
+
{
|
|
952
|
+
value: x.value,
|
|
953
|
+
scriptPubKey: x.scriptPubKey
|
|
954
|
+
},
|
|
955
|
+
a
|
|
956
|
+
);
|
|
957
|
+
i.addInput({
|
|
958
|
+
hash: d.hash,
|
|
959
|
+
index: d.index,
|
|
960
|
+
sequence: d.sequence,
|
|
961
|
+
...w
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
for (const d of r.outs)
|
|
965
|
+
i.addOutput({
|
|
966
|
+
script: d.script,
|
|
967
|
+
value: d.value
|
|
968
|
+
});
|
|
969
|
+
const p = await this.config.btcWallet.signPsbt(i.toHex()), T = ft.fromHex(p);
|
|
970
|
+
try {
|
|
971
|
+
T.finalizeAllInputs();
|
|
972
|
+
} catch (d) {
|
|
973
|
+
if (!T.data.inputs.every(
|
|
974
|
+
(f) => f.finalScriptWitness || f.finalScriptSig
|
|
975
|
+
))
|
|
976
|
+
throw new Error(
|
|
977
|
+
`PSBT finalization failed and wallet did not auto-finalize: ${d}`
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
const P = T.extractTransaction().toHex();
|
|
981
|
+
return await ye(P, l);
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Registers a peg-in on Ethereum by calling the BTCVaultRegistry contract.
|
|
985
|
+
*
|
|
986
|
+
* This method:
|
|
987
|
+
* 1. Re-verifies the PopSignature against the currently connected ETH
|
|
988
|
+
* and BTC wallets — refuses to proceed if either has changed
|
|
989
|
+
* 2. Derives vault ID and checks if it already exists (pre-flight)
|
|
990
|
+
* 3. Encodes the contract call using viem
|
|
991
|
+
* 4. Estimates gas (catches contract errors early with proper revert
|
|
992
|
+
* reasons)
|
|
993
|
+
* 5. Sends transaction with pre-estimated gas via
|
|
994
|
+
* ethWallet.sendTransaction()
|
|
995
|
+
*
|
|
996
|
+
* The PopSignature must be obtained via
|
|
997
|
+
* {@link signProofOfPossession} before this call.
|
|
998
|
+
*
|
|
999
|
+
* @param params - Registration parameters including the PopSignature
|
|
1000
|
+
* and the prepared Pre-PegIn / PegIn transactions
|
|
1001
|
+
* @returns Result containing Ethereum transaction hash and vault ID
|
|
1002
|
+
* @throws Error if the PopSignature does not match the connected wallets
|
|
1003
|
+
* @throws Error if the vault already exists
|
|
1004
|
+
* @throws Error if contract simulation fails (e.g., invalid signature,
|
|
1005
|
+
* unauthorized)
|
|
1006
|
+
*/
|
|
1007
|
+
async registerPeginOnChain(t) {
|
|
1008
|
+
const {
|
|
1009
|
+
unsignedPrePeginTx: n,
|
|
1010
|
+
depositorSignedPeginTx: s,
|
|
391
1011
|
vaultProvider: o,
|
|
392
1012
|
hashlock: r,
|
|
393
1013
|
htlcVout: i,
|
|
394
1014
|
depositorPayoutBtcAddress: a,
|
|
395
|
-
depositorWotsPkHash:
|
|
1015
|
+
depositorWotsPkHash: l,
|
|
396
1016
|
popSignature: u
|
|
397
1017
|
} = t;
|
|
398
1018
|
if (!this.config.ethWallet.account)
|
|
399
1019
|
throw new Error("Ethereum wallet account not found");
|
|
400
1020
|
const c = this.config.ethWallet.account.address;
|
|
401
|
-
if (!
|
|
1021
|
+
if (!gt(u.depositorEthAddress, c))
|
|
402
1022
|
throw new Error(
|
|
403
1023
|
`Proof of possession was signed for ${u.depositorEthAddress} but the Ethereum wallet is currently connected to ${c}. Reconnect the original account or call signProofOfPossession() again.`
|
|
404
1024
|
);
|
|
405
1025
|
await this.assertPopMatchesBtcWallet(u);
|
|
406
|
-
const
|
|
1026
|
+
const y = u.btcPopSignature, g = I(u.depositorBtcPubkey), h = I(n), p = I(s), T = await this.resolvePayoutScriptPubKey(
|
|
407
1027
|
a
|
|
408
|
-
), P =
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
), d = I(
|
|
1028
|
+
), P = q(p), v = await mt(
|
|
1029
|
+
_(P),
|
|
1030
|
+
_(c)
|
|
1031
|
+
), d = I(v);
|
|
412
1032
|
if (await this.checkVaultExists(d))
|
|
413
1033
|
throw new Error(
|
|
414
1034
|
`Vault already exists (ID: ${d}, peginTxHash: ${P}). Vault IDs are derived from the pegin transaction hash and depositor address. To create a new vault, use different UTXOs or a different amount to generate a unique transaction.`
|
|
415
1035
|
);
|
|
416
|
-
const
|
|
1036
|
+
const f = j({
|
|
417
1037
|
chain: this.config.ethChain,
|
|
418
|
-
transport:
|
|
1038
|
+
transport: z()
|
|
419
1039
|
});
|
|
420
|
-
let
|
|
1040
|
+
let m;
|
|
421
1041
|
try {
|
|
422
|
-
|
|
1042
|
+
m = await f.readContract({
|
|
423
1043
|
address: this.config.vaultContracts.btcVaultRegistry,
|
|
424
|
-
abi:
|
|
1044
|
+
abi: C,
|
|
425
1045
|
functionName: "getPegInFee",
|
|
426
1046
|
args: [o]
|
|
427
1047
|
});
|
|
@@ -430,56 +1050,56 @@ class Nn {
|
|
|
430
1050
|
"Failed to query pegin fee from the contract. Please check your network connection and that the contract address is correct."
|
|
431
1051
|
);
|
|
432
1052
|
}
|
|
433
|
-
const
|
|
434
|
-
abi:
|
|
1053
|
+
const w = pt({
|
|
1054
|
+
abi: C,
|
|
435
1055
|
functionName: "submitPeginRequest",
|
|
436
1056
|
args: [
|
|
437
1057
|
c,
|
|
438
|
-
|
|
439
|
-
m,
|
|
1058
|
+
g,
|
|
440
1059
|
y,
|
|
441
|
-
|
|
1060
|
+
h,
|
|
1061
|
+
p,
|
|
442
1062
|
o,
|
|
443
1063
|
r,
|
|
444
1064
|
i,
|
|
445
|
-
|
|
446
|
-
|
|
1065
|
+
T,
|
|
1066
|
+
l
|
|
447
1067
|
]
|
|
448
1068
|
});
|
|
449
|
-
let
|
|
1069
|
+
let E;
|
|
450
1070
|
try {
|
|
451
|
-
|
|
1071
|
+
E = await f.estimateGas({
|
|
452
1072
|
to: this.config.vaultContracts.btcVaultRegistry,
|
|
453
|
-
data:
|
|
454
|
-
value:
|
|
1073
|
+
data: w,
|
|
1074
|
+
value: m,
|
|
455
1075
|
account: this.config.ethWallet.account.address
|
|
456
1076
|
});
|
|
457
|
-
} catch (
|
|
458
|
-
|
|
1077
|
+
} catch (D) {
|
|
1078
|
+
H(D);
|
|
459
1079
|
}
|
|
460
1080
|
let B;
|
|
461
1081
|
try {
|
|
462
1082
|
B = await this.config.ethWallet.sendTransaction({
|
|
463
1083
|
to: this.config.vaultContracts.btcVaultRegistry,
|
|
464
|
-
data:
|
|
465
|
-
value:
|
|
1084
|
+
data: w,
|
|
1085
|
+
value: m,
|
|
466
1086
|
account: this.config.ethWallet.account,
|
|
467
1087
|
chain: this.config.ethChain,
|
|
468
|
-
gas:
|
|
1088
|
+
gas: E
|
|
469
1089
|
});
|
|
470
|
-
} catch (
|
|
471
|
-
|
|
1090
|
+
} catch (D) {
|
|
1091
|
+
H(D);
|
|
472
1092
|
}
|
|
473
|
-
const
|
|
1093
|
+
const K = await f.waitForTransactionReceipt({
|
|
474
1094
|
hash: B,
|
|
475
|
-
timeout:
|
|
1095
|
+
timeout: Ot
|
|
476
1096
|
});
|
|
477
|
-
return
|
|
1097
|
+
return K.status === "reverted" && H(
|
|
478
1098
|
new Error(
|
|
479
1099
|
`Transaction reverted. Hash: ${B}. Check the transaction on block explorer for details.`
|
|
480
1100
|
)
|
|
481
1101
|
), {
|
|
482
|
-
ethTxHash:
|
|
1102
|
+
ethTxHash: K.transactionHash,
|
|
483
1103
|
vaultId: d,
|
|
484
1104
|
peginTxHash: P
|
|
485
1105
|
};
|
|
@@ -501,39 +1121,39 @@ class Nn {
|
|
|
501
1121
|
if (!this.config.ethWallet.account)
|
|
502
1122
|
throw new Error("Ethereum wallet account not found");
|
|
503
1123
|
const i = this.config.ethWallet.account.address;
|
|
504
|
-
if (!
|
|
1124
|
+
if (!gt(r.depositorEthAddress, i))
|
|
505
1125
|
throw new Error(
|
|
506
1126
|
`Proof of possession was signed for ${r.depositorEthAddress} but the Ethereum wallet is currently connected to ${i}. Reconnect the original account or call signProofOfPossession() again.`
|
|
507
1127
|
);
|
|
508
1128
|
await this.assertPopMatchesBtcWallet(r);
|
|
509
|
-
const a = r.btcPopSignature,
|
|
510
|
-
for (const
|
|
511
|
-
|
|
512
|
-
await this.resolvePayoutScriptPubKey(
|
|
1129
|
+
const a = r.btcPopSignature, l = [];
|
|
1130
|
+
for (const f of o)
|
|
1131
|
+
l.push(
|
|
1132
|
+
await this.resolvePayoutScriptPubKey(f.depositorPayoutBtcAddress)
|
|
513
1133
|
);
|
|
514
1134
|
const u = [];
|
|
515
|
-
for (const
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
),
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
), B = I(
|
|
1135
|
+
for (const f of o) {
|
|
1136
|
+
const m = I(
|
|
1137
|
+
f.depositorSignedPeginTx
|
|
1138
|
+
), w = q(m), E = await mt(
|
|
1139
|
+
_(w),
|
|
1140
|
+
_(i)
|
|
1141
|
+
), B = I(E);
|
|
522
1142
|
if (await this.checkVaultExists(B))
|
|
523
1143
|
throw new Error(
|
|
524
|
-
`Vault already exists (ID: ${B}, peginTxHash: ${
|
|
1144
|
+
`Vault already exists (ID: ${B}, peginTxHash: ${w}). To create a new vault, use different UTXOs or a different amount.`
|
|
525
1145
|
);
|
|
526
|
-
u.push({ vaultId: B, peginTxHash:
|
|
1146
|
+
u.push({ vaultId: B, peginTxHash: w });
|
|
527
1147
|
}
|
|
528
|
-
const c =
|
|
1148
|
+
const c = j({
|
|
529
1149
|
chain: this.config.ethChain,
|
|
530
|
-
transport:
|
|
1150
|
+
transport: z()
|
|
531
1151
|
});
|
|
532
|
-
let
|
|
1152
|
+
let y;
|
|
533
1153
|
try {
|
|
534
|
-
|
|
1154
|
+
y = await c.readContract({
|
|
535
1155
|
address: this.config.vaultContracts.btcVaultRegistry,
|
|
536
|
-
abi:
|
|
1156
|
+
abi: C,
|
|
537
1157
|
functionName: "getPegInFee",
|
|
538
1158
|
args: [n]
|
|
539
1159
|
});
|
|
@@ -542,756 +1162,178 @@ class Nn {
|
|
|
542
1162
|
"Failed to query pegin fee from the contract. Please check your network connection and that the contract address is correct."
|
|
543
1163
|
);
|
|
544
1164
|
}
|
|
545
|
-
const
|
|
1165
|
+
const g = y * BigInt(o.length), h = I(
|
|
546
1166
|
r.depositorBtcPubkey
|
|
547
|
-
),
|
|
548
|
-
depositorBtcPubKey:
|
|
1167
|
+
), p = I(s), T = o.map((f, m) => ({
|
|
1168
|
+
depositorBtcPubKey: h,
|
|
549
1169
|
btcPopSignature: a,
|
|
550
|
-
unsignedPrePeginTx:
|
|
1170
|
+
unsignedPrePeginTx: p,
|
|
551
1171
|
depositorSignedPeginTx: I(
|
|
552
|
-
|
|
1172
|
+
f.depositorSignedPeginTx
|
|
553
1173
|
),
|
|
554
|
-
hashlock:
|
|
555
|
-
htlcVout:
|
|
556
|
-
referralCode:
|
|
557
|
-
depositorPayoutBtcAddress:
|
|
558
|
-
depositorWotsPkHash:
|
|
559
|
-
})), P =
|
|
560
|
-
abi:
|
|
1174
|
+
hashlock: f.hashlock,
|
|
1175
|
+
htlcVout: f.htlcVout,
|
|
1176
|
+
referralCode: pn,
|
|
1177
|
+
depositorPayoutBtcAddress: l[m],
|
|
1178
|
+
depositorWotsPkHash: f.depositorWotsPkHash
|
|
1179
|
+
})), P = pt({
|
|
1180
|
+
abi: C,
|
|
561
1181
|
functionName: "submitPeginRequestBatch",
|
|
562
|
-
args: [i, n,
|
|
1182
|
+
args: [i, n, T]
|
|
563
1183
|
});
|
|
564
|
-
let
|
|
1184
|
+
let v;
|
|
565
1185
|
try {
|
|
566
|
-
|
|
1186
|
+
v = await c.estimateGas({
|
|
567
1187
|
to: this.config.vaultContracts.btcVaultRegistry,
|
|
568
1188
|
data: P,
|
|
569
|
-
value:
|
|
1189
|
+
value: g,
|
|
570
1190
|
account: this.config.ethWallet.account.address
|
|
571
1191
|
});
|
|
572
|
-
} catch (
|
|
573
|
-
|
|
1192
|
+
} catch (f) {
|
|
1193
|
+
H(f);
|
|
574
1194
|
}
|
|
575
1195
|
let d;
|
|
576
1196
|
try {
|
|
577
1197
|
d = await this.config.ethWallet.sendTransaction({
|
|
578
1198
|
to: this.config.vaultContracts.btcVaultRegistry,
|
|
579
1199
|
data: P,
|
|
580
|
-
value:
|
|
1200
|
+
value: g,
|
|
581
1201
|
account: this.config.ethWallet.account,
|
|
582
1202
|
chain: this.config.ethChain,
|
|
583
|
-
gas:
|
|
584
|
-
});
|
|
585
|
-
} catch (
|
|
586
|
-
|
|
587
|
-
}
|
|
588
|
-
const g = await c.waitForTransactionReceipt({
|
|
589
|
-
hash: d,
|
|
590
|
-
timeout: _t
|
|
591
|
-
});
|
|
592
|
-
return g.status === "reverted" && A(
|
|
593
|
-
new Error(
|
|
594
|
-
`Batch transaction reverted. Hash: ${d}. Check the transaction on block explorer for details.`
|
|
595
|
-
)
|
|
596
|
-
), {
|
|
597
|
-
ethTxHash: g.transactionHash,
|
|
598
|
-
vaults: u
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Check if a vault already exists for a given vault ID.
|
|
603
|
-
*
|
|
604
|
-
* @param vaultId - The Bitcoin transaction hash (vault ID)
|
|
605
|
-
* @returns True if vault exists, false otherwise
|
|
606
|
-
*/
|
|
607
|
-
async checkVaultExists(t) {
|
|
608
|
-
try {
|
|
609
|
-
return (await q({
|
|
610
|
-
chain: this.config.ethChain,
|
|
611
|
-
transport: Z()
|
|
612
|
-
}).readContract({
|
|
613
|
-
address: this.config.vaultContracts.btcVaultRegistry,
|
|
614
|
-
abi: O,
|
|
615
|
-
functionName: "getBtcVaultBasicInfo",
|
|
616
|
-
args: [t]
|
|
617
|
-
}))[0] !== oe;
|
|
618
|
-
} catch {
|
|
619
|
-
return !1;
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
/**
|
|
623
|
-
* Resolve the BTC payout address to a scriptPubKey hex for the contract.
|
|
624
|
-
*
|
|
625
|
-
* If a payout address is provided, converts it directly.
|
|
626
|
-
* If omitted, uses the wallet's address and validates it against the
|
|
627
|
-
* wallet's public key to guard against a compromised wallet provider.
|
|
628
|
-
*/
|
|
629
|
-
async resolvePayoutScriptPubKey(t) {
|
|
630
|
-
let n;
|
|
631
|
-
if (t)
|
|
632
|
-
n = t;
|
|
633
|
-
else {
|
|
634
|
-
n = await this.config.btcWallet.getAddress();
|
|
635
|
-
const o = await this.config.btcWallet.getPublicKeyHex();
|
|
636
|
-
if (!he(
|
|
637
|
-
n,
|
|
638
|
-
o,
|
|
639
|
-
this.config.btcNetwork
|
|
640
|
-
))
|
|
641
|
-
throw new Error(
|
|
642
|
-
"The BTC address from your wallet does not match the wallet's public key. Please ensure your wallet is using a supported address type (Taproot or Native SegWit)."
|
|
643
|
-
);
|
|
644
|
-
}
|
|
645
|
-
const s = kt(this.config.btcNetwork);
|
|
646
|
-
try {
|
|
647
|
-
return `0x${ne.address.toOutputScript(n, s).toString("hex")}`;
|
|
648
|
-
} catch {
|
|
649
|
-
throw new Error(
|
|
650
|
-
`Invalid BTC payout address: "${n}". Please provide a valid Bitcoin address for the ${this.config.btcNetwork} network.`
|
|
651
|
-
);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
/**
|
|
655
|
-
* Sign a BIP-322 BTC Proof-of-Possession binding the connected BTC
|
|
656
|
-
* wallet to the connected ETH account for this chain and vault
|
|
657
|
-
* registry. The returned {@link PopSignature} can be reused across
|
|
658
|
-
* every register call in the same session.
|
|
659
|
-
*/
|
|
660
|
-
async signProofOfPossession() {
|
|
661
|
-
if (!this.config.ethWallet.account)
|
|
662
|
-
throw new Error("Ethereum wallet account not found");
|
|
663
|
-
const t = this.config.ethWallet.account.address, n = $(
|
|
664
|
-
await this.config.btcWallet.getPublicKeyHex()
|
|
665
|
-
), s = this.config.vaultContracts.btcVaultRegistry, o = `${t.toLowerCase()}:${this.config.ethChain.id}:pegin:${s.toLowerCase()}`, r = await this.config.btcWallet.signMessage(
|
|
666
|
-
o,
|
|
667
|
-
"bip322-simple"
|
|
668
|
-
);
|
|
669
|
-
return {
|
|
670
|
-
btcPopSignature: Oe(r),
|
|
671
|
-
depositorEthAddress: t,
|
|
672
|
-
depositorBtcPubkey: n
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
async assertPopMatchesBtcWallet(t) {
|
|
676
|
-
const n = $(
|
|
677
|
-
await this.config.btcWallet.getPublicKeyHex()
|
|
678
|
-
), s = $(t.depositorBtcPubkey);
|
|
679
|
-
if (n !== s)
|
|
680
|
-
throw new Error(
|
|
681
|
-
`Proof of possession was signed with BTC pubkey ${s} but the BTC wallet is currently connected to ${n}. Reconnect the original wallet or call signProofOfPossession() again.`
|
|
682
|
-
);
|
|
683
|
-
}
|
|
684
|
-
/**
|
|
685
|
-
* Gets the configured Bitcoin network.
|
|
686
|
-
*
|
|
687
|
-
* @returns The Bitcoin network (mainnet, testnet, signet, regtest)
|
|
688
|
-
*/
|
|
689
|
-
getNetwork() {
|
|
690
|
-
return this.config.btcNetwork;
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Gets the configured BTCVaultRegistry contract address.
|
|
694
|
-
*
|
|
695
|
-
* @returns The Ethereum address of the BTCVaultRegistry contract
|
|
696
|
-
*/
|
|
697
|
-
getVaultContractAddress() {
|
|
698
|
-
return this.config.vaultContracts.btcVaultRegistry;
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
class Ft {
|
|
702
|
-
constructor(t, n) {
|
|
703
|
-
b(this, "oHash");
|
|
704
|
-
b(this, "iHash");
|
|
705
|
-
b(this, "blockLen");
|
|
706
|
-
b(this, "outputLen");
|
|
707
|
-
b(this, "finished", !1);
|
|
708
|
-
b(this, "destroyed", !1);
|
|
709
|
-
if (ht(t), U(n, void 0, "key"), this.iHash = t.create(), typeof this.iHash.update != "function")
|
|
710
|
-
throw new Error("Expected instance of class which extends utils.Hash");
|
|
711
|
-
this.blockLen = this.iHash.blockLen, this.outputLen = this.iHash.outputLen;
|
|
712
|
-
const s = this.blockLen, o = new Uint8Array(s);
|
|
713
|
-
o.set(n.length > s ? t.create().update(n).digest() : n);
|
|
714
|
-
for (let r = 0; r < o.length; r++)
|
|
715
|
-
o[r] ^= 54;
|
|
716
|
-
this.iHash.update(o), this.oHash = t.create();
|
|
717
|
-
for (let r = 0; r < o.length; r++)
|
|
718
|
-
o[r] ^= 106;
|
|
719
|
-
this.oHash.update(o), S(o);
|
|
720
|
-
}
|
|
721
|
-
update(t) {
|
|
722
|
-
return V(this), this.iHash.update(t), this;
|
|
723
|
-
}
|
|
724
|
-
digestInto(t) {
|
|
725
|
-
V(this), U(t, this.outputLen, "output"), this.finished = !0, this.iHash.digestInto(t), this.oHash.update(t), this.oHash.digestInto(t), this.destroy();
|
|
726
|
-
}
|
|
727
|
-
digest() {
|
|
728
|
-
const t = new Uint8Array(this.oHash.outputLen);
|
|
729
|
-
return this.digestInto(t), t;
|
|
730
|
-
}
|
|
731
|
-
_cloneInto(t) {
|
|
732
|
-
t || (t = Object.create(Object.getPrototypeOf(this), {}));
|
|
733
|
-
const { oHash: n, iHash: s, finished: o, destroyed: r, blockLen: i, outputLen: a } = this;
|
|
734
|
-
return t = t, t.finished = o, t.destroyed = r, t.blockLen = i, t.outputLen = a, t.oHash = n._cloneInto(t.oHash), t.iHash = s._cloneInto(t.iHash), t;
|
|
735
|
-
}
|
|
736
|
-
clone() {
|
|
737
|
-
return this._cloneInto();
|
|
738
|
-
}
|
|
739
|
-
destroy() {
|
|
740
|
-
this.destroyed = !0, this.oHash.destroy(), this.iHash.destroy();
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
const K = (e, t, n) => new Ft(e, t).update(n).digest();
|
|
744
|
-
K.create = (e, t) => new Ft(e, t);
|
|
745
|
-
const Le = /* @__PURE__ */ Uint8Array.from([
|
|
746
|
-
7,
|
|
747
|
-
4,
|
|
748
|
-
13,
|
|
749
|
-
1,
|
|
750
|
-
10,
|
|
751
|
-
6,
|
|
752
|
-
15,
|
|
753
|
-
3,
|
|
754
|
-
12,
|
|
755
|
-
0,
|
|
756
|
-
9,
|
|
757
|
-
5,
|
|
758
|
-
2,
|
|
759
|
-
14,
|
|
760
|
-
11,
|
|
761
|
-
8
|
|
762
|
-
]), Mt = Uint8Array.from(new Array(16).fill(0).map((e, t) => t)), Re = Mt.map((e) => (9 * e + 5) % 16), Nt = /* @__PURE__ */ (() => {
|
|
763
|
-
const n = [[Mt], [Re]];
|
|
764
|
-
for (let s = 0; s < 4; s++)
|
|
765
|
-
for (let o of n)
|
|
766
|
-
o.push(o[s].map((r) => Le[r]));
|
|
767
|
-
return n;
|
|
768
|
-
})(), Vt = Nt[0], Dt = Nt[1], Kt = /* @__PURE__ */ [
|
|
769
|
-
[11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],
|
|
770
|
-
[12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],
|
|
771
|
-
[13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],
|
|
772
|
-
[14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],
|
|
773
|
-
[15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5]
|
|
774
|
-
].map((e) => Uint8Array.from(e)), Ue = /* @__PURE__ */ Vt.map((e, t) => e.map((n) => Kt[t][n])), We = /* @__PURE__ */ Dt.map((e, t) => e.map((n) => Kt[t][n])), Fe = /* @__PURE__ */ Uint32Array.from([
|
|
775
|
-
0,
|
|
776
|
-
1518500249,
|
|
777
|
-
1859775393,
|
|
778
|
-
2400959708,
|
|
779
|
-
2840853838
|
|
780
|
-
]), Me = /* @__PURE__ */ Uint32Array.from([
|
|
781
|
-
1352829926,
|
|
782
|
-
1548603684,
|
|
783
|
-
1836072691,
|
|
784
|
-
2053994217,
|
|
785
|
-
0
|
|
786
|
-
]);
|
|
787
|
-
function vt(e, t, n, s) {
|
|
788
|
-
return e === 0 ? t ^ n ^ s : e === 1 ? t & n | ~t & s : e === 2 ? (t | ~n) ^ s : e === 3 ? t & s | n & ~s : t ^ (n | ~s);
|
|
789
|
-
}
|
|
790
|
-
const M = /* @__PURE__ */ new Uint32Array(16);
|
|
791
|
-
class Ne extends be {
|
|
792
|
-
constructor() {
|
|
793
|
-
super(64, 20, 8, !0);
|
|
794
|
-
b(this, "h0", 1732584193);
|
|
795
|
-
b(this, "h1", -271733879);
|
|
796
|
-
b(this, "h2", -1732584194);
|
|
797
|
-
b(this, "h3", 271733878);
|
|
798
|
-
b(this, "h4", -1009589776);
|
|
799
|
-
}
|
|
800
|
-
get() {
|
|
801
|
-
const { h0: n, h1: s, h2: o, h3: r, h4: i } = this;
|
|
802
|
-
return [n, s, o, r, i];
|
|
803
|
-
}
|
|
804
|
-
set(n, s, o, r, i) {
|
|
805
|
-
this.h0 = n | 0, this.h1 = s | 0, this.h2 = o | 0, this.h3 = r | 0, this.h4 = i | 0;
|
|
806
|
-
}
|
|
807
|
-
process(n, s) {
|
|
808
|
-
for (let f = 0; f < 16; f++, s += 4)
|
|
809
|
-
M[f] = n.getUint32(s, !0);
|
|
810
|
-
let o = this.h0 | 0, r = o, i = this.h1 | 0, a = i, h = this.h2 | 0, u = h, c = this.h3 | 0, m = c, l = this.h4 | 0, y = l;
|
|
811
|
-
for (let f = 0; f < 5; f++) {
|
|
812
|
-
const x = 4 - f, P = Fe[f], w = Me[f], d = Vt[f], g = Dt[f], p = Ue[f], E = We[f];
|
|
813
|
-
for (let k = 0; k < 16; k++) {
|
|
814
|
-
const _ = F(o + vt(f, i, h, c) + M[d[k]] + P, p[k]) + l | 0;
|
|
815
|
-
o = l, l = c, c = F(h, 10) | 0, h = i, i = _;
|
|
816
|
-
}
|
|
817
|
-
for (let k = 0; k < 16; k++) {
|
|
818
|
-
const _ = F(r + vt(x, a, u, m) + M[g[k]] + w, E[k]) + y | 0;
|
|
819
|
-
r = y, y = m, m = F(u, 10) | 0, u = a, a = _;
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
this.set(this.h1 + h + m | 0, this.h2 + c + y | 0, this.h3 + l + r | 0, this.h4 + o + a | 0, this.h0 + i + u | 0);
|
|
823
|
-
}
|
|
824
|
-
roundClean() {
|
|
825
|
-
S(M);
|
|
826
|
-
}
|
|
827
|
-
destroy() {
|
|
828
|
-
this.destroyed = !0, S(this.buffer), this.set(0, 0, 0, 0, 0);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
const Ve = /* @__PURE__ */ Ut(() => new Ne()), De = BigInt(0), L = BigInt(1), Ke = BigInt(2), Xe = BigInt(7), je = BigInt(256), qe = BigInt(113), Xt = [], jt = [], qt = [];
|
|
832
|
-
for (let e = 0, t = L, n = 1, s = 0; e < 24; e++) {
|
|
833
|
-
[n, s] = [s, (2 * n + 3 * s) % 5], Xt.push(2 * (5 * s + n)), jt.push((e + 1) * (e + 2) / 2 % 64);
|
|
834
|
-
let o = De;
|
|
835
|
-
for (let r = 0; r < 7; r++)
|
|
836
|
-
t = (t << L ^ (t >> Xe) * qe) % je, t & Ke && (o ^= L << (L << BigInt(r)) - L);
|
|
837
|
-
qt.push(o);
|
|
838
|
-
}
|
|
839
|
-
const Zt = xe(qt, !0), Ze = Zt[0], Ge = Zt[1], Bt = (e, t, n) => n > 32 ? Ie(e, t, n) : Ee(e, t, n), St = (e, t, n) => n > 32 ? _e(e, t, n) : Te(e, t, n);
|
|
840
|
-
function ze(e, t = 24) {
|
|
841
|
-
const n = new Uint32Array(10);
|
|
842
|
-
for (let s = 24 - t; s < 24; s++) {
|
|
843
|
-
for (let i = 0; i < 10; i++)
|
|
844
|
-
n[i] = e[i] ^ e[i + 10] ^ e[i + 20] ^ e[i + 30] ^ e[i + 40];
|
|
845
|
-
for (let i = 0; i < 10; i += 2) {
|
|
846
|
-
const a = (i + 8) % 10, h = (i + 2) % 10, u = n[h], c = n[h + 1], m = Bt(u, c, 1) ^ n[a], l = St(u, c, 1) ^ n[a + 1];
|
|
847
|
-
for (let y = 0; y < 50; y += 10)
|
|
848
|
-
e[i + y] ^= m, e[i + y + 1] ^= l;
|
|
849
|
-
}
|
|
850
|
-
let o = e[2], r = e[3];
|
|
851
|
-
for (let i = 0; i < 24; i++) {
|
|
852
|
-
const a = jt[i], h = Bt(o, r, a), u = St(o, r, a), c = Xt[i];
|
|
853
|
-
o = e[c], r = e[c + 1], e[c] = h, e[c + 1] = u;
|
|
854
|
-
}
|
|
855
|
-
for (let i = 0; i < 50; i += 10) {
|
|
856
|
-
for (let a = 0; a < 10; a++)
|
|
857
|
-
n[a] = e[i + a];
|
|
858
|
-
for (let a = 0; a < 10; a++)
|
|
859
|
-
e[i + a] ^= ~n[(a + 2) % 10] & n[(a + 4) % 10];
|
|
860
|
-
}
|
|
861
|
-
e[0] ^= Ze[s], e[1] ^= Ge[s];
|
|
862
|
-
}
|
|
863
|
-
S(n);
|
|
864
|
-
}
|
|
865
|
-
class ft {
|
|
866
|
-
// NOTE: we accept arguments in bytes instead of bits here.
|
|
867
|
-
constructor(t, n, s, o = !1, r = 24) {
|
|
868
|
-
b(this, "state");
|
|
869
|
-
b(this, "pos", 0);
|
|
870
|
-
b(this, "posOut", 0);
|
|
871
|
-
b(this, "finished", !1);
|
|
872
|
-
b(this, "state32");
|
|
873
|
-
b(this, "destroyed", !1);
|
|
874
|
-
b(this, "blockLen");
|
|
875
|
-
b(this, "suffix");
|
|
876
|
-
b(this, "outputLen");
|
|
877
|
-
b(this, "enableXOF", !1);
|
|
878
|
-
b(this, "rounds");
|
|
879
|
-
if (this.blockLen = t, this.suffix = n, this.outputLen = s, this.enableXOF = o, this.rounds = r, C(s, "outputLen"), !(0 < t && t < 200))
|
|
880
|
-
throw new Error("only keccak-f1600 function is supported");
|
|
881
|
-
this.state = new Uint8Array(200), this.state32 = Pe(this.state);
|
|
882
|
-
}
|
|
883
|
-
clone() {
|
|
884
|
-
return this._cloneInto();
|
|
885
|
-
}
|
|
886
|
-
keccak() {
|
|
887
|
-
Tt(this.state32), ze(this.state32, this.rounds), Tt(this.state32), this.posOut = 0, this.pos = 0;
|
|
888
|
-
}
|
|
889
|
-
update(t) {
|
|
890
|
-
V(this), U(t);
|
|
891
|
-
const { blockLen: n, state: s } = this, o = t.length;
|
|
892
|
-
for (let r = 0; r < o; ) {
|
|
893
|
-
const i = Math.min(n - this.pos, o - r);
|
|
894
|
-
for (let a = 0; a < i; a++)
|
|
895
|
-
s[this.pos++] ^= t[r++];
|
|
896
|
-
this.pos === n && this.keccak();
|
|
897
|
-
}
|
|
898
|
-
return this;
|
|
899
|
-
}
|
|
900
|
-
finish() {
|
|
901
|
-
if (this.finished)
|
|
902
|
-
return;
|
|
903
|
-
this.finished = !0;
|
|
904
|
-
const { state: t, suffix: n, pos: s, blockLen: o } = this;
|
|
905
|
-
t[s] ^= n, (n & 128) !== 0 && s === o - 1 && this.keccak(), t[o - 1] ^= 128, this.keccak();
|
|
906
|
-
}
|
|
907
|
-
writeInto(t) {
|
|
908
|
-
V(this, !1), U(t), this.finish();
|
|
909
|
-
const n = this.state, { blockLen: s } = this;
|
|
910
|
-
for (let o = 0, r = t.length; o < r; ) {
|
|
911
|
-
this.posOut >= s && this.keccak();
|
|
912
|
-
const i = Math.min(s - this.posOut, r - o);
|
|
913
|
-
t.set(n.subarray(this.posOut, this.posOut + i), o), this.posOut += i, o += i;
|
|
1203
|
+
gas: v
|
|
1204
|
+
});
|
|
1205
|
+
} catch (f) {
|
|
1206
|
+
H(f);
|
|
914
1207
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
throw new Error("digest() was already called");
|
|
928
|
-
return this.writeInto(t), this.destroy(), t;
|
|
929
|
-
}
|
|
930
|
-
digest() {
|
|
931
|
-
return this.digestInto(new Uint8Array(this.outputLen));
|
|
932
|
-
}
|
|
933
|
-
destroy() {
|
|
934
|
-
this.destroyed = !0, S(this.state);
|
|
935
|
-
}
|
|
936
|
-
_cloneInto(t) {
|
|
937
|
-
const { blockLen: n, suffix: s, outputLen: o, rounds: r, enableXOF: i } = this;
|
|
938
|
-
return t || (t = new ft(n, s, o, i, r)), t.state32.set(this.state32), t.pos = this.pos, t.posOut = this.posOut, t.finished = this.finished, t.rounds = r, t.suffix = s, t.outputLen = o, t.enableXOF = i, t.destroyed = this.destroyed, t;
|
|
1208
|
+
const x = await c.waitForTransactionReceipt({
|
|
1209
|
+
hash: d,
|
|
1210
|
+
timeout: Ot
|
|
1211
|
+
});
|
|
1212
|
+
return x.status === "reverted" && H(
|
|
1213
|
+
new Error(
|
|
1214
|
+
`Batch transaction reverted. Hash: ${d}. Check the transaction on block explorer for details.`
|
|
1215
|
+
)
|
|
1216
|
+
), {
|
|
1217
|
+
ethTxHash: x.transactionHash,
|
|
1218
|
+
vaults: u
|
|
1219
|
+
};
|
|
939
1220
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
m.setInt32(0, y, !1), (u = h._cloneInto(u)).update(c).digestInto(l), x.set(l.subarray(0, x.length));
|
|
960
|
-
for (let P = 1; P < o; P++) {
|
|
961
|
-
a._cloneInto(u).update(l).digestInto(l);
|
|
962
|
-
for (let w = 0; w < x.length; w++)
|
|
963
|
-
x[w] ^= l[w];
|
|
1221
|
+
/**
|
|
1222
|
+
* Check if a vault already exists for a given vault ID.
|
|
1223
|
+
*
|
|
1224
|
+
* @param vaultId - The Bitcoin transaction hash (vault ID)
|
|
1225
|
+
* @returns True if vault exists, false otherwise
|
|
1226
|
+
*/
|
|
1227
|
+
async checkVaultExists(t) {
|
|
1228
|
+
try {
|
|
1229
|
+
return (await j({
|
|
1230
|
+
chain: this.config.ethChain,
|
|
1231
|
+
transport: z()
|
|
1232
|
+
}).readContract({
|
|
1233
|
+
address: this.config.vaultContracts.btcVaultRegistry,
|
|
1234
|
+
abi: C,
|
|
1235
|
+
functionName: "getBtcVaultBasicInfo",
|
|
1236
|
+
args: [t]
|
|
1237
|
+
})).depositor !== se;
|
|
1238
|
+
} catch {
|
|
1239
|
+
return !1;
|
|
964
1240
|
}
|
|
965
1241
|
}
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
const
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
n.set(o, s), s += o.length;
|
|
989
|
-
return n;
|
|
990
|
-
}
|
|
991
|
-
function J(e) {
|
|
992
|
-
return new TextEncoder().encode(e);
|
|
993
|
-
}
|
|
994
|
-
function Q(e) {
|
|
995
|
-
const t = new Uint8Array(rn);
|
|
996
|
-
return new DataView(t.buffer).setUint32(0, e.length, !1), ct(t, e);
|
|
997
|
-
}
|
|
998
|
-
function At(e) {
|
|
999
|
-
return e.startsWith("0x") || e.startsWith("0X") ? e.slice(2) : e;
|
|
1000
|
-
}
|
|
1001
|
-
const ln = (e) => Array.from(e).map((t) => t.toString(16).padStart(2, "0")).join("");
|
|
1002
|
-
function un(e, t) {
|
|
1003
|
-
return K(Wt, e, t);
|
|
1004
|
-
}
|
|
1005
|
-
function gt(e) {
|
|
1006
|
-
return Ve(W(e));
|
|
1007
|
-
}
|
|
1008
|
-
function Yt(e) {
|
|
1009
|
-
return (1 << e) - 1;
|
|
1010
|
-
}
|
|
1011
|
-
function hn(e) {
|
|
1012
|
-
let t = 1;
|
|
1013
|
-
for (; t * t < e + 1; ) t++;
|
|
1014
|
-
return Math.max(t, 2);
|
|
1015
|
-
}
|
|
1016
|
-
function dn(e) {
|
|
1017
|
-
const t = at, n = Yt(t), s = e * n;
|
|
1018
|
-
return { d: t, n: e, checksum_radix: hn(s) };
|
|
1019
|
-
}
|
|
1020
|
-
function tt(e, t) {
|
|
1021
|
-
const n = [];
|
|
1022
|
-
let s = t;
|
|
1023
|
-
for (; s > 0; )
|
|
1024
|
-
n.push(s & 255), s >>>= 8;
|
|
1025
|
-
const o = new Uint8Array(e.length + n.length);
|
|
1026
|
-
o.set(e);
|
|
1027
|
-
for (let r = 0; r < n.length; r++)
|
|
1028
|
-
o[e.length + r] = n[r];
|
|
1029
|
-
return gt(o);
|
|
1030
|
-
}
|
|
1031
|
-
function et(e, t) {
|
|
1032
|
-
let n = e;
|
|
1033
|
-
for (let s = 0; s < t; s++)
|
|
1034
|
-
n = gt(n);
|
|
1035
|
-
return n;
|
|
1036
|
-
}
|
|
1037
|
-
function fn(e, t) {
|
|
1038
|
-
const n = Yt(t.d), s = t.checksum_radix - 1, o = Math.floor(t.n * n / t.checksum_radix), r = [];
|
|
1039
|
-
for (let c = 0; c < t.n; c++) {
|
|
1040
|
-
const m = tt(e, c + zt), l = et(m, n);
|
|
1041
|
-
r.push(Array.from(l));
|
|
1042
|
-
}
|
|
1043
|
-
const i = tt(
|
|
1044
|
-
e,
|
|
1045
|
-
an
|
|
1046
|
-
), a = et(
|
|
1047
|
-
i,
|
|
1048
|
-
s
|
|
1049
|
-
), h = tt(
|
|
1050
|
-
e,
|
|
1051
|
-
cn
|
|
1052
|
-
), u = et(
|
|
1053
|
-
h,
|
|
1054
|
-
o
|
|
1055
|
-
);
|
|
1056
|
-
return {
|
|
1057
|
-
config: t,
|
|
1058
|
-
message_terminals: r,
|
|
1059
|
-
checksum_major_terminal: Array.from(u),
|
|
1060
|
-
checksum_minor_terminal: Array.from(a)
|
|
1061
|
-
};
|
|
1062
|
-
}
|
|
1063
|
-
function gn(e) {
|
|
1064
|
-
const t = on(e), n = new Uint8Array(t);
|
|
1065
|
-
return t.fill(0), n;
|
|
1066
|
-
}
|
|
1067
|
-
async function pn(e, t, n, s) {
|
|
1068
|
-
if (e.length !== Y)
|
|
1069
|
-
throw new Error(
|
|
1070
|
-
`WOTS seed must be exactly ${Y} bytes, got ${e.length}`
|
|
1071
|
-
);
|
|
1072
|
-
const o = At(t).toLowerCase(), r = At(n).toLowerCase(), i = e.slice(z, Y), a = e.slice(0, z), h = ct(
|
|
1073
|
-
a,
|
|
1074
|
-
ct(
|
|
1075
|
-
Q(J(o)),
|
|
1076
|
-
Q(J(r)),
|
|
1077
|
-
Q(J(s.toLowerCase()))
|
|
1078
|
-
)
|
|
1079
|
-
), u = un(i, h), c = u.slice(0, z);
|
|
1080
|
-
try {
|
|
1081
|
-
const m = [];
|
|
1082
|
-
for (let l = 0; l < N.length; l++) {
|
|
1083
|
-
const y = N[l], f = dn(y), x = new Uint8Array(c.length + 1);
|
|
1084
|
-
x.set(c), x[c.length] = l;
|
|
1085
|
-
const P = gt(x);
|
|
1086
|
-
try {
|
|
1087
|
-
const w = fn(P, f);
|
|
1088
|
-
if (w.config.d !== at)
|
|
1089
|
-
throw new Error(`Block ${l}: expected d=${at}, got d=${w.config.d}`);
|
|
1090
|
-
if (w.config.n !== y)
|
|
1091
|
-
throw new Error(`Block ${l}: expected n=${y}, got n=${w.config.n}`);
|
|
1092
|
-
if (w.message_terminals.length !== y)
|
|
1093
|
-
throw new Error(`Block ${l}: expected ${y} message terminals, got ${w.message_terminals.length}`);
|
|
1094
|
-
for (let d = 0; d < w.message_terminals.length; d++)
|
|
1095
|
-
if (w.message_terminals[d].length !== T)
|
|
1096
|
-
throw new Error(`Block ${l} terminal ${d}: expected ${T} bytes, got ${w.message_terminals[d].length}`);
|
|
1097
|
-
if (w.checksum_minor_terminal.length !== T)
|
|
1098
|
-
throw new Error(`Block ${l} checksum_minor: expected ${T} bytes`);
|
|
1099
|
-
if (w.checksum_major_terminal.length !== T)
|
|
1100
|
-
throw new Error(`Block ${l} checksum_major: expected ${T} bytes`);
|
|
1101
|
-
m.push(w);
|
|
1102
|
-
} finally {
|
|
1103
|
-
x.fill(0), P.fill(0);
|
|
1104
|
-
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Resolve the BTC payout address to a scriptPubKey hex for the contract.
|
|
1244
|
+
*
|
|
1245
|
+
* If a payout address is provided, converts it directly.
|
|
1246
|
+
* If omitted, uses the wallet's address and validates it against the
|
|
1247
|
+
* wallet's public key to guard against a compromised wallet provider.
|
|
1248
|
+
*/
|
|
1249
|
+
async resolvePayoutScriptPubKey(t) {
|
|
1250
|
+
let n;
|
|
1251
|
+
if (t)
|
|
1252
|
+
n = t;
|
|
1253
|
+
else {
|
|
1254
|
+
n = await this.config.btcWallet.getAddress();
|
|
1255
|
+
const o = await this.config.btcWallet.getPublicKeyHex();
|
|
1256
|
+
if (!ce(
|
|
1257
|
+
n,
|
|
1258
|
+
o,
|
|
1259
|
+
this.config.btcNetwork
|
|
1260
|
+
))
|
|
1261
|
+
throw new Error(
|
|
1262
|
+
"The BTC address from your wallet does not match the wallet's public key. Please ensure your wallet is using a supported address type (Taproot or Native SegWit)."
|
|
1263
|
+
);
|
|
1105
1264
|
}
|
|
1106
|
-
|
|
1265
|
+
const s = wt(this.config.btcNetwork);
|
|
1266
|
+
try {
|
|
1267
|
+
return `0x${ee.address.toOutputScript(n, s).toString("hex")}`;
|
|
1268
|
+
} catch {
|
|
1107
1269
|
throw new Error(
|
|
1108
|
-
`
|
|
1270
|
+
`Invalid BTC payout address: "${n}". Please provide a valid Bitcoin address for the ${this.config.btcNetwork} network.`
|
|
1109
1271
|
);
|
|
1110
|
-
|
|
1111
|
-
} finally {
|
|
1112
|
-
h.fill(0), i.fill(0), a.fill(0), u.fill(0), c.fill(0), e.fill(0);
|
|
1272
|
+
}
|
|
1113
1273
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1274
|
+
/**
|
|
1275
|
+
* Sign a BIP-322 BTC Proof-of-Possession binding the connected BTC
|
|
1276
|
+
* wallet to the connected ETH account for this chain and vault
|
|
1277
|
+
* registry. The returned {@link PopSignature} can be reused across
|
|
1278
|
+
* every register call in the same session.
|
|
1279
|
+
*/
|
|
1280
|
+
async signProofOfPossession() {
|
|
1281
|
+
if (!this.config.ethWallet.account)
|
|
1282
|
+
throw new Error("Ethereum wallet account not found");
|
|
1283
|
+
const t = this.config.ethWallet.account.address, n = $(
|
|
1284
|
+
await this.config.btcWallet.getPublicKeyHex()
|
|
1285
|
+
), s = this.config.vaultContracts.btcVaultRegistry, o = `${t.toLowerCase()}:${this.config.ethChain.id}:pegin:${s.toLowerCase()}`, r = await this.config.btcWallet.signMessage(
|
|
1286
|
+
o,
|
|
1287
|
+
"bip322-simple"
|
|
1119
1288
|
);
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1289
|
+
return {
|
|
1290
|
+
btcPopSignature: xn(r),
|
|
1291
|
+
depositorEthAddress: t,
|
|
1292
|
+
depositorBtcPubkey: n
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
async assertPopMatchesBtcWallet(t) {
|
|
1296
|
+
const n = $(
|
|
1297
|
+
await this.config.btcWallet.getPublicKeyHex()
|
|
1298
|
+
), s = $(t.depositorBtcPubkey);
|
|
1299
|
+
if (n !== s)
|
|
1123
1300
|
throw new Error(
|
|
1124
|
-
`
|
|
1301
|
+
`Proof of possession was signed with BTC pubkey ${s} but the BTC wallet is currently connected to ${n}. Reconnect the original wallet or call signProofOfPossession() again.`
|
|
1125
1302
|
);
|
|
1126
1303
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
for (let a = 0; a < i.message_terminals.length; a++)
|
|
1135
|
-
nt(i.message_terminals[a], r, `message_terminal[${a}]`);
|
|
1136
|
-
}
|
|
1137
|
-
let t = 0;
|
|
1138
|
-
for (const r of e)
|
|
1139
|
-
t += zt + r.message_terminals.length;
|
|
1140
|
-
const n = new Uint8Array(t * T);
|
|
1141
|
-
let s = 0;
|
|
1142
|
-
for (const r of e) {
|
|
1143
|
-
n.set(r.checksum_minor_terminal, s), s += T, n.set(r.checksum_major_terminal, s), s += T;
|
|
1144
|
-
for (const i of r.message_terminals)
|
|
1145
|
-
n.set(i, s), s += T;
|
|
1304
|
+
/**
|
|
1305
|
+
* Gets the configured Bitcoin network.
|
|
1306
|
+
*
|
|
1307
|
+
* @returns The Bitcoin network (mainnet, testnet, signet, regtest)
|
|
1308
|
+
*/
|
|
1309
|
+
getNetwork() {
|
|
1310
|
+
return this.config.btcNetwork;
|
|
1146
1311
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
o,
|
|
1155
|
-
t,
|
|
1156
|
-
n,
|
|
1157
|
-
s
|
|
1158
|
-
);
|
|
1159
|
-
return mn(r);
|
|
1160
|
-
} finally {
|
|
1161
|
-
o.fill(0);
|
|
1312
|
+
/**
|
|
1313
|
+
* Gets the configured BTCVaultRegistry contract address.
|
|
1314
|
+
*
|
|
1315
|
+
* @returns The Ethereum address of the BTCVaultRegistry contract
|
|
1316
|
+
*/
|
|
1317
|
+
getVaultContractAddress() {
|
|
1318
|
+
return this.config.vaultContracts.btcVaultRegistry;
|
|
1162
1319
|
}
|
|
1163
1320
|
}
|
|
1164
|
-
function Dn(e) {
|
|
1165
|
-
const t = (e instanceof Error ? e.message : typeof e == "string" ? e : "").toLowerCase();
|
|
1166
|
-
return t.includes("wots") && t.includes("hash") && t.includes("does not match");
|
|
1167
|
-
}
|
|
1168
|
-
const st = /* @__PURE__ */ Uint8Array.of(0), Ct = /* @__PURE__ */ Uint8Array.of();
|
|
1169
|
-
function pt(e, t, n, s = 32) {
|
|
1170
|
-
ht(e), C(s, "length");
|
|
1171
|
-
const o = e.outputLen;
|
|
1172
|
-
if (s > 255 * o)
|
|
1173
|
-
throw new Error("Length must be <= 255*HashLen");
|
|
1174
|
-
const r = Math.ceil(s / o);
|
|
1175
|
-
n === void 0 ? n = Ct : U(n, void 0, "info");
|
|
1176
|
-
const i = new Uint8Array(r * o), a = K.create(e, t), h = a._cloneInto(), u = new Uint8Array(a.outputLen);
|
|
1177
|
-
for (let c = 0; c < r; c++)
|
|
1178
|
-
st[0] = c + 1, h.update(c === 0 ? Ct : u).update(n).update(st).digestInto(u), i.set(u, o * c), a._cloneInto(h);
|
|
1179
|
-
return a.destroy(), h.destroy(), S(u, st), i.slice(0, s);
|
|
1180
|
-
}
|
|
1181
|
-
const ot = new TextEncoder().encode("babylonvault"), Ht = 255, Ot = 65535, $t = 2, wn = "hashlock", yn = "auth-anchor", bn = "wots-seed";
|
|
1182
|
-
function Jt(e) {
|
|
1183
|
-
if (!Number.isInteger(e) || e < 0 || e > 4294967295)
|
|
1184
|
-
throw new Error(`i2osp4: value must be a u32, got ${e}`);
|
|
1185
|
-
const t = new Uint8Array(4);
|
|
1186
|
-
return t[0] = e >>> 24 & 255, t[1] = e >>> 16 & 255, t[2] = e >>> 8 & 255, t[3] = e & 255, t;
|
|
1187
|
-
}
|
|
1188
|
-
function mt(e, t = new Uint8Array(0)) {
|
|
1189
|
-
const n = new TextEncoder().encode(e);
|
|
1190
|
-
if (n.length === 0 || n.length > Ht)
|
|
1191
|
-
throw new Error(
|
|
1192
|
-
`info: label length must be in [1, ${Ht}], got ${n.length}`
|
|
1193
|
-
);
|
|
1194
|
-
if (t.length > Ot)
|
|
1195
|
-
throw new Error(
|
|
1196
|
-
`info: ctx length must be in [0, ${Ot}], got ${t.length}`
|
|
1197
|
-
);
|
|
1198
|
-
const s = ot.length + 1 + n.length + $t + t.length, o = new Uint8Array(s);
|
|
1199
|
-
let r = 0;
|
|
1200
|
-
return o.set(ot, r), r += ot.length, o[r] = n.length, r += 1, o.set(n, r), r += n.length, o[r] = t.length >>> 8 & 255, o[r + 1] = t.length & 255, r += $t, o.set(t, r), o;
|
|
1201
|
-
}
|
|
1202
|
-
const Lt = 32, xn = 32, Pn = 32, kn = 64;
|
|
1203
|
-
function wt(e) {
|
|
1204
|
-
if (e.length !== Lt)
|
|
1205
|
-
throw new Error(
|
|
1206
|
-
`vault-secrets: root must be exactly ${Lt} bytes, got ${e.length}`
|
|
1207
|
-
);
|
|
1208
|
-
}
|
|
1209
|
-
function Kn(e) {
|
|
1210
|
-
return wt(e), pt(
|
|
1211
|
-
W,
|
|
1212
|
-
e,
|
|
1213
|
-
mt(yn),
|
|
1214
|
-
xn
|
|
1215
|
-
);
|
|
1216
|
-
}
|
|
1217
|
-
function Xn(e, t) {
|
|
1218
|
-
return wt(e), pt(
|
|
1219
|
-
W,
|
|
1220
|
-
e,
|
|
1221
|
-
mt(wn, Jt(t)),
|
|
1222
|
-
Pn
|
|
1223
|
-
);
|
|
1224
|
-
}
|
|
1225
|
-
function jn(e, t) {
|
|
1226
|
-
return wt(e), pt(
|
|
1227
|
-
W,
|
|
1228
|
-
e,
|
|
1229
|
-
mt(bn, Jt(t)),
|
|
1230
|
-
kn
|
|
1231
|
-
);
|
|
1232
|
-
}
|
|
1233
|
-
const R = 32, rt = 32, lt = 36, Qt = 32, D = 4, En = D + R + D + Qt;
|
|
1234
|
-
function ut(e, t, n) {
|
|
1235
|
-
e[t] = n >>> 24 & 255, e[t + 1] = n >>> 16 & 255, e[t + 2] = n >>> 8 & 255, e[t + 3] = n & 255;
|
|
1236
|
-
}
|
|
1237
|
-
function Tn(e) {
|
|
1238
|
-
if (e.txid.length !== rt)
|
|
1239
|
-
throw new Error(
|
|
1240
|
-
`outpoint.txid must be exactly ${rt} bytes, got ${e.txid.length}`
|
|
1241
|
-
);
|
|
1242
|
-
if (!Number.isInteger(e.vout) || e.vout < 0 || e.vout > 4294967295)
|
|
1243
|
-
throw new Error(`outpoint.vout must be a u32, got ${e.vout}`);
|
|
1244
|
-
const t = new Uint8Array(lt);
|
|
1245
|
-
return t.set(e.txid, 0), ut(t, rt, e.vout), t;
|
|
1246
|
-
}
|
|
1247
|
-
function Rt(e, t) {
|
|
1248
|
-
const n = Math.min(e.length, t.length);
|
|
1249
|
-
for (let s = 0; s < n; s++)
|
|
1250
|
-
if (e[s] !== t[s]) return e[s] - t[s];
|
|
1251
|
-
return e.length - t.length;
|
|
1252
|
-
}
|
|
1253
|
-
function In(e) {
|
|
1254
|
-
if (e.length === 0)
|
|
1255
|
-
throw new Error(
|
|
1256
|
-
"buildFundingOutpointsCommitment: outpoints must be non-empty"
|
|
1257
|
-
);
|
|
1258
|
-
const t = e.map(Tn);
|
|
1259
|
-
t.sort(Rt);
|
|
1260
|
-
for (let s = 1; s < t.length; s++)
|
|
1261
|
-
if (Rt(t[s - 1], t[s]) === 0)
|
|
1262
|
-
throw new Error(
|
|
1263
|
-
"buildFundingOutpointsCommitment: duplicate outpoint detected"
|
|
1264
|
-
);
|
|
1265
|
-
const n = new Uint8Array(t.length * lt);
|
|
1266
|
-
for (let s = 0; s < t.length; s++)
|
|
1267
|
-
n.set(t[s], s * lt);
|
|
1268
|
-
return W(n);
|
|
1269
|
-
}
|
|
1270
|
-
function qn(e) {
|
|
1271
|
-
if (e.depositorBtcPubkey.length !== R)
|
|
1272
|
-
throw new Error(
|
|
1273
|
-
`vaultContext: depositorBtcPubkey must be exactly ${R} bytes, got ${e.depositorBtcPubkey.length}`
|
|
1274
|
-
);
|
|
1275
|
-
const t = In(e.fundingOutpoints), n = new Uint8Array(En);
|
|
1276
|
-
let s = 0;
|
|
1277
|
-
return ut(n, s, R), s += D, n.set(e.depositorBtcPubkey, s), s += R, ut(n, s, Qt), s += D, n.set(t, s), n;
|
|
1278
|
-
}
|
|
1279
1321
|
export {
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1322
|
+
S as C,
|
|
1323
|
+
Mn as P,
|
|
1324
|
+
We as V,
|
|
1325
|
+
Nn as a,
|
|
1326
|
+
Wn as b,
|
|
1327
|
+
gn as c,
|
|
1328
|
+
fn as d,
|
|
1329
|
+
at as e,
|
|
1330
|
+
Oe as f,
|
|
1331
|
+
Ln as g,
|
|
1332
|
+
H as h,
|
|
1333
|
+
Vn as i,
|
|
1334
|
+
$e as j,
|
|
1335
|
+
Le as k,
|
|
1336
|
+
Ve as l,
|
|
1337
|
+
Me as m
|
|
1296
1338
|
};
|
|
1297
|
-
//# sourceMappingURL=
|
|
1339
|
+
//# sourceMappingURL=PeginManager-DzMSIQ0I.js.map
|