@babylonlabs-io/ts-sdk 0.68.1 → 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-Bsv6caG3.js → PeginManager-DSFecw-w.js} +601 -564
- 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/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 +4 -4
- 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/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 +4 -4
- 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/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 +4 -4
- package/dist/{toRefundInputs-4UJfSVEz.js → toRefundInputs-C012ZXcp.js} +3 -3
- package/dist/{toRefundInputs-4UJfSVEz.js.map → toRefundInputs-C012ZXcp.js.map} +1 -1
- package/dist/{toRefundInputs-DgDhx_Ut.cjs → toRefundInputs-DaxiTty9.cjs} +2 -2
- package/dist/{toRefundInputs-DgDhx_Ut.cjs.map → toRefundInputs-DaxiTty9.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/PeginManager-Bsv6caG3.js.map +0 -1
- package/dist/PeginManager-C5NWzGT7.cjs +0 -2
- package/dist/PeginManager-C5NWzGT7.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/signPsbtsWithFallback-Bv79gLFe.js.map +0 -1
- package/dist/signPsbtsWithFallback-DJ4kE9UI.cjs +0 -2
- package/dist/signPsbtsWithFallback-DJ4kE9UI.cjs.map +0 -1
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var x = (s,
|
|
4
|
-
import { c as
|
|
5
|
-
import * as
|
|
6
|
-
import { Transaction as
|
|
1
|
+
var Ge = Object.defineProperty;
|
|
2
|
+
var qe = (s, e, t) => e in s ? Ge(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
|
|
3
|
+
var x = (s, e, t) => qe(s, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { c as _e, H as Ye, r as W, a as K, b as ae, u as ze, d as ce, e as le, f as ue, g as je, s as Se } from "./sha2-BYVxyZzX.js";
|
|
5
|
+
import * as Ce from "bitcoinjs-lib";
|
|
6
|
+
import { Transaction as Ae, Psbt as he } from "bitcoinjs-lib";
|
|
7
7
|
import { Buffer as O } from "buffer";
|
|
8
|
-
import { isAddressEqual as
|
|
8
|
+
import { isAddressEqual as de, encodeFunctionData as ee, zeroAddress as Qe } from "viem";
|
|
9
9
|
import { B as H } from "./BTCVaultRegistry.abi-CJwWI2EO.js";
|
|
10
10
|
import { h as R } from "./errors-Blc-JWnI.js";
|
|
11
|
-
import { expandWotsSeed as
|
|
12
|
-
import { a as
|
|
13
|
-
import { d as
|
|
14
|
-
import { p as
|
|
15
|
-
import { c as
|
|
16
|
-
import { M as
|
|
17
|
-
import { p as
|
|
18
|
-
import { c as
|
|
19
|
-
import { s as
|
|
20
|
-
import { p as
|
|
21
|
-
import { M as X, B as
|
|
22
|
-
import { l as
|
|
23
|
-
import * as
|
|
24
|
-
const
|
|
25
|
-
function
|
|
26
|
-
return
|
|
11
|
+
import { expandWotsSeed as Ze, expandHashlockSecret as Je, expandAuthAnchor as et, deriveVaultId as pe } from "@babylonlabs-io/babylon-tbv-rust-wasm";
|
|
12
|
+
import { a as fe, b as tt, f as ge, g as st } from "./verifyScriptPathSchnorrSignature-Dy9gF5RF.js";
|
|
13
|
+
import { d as ot, b as nt, e as rt, f as it, c as at } from "./verifyKeyPathSchnorrSignature-C6Cmk0R1.js";
|
|
14
|
+
import { p as ct, h as te, u as se, e as A, i as me, s as k, k as Pe, X as lt } from "./bitcoin-Ch_jxnDa.js";
|
|
15
|
+
import { c as ut } from "./signing-DaLvGwQe.js";
|
|
16
|
+
import { M as be } from "./validation-Dj3dqYtl.js";
|
|
17
|
+
import { p as ht, d as Ie } from "./parseFundingOutpoints-CO-f6IHK.js";
|
|
18
|
+
import { c as dt, s as F, r as pt, b as ft, d as gt } from "./signPsbtsWithFallback-DCZO2h6i.js";
|
|
19
|
+
import { s as mt, f as q, i as Pt, w as we } from "./waitForTransactionReceiptSmartAware-lobLm0q0.js";
|
|
20
|
+
import { p as bt, f as wt } from "./fundPeginTransaction-B2wyjqp0.js";
|
|
21
|
+
import { M as X, B as yt } from "./constants-GjWXdaqV.js";
|
|
22
|
+
import { l as xt, P as kt, m as Et, n as Tt, p as vt, V as Bt, i as _t } from "./mempoolApi-71R_CNZa.js";
|
|
23
|
+
import * as St from "@bitcoin-js/tiny-secp256k1-asmjs";
|
|
24
|
+
const D = /* @__PURE__ */ BigInt(2 ** 32 - 1), ye = /* @__PURE__ */ BigInt(32);
|
|
25
|
+
function Ct(s, e = !1) {
|
|
26
|
+
return e ? { h: Number(s & D), l: Number(s >> ye & D) } : { h: Number(s >> ye & D) | 0, l: Number(s & D) | 0 };
|
|
27
27
|
}
|
|
28
|
-
function
|
|
29
|
-
const
|
|
30
|
-
let o = new Uint32Array(
|
|
31
|
-
for (let n = 0; n <
|
|
32
|
-
const { h: r, l: a } =
|
|
28
|
+
function At(s, e = !1) {
|
|
29
|
+
const t = s.length;
|
|
30
|
+
let o = new Uint32Array(t), i = new Uint32Array(t);
|
|
31
|
+
for (let n = 0; n < t; n++) {
|
|
32
|
+
const { h: r, l: a } = Ct(s[n], e);
|
|
33
33
|
[o[n], i[n]] = [r, a];
|
|
34
34
|
}
|
|
35
35
|
return [o, i];
|
|
36
36
|
}
|
|
37
|
-
const
|
|
38
|
-
function
|
|
39
|
-
const
|
|
40
|
-
if (!/^[0-9a-f]+$/.test(
|
|
37
|
+
const It = (s, e, t) => s << t | e >>> 32 - t, Ht = (s, e, t) => e << t | s >>> 32 - t, Rt = (s, e, t) => e << t - 32 | s >>> 64 - t, $t = (s, e, t) => s << t - 32 | e >>> 64 - t, Ot = 64;
|
|
38
|
+
function Vt(s) {
|
|
39
|
+
const e = s.prepeginTxid.toLowerCase();
|
|
40
|
+
if (!/^[0-9a-f]+$/.test(e) || e.length !== Ot)
|
|
41
41
|
throw new Error(
|
|
42
42
|
`buildDepositTerms: prepeginTxid must be 64 hex chars, got "${s.prepeginTxid}"`
|
|
43
43
|
);
|
|
@@ -49,7 +49,7 @@ function Ve(s) {
|
|
|
49
49
|
throw new Error(
|
|
50
50
|
`buildDepositTerms: maxAcceptableCommissionBps must be an integer in [0, ${X}), got ${s.maxAcceptableCommissionBps}`
|
|
51
51
|
);
|
|
52
|
-
const
|
|
52
|
+
const t = BigInt(yt), o = s.peginAmounts.map(
|
|
53
53
|
(i, n) => ({
|
|
54
54
|
htlcVout: n,
|
|
55
55
|
vaultProviderBtcPubkey: s.vaultProviderBtcPubkey,
|
|
@@ -58,7 +58,7 @@ function Ve(s) {
|
|
|
58
58
|
// the same bound the registration calldata enforces on-chain, so any
|
|
59
59
|
// stamped commission the contract admits stays under it (firmware
|
|
60
60
|
// >= c8db53e checks the payout commission output <= this value).
|
|
61
|
-
commissionFee: i * BigInt(s.maxAcceptableCommissionBps) /
|
|
61
|
+
commissionFee: i * BigInt(s.maxAcceptableCommissionBps) / t,
|
|
62
62
|
depositorClaimValue: s.depositorClaimValue,
|
|
63
63
|
peginMaxFee: s.peginMaxFee
|
|
64
64
|
})
|
|
@@ -69,90 +69,91 @@ function Ve(s) {
|
|
|
69
69
|
timelockPegin: s.timelockPegin,
|
|
70
70
|
timelockAssert: s.timelockAssert,
|
|
71
71
|
timelockRefund: s.timelockRefund,
|
|
72
|
-
prepeginTxid:
|
|
72
|
+
prepeginTxid: e,
|
|
73
73
|
prepeginMaxFee: s.prepeginMaxFee,
|
|
74
74
|
vaultKeeperBtcPubkeys: [...s.vaultKeeperBtcPubkeys],
|
|
75
75
|
universalChallengerBtcPubkeys: [...s.universalChallengerBtcPubkeys],
|
|
76
76
|
vaults: o
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
-
const
|
|
79
|
+
const oe = 25, He = 9999;
|
|
80
80
|
function Y(s) {
|
|
81
81
|
if (!Number.isInteger(s) || s < 0 || s >= X)
|
|
82
82
|
throw new Error(
|
|
83
83
|
`Quoted commissionBps must be an integer in [0, ${X}), got ${s}`
|
|
84
84
|
);
|
|
85
85
|
return Math.min(
|
|
86
|
-
s +
|
|
87
|
-
|
|
86
|
+
s + oe,
|
|
87
|
+
He
|
|
88
88
|
);
|
|
89
89
|
}
|
|
90
|
-
const
|
|
90
|
+
const Ft = /^0x[0-9a-f]+$/i, Mt = /^[0-9a-f]+$/i, Wt = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
91
91
|
function $(s) {
|
|
92
92
|
if (typeof s != "string" || s.length === 0)
|
|
93
93
|
throw new Error("BTC wallet returned empty public key");
|
|
94
|
-
return
|
|
94
|
+
return ct(s).toLowerCase();
|
|
95
95
|
}
|
|
96
|
-
function
|
|
96
|
+
function Dt(s) {
|
|
97
97
|
if (typeof s != "string" || s.length === 0)
|
|
98
98
|
throw new Error("BTC wallet returned empty BIP-322 signature");
|
|
99
99
|
if (s.startsWith("0x") || s.startsWith("0X")) {
|
|
100
|
-
if (!
|
|
100
|
+
if (!Ft.test(s) || s.length < 4 || s.length % 2 !== 0)
|
|
101
101
|
throw new Error("BTC wallet returned malformed hex BIP-322 signature");
|
|
102
102
|
return s.toLowerCase();
|
|
103
103
|
}
|
|
104
|
-
if (
|
|
104
|
+
if (Mt.test(s)) {
|
|
105
105
|
if (s.length % 2 !== 0)
|
|
106
106
|
throw new Error("BTC wallet returned malformed hex BIP-322 signature");
|
|
107
107
|
return `0x${s.toLowerCase()}`;
|
|
108
108
|
}
|
|
109
|
-
if (!
|
|
109
|
+
if (!Wt.test(s) || s.length % 4 !== 0)
|
|
110
110
|
throw new Error("BTC wallet returned malformed base64 BIP-322 signature");
|
|
111
|
-
const
|
|
112
|
-
if (
|
|
111
|
+
const e = O.from(s, "base64");
|
|
112
|
+
if (e.length === 0 || e.toString("base64") !== s)
|
|
113
113
|
throw new Error("BTC wallet returned malformed base64 BIP-322 signature");
|
|
114
|
-
return `0x${
|
|
114
|
+
return `0x${e.toString("hex")}`;
|
|
115
115
|
}
|
|
116
|
-
async function
|
|
117
|
-
const { wallet:
|
|
118
|
-
if (!n && !
|
|
116
|
+
async function Nt(s) {
|
|
117
|
+
const { wallet: e, depositTerms: t, fundedPrePeginTxHex: o, depositorBtcPubkey: i } = s, n = typeof e.approveDepositTerms == "function" ? e.approveDepositTerms : void 0;
|
|
118
|
+
if (!n && !t)
|
|
119
119
|
return;
|
|
120
|
-
const r = o.startsWith("0x") ? o.slice(2) : o, c =
|
|
121
|
-
if (
|
|
120
|
+
const r = o.startsWith("0x") ? o.slice(2) : o, c = Ae.fromHex(r).getId();
|
|
121
|
+
if (t && t.prepeginTxid.replace(/^0x/, "").toLowerCase() !== c)
|
|
122
122
|
throw new Error(
|
|
123
|
-
`Deposit terms do not match the transaction being broadcast: terms are for prepeginTxid ${
|
|
123
|
+
`Deposit terms do not match the transaction being broadcast: terms are for prepeginTxid ${t.prepeginTxid}, but this transaction is ${c}.`
|
|
124
124
|
);
|
|
125
125
|
if (!n)
|
|
126
126
|
return;
|
|
127
|
-
if (!
|
|
127
|
+
if (!t)
|
|
128
128
|
throw new Error(
|
|
129
129
|
"This wallet requires approved deposit terms before signing the Pre-PegIn transaction, but none were provided. Pass PreparePeginResult.depositTerms (fresh flows) or a resume rebuild."
|
|
130
130
|
);
|
|
131
|
-
if (typeof
|
|
131
|
+
if (typeof e.deriveContextHash != "function")
|
|
132
132
|
throw new Error(
|
|
133
133
|
"A deposit-approval wallet must also implement deriveContextHash, but this one does not."
|
|
134
134
|
);
|
|
135
|
-
if (typeof
|
|
135
|
+
if (typeof e.holdsApprovedDepositTerms == "function") {
|
|
136
136
|
let g = !1;
|
|
137
137
|
try {
|
|
138
|
-
g = await
|
|
138
|
+
g = await e.holdsApprovedDepositTerms(t);
|
|
139
139
|
} catch {
|
|
140
140
|
}
|
|
141
141
|
if (g)
|
|
142
142
|
return;
|
|
143
143
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
typeof e.validateDepositTerms == "function" && await e.validateDepositTerms(t);
|
|
145
|
+
const h = ht(o);
|
|
146
|
+
(await Ie(
|
|
147
|
+
{ deriveContextHash: e.deriveContextHash.bind(e) },
|
|
147
148
|
{
|
|
148
|
-
depositorBtcPubkey:
|
|
149
|
+
depositorBtcPubkey: te(
|
|
149
150
|
$(i)
|
|
150
151
|
),
|
|
151
|
-
fundingOutpoints:
|
|
152
|
+
fundingOutpoints: h
|
|
152
153
|
}
|
|
153
|
-
)).fill(0), await n.call(
|
|
154
|
+
)).fill(0), await n.call(e, t);
|
|
154
155
|
}
|
|
155
|
-
const
|
|
156
|
+
const Ut = /* @__PURE__ */ Uint8Array.from([
|
|
156
157
|
7,
|
|
157
158
|
4,
|
|
158
159
|
13,
|
|
@@ -169,36 +170,36 @@ const De = /* @__PURE__ */ Uint8Array.from([
|
|
|
169
170
|
14,
|
|
170
171
|
11,
|
|
171
172
|
8
|
|
172
|
-
]),
|
|
173
|
-
const
|
|
173
|
+
]), Re = Uint8Array.from(new Array(16).fill(0).map((s, e) => e)), Lt = Re.map((s) => (9 * s + 5) % 16), $e = /* @__PURE__ */ (() => {
|
|
174
|
+
const t = [[Re], [Lt]];
|
|
174
175
|
for (let o = 0; o < 4; o++)
|
|
175
|
-
for (let i of
|
|
176
|
-
i.push(i[o].map((n) =>
|
|
177
|
-
return
|
|
178
|
-
})(),
|
|
176
|
+
for (let i of t)
|
|
177
|
+
i.push(i[o].map((n) => Ut[n]));
|
|
178
|
+
return t;
|
|
179
|
+
})(), Oe = $e[0], Ve = $e[1], Fe = /* @__PURE__ */ [
|
|
179
180
|
[11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],
|
|
180
181
|
[12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],
|
|
181
182
|
[13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],
|
|
182
183
|
[14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],
|
|
183
184
|
[15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5]
|
|
184
|
-
].map((s) => Uint8Array.from(s)),
|
|
185
|
+
].map((s) => Uint8Array.from(s)), Kt = /* @__PURE__ */ Oe.map((s, e) => s.map((t) => Fe[e][t])), Xt = /* @__PURE__ */ Ve.map((s, e) => s.map((t) => Fe[e][t])), Gt = /* @__PURE__ */ Uint32Array.from([
|
|
185
186
|
0,
|
|
186
187
|
1518500249,
|
|
187
188
|
1859775393,
|
|
188
189
|
2400959708,
|
|
189
190
|
2840853838
|
|
190
|
-
]),
|
|
191
|
+
]), qt = /* @__PURE__ */ Uint32Array.from([
|
|
191
192
|
1352829926,
|
|
192
193
|
1548603684,
|
|
193
194
|
1836072691,
|
|
194
195
|
2053994217,
|
|
195
196
|
0
|
|
196
197
|
]);
|
|
197
|
-
function
|
|
198
|
-
return s === 0 ?
|
|
198
|
+
function xe(s, e, t, o) {
|
|
199
|
+
return s === 0 ? e ^ t ^ o : s === 1 ? e & t | ~e & o : s === 2 ? (e | ~t) ^ o : s === 3 ? e & o | t & ~o : e ^ (t | ~o);
|
|
199
200
|
}
|
|
200
|
-
const
|
|
201
|
-
class
|
|
201
|
+
const N = /* @__PURE__ */ new Uint32Array(16);
|
|
202
|
+
class Yt extends Ye {
|
|
202
203
|
constructor() {
|
|
203
204
|
super(64, 20, 8, !0);
|
|
204
205
|
x(this, "h0", 1732584193);
|
|
@@ -208,73 +209,73 @@ class Ye extends Yt {
|
|
|
208
209
|
x(this, "h4", -1009589776);
|
|
209
210
|
}
|
|
210
211
|
get() {
|
|
211
|
-
const { h0:
|
|
212
|
-
return [
|
|
212
|
+
const { h0: t, h1: o, h2: i, h3: n, h4: r } = this;
|
|
213
|
+
return [t, o, i, n, r];
|
|
213
214
|
}
|
|
214
|
-
set(
|
|
215
|
-
this.h0 =
|
|
215
|
+
set(t, o, i, n, r) {
|
|
216
|
+
this.h0 = t | 0, this.h1 = o | 0, this.h2 = i | 0, this.h3 = n | 0, this.h4 = r | 0;
|
|
216
217
|
}
|
|
217
|
-
process(
|
|
218
|
-
for (let
|
|
219
|
-
|
|
220
|
-
let i = this.h0 | 0, n = i, r = this.h1 | 0, a = r, c = this.h2 | 0,
|
|
221
|
-
for (let
|
|
222
|
-
const
|
|
223
|
-
for (let
|
|
224
|
-
const y = W(i +
|
|
225
|
-
i =
|
|
218
|
+
process(t, o) {
|
|
219
|
+
for (let l = 0; l < 16; l++, o += 4)
|
|
220
|
+
N[l] = t.getUint32(o, !0);
|
|
221
|
+
let i = this.h0 | 0, n = i, r = this.h1 | 0, a = r, c = this.h2 | 0, h = c, d = this.h3 | 0, g = d, P = this.h4 | 0, b = P;
|
|
222
|
+
for (let l = 0; l < 5; l++) {
|
|
223
|
+
const T = 4 - l, E = Gt[l], p = qt[l], B = Oe[l], S = Ve[l], f = Kt[l], w = Xt[l];
|
|
224
|
+
for (let u = 0; u < 16; u++) {
|
|
225
|
+
const y = W(i + xe(l, r, c, d) + N[B[u]] + E, f[u]) + P | 0;
|
|
226
|
+
i = P, P = d, d = W(c, 10) | 0, c = r, r = y;
|
|
226
227
|
}
|
|
227
|
-
for (let
|
|
228
|
-
const y = W(n +
|
|
229
|
-
n = b, b = g, g = W(
|
|
228
|
+
for (let u = 0; u < 16; u++) {
|
|
229
|
+
const y = W(n + xe(T, a, h, g) + N[S[u]] + p, w[u]) + b | 0;
|
|
230
|
+
n = b, b = g, g = W(h, 10) | 0, h = a, a = y;
|
|
230
231
|
}
|
|
231
232
|
}
|
|
232
|
-
this.set(this.h1 + c + g | 0, this.h2 +
|
|
233
|
+
this.set(this.h1 + c + g | 0, this.h2 + d + b | 0, this.h3 + P + n | 0, this.h4 + i + a | 0, this.h0 + r + h | 0);
|
|
233
234
|
}
|
|
234
235
|
roundClean() {
|
|
235
|
-
K(
|
|
236
|
+
K(N);
|
|
236
237
|
}
|
|
237
238
|
destroy() {
|
|
238
239
|
this.destroyed = !0, K(this.buffer), this.set(0, 0, 0, 0, 0);
|
|
239
240
|
}
|
|
240
241
|
}
|
|
241
|
-
const
|
|
242
|
-
for (let s = 0,
|
|
243
|
-
[
|
|
244
|
-
let i =
|
|
242
|
+
const zt = /* @__PURE__ */ _e(() => new Yt()), jt = BigInt(0), M = BigInt(1), Qt = BigInt(2), Zt = BigInt(7), Jt = BigInt(256), es = BigInt(113), Me = [], We = [], De = [];
|
|
243
|
+
for (let s = 0, e = M, t = 1, o = 0; s < 24; s++) {
|
|
244
|
+
[t, o] = [o, (2 * t + 3 * o) % 5], Me.push(2 * (5 * o + t)), We.push((s + 1) * (s + 2) / 2 % 64);
|
|
245
|
+
let i = jt;
|
|
245
246
|
for (let n = 0; n < 7; n++)
|
|
246
|
-
|
|
247
|
-
|
|
247
|
+
e = (e << M ^ (e >> Zt) * es) % Jt, e & Qt && (i ^= M << (M << BigInt(n)) - M);
|
|
248
|
+
De.push(i);
|
|
248
249
|
}
|
|
249
|
-
const
|
|
250
|
-
function os(s,
|
|
251
|
-
const
|
|
252
|
-
for (let o = 24 -
|
|
250
|
+
const Ne = At(De, !0), ts = Ne[0], ss = Ne[1], ke = (s, e, t) => t > 32 ? Rt(s, e, t) : It(s, e, t), Ee = (s, e, t) => t > 32 ? $t(s, e, t) : Ht(s, e, t);
|
|
251
|
+
function os(s, e = 24) {
|
|
252
|
+
const t = new Uint32Array(10);
|
|
253
|
+
for (let o = 24 - e; o < 24; o++) {
|
|
253
254
|
for (let r = 0; r < 10; r++)
|
|
254
|
-
|
|
255
|
+
t[r] = s[r] ^ s[r + 10] ^ s[r + 20] ^ s[r + 30] ^ s[r + 40];
|
|
255
256
|
for (let r = 0; r < 10; r += 2) {
|
|
256
|
-
const a = (r + 8) % 10, c = (r + 2) % 10,
|
|
257
|
+
const a = (r + 8) % 10, c = (r + 2) % 10, h = t[c], d = t[c + 1], g = ke(h, d, 1) ^ t[a], P = Ee(h, d, 1) ^ t[a + 1];
|
|
257
258
|
for (let b = 0; b < 50; b += 10)
|
|
258
|
-
s[r + b] ^= g, s[r + b + 1] ^=
|
|
259
|
+
s[r + b] ^= g, s[r + b + 1] ^= P;
|
|
259
260
|
}
|
|
260
261
|
let i = s[2], n = s[3];
|
|
261
262
|
for (let r = 0; r < 24; r++) {
|
|
262
|
-
const a =
|
|
263
|
-
i = s[
|
|
263
|
+
const a = We[r], c = ke(i, n, a), h = Ee(i, n, a), d = Me[r];
|
|
264
|
+
i = s[d], n = s[d + 1], s[d] = c, s[d + 1] = h;
|
|
264
265
|
}
|
|
265
266
|
for (let r = 0; r < 50; r += 10) {
|
|
266
267
|
for (let a = 0; a < 10; a++)
|
|
267
|
-
|
|
268
|
+
t[a] = s[r + a];
|
|
268
269
|
for (let a = 0; a < 10; a++)
|
|
269
|
-
s[r + a] ^= ~
|
|
270
|
+
s[r + a] ^= ~t[(a + 2) % 10] & t[(a + 4) % 10];
|
|
270
271
|
}
|
|
271
|
-
s[0] ^=
|
|
272
|
+
s[0] ^= ts[o], s[1] ^= ss[o];
|
|
272
273
|
}
|
|
273
|
-
K(
|
|
274
|
+
K(t);
|
|
274
275
|
}
|
|
275
|
-
class
|
|
276
|
+
class re {
|
|
276
277
|
// NOTE: we accept arguments in bytes instead of bits here.
|
|
277
|
-
constructor(
|
|
278
|
+
constructor(e, t, o, i = !1, n = 24) {
|
|
278
279
|
x(this, "state");
|
|
279
280
|
x(this, "pos", 0);
|
|
280
281
|
x(this, "posOut", 0);
|
|
@@ -286,24 +287,24 @@ class rt {
|
|
|
286
287
|
x(this, "outputLen");
|
|
287
288
|
x(this, "enableXOF", !1);
|
|
288
289
|
x(this, "rounds");
|
|
289
|
-
if (this.blockLen =
|
|
290
|
+
if (this.blockLen = e, this.suffix = t, this.outputLen = o, this.enableXOF = i, this.rounds = n, ae(o, "outputLen"), !(0 < e && e < 200))
|
|
290
291
|
throw new Error("only keccak-f1600 function is supported");
|
|
291
|
-
this.state = new Uint8Array(200), this.state32 =
|
|
292
|
+
this.state = new Uint8Array(200), this.state32 = ze(this.state);
|
|
292
293
|
}
|
|
293
294
|
clone() {
|
|
294
295
|
return this._cloneInto();
|
|
295
296
|
}
|
|
296
297
|
keccak() {
|
|
297
|
-
|
|
298
|
+
ce(this.state32), os(this.state32, this.rounds), ce(this.state32), this.posOut = 0, this.pos = 0;
|
|
298
299
|
}
|
|
299
|
-
update(
|
|
300
|
-
|
|
301
|
-
const { blockLen:
|
|
300
|
+
update(e) {
|
|
301
|
+
le(this), ue(e);
|
|
302
|
+
const { blockLen: t, state: o } = this, i = e.length;
|
|
302
303
|
for (let n = 0; n < i; ) {
|
|
303
|
-
const r = Math.min(
|
|
304
|
+
const r = Math.min(t - this.pos, i - n);
|
|
304
305
|
for (let a = 0; a < r; a++)
|
|
305
|
-
o[this.pos++] ^=
|
|
306
|
-
this.pos ===
|
|
306
|
+
o[this.pos++] ^= e[n++];
|
|
307
|
+
this.pos === t && this.keccak();
|
|
307
308
|
}
|
|
308
309
|
return this;
|
|
309
310
|
}
|
|
@@ -311,31 +312,31 @@ class rt {
|
|
|
311
312
|
if (this.finished)
|
|
312
313
|
return;
|
|
313
314
|
this.finished = !0;
|
|
314
|
-
const { state:
|
|
315
|
-
|
|
315
|
+
const { state: e, suffix: t, pos: o, blockLen: i } = this;
|
|
316
|
+
e[o] ^= t, (t & 128) !== 0 && o === i - 1 && this.keccak(), e[i - 1] ^= 128, this.keccak();
|
|
316
317
|
}
|
|
317
|
-
writeInto(
|
|
318
|
-
|
|
319
|
-
const
|
|
320
|
-
for (let i = 0, n =
|
|
318
|
+
writeInto(e) {
|
|
319
|
+
le(this, !1), ue(e), this.finish();
|
|
320
|
+
const t = this.state, { blockLen: o } = this;
|
|
321
|
+
for (let i = 0, n = e.length; i < n; ) {
|
|
321
322
|
this.posOut >= o && this.keccak();
|
|
322
323
|
const r = Math.min(o - this.posOut, n - i);
|
|
323
|
-
|
|
324
|
+
e.set(t.subarray(this.posOut, this.posOut + r), i), this.posOut += r, i += r;
|
|
324
325
|
}
|
|
325
|
-
return
|
|
326
|
+
return e;
|
|
326
327
|
}
|
|
327
|
-
xofInto(
|
|
328
|
+
xofInto(e) {
|
|
328
329
|
if (!this.enableXOF)
|
|
329
330
|
throw new Error("XOF is not possible for this instance");
|
|
330
|
-
return this.writeInto(
|
|
331
|
+
return this.writeInto(e);
|
|
331
332
|
}
|
|
332
|
-
xof(
|
|
333
|
-
return
|
|
333
|
+
xof(e) {
|
|
334
|
+
return ae(e), this.xofInto(new Uint8Array(e));
|
|
334
335
|
}
|
|
335
|
-
digestInto(
|
|
336
|
-
if (
|
|
336
|
+
digestInto(e) {
|
|
337
|
+
if (je(e, this), this.finished)
|
|
337
338
|
throw new Error("digest() was already called");
|
|
338
|
-
return this.writeInto(
|
|
339
|
+
return this.writeInto(e), this.destroy(), e;
|
|
339
340
|
}
|
|
340
341
|
digest() {
|
|
341
342
|
return this.digestInto(new Uint8Array(this.outputLen));
|
|
@@ -343,49 +344,49 @@ class rt {
|
|
|
343
344
|
destroy() {
|
|
344
345
|
this.destroyed = !0, K(this.state);
|
|
345
346
|
}
|
|
346
|
-
_cloneInto(
|
|
347
|
-
const { blockLen:
|
|
348
|
-
return
|
|
347
|
+
_cloneInto(e) {
|
|
348
|
+
const { blockLen: t, suffix: o, outputLen: i, rounds: n, enableXOF: r } = this;
|
|
349
|
+
return e || (e = new re(t, o, i, r, n)), e.state32.set(this.state32), e.pos = this.pos, e.posOut = this.posOut, e.finished = this.finished, e.rounds = n, e.suffix = o, e.outputLen = i, e.enableXOF = r, e.destroyed = this.destroyed, e;
|
|
349
350
|
}
|
|
350
351
|
}
|
|
351
|
-
const ns = (s,
|
|
352
|
-
function
|
|
353
|
-
return
|
|
352
|
+
const ns = (s, e, t, o = {}) => _e(() => new re(e, s, t), o), rs = /* @__PURE__ */ ns(1, 136, 32), Te = 64, _ = 20, ne = 4, Ue = 2, is = 0, as = 1, U = [64, 64], cs = (s) => Array.from(s).map((e) => e.toString(16).padStart(2, "0")).join("");
|
|
353
|
+
function ie(s) {
|
|
354
|
+
return zt(Se(s));
|
|
354
355
|
}
|
|
355
|
-
function
|
|
356
|
+
function Le(s) {
|
|
356
357
|
return (1 << s) - 1;
|
|
357
358
|
}
|
|
358
359
|
function ls(s) {
|
|
359
|
-
let
|
|
360
|
-
for (;
|
|
361
|
-
return Math.max(
|
|
360
|
+
let e = 1;
|
|
361
|
+
for (; e * e < s + 1; ) e++;
|
|
362
|
+
return Math.max(e, 2);
|
|
362
363
|
}
|
|
363
364
|
function us(s) {
|
|
364
|
-
const
|
|
365
|
-
return { d:
|
|
365
|
+
const e = ne, t = s * Le(e);
|
|
366
|
+
return { d: e, n: s, checksum_radix: ls(t) };
|
|
366
367
|
}
|
|
367
|
-
function z(s,
|
|
368
|
-
const
|
|
369
|
-
let o =
|
|
368
|
+
function z(s, e) {
|
|
369
|
+
const t = [];
|
|
370
|
+
let o = e;
|
|
370
371
|
for (; o > 0; )
|
|
371
|
-
|
|
372
|
-
const i = new Uint8Array(s.length +
|
|
372
|
+
t.push(o & 255), o >>>= 8;
|
|
373
|
+
const i = new Uint8Array(s.length + t.length);
|
|
373
374
|
i.set(s);
|
|
374
|
-
for (let n = 0; n <
|
|
375
|
-
i[s.length + n] =
|
|
376
|
-
return
|
|
375
|
+
for (let n = 0; n < t.length; n++)
|
|
376
|
+
i[s.length + n] = t[n];
|
|
377
|
+
return ie(i);
|
|
377
378
|
}
|
|
378
|
-
function j(s,
|
|
379
|
-
let
|
|
380
|
-
for (let o = 0; o <
|
|
381
|
-
|
|
382
|
-
return
|
|
379
|
+
function j(s, e) {
|
|
380
|
+
let t = s;
|
|
381
|
+
for (let o = 0; o < e; o++)
|
|
382
|
+
t = ie(t);
|
|
383
|
+
return t;
|
|
383
384
|
}
|
|
384
|
-
function hs(s,
|
|
385
|
-
const
|
|
386
|
-
for (let
|
|
387
|
-
const g = z(s,
|
|
388
|
-
n.push(Array.from(
|
|
385
|
+
function hs(s, e) {
|
|
386
|
+
const t = Le(e.d), o = e.checksum_radix - 1, i = Math.floor(e.n * t / e.checksum_radix), n = [];
|
|
387
|
+
for (let d = 0; d < e.n; d++) {
|
|
388
|
+
const g = z(s, d + Ue), P = j(g, t);
|
|
389
|
+
n.push(Array.from(P));
|
|
389
390
|
}
|
|
390
391
|
const r = z(
|
|
391
392
|
s,
|
|
@@ -396,83 +397,83 @@ function hs(s, t) {
|
|
|
396
397
|
), c = z(
|
|
397
398
|
s,
|
|
398
399
|
as
|
|
399
|
-
),
|
|
400
|
+
), h = j(
|
|
400
401
|
c,
|
|
401
402
|
i
|
|
402
403
|
);
|
|
403
404
|
return {
|
|
404
|
-
config:
|
|
405
|
+
config: e,
|
|
405
406
|
message_terminals: n,
|
|
406
|
-
checksum_major_terminal: Array.from(
|
|
407
|
+
checksum_major_terminal: Array.from(h),
|
|
407
408
|
checksum_minor_terminal: Array.from(a)
|
|
408
409
|
};
|
|
409
410
|
}
|
|
410
411
|
async function ds(s) {
|
|
411
412
|
try {
|
|
412
|
-
if (s.length !==
|
|
413
|
+
if (s.length !== Te)
|
|
413
414
|
throw new Error(
|
|
414
|
-
`WOTS seed must be exactly ${
|
|
415
|
+
`WOTS seed must be exactly ${Te} bytes, got ${s.length}`
|
|
415
416
|
);
|
|
416
|
-
const
|
|
417
|
-
for (let
|
|
418
|
-
const o =
|
|
419
|
-
n.set(s), n[s.length] =
|
|
420
|
-
const r =
|
|
417
|
+
const e = [];
|
|
418
|
+
for (let t = 0; t < U.length; t++) {
|
|
419
|
+
const o = U[t], i = us(o), n = new Uint8Array(s.length + 1);
|
|
420
|
+
n.set(s), n[s.length] = t;
|
|
421
|
+
const r = ie(n);
|
|
421
422
|
try {
|
|
422
423
|
const a = hs(r, i);
|
|
423
|
-
if (a.config.d !==
|
|
424
|
+
if (a.config.d !== ne)
|
|
424
425
|
throw new Error(
|
|
425
|
-
`Block ${
|
|
426
|
+
`Block ${t}: expected d=${ne}, got d=${a.config.d}`
|
|
426
427
|
);
|
|
427
428
|
if (a.config.n !== o)
|
|
428
429
|
throw new Error(
|
|
429
|
-
`Block ${
|
|
430
|
+
`Block ${t}: expected n=${o}, got n=${a.config.n}`
|
|
430
431
|
);
|
|
431
432
|
if (a.message_terminals.length !== o)
|
|
432
433
|
throw new Error(
|
|
433
|
-
`Block ${
|
|
434
|
+
`Block ${t}: expected ${o} message terminals, got ${a.message_terminals.length}`
|
|
434
435
|
);
|
|
435
436
|
for (let c = 0; c < a.message_terminals.length; c++)
|
|
436
437
|
if (a.message_terminals[c].length !== _)
|
|
437
438
|
throw new Error(
|
|
438
|
-
`Block ${
|
|
439
|
+
`Block ${t} terminal ${c}: expected ${_} bytes, got ${a.message_terminals[c].length}`
|
|
439
440
|
);
|
|
440
441
|
if (a.checksum_minor_terminal.length !== _)
|
|
441
442
|
throw new Error(
|
|
442
|
-
`Block ${
|
|
443
|
+
`Block ${t} checksum_minor: expected ${_} bytes`
|
|
443
444
|
);
|
|
444
445
|
if (a.checksum_major_terminal.length !== _)
|
|
445
446
|
throw new Error(
|
|
446
|
-
`Block ${
|
|
447
|
+
`Block ${t} checksum_major: expected ${_} bytes`
|
|
447
448
|
);
|
|
448
|
-
|
|
449
|
+
e.push(a);
|
|
449
450
|
} finally {
|
|
450
451
|
n.fill(0), r.fill(0);
|
|
451
452
|
}
|
|
452
453
|
}
|
|
453
|
-
if (
|
|
454
|
+
if (e.length !== U.length)
|
|
454
455
|
throw new Error(
|
|
455
|
-
`Expected ${
|
|
456
|
+
`Expected ${U.length} blocks, got ${e.length}`
|
|
456
457
|
);
|
|
457
|
-
return
|
|
458
|
+
return e;
|
|
458
459
|
} finally {
|
|
459
460
|
s.fill(0);
|
|
460
461
|
}
|
|
461
462
|
}
|
|
462
|
-
function Q(s,
|
|
463
|
+
function Q(s, e, t) {
|
|
463
464
|
if (s.length !== _)
|
|
464
465
|
throw new Error(
|
|
465
|
-
`Block ${
|
|
466
|
+
`Block ${e} ${t}: expected ${_} bytes, got ${s.length}`
|
|
466
467
|
);
|
|
467
468
|
for (let o = 0; o < s.length; o++) {
|
|
468
469
|
const i = s[o];
|
|
469
470
|
if (!Number.isInteger(i) || i < 0 || i > 255)
|
|
470
471
|
throw new Error(
|
|
471
|
-
`Block ${
|
|
472
|
+
`Block ${e} ${t}[${o}]: invalid byte value ${i}`
|
|
472
473
|
);
|
|
473
474
|
}
|
|
474
475
|
}
|
|
475
|
-
function
|
|
476
|
+
function ps(s) {
|
|
476
477
|
if (s.length === 0)
|
|
477
478
|
throw new Error("Public keys array must not be empty");
|
|
478
479
|
for (let n = 0; n < s.length; n++) {
|
|
@@ -481,34 +482,34 @@ function fs(s) {
|
|
|
481
482
|
for (let a = 0; a < r.message_terminals.length; a++)
|
|
482
483
|
Q(r.message_terminals[a], n, `message_terminal[${a}]`);
|
|
483
484
|
}
|
|
484
|
-
let
|
|
485
|
+
let e = 0;
|
|
485
486
|
for (const n of s)
|
|
486
|
-
|
|
487
|
-
const
|
|
487
|
+
e += Ue + n.message_terminals.length;
|
|
488
|
+
const t = new Uint8Array(e * _);
|
|
488
489
|
let o = 0;
|
|
489
490
|
for (const n of s) {
|
|
490
|
-
|
|
491
|
+
t.set(n.checksum_minor_terminal, o), o += _, t.set(n.checksum_major_terminal, o), o += _;
|
|
491
492
|
for (const r of n.message_terminals)
|
|
492
|
-
|
|
493
|
+
t.set(r, o), o += _;
|
|
493
494
|
}
|
|
494
|
-
const i = rs(
|
|
495
|
+
const i = rs(t);
|
|
495
496
|
return `0x${cs(i)}`;
|
|
496
497
|
}
|
|
497
|
-
async function
|
|
498
|
-
const
|
|
498
|
+
async function fs(s, e) {
|
|
499
|
+
const t = [], o = [], i = [], n = [];
|
|
499
500
|
try {
|
|
500
|
-
for (let r = 0; r <
|
|
501
|
-
const a = await
|
|
501
|
+
for (let r = 0; r < e; r++) {
|
|
502
|
+
const a = await Ze(s, r);
|
|
502
503
|
try {
|
|
503
|
-
const
|
|
504
|
-
|
|
504
|
+
const h = await ds(a);
|
|
505
|
+
t.push(h), o.push(ps(h));
|
|
505
506
|
} finally {
|
|
506
507
|
a.fill(0);
|
|
507
508
|
}
|
|
508
|
-
const c = await
|
|
509
|
+
const c = await Je(s, r);
|
|
509
510
|
try {
|
|
510
|
-
const
|
|
511
|
-
i.push(
|
|
511
|
+
const h = se(c);
|
|
512
|
+
i.push(h), n.push(dt(A(h)).slice(2));
|
|
512
513
|
} finally {
|
|
513
514
|
c.fill(0);
|
|
514
515
|
}
|
|
@@ -516,23 +517,23 @@ async function ps(s, t) {
|
|
|
516
517
|
} finally {
|
|
517
518
|
s.fill(0);
|
|
518
519
|
}
|
|
519
|
-
return { perVaultWotsKeys:
|
|
520
|
+
return { perVaultWotsKeys: t, wotsPkHashes: o, htlcSecretHexes: i, hashlocks: n };
|
|
520
521
|
}
|
|
521
|
-
const gs = 1, ms = 2,
|
|
522
|
+
const gs = 1, ms = 2, Ps = 33, bs = 2, ws = 3, ys = 1, L = 64, xs = 0, Z = 1, ve = /^[0-9a-f]{64}$/i, ks = /^(?:[0-9a-f]{2})+$/;
|
|
522
523
|
function Es(s) {
|
|
523
|
-
const
|
|
524
|
-
if (!ks.test(
|
|
524
|
+
const e = s.slice(2);
|
|
525
|
+
if (!ks.test(e))
|
|
525
526
|
throw new Error(
|
|
526
527
|
"proof of possession witness is not even-length lowercase hex"
|
|
527
528
|
);
|
|
528
|
-
return
|
|
529
|
-
Uint8Array.from(O.from(
|
|
529
|
+
return ot(
|
|
530
|
+
Uint8Array.from(O.from(e, "hex")),
|
|
530
531
|
"proof of possession witness"
|
|
531
532
|
);
|
|
532
533
|
}
|
|
533
|
-
function Ts(s,
|
|
534
|
+
function Ts(s, e, t) {
|
|
534
535
|
var i;
|
|
535
|
-
const o = Es(
|
|
536
|
+
const o = Es(t);
|
|
536
537
|
if (o.length === gs) {
|
|
537
538
|
const [n] = o;
|
|
538
539
|
let r, a;
|
|
@@ -544,39 +545,39 @@ function Ts(s, t, e) {
|
|
|
544
545
|
throw new Error(
|
|
545
546
|
"proof of possession witness item must be a 64-byte Schnorr signature (or 65 bytes ending in 0x01)"
|
|
546
547
|
);
|
|
547
|
-
if (!
|
|
548
|
+
if (!ve.test(e))
|
|
548
549
|
throw new Error(
|
|
549
|
-
`depositor public key must be bare 64-char x-only hex, got "${
|
|
550
|
+
`depositor public key must be bare 64-char x-only hex, got "${e}"`
|
|
550
551
|
);
|
|
551
|
-
const c = Uint8Array.from(O.from(
|
|
552
|
-
if (!
|
|
552
|
+
const c = Uint8Array.from(O.from(e, "hex"));
|
|
553
|
+
if (!xt(s, c, r, a))
|
|
553
554
|
throw new Error(
|
|
554
555
|
"proof of possession signature does not verify against the depositor key"
|
|
555
556
|
);
|
|
556
557
|
return { kind: "p2tr-verified" };
|
|
557
558
|
}
|
|
558
559
|
if (o.length === ms) {
|
|
559
|
-
if (!
|
|
560
|
+
if (!ve.test(e))
|
|
560
561
|
throw new Error(
|
|
561
|
-
`depositor public key must be bare 64-char x-only hex, got "${
|
|
562
|
+
`depositor public key must be bare 64-char x-only hex, got "${e}"`
|
|
562
563
|
);
|
|
563
564
|
const [n, r] = o;
|
|
564
|
-
if (r.length !==
|
|
565
|
+
if (r.length !== Ps || r[0] !== bs && r[0] !== ws)
|
|
565
566
|
throw new Error(
|
|
566
567
|
`proof of possession P2WPKH witness item 1 is not a compressed public key (${r.length} bytes, prefix 0x${((i = r[0]) == null ? void 0 : i.toString(16)) ?? "none"})`
|
|
567
568
|
);
|
|
568
|
-
if (!
|
|
569
|
+
if (!St.isPointCompressed(r))
|
|
569
570
|
throw new Error(
|
|
570
571
|
"proof of possession P2WPKH witness pubkey is not a valid secp256k1 point"
|
|
571
572
|
);
|
|
572
573
|
const a = O.from(
|
|
573
574
|
r.subarray(ys)
|
|
574
575
|
).toString("hex");
|
|
575
|
-
if (a !==
|
|
576
|
+
if (a !== e.toLowerCase())
|
|
576
577
|
throw new Error(
|
|
577
|
-
`proof of possession witness pubkey does not match the depositor key: witness carries ${a}, expected ${
|
|
578
|
+
`proof of possession witness pubkey does not match the depositor key: witness carries ${a}, expected ${e}`
|
|
578
579
|
);
|
|
579
|
-
if (n.length <
|
|
580
|
+
if (n.length < kt || n.length > Et)
|
|
580
581
|
throw new Error(
|
|
581
582
|
`proof of possession signature is ${n.length} bytes; vault ingestion accepts only 71/72-byte DER signatures with a sighash byte — try a different account or a Taproot address`
|
|
582
583
|
);
|
|
@@ -584,7 +585,7 @@ function Ts(s, t, e) {
|
|
|
584
585
|
throw new Error(
|
|
585
586
|
`proof of possession P2WPKH signature must end in a SIGHASH_ALL (0x01) byte, got 0x${n[n.length - 1].toString(16)}`
|
|
586
587
|
);
|
|
587
|
-
if (!
|
|
588
|
+
if (!Tt(s, r, n))
|
|
588
589
|
throw new Error(
|
|
589
590
|
"proof of possession signature does not verify against the depositor key"
|
|
590
591
|
);
|
|
@@ -594,40 +595,40 @@ function Ts(s, t, e) {
|
|
|
594
595
|
`proof of possession witness has ${o.length} items; expected 1 (P2TR) or 2 (P2WPKH)`
|
|
595
596
|
);
|
|
596
597
|
}
|
|
597
|
-
const
|
|
598
|
-
function
|
|
599
|
-
const
|
|
598
|
+
const Ke = 0, J = "00".repeat(32), vs = "00".repeat(32);
|
|
599
|
+
function Bs(s, e) {
|
|
600
|
+
const t = {
|
|
600
601
|
bitcoin: "bc",
|
|
601
602
|
testnet: "tb",
|
|
602
603
|
signet: "tb",
|
|
603
604
|
regtest: "bcrt"
|
|
604
605
|
};
|
|
605
606
|
try {
|
|
606
|
-
const o =
|
|
607
|
-
return o.prefix === e
|
|
607
|
+
const o = Ce.address.fromBech32(s);
|
|
608
|
+
return o.prefix === t[e] && o.version === 0 && o.data.length === 20;
|
|
608
609
|
} catch {
|
|
609
610
|
return !1;
|
|
610
611
|
}
|
|
611
612
|
}
|
|
612
|
-
function
|
|
613
|
-
const i =
|
|
613
|
+
function _s(s, e, t, o) {
|
|
614
|
+
const i = t == null ? void 0 : t[`${s}:${e}`];
|
|
614
615
|
return i ? Promise.resolve({
|
|
615
616
|
txid: s,
|
|
616
|
-
vout:
|
|
617
|
+
vout: e,
|
|
617
618
|
value: i.value,
|
|
618
619
|
scriptPubKey: i.scriptPubKey
|
|
619
|
-
}) :
|
|
620
|
+
}) : _t(s, e, o);
|
|
620
621
|
}
|
|
621
|
-
const
|
|
622
|
-
class
|
|
622
|
+
const Be = 12e4;
|
|
623
|
+
class Js {
|
|
623
624
|
/**
|
|
624
625
|
* Creates a new PeginManager instance.
|
|
625
626
|
*
|
|
626
627
|
* @param config - Manager configuration including wallets and contract addresses
|
|
627
628
|
*/
|
|
628
|
-
constructor(
|
|
629
|
+
constructor(e) {
|
|
629
630
|
x(this, "config");
|
|
630
|
-
this.config =
|
|
631
|
+
this.config = e;
|
|
631
632
|
}
|
|
632
633
|
/**
|
|
633
634
|
* Prepare a peg-in: sizing pass → vault-root derivation (one wallet
|
|
@@ -639,78 +640,92 @@ class Zs {
|
|
|
639
640
|
* @throws If the wallet rejects, insufficient funds, or an internal
|
|
640
641
|
* invariant violation.
|
|
641
642
|
*/
|
|
642
|
-
async preparePegin(
|
|
643
|
-
if (
|
|
643
|
+
async preparePegin(e) {
|
|
644
|
+
if (e.amounts.length === 0)
|
|
644
645
|
throw new Error("amounts must contain at least one entry");
|
|
645
|
-
const
|
|
646
|
-
if (
|
|
647
|
-
const
|
|
648
|
-
if (
|
|
646
|
+
const t = await this.config.btcWallet.getPublicKeyHex(), o = $(t);
|
|
647
|
+
if (F(this.config.btcWallet)) {
|
|
648
|
+
const p = (await pt(this.config.btcWallet)).trim();
|
|
649
|
+
if (e.changeAddress.trim() !== p)
|
|
649
650
|
throw new Error(
|
|
650
|
-
`Pre-PegIn changeAddress "${
|
|
651
|
+
`Pre-PegIn changeAddress "${e.changeAddress}" is not the approval wallet's change address ("${p}"). Refusing to build a tx the signing device would reject.`
|
|
651
652
|
);
|
|
652
|
-
} else if (!
|
|
653
|
-
|
|
654
|
-
|
|
653
|
+
} else if (!me(
|
|
654
|
+
e.changeAddress,
|
|
655
|
+
t,
|
|
655
656
|
this.config.btcNetwork
|
|
656
657
|
))
|
|
657
658
|
throw new Error(
|
|
658
|
-
`Pre-PegIn changeAddress "${
|
|
659
|
+
`Pre-PegIn changeAddress "${e.changeAddress}" is not derived from the connected wallet's public key. Refusing to build a tx that would send change to an address the signing key doesn't control.`
|
|
660
|
+
);
|
|
661
|
+
const i = await this.prepareSizing(o, e);
|
|
662
|
+
if (F(this.config.btcWallet)) {
|
|
663
|
+
const { validateDepositTerms: p } = this.config.btcWallet;
|
|
664
|
+
typeof p == "function" && await p.call(
|
|
665
|
+
this.config.btcWallet,
|
|
666
|
+
this.buildPeginDepositTerms({
|
|
667
|
+
params: e,
|
|
668
|
+
prepeginTxid: vs,
|
|
669
|
+
prepeginMaxFee: i.fee,
|
|
670
|
+
depositorClaimValue: i.depositorClaimValue,
|
|
671
|
+
peginMaxFee: i.minPeginFee
|
|
672
|
+
})
|
|
659
673
|
);
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
674
|
+
}
|
|
675
|
+
const n = i.selectedUTXOs.map(
|
|
676
|
+
(p) => ({
|
|
677
|
+
txid: te(p.txid),
|
|
678
|
+
vout: p.vout
|
|
664
679
|
})
|
|
665
|
-
), r = await
|
|
666
|
-
depositorBtcPubkey:
|
|
680
|
+
), r = await Ie(this.config.btcWallet, {
|
|
681
|
+
depositorBtcPubkey: te(o),
|
|
667
682
|
fundingOutpoints: n
|
|
668
683
|
});
|
|
669
684
|
let a, c;
|
|
670
685
|
try {
|
|
671
|
-
const
|
|
686
|
+
const p = await et(r);
|
|
672
687
|
try {
|
|
673
|
-
a =
|
|
688
|
+
a = se(p), c = se(Se(p));
|
|
674
689
|
} finally {
|
|
675
|
-
|
|
690
|
+
p.fill(0);
|
|
676
691
|
}
|
|
677
|
-
} catch (
|
|
678
|
-
throw r.fill(0),
|
|
692
|
+
} catch (p) {
|
|
693
|
+
throw r.fill(0), p;
|
|
679
694
|
}
|
|
680
|
-
const
|
|
681
|
-
depositorBtcPubkeyRaw:
|
|
695
|
+
const h = await fs(r, e.amounts.length), { perVaultWotsKeys: d, wotsPkHashes: g, htlcSecretHexes: P, hashlocks: b } = h, l = await this.preparePeginCommit({
|
|
696
|
+
depositorBtcPubkeyRaw: t,
|
|
682
697
|
depositorBtcPubkey: o,
|
|
683
698
|
hashlocks: b,
|
|
684
699
|
authAnchorHash: c,
|
|
685
700
|
sizing: i,
|
|
686
|
-
params:
|
|
701
|
+
params: e
|
|
687
702
|
});
|
|
688
|
-
for (let
|
|
689
|
-
if (
|
|
703
|
+
for (let p = 0; p < l.perVault.length; p++)
|
|
704
|
+
if (l.perVault[p].htlcVout !== p)
|
|
690
705
|
throw new Error(
|
|
691
|
-
`Internal invariant violation: htlcVout/index mismatch at vault ${
|
|
706
|
+
`Internal invariant violation: htlcVout/index mismatch at vault ${p} (expected ${p}, got ${l.perVault[p].htlcVout})`
|
|
692
707
|
);
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
708
|
+
ft(
|
|
709
|
+
l.fundedPrePeginTxHex,
|
|
710
|
+
e.amounts.length,
|
|
696
711
|
c
|
|
697
712
|
);
|
|
698
|
-
const { depositTerms:
|
|
713
|
+
const { depositTerms: T, ...E } = l;
|
|
699
714
|
return {
|
|
700
715
|
transaction: {
|
|
701
|
-
...
|
|
716
|
+
...E,
|
|
702
717
|
selectedUTXOs: i.selectedUTXOs,
|
|
703
718
|
fee: i.fee,
|
|
704
719
|
changeAmount: i.changeAmount
|
|
705
720
|
},
|
|
706
721
|
depositorBtcPubkey: o,
|
|
707
722
|
derivedSecrets: {
|
|
708
|
-
perVaultWotsKeys:
|
|
723
|
+
perVaultWotsKeys: d,
|
|
709
724
|
wotsPkHashes: g,
|
|
710
|
-
htlcSecretHexes:
|
|
725
|
+
htlcSecretHexes: P,
|
|
711
726
|
authAnchorHex: a
|
|
712
727
|
},
|
|
713
|
-
depositTerms:
|
|
728
|
+
depositTerms: T
|
|
714
729
|
};
|
|
715
730
|
}
|
|
716
731
|
/**
|
|
@@ -729,47 +744,75 @@ class Zs {
|
|
|
729
744
|
* real values. Output budget is identical (32-byte push regardless of
|
|
730
745
|
* content), so UTXO selection is invariant under substitution.
|
|
731
746
|
*/
|
|
732
|
-
async prepareSizing(
|
|
733
|
-
const o =
|
|
747
|
+
async prepareSizing(e, t) {
|
|
748
|
+
const o = t.amounts.map(
|
|
734
749
|
() => J
|
|
735
|
-
), i =
|
|
736
|
-
vaultCoreVersion:
|
|
737
|
-
depositorPubkey:
|
|
738
|
-
vaultProviderPubkey:
|
|
739
|
-
vaultKeeperPubkeys:
|
|
740
|
-
universalChallengerPubkeys:
|
|
750
|
+
), i = t.vaultKeeperBtcPubkeys.length, n = await fe({
|
|
751
|
+
vaultCoreVersion: t.vaultCoreVersion,
|
|
752
|
+
depositorPubkey: e,
|
|
753
|
+
vaultProviderPubkey: k(t.vaultProviderBtcPubkey),
|
|
754
|
+
vaultKeeperPubkeys: t.vaultKeeperBtcPubkeys.map(k),
|
|
755
|
+
universalChallengerPubkeys: t.universalChallengerBtcPubkeys.map(k),
|
|
741
756
|
hashlocks: o,
|
|
742
|
-
timelockRefund:
|
|
743
|
-
pegInAmounts:
|
|
744
|
-
feeRate:
|
|
745
|
-
minPeginFeeRate:
|
|
757
|
+
timelockRefund: t.timelockRefund,
|
|
758
|
+
pegInAmounts: t.amounts,
|
|
759
|
+
feeRate: t.protocolFeeRate,
|
|
760
|
+
minPeginFeeRate: t.minPeginFeeRate,
|
|
746
761
|
numLocalChallengers: i,
|
|
747
|
-
councilQuorum:
|
|
748
|
-
councilSize:
|
|
762
|
+
councilQuorum: t.councilQuorum,
|
|
763
|
+
councilSize: t.councilSize,
|
|
749
764
|
network: this.config.btcNetwork,
|
|
750
765
|
authAnchorHash: J
|
|
751
|
-
}), r =
|
|
752
|
-
[...
|
|
766
|
+
}), r = mt(
|
|
767
|
+
[...t.availableUTXOs],
|
|
753
768
|
n.totalOutputValue,
|
|
754
|
-
|
|
755
|
-
|
|
769
|
+
t.mempoolFeeRate,
|
|
770
|
+
bt(n.htlcValues.length, !0)
|
|
756
771
|
);
|
|
757
772
|
return {
|
|
758
773
|
selectedUTXOs: r.selectedUTXOs,
|
|
759
774
|
fee: r.fee,
|
|
760
|
-
changeAmount: r.changeAmount
|
|
775
|
+
changeAmount: r.changeAmount,
|
|
776
|
+
depositorClaimValue: n.depositorClaimValue,
|
|
777
|
+
minPeginFee: n.minPeginFee
|
|
761
778
|
};
|
|
762
779
|
}
|
|
780
|
+
/**
|
|
781
|
+
* One projection for both the provisional (pre-derive, placeholder-txid)
|
|
782
|
+
* terms and the final approved terms, so the fields the pre-check validated
|
|
783
|
+
* cannot drift from the fields the device later displays (#2110 T4).
|
|
784
|
+
*/
|
|
785
|
+
buildPeginDepositTerms(e) {
|
|
786
|
+
const { params: t } = e;
|
|
787
|
+
return Vt({
|
|
788
|
+
vaultCoreVersion: t.vaultCoreVersion,
|
|
789
|
+
protocolFeeRate: t.protocolFeeRate,
|
|
790
|
+
timelockPegin: t.timelockPegin,
|
|
791
|
+
timelockAssert: t.timelockAssert,
|
|
792
|
+
timelockRefund: t.timelockRefund,
|
|
793
|
+
prepeginTxid: e.prepeginTxid,
|
|
794
|
+
prepeginMaxFee: e.prepeginMaxFee,
|
|
795
|
+
vaultProviderBtcPubkey: k(t.vaultProviderBtcPubkey),
|
|
796
|
+
vaultKeeperBtcPubkeys: t.vaultKeeperBtcPubkeys.map(k),
|
|
797
|
+
universalChallengerBtcPubkeys: t.universalChallengerBtcPubkeys.map(k),
|
|
798
|
+
maxAcceptableCommissionBps: Y(
|
|
799
|
+
t.commissionBps
|
|
800
|
+
),
|
|
801
|
+
peginAmounts: t.amounts,
|
|
802
|
+
depositorClaimValue: e.depositorClaimValue,
|
|
803
|
+
peginMaxFee: e.peginMaxFee
|
|
804
|
+
});
|
|
805
|
+
}
|
|
763
806
|
/** Build PegIn txs and batch-sign their inputs with real hashlocks. */
|
|
764
|
-
async preparePeginCommit(
|
|
807
|
+
async preparePeginCommit(e) {
|
|
765
808
|
const {
|
|
766
|
-
depositorBtcPubkeyRaw:
|
|
809
|
+
depositorBtcPubkeyRaw: t,
|
|
767
810
|
depositorBtcPubkey: o,
|
|
768
811
|
hashlocks: i,
|
|
769
812
|
authAnchorHash: n,
|
|
770
813
|
sizing: r,
|
|
771
814
|
params: a
|
|
772
|
-
} =
|
|
815
|
+
} = e, c = J.toLowerCase();
|
|
773
816
|
for (let m = 0; m < i.length; m++)
|
|
774
817
|
if (i[m].toLowerCase() === c)
|
|
775
818
|
throw new Error(
|
|
@@ -779,114 +822,108 @@ class Zs {
|
|
|
779
822
|
throw new Error(
|
|
780
823
|
"preparePeginCommit refusing to build with sizing-pass placeholder auth-anchor hash — internal substitution bug"
|
|
781
824
|
);
|
|
782
|
-
const
|
|
825
|
+
const h = k(
|
|
783
826
|
a.vaultProviderBtcPubkey
|
|
784
|
-
),
|
|
827
|
+
), d = a.vaultKeeperBtcPubkeys.map(k), g = a.universalChallengerBtcPubkeys.map(k), P = d.length, b = {
|
|
785
828
|
vaultCoreVersion: a.vaultCoreVersion,
|
|
786
829
|
depositorPubkey: o,
|
|
787
|
-
vaultProviderPubkey:
|
|
788
|
-
vaultKeeperPubkeys:
|
|
830
|
+
vaultProviderPubkey: h,
|
|
831
|
+
vaultKeeperPubkeys: d,
|
|
789
832
|
universalChallengerPubkeys: g,
|
|
790
833
|
hashlocks: i,
|
|
791
834
|
timelockRefund: a.timelockRefund,
|
|
792
835
|
pegInAmounts: a.amounts,
|
|
793
836
|
feeRate: a.protocolFeeRate,
|
|
794
837
|
minPeginFeeRate: a.minPeginFeeRate,
|
|
795
|
-
numLocalChallengers:
|
|
838
|
+
numLocalChallengers: P,
|
|
796
839
|
councilQuorum: a.councilQuorum,
|
|
797
840
|
councilSize: a.councilSize,
|
|
798
841
|
network: this.config.btcNetwork,
|
|
799
842
|
authAnchorHash: n
|
|
800
|
-
},
|
|
801
|
-
|
|
843
|
+
}, l = await fe(b);
|
|
844
|
+
if (l.depositorClaimValue !== r.depositorClaimValue || l.minPeginFee !== r.minPeginFee)
|
|
845
|
+
throw new Error(
|
|
846
|
+
`Pre-PegIn sizing/commit divergence: depositorClaimValue ${r.depositorClaimValue} -> ${l.depositorClaimValue}, minPeginFee ${r.minPeginFee} -> ${l.minPeginFee}. The provisional deposit terms validated before derivation would not match the terms sent for approval; refusing to continue.`
|
|
847
|
+
);
|
|
848
|
+
const T = Pe(this.config.btcNetwork), E = wt({
|
|
849
|
+
unfundedTxHex: l.psbtHex,
|
|
802
850
|
selectedUTXOs: r.selectedUTXOs,
|
|
803
851
|
changeAddress: a.changeAddress,
|
|
804
852
|
changeAmount: r.changeAmount,
|
|
805
|
-
network:
|
|
806
|
-
}),
|
|
807
|
-
if (
|
|
853
|
+
network: T
|
|
854
|
+
}), p = r.selectedUTXOs.reduce((m, v) => m + BigInt(v.value), 0n) - l.totalOutputValue - r.changeAmount;
|
|
855
|
+
if (p !== r.fee)
|
|
808
856
|
throw new Error(
|
|
809
|
-
`Pre-PegIn funded fee ${
|
|
857
|
+
`Pre-PegIn funded fee ${p} does not match the sizing-pass fee ${r.fee}; refusing to publish a deposit-terms fee bound the funded transaction does not pay.`
|
|
810
858
|
);
|
|
811
|
-
const
|
|
812
|
-
q(
|
|
813
|
-
),
|
|
859
|
+
const B = k(
|
|
860
|
+
q(E)
|
|
861
|
+
), S = [], f = [], w = [];
|
|
814
862
|
for (let m = 0; m < i.length; m++) {
|
|
815
|
-
const
|
|
863
|
+
const v = await tt({
|
|
816
864
|
prePeginParams: b,
|
|
817
865
|
timelockPegin: a.timelockPegin,
|
|
818
|
-
fundedPrePeginTxHex:
|
|
866
|
+
fundedPrePeginTxHex: E,
|
|
819
867
|
htlcVout: m
|
|
820
|
-
}), I = await
|
|
868
|
+
}), I = await nt({
|
|
821
869
|
vaultCoreVersion: a.vaultCoreVersion,
|
|
822
|
-
peginTxHex:
|
|
823
|
-
fundedPrePeginTxHex:
|
|
870
|
+
peginTxHex: v.txHex,
|
|
871
|
+
fundedPrePeginTxHex: E,
|
|
824
872
|
depositorPubkey: o,
|
|
825
|
-
vaultProviderPubkey:
|
|
826
|
-
vaultKeeperPubkeys:
|
|
873
|
+
vaultProviderPubkey: h,
|
|
874
|
+
vaultKeeperPubkeys: d,
|
|
827
875
|
universalChallengerPubkeys: g,
|
|
828
876
|
hashlock: i[m],
|
|
829
877
|
timelockRefund: a.timelockRefund,
|
|
830
878
|
network: this.config.btcNetwork
|
|
831
879
|
});
|
|
832
|
-
|
|
833
|
-
|
|
880
|
+
S.push(v), f.push(I.psbtHex), w.push(
|
|
881
|
+
ut(t, 1)
|
|
834
882
|
);
|
|
835
883
|
}
|
|
836
|
-
const
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
timelockPegin: a.timelockPegin,
|
|
840
|
-
timelockAssert: a.timelockAssert,
|
|
841
|
-
timelockRefund: a.timelockRefund,
|
|
842
|
-
prepeginTxid: v,
|
|
884
|
+
const u = this.buildPeginDepositTerms({
|
|
885
|
+
params: a,
|
|
886
|
+
prepeginTxid: B,
|
|
843
887
|
prepeginMaxFee: r.fee,
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
universalChallengerBtcPubkeys: g,
|
|
847
|
-
maxAcceptableCommissionBps: Y(
|
|
848
|
-
a.commissionBps
|
|
849
|
-
),
|
|
850
|
-
peginAmounts: a.amounts,
|
|
851
|
-
depositorClaimValue: d.depositorClaimValue,
|
|
852
|
-
peginMaxFee: d.minPeginFee
|
|
888
|
+
depositorClaimValue: l.depositorClaimValue,
|
|
889
|
+
peginMaxFee: l.minPeginFee
|
|
853
890
|
});
|
|
854
|
-
|
|
855
|
-
const y = await
|
|
891
|
+
F(this.config.btcWallet) && await this.config.btcWallet.approveDepositTerms(u);
|
|
892
|
+
const y = await gt(
|
|
856
893
|
this.config.btcWallet,
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
),
|
|
894
|
+
f,
|
|
895
|
+
w
|
|
896
|
+
), C = [];
|
|
860
897
|
for (let m = 0; m < y.length; m++) {
|
|
861
|
-
|
|
862
|
-
requestedPsbtHex:
|
|
898
|
+
ge({
|
|
899
|
+
requestedPsbtHex: f[m],
|
|
863
900
|
returnedPsbtHex: y[m]
|
|
864
901
|
});
|
|
865
|
-
const
|
|
902
|
+
const v = rt(
|
|
866
903
|
y[m],
|
|
867
904
|
o
|
|
868
905
|
);
|
|
869
|
-
|
|
870
|
-
requestedPsbtHex:
|
|
871
|
-
signatureHex:
|
|
906
|
+
st({
|
|
907
|
+
requestedPsbtHex: f[m],
|
|
908
|
+
signatureHex: v,
|
|
872
909
|
signerXOnlyPubkeyHex: o,
|
|
873
910
|
inputIndex: 0
|
|
874
911
|
});
|
|
875
|
-
const I =
|
|
876
|
-
|
|
912
|
+
const I = it(y[m]);
|
|
913
|
+
C.push({
|
|
877
914
|
htlcVout: m,
|
|
878
|
-
htlcValue:
|
|
915
|
+
htlcValue: l.htlcValues[m],
|
|
879
916
|
peginTxHex: I,
|
|
880
|
-
peginTxid:
|
|
881
|
-
peginInputSignature:
|
|
882
|
-
vaultScriptPubKey:
|
|
917
|
+
peginTxid: S[m].txid,
|
|
918
|
+
peginInputSignature: v,
|
|
919
|
+
vaultScriptPubKey: S[m].vaultScriptPubKey
|
|
883
920
|
});
|
|
884
921
|
}
|
|
885
922
|
return {
|
|
886
|
-
fundedPrePeginTxHex:
|
|
887
|
-
prePeginTxid:
|
|
888
|
-
perVault:
|
|
889
|
-
depositTerms:
|
|
923
|
+
fundedPrePeginTxHex: E,
|
|
924
|
+
prePeginTxid: B,
|
|
925
|
+
perVault: C,
|
|
926
|
+
depositTerms: u
|
|
890
927
|
};
|
|
891
928
|
}
|
|
892
929
|
/**
|
|
@@ -912,88 +949,88 @@ class Zs {
|
|
|
912
949
|
* @returns The broadcasted Bitcoin transaction ID
|
|
913
950
|
* @throws Error if signing or broadcasting fails
|
|
914
951
|
*/
|
|
915
|
-
async signAndBroadcast(
|
|
916
|
-
const { fundedPrePeginTxHex:
|
|
952
|
+
async signAndBroadcast(e) {
|
|
953
|
+
const { fundedPrePeginTxHex: t, depositorBtcPubkey: o } = e, i = t.startsWith("0x") ? t.slice(2) : t, n = Ae.fromHex(i);
|
|
917
954
|
if (n.ins.length === 0)
|
|
918
955
|
throw new Error("Transaction has no inputs");
|
|
919
|
-
const r = new
|
|
956
|
+
const r = new he();
|
|
920
957
|
r.setVersion(n.version), r.setLocktime(n.locktime);
|
|
921
958
|
const a = O.from(
|
|
922
959
|
$(o),
|
|
923
960
|
"hex"
|
|
924
|
-
), c = this.config.mempoolApiUrl,
|
|
925
|
-
const
|
|
926
|
-
return
|
|
927
|
-
(y) => ({ input:
|
|
961
|
+
), c = this.config.mempoolApiUrl, h = n.ins.map((f) => {
|
|
962
|
+
const w = O.from(f.hash).reverse().toString("hex"), u = f.index;
|
|
963
|
+
return _s(w, u, e.localPrevouts, c).then(
|
|
964
|
+
(y) => ({ input: f, utxoData: y, txid: w, vout: u })
|
|
928
965
|
);
|
|
929
|
-
}),
|
|
930
|
-
(
|
|
966
|
+
}), d = await Promise.all(h), g = d.reduce(
|
|
967
|
+
(f, w) => f + BigInt(w.utxoData.value),
|
|
931
968
|
0n
|
|
932
|
-
),
|
|
933
|
-
(
|
|
969
|
+
), P = n.outs.reduce(
|
|
970
|
+
(f, w) => f + BigInt(w.value),
|
|
934
971
|
0n
|
|
935
972
|
);
|
|
936
|
-
if (g <
|
|
973
|
+
if (g < P)
|
|
937
974
|
throw new Error(
|
|
938
|
-
`UTXO value mismatch: total input value (${g} sat) is less than total output value (${
|
|
975
|
+
`UTXO value mismatch: total input value (${g} sat) is less than total output value (${P} sat). This may indicate the mempool API returned manipulated UTXO data.`
|
|
939
976
|
);
|
|
940
|
-
const b = g -
|
|
941
|
-
if (b >
|
|
977
|
+
const b = g - P;
|
|
978
|
+
if (b > be)
|
|
942
979
|
throw new Error(
|
|
943
|
-
`Implied transaction fee (${b} sat) exceeds maximum reasonable fee (${
|
|
980
|
+
`Implied transaction fee (${b} sat) exceeds maximum reasonable fee (${be} sat). This may indicate manipulated UTXO data.`
|
|
944
981
|
);
|
|
945
|
-
for (const { input:
|
|
946
|
-
const
|
|
982
|
+
for (const { input: f, utxoData: w, txid: u, vout: y } of d) {
|
|
983
|
+
const C = Pt(
|
|
947
984
|
{
|
|
948
|
-
value:
|
|
949
|
-
scriptPubKey:
|
|
985
|
+
value: w.value,
|
|
986
|
+
scriptPubKey: w.scriptPubKey
|
|
950
987
|
},
|
|
951
988
|
a
|
|
952
989
|
);
|
|
953
990
|
r.addInput({
|
|
954
|
-
hash:
|
|
955
|
-
index:
|
|
956
|
-
sequence:
|
|
957
|
-
...
|
|
991
|
+
hash: f.hash,
|
|
992
|
+
index: f.index,
|
|
993
|
+
sequence: f.sequence,
|
|
994
|
+
...C
|
|
958
995
|
});
|
|
959
996
|
}
|
|
960
|
-
for (const
|
|
997
|
+
for (const f of n.outs)
|
|
961
998
|
r.addOutput({
|
|
962
|
-
script:
|
|
963
|
-
value:
|
|
999
|
+
script: f.script,
|
|
1000
|
+
value: f.value
|
|
964
1001
|
});
|
|
965
|
-
await
|
|
1002
|
+
await Nt({
|
|
966
1003
|
wallet: this.config.btcWallet,
|
|
967
|
-
depositTerms:
|
|
968
|
-
fundedPrePeginTxHex:
|
|
1004
|
+
depositTerms: e.depositTerms,
|
|
1005
|
+
fundedPrePeginTxHex: t,
|
|
969
1006
|
depositorBtcPubkey: o
|
|
970
1007
|
});
|
|
971
|
-
const
|
|
972
|
-
|
|
973
|
-
requestedPsbtHex:
|
|
974
|
-
returnedPsbtHex:
|
|
1008
|
+
const l = r.toHex(), T = await this.config.btcWallet.signPsbt(l);
|
|
1009
|
+
ge({
|
|
1010
|
+
requestedPsbtHex: l,
|
|
1011
|
+
returnedPsbtHex: T
|
|
975
1012
|
});
|
|
976
|
-
const
|
|
977
|
-
requestedPsbtHex:
|
|
978
|
-
returnedPsbtHex:
|
|
1013
|
+
const E = at({
|
|
1014
|
+
requestedPsbtHex: l,
|
|
1015
|
+
returnedPsbtHex: T
|
|
979
1016
|
});
|
|
980
|
-
if (
|
|
1017
|
+
if (F(this.config.btcWallet) && E !== r.data.inputs.length)
|
|
981
1018
|
throw new Error(
|
|
982
|
-
`Key-path verification covered ${
|
|
1019
|
+
`Key-path verification covered ${E} of ${r.data.inputs.length} Pre-PegIn inputs; an approval wallet signs every input key-path, so the unverified ones must not be broadcast.`
|
|
983
1020
|
);
|
|
984
|
-
const
|
|
1021
|
+
const p = he.fromHex(T);
|
|
985
1022
|
try {
|
|
986
|
-
|
|
987
|
-
} catch (
|
|
988
|
-
if (!
|
|
989
|
-
(
|
|
1023
|
+
p.finalizeAllInputs();
|
|
1024
|
+
} catch (f) {
|
|
1025
|
+
if (!p.data.inputs.every(
|
|
1026
|
+
(u) => u.finalScriptWitness || u.finalScriptSig
|
|
990
1027
|
))
|
|
991
1028
|
throw new Error(
|
|
992
|
-
`PSBT finalization failed and wallet did not auto-finalize: ${
|
|
1029
|
+
`PSBT finalization failed and wallet did not auto-finalize: ${f}`
|
|
993
1030
|
);
|
|
994
1031
|
}
|
|
995
|
-
const
|
|
996
|
-
return await
|
|
1032
|
+
const B = p.extractTransaction().toHex();
|
|
1033
|
+
return await vt(B, c);
|
|
997
1034
|
}
|
|
998
1035
|
/**
|
|
999
1036
|
* Registers a peg-in on Ethereum by calling the BTCVaultRegistry contract.
|
|
@@ -1019,41 +1056,41 @@ class Zs {
|
|
|
1019
1056
|
* @throws Error if contract simulation fails (e.g., invalid signature,
|
|
1020
1057
|
* unauthorized)
|
|
1021
1058
|
*/
|
|
1022
|
-
async registerPeginOnChain(
|
|
1059
|
+
async registerPeginOnChain(e) {
|
|
1023
1060
|
const {
|
|
1024
|
-
unsignedPrePeginTx:
|
|
1061
|
+
unsignedPrePeginTx: t,
|
|
1025
1062
|
depositorSignedPeginTx: o,
|
|
1026
1063
|
vaultProvider: i,
|
|
1027
1064
|
hashlock: n,
|
|
1028
1065
|
htlcVout: r,
|
|
1029
1066
|
depositorPayoutBtcAddress: a,
|
|
1030
1067
|
depositorWotsPkHash: c,
|
|
1031
|
-
popSignature:
|
|
1032
|
-
} =
|
|
1068
|
+
popSignature: h
|
|
1069
|
+
} = e;
|
|
1033
1070
|
if (!this.config.ethWallet.account)
|
|
1034
1071
|
throw new Error("Ethereum wallet account not found");
|
|
1035
|
-
const
|
|
1036
|
-
if (!
|
|
1072
|
+
const d = this.config.ethWallet.account.address;
|
|
1073
|
+
if (!de(h.depositorEthAddress, d))
|
|
1037
1074
|
throw new Error(
|
|
1038
|
-
`Proof of possession was signed for ${
|
|
1075
|
+
`Proof of possession was signed for ${h.depositorEthAddress} but the Ethereum wallet is currently connected to ${d}. Reconnect the original account or call signProofOfPossession() again.`
|
|
1039
1076
|
);
|
|
1040
|
-
const g = await this.assertPopMatchesBtcWallet(
|
|
1041
|
-
|
|
1042
|
-
),
|
|
1077
|
+
const g = await this.assertPopMatchesBtcWallet(h), P = h.btcPopSignature, b = A(
|
|
1078
|
+
h.depositorBtcPubkey
|
|
1079
|
+
), l = A(t), T = A(o), E = a ?? await this.config.btcWallet.getAddress(), p = this.resolvePayoutScriptPubKey(
|
|
1043
1080
|
g,
|
|
1044
|
-
|
|
1045
|
-
),
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
),
|
|
1049
|
-
if (await this.checkVaultExists(
|
|
1081
|
+
E
|
|
1082
|
+
), B = q(T), S = await pe(
|
|
1083
|
+
k(B),
|
|
1084
|
+
k(d)
|
|
1085
|
+
), f = A(S);
|
|
1086
|
+
if (await this.checkVaultExists(f))
|
|
1050
1087
|
throw new Error(
|
|
1051
|
-
`Vault already exists (ID: ${
|
|
1088
|
+
`Vault already exists (ID: ${f}, peginTxHash: ${B}). 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.`
|
|
1052
1089
|
);
|
|
1053
|
-
const
|
|
1090
|
+
const u = this.config.publicClient;
|
|
1054
1091
|
let y;
|
|
1055
1092
|
try {
|
|
1056
|
-
y = await
|
|
1093
|
+
y = await u.readContract({
|
|
1057
1094
|
address: this.config.vaultContracts.btcVaultRegistry,
|
|
1058
1095
|
abi: H,
|
|
1059
1096
|
functionName: "getPegInFee",
|
|
@@ -1065,29 +1102,29 @@ class Zs {
|
|
|
1065
1102
|
{ cause: V }
|
|
1066
1103
|
);
|
|
1067
1104
|
}
|
|
1068
|
-
const
|
|
1105
|
+
const C = await this.resolveMaxAcceptableCommissionBps(
|
|
1069
1106
|
i,
|
|
1070
|
-
|
|
1071
|
-
), m =
|
|
1107
|
+
e.quotedCommissionBps
|
|
1108
|
+
), m = ee({
|
|
1072
1109
|
abi: H,
|
|
1073
1110
|
functionName: "submitPeginRequest",
|
|
1074
1111
|
args: [
|
|
1075
|
-
h,
|
|
1076
|
-
b,
|
|
1077
|
-
w,
|
|
1078
1112
|
d,
|
|
1079
|
-
|
|
1113
|
+
b,
|
|
1114
|
+
P,
|
|
1115
|
+
l,
|
|
1116
|
+
T,
|
|
1080
1117
|
i,
|
|
1081
|
-
|
|
1118
|
+
C,
|
|
1082
1119
|
n,
|
|
1083
1120
|
r,
|
|
1084
|
-
|
|
1121
|
+
p,
|
|
1085
1122
|
c
|
|
1086
1123
|
]
|
|
1087
1124
|
});
|
|
1088
|
-
let
|
|
1125
|
+
let v;
|
|
1089
1126
|
try {
|
|
1090
|
-
|
|
1127
|
+
v = await u.estimateGas({
|
|
1091
1128
|
to: this.config.vaultContracts.btcVaultRegistry,
|
|
1092
1129
|
data: m,
|
|
1093
1130
|
value: y,
|
|
@@ -1104,16 +1141,16 @@ class Zs {
|
|
|
1104
1141
|
value: y,
|
|
1105
1142
|
account: this.config.ethWallet.account,
|
|
1106
1143
|
chain: this.config.ethChain,
|
|
1107
|
-
gas:
|
|
1144
|
+
gas: v
|
|
1108
1145
|
});
|
|
1109
1146
|
} catch (V) {
|
|
1110
1147
|
R(V);
|
|
1111
1148
|
}
|
|
1112
|
-
const G = await
|
|
1113
|
-
publicClient:
|
|
1149
|
+
const G = await we({
|
|
1150
|
+
publicClient: u,
|
|
1114
1151
|
walletAddress: this.config.ethWallet.account.address,
|
|
1115
1152
|
hash: I,
|
|
1116
|
-
timeout:
|
|
1153
|
+
timeout: Be
|
|
1117
1154
|
});
|
|
1118
1155
|
return G.status === "reverted" && R(
|
|
1119
1156
|
new Error(
|
|
@@ -1121,8 +1158,8 @@ class Zs {
|
|
|
1121
1158
|
)
|
|
1122
1159
|
), {
|
|
1123
1160
|
ethTxHash: G.transactionHash,
|
|
1124
|
-
vaultId:
|
|
1125
|
-
peginTxHash:
|
|
1161
|
+
vaultId: f,
|
|
1162
|
+
peginTxHash: B
|
|
1126
1163
|
};
|
|
1127
1164
|
}
|
|
1128
1165
|
/**
|
|
@@ -1135,142 +1172,142 @@ class Zs {
|
|
|
1135
1172
|
* @param params - Batch registration parameters
|
|
1136
1173
|
* @returns Batch result with per-vault IDs and single ETH tx hash
|
|
1137
1174
|
*/
|
|
1138
|
-
async registerPeginBatchOnChain(
|
|
1139
|
-
const { vaultProvider:
|
|
1175
|
+
async registerPeginBatchOnChain(e) {
|
|
1176
|
+
const { vaultProvider: t, unsignedPrePeginTx: o, requests: i, popSignature: n } = e;
|
|
1140
1177
|
if (i.length === 0)
|
|
1141
1178
|
throw new Error("Batch pegin requires at least one request");
|
|
1142
1179
|
if (!this.config.ethWallet.account)
|
|
1143
1180
|
throw new Error("Ethereum wallet account not found");
|
|
1144
1181
|
const r = this.config.ethWallet.account.address;
|
|
1145
|
-
if (!
|
|
1182
|
+
if (!de(n.depositorEthAddress, r))
|
|
1146
1183
|
throw new Error(
|
|
1147
1184
|
`Proof of possession was signed for ${n.depositorEthAddress} but the Ethereum wallet is currently connected to ${r}. Reconnect the original account or call signProofOfPossession() again.`
|
|
1148
1185
|
);
|
|
1149
|
-
const a = await this.assertPopMatchesBtcWallet(n), c = n.btcPopSignature,
|
|
1150
|
-
(
|
|
1186
|
+
const a = await this.assertPopMatchesBtcWallet(n), c = n.btcPopSignature, h = i.map(
|
|
1187
|
+
(u) => this.resolvePayoutScriptPubKey(
|
|
1151
1188
|
a,
|
|
1152
|
-
|
|
1189
|
+
u.depositorPayoutBtcAddress
|
|
1153
1190
|
)
|
|
1154
|
-
),
|
|
1155
|
-
for (const
|
|
1156
|
-
const y =
|
|
1157
|
-
|
|
1158
|
-
),
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
),
|
|
1162
|
-
if (await this.checkVaultExists(
|
|
1191
|
+
), d = [];
|
|
1192
|
+
for (const u of i) {
|
|
1193
|
+
const y = A(
|
|
1194
|
+
u.depositorSignedPeginTx
|
|
1195
|
+
), C = q(y), m = await pe(
|
|
1196
|
+
k(C),
|
|
1197
|
+
k(r)
|
|
1198
|
+
), v = A(m);
|
|
1199
|
+
if (await this.checkVaultExists(v))
|
|
1163
1200
|
throw new Error(
|
|
1164
|
-
`Vault already exists (ID: ${
|
|
1201
|
+
`Vault already exists (ID: ${v}, peginTxHash: ${C}). To create a new vault, use different UTXOs or a different amount.`
|
|
1165
1202
|
);
|
|
1166
|
-
|
|
1203
|
+
d.push({ vaultId: v, peginTxHash: C });
|
|
1167
1204
|
}
|
|
1168
1205
|
const g = this.config.publicClient;
|
|
1169
|
-
let
|
|
1206
|
+
let P;
|
|
1170
1207
|
try {
|
|
1171
|
-
|
|
1208
|
+
P = await g.readContract({
|
|
1172
1209
|
address: this.config.vaultContracts.btcVaultRegistry,
|
|
1173
1210
|
abi: H,
|
|
1174
1211
|
functionName: "getPegInFee",
|
|
1175
|
-
args: [
|
|
1212
|
+
args: [t]
|
|
1176
1213
|
});
|
|
1177
|
-
} catch (
|
|
1214
|
+
} catch (u) {
|
|
1178
1215
|
throw new Error(
|
|
1179
1216
|
"Failed to query pegin fee from the contract. Please check your network connection and that the contract address is correct.",
|
|
1180
|
-
{ cause:
|
|
1217
|
+
{ cause: u }
|
|
1181
1218
|
);
|
|
1182
1219
|
}
|
|
1183
|
-
const b =
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
),
|
|
1220
|
+
const b = P * BigInt(i.length), l = await this.resolveMaxAcceptableCommissionBps(
|
|
1221
|
+
t,
|
|
1222
|
+
e.quotedCommissionBps
|
|
1223
|
+
), T = A(
|
|
1187
1224
|
n.depositorBtcPubkey
|
|
1188
|
-
),
|
|
1189
|
-
depositorBtcPubKey:
|
|
1225
|
+
), E = A(o), p = i.map((u, y) => ({
|
|
1226
|
+
depositorBtcPubKey: T,
|
|
1190
1227
|
btcPopSignature: c,
|
|
1191
|
-
unsignedPrePeginTx:
|
|
1192
|
-
depositorSignedPeginTx:
|
|
1193
|
-
|
|
1228
|
+
unsignedPrePeginTx: E,
|
|
1229
|
+
depositorSignedPeginTx: A(
|
|
1230
|
+
u.depositorSignedPeginTx
|
|
1194
1231
|
),
|
|
1195
|
-
hashlock:
|
|
1196
|
-
htlcVout:
|
|
1197
|
-
referralCode:
|
|
1198
|
-
depositorPayoutBtcAddress:
|
|
1199
|
-
depositorWotsPkHash:
|
|
1200
|
-
})),
|
|
1232
|
+
hashlock: u.hashlock,
|
|
1233
|
+
htlcVout: u.htlcVout,
|
|
1234
|
+
referralCode: Ke,
|
|
1235
|
+
depositorPayoutBtcAddress: h[y],
|
|
1236
|
+
depositorWotsPkHash: u.depositorWotsPkHash
|
|
1237
|
+
})), B = ee({
|
|
1201
1238
|
abi: H,
|
|
1202
1239
|
functionName: "submitPeginRequestBatch",
|
|
1203
1240
|
args: [
|
|
1204
1241
|
r,
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1242
|
+
t,
|
|
1243
|
+
l,
|
|
1244
|
+
p
|
|
1208
1245
|
]
|
|
1209
1246
|
});
|
|
1210
|
-
let
|
|
1247
|
+
let S;
|
|
1211
1248
|
try {
|
|
1212
|
-
|
|
1249
|
+
S = await g.estimateGas({
|
|
1213
1250
|
to: this.config.vaultContracts.btcVaultRegistry,
|
|
1214
|
-
data:
|
|
1251
|
+
data: B,
|
|
1215
1252
|
value: b,
|
|
1216
1253
|
account: this.config.ethWallet.account.address
|
|
1217
1254
|
});
|
|
1218
|
-
} catch (
|
|
1219
|
-
R(
|
|
1255
|
+
} catch (u) {
|
|
1256
|
+
R(u);
|
|
1220
1257
|
}
|
|
1221
|
-
let
|
|
1258
|
+
let f;
|
|
1222
1259
|
try {
|
|
1223
|
-
|
|
1260
|
+
f = await this.config.ethWallet.sendTransaction({
|
|
1224
1261
|
to: this.config.vaultContracts.btcVaultRegistry,
|
|
1225
|
-
data:
|
|
1262
|
+
data: B,
|
|
1226
1263
|
value: b,
|
|
1227
1264
|
account: this.config.ethWallet.account,
|
|
1228
1265
|
chain: this.config.ethChain,
|
|
1229
|
-
gas:
|
|
1266
|
+
gas: S
|
|
1230
1267
|
});
|
|
1231
|
-
} catch (
|
|
1232
|
-
R(
|
|
1268
|
+
} catch (u) {
|
|
1269
|
+
R(u);
|
|
1233
1270
|
}
|
|
1234
|
-
const
|
|
1271
|
+
const w = await we({
|
|
1235
1272
|
publicClient: g,
|
|
1236
1273
|
walletAddress: this.config.ethWallet.account.address,
|
|
1237
|
-
hash:
|
|
1238
|
-
timeout:
|
|
1274
|
+
hash: f,
|
|
1275
|
+
timeout: Be
|
|
1239
1276
|
});
|
|
1240
|
-
return
|
|
1277
|
+
return w.status === "reverted" && R(
|
|
1241
1278
|
new Error(
|
|
1242
|
-
`Batch transaction reverted. Hash: ${
|
|
1279
|
+
`Batch transaction reverted. Hash: ${w.transactionHash}. Check the transaction on block explorer for details.`
|
|
1243
1280
|
)
|
|
1244
1281
|
), {
|
|
1245
|
-
ethTxHash:
|
|
1246
|
-
vaults:
|
|
1282
|
+
ethTxHash: w.transactionHash,
|
|
1283
|
+
vaults: d
|
|
1247
1284
|
};
|
|
1248
1285
|
}
|
|
1249
1286
|
// Anchor to quoted+headroom when supplied (refuse if chain drifted past it);
|
|
1250
1287
|
// otherwise fall back to chain-current+headroom — see #1691.
|
|
1251
|
-
async resolveMaxAcceptableCommissionBps(
|
|
1252
|
-
if (
|
|
1288
|
+
async resolveMaxAcceptableCommissionBps(e, t) {
|
|
1289
|
+
if (t === void 0 && F(this.config.btcWallet))
|
|
1253
1290
|
throw new Error(
|
|
1254
1291
|
"quotedCommissionBps is required when the wallet approved deposit terms: the registration ceiling must anchor to the approved quote."
|
|
1255
1292
|
);
|
|
1256
1293
|
let o;
|
|
1257
1294
|
try {
|
|
1258
|
-
o = await new
|
|
1295
|
+
o = await new Bt(
|
|
1259
1296
|
this.config.publicClient,
|
|
1260
1297
|
this.config.vaultContracts.btcVaultRegistry
|
|
1261
|
-
).getVaultProviderCommission(
|
|
1298
|
+
).getVaultProviderCommission(e);
|
|
1262
1299
|
} catch (i) {
|
|
1263
1300
|
throw new Error(
|
|
1264
1301
|
"Failed to query vault provider commission from the contract. Please check your network connection and that the contract address is correct.",
|
|
1265
1302
|
{ cause: i }
|
|
1266
1303
|
);
|
|
1267
1304
|
}
|
|
1268
|
-
if (
|
|
1269
|
-
if (o >
|
|
1305
|
+
if (t !== void 0) {
|
|
1306
|
+
if (o > t + oe)
|
|
1270
1307
|
throw new Error(
|
|
1271
|
-
`Vault provider commission changed since quote: quoted ${
|
|
1308
|
+
`Vault provider commission changed since quote: quoted ${t} bps, chain currently reports ${o} bps (allowed drift ${oe} bps). Please refresh to see the new commission and try again.`
|
|
1272
1309
|
);
|
|
1273
|
-
return Y(
|
|
1310
|
+
return Y(t);
|
|
1274
1311
|
}
|
|
1275
1312
|
return Y(o);
|
|
1276
1313
|
}
|
|
@@ -1287,13 +1324,13 @@ class Zs {
|
|
|
1287
1324
|
* @returns True if vault exists, false otherwise
|
|
1288
1325
|
* @throws If the underlying RPC read fails
|
|
1289
1326
|
*/
|
|
1290
|
-
async checkVaultExists(
|
|
1327
|
+
async checkVaultExists(e) {
|
|
1291
1328
|
return (await this.config.publicClient.readContract({
|
|
1292
1329
|
address: this.config.vaultContracts.btcVaultRegistry,
|
|
1293
1330
|
abi: H,
|
|
1294
1331
|
functionName: "getBtcVaultBasicInfo",
|
|
1295
|
-
args: [
|
|
1296
|
-
})).depositor !==
|
|
1332
|
+
args: [e]
|
|
1333
|
+
})).depositor !== Qe;
|
|
1297
1334
|
}
|
|
1298
1335
|
/**
|
|
1299
1336
|
* Resolve the BTC scriptPubKey to register as the depositor's payout sink.
|
|
@@ -1311,23 +1348,23 @@ class Zs {
|
|
|
1311
1348
|
* state-race or stale FE state that lets a non-wallet address reach the
|
|
1312
1349
|
* on-chain payout-script registration.
|
|
1313
1350
|
*/
|
|
1314
|
-
resolvePayoutScriptPubKey(
|
|
1315
|
-
if (!
|
|
1316
|
-
e,
|
|
1351
|
+
resolvePayoutScriptPubKey(e, t) {
|
|
1352
|
+
if (!me(
|
|
1317
1353
|
t,
|
|
1354
|
+
e,
|
|
1318
1355
|
this.config.btcNetwork
|
|
1319
1356
|
))
|
|
1320
|
-
throw
|
|
1321
|
-
`BTC payout address "${
|
|
1357
|
+
throw k(e).length === lt && Bs(t, this.config.btcNetwork) ? new Error(
|
|
1358
|
+
`BTC payout address "${t}" is a P2WPKH (Native SegWit) address, but the connected wallet only exposes an x-only public key. P2WPKH validation requires a compressed key with known y-parity. Use a P2TR (Taproot) payout address instead.`
|
|
1322
1359
|
) : new Error(
|
|
1323
|
-
`BTC payout address "${
|
|
1360
|
+
`BTC payout address "${t}" is not derived from the connected wallet's public key. The payout sink must be controlled by the same key that signs the pegin; refusing to register a mismatched address.`
|
|
1324
1361
|
);
|
|
1325
|
-
const o =
|
|
1362
|
+
const o = Pe(this.config.btcNetwork);
|
|
1326
1363
|
try {
|
|
1327
|
-
return `0x${
|
|
1364
|
+
return `0x${Ce.address.toOutputScript(t, o).toString("hex")}`;
|
|
1328
1365
|
} catch {
|
|
1329
1366
|
throw new Error(
|
|
1330
|
-
`Invalid BTC payout address: "${
|
|
1367
|
+
`Invalid BTC payout address: "${t}". Please provide a valid Bitcoin address for the ${this.config.btcNetwork} network.`
|
|
1331
1368
|
);
|
|
1332
1369
|
}
|
|
1333
1370
|
}
|
|
@@ -1347,17 +1384,17 @@ class Zs {
|
|
|
1347
1384
|
async signProofOfPossession() {
|
|
1348
1385
|
if (!this.config.ethWallet.account)
|
|
1349
1386
|
throw new Error("Ethereum wallet account not found");
|
|
1350
|
-
const
|
|
1387
|
+
const e = this.config.ethWallet.account.address, t = $(
|
|
1351
1388
|
await this.config.btcWallet.getPublicKeyHex()
|
|
1352
|
-
), o = this.config.vaultContracts.btcVaultRegistry, i = `${
|
|
1389
|
+
), o = this.config.vaultContracts.btcVaultRegistry, i = `${e.toLowerCase()}:${this.config.ethChain.id}:pegin:${o.toLowerCase()}`, n = await this.config.btcWallet.signMessage(
|
|
1353
1390
|
i,
|
|
1354
1391
|
"bip322-simple"
|
|
1355
|
-
), r =
|
|
1392
|
+
), r = Dt(n);
|
|
1356
1393
|
return Ts(
|
|
1357
1394
|
new TextEncoder().encode(i),
|
|
1358
|
-
|
|
1395
|
+
t,
|
|
1359
1396
|
r
|
|
1360
|
-
), { btcPopSignature: r, depositorEthAddress:
|
|
1397
|
+
), { btcPopSignature: r, depositorEthAddress: e, depositorBtcPubkey: t };
|
|
1361
1398
|
}
|
|
1362
1399
|
/**
|
|
1363
1400
|
* Confirm the connected BTC wallet still matches the PoP it produced, and
|
|
@@ -1367,13 +1404,13 @@ class Zs {
|
|
|
1367
1404
|
* a parity-bearing compressed key — an x-only form would let an attacker
|
|
1368
1405
|
* substitute the opposite-parity P2WPKH address.
|
|
1369
1406
|
*/
|
|
1370
|
-
async assertPopMatchesBtcWallet(
|
|
1371
|
-
const
|
|
1407
|
+
async assertPopMatchesBtcWallet(e) {
|
|
1408
|
+
const t = await this.config.btcWallet.getPublicKeyHex(), o = $(t), i = $(e.depositorBtcPubkey);
|
|
1372
1409
|
if (o !== i)
|
|
1373
1410
|
throw new Error(
|
|
1374
1411
|
`Proof of possession was signed with BTC pubkey ${i} but the BTC wallet is currently connected to ${o}. Reconnect the original wallet or call signProofOfPossession() again.`
|
|
1375
1412
|
);
|
|
1376
|
-
return
|
|
1413
|
+
return t;
|
|
1377
1414
|
}
|
|
1378
1415
|
/**
|
|
1379
1416
|
* Gets the configured Bitcoin network.
|
|
@@ -1392,32 +1429,32 @@ class Zs {
|
|
|
1392
1429
|
return this.config.vaultContracts.btcVaultRegistry;
|
|
1393
1430
|
}
|
|
1394
1431
|
}
|
|
1395
|
-
const
|
|
1396
|
-
function
|
|
1397
|
-
const
|
|
1432
|
+
const Ss = 80, Cs = 250, As = 300, Is = 22, Xe = "ab";
|
|
1433
|
+
function Hs(s, e) {
|
|
1434
|
+
const t = Xe.repeat(As), o = k(s).toLowerCase(), i = e.toString(16).padStart(8, "0"), n = `${o}${i}`, r = t.slice(n.length);
|
|
1398
1435
|
return `0x${n}${r}`;
|
|
1399
1436
|
}
|
|
1400
|
-
function
|
|
1401
|
-
const
|
|
1437
|
+
function Rs(s, e) {
|
|
1438
|
+
const t = (o) => `0x${Xe.repeat(o)}`;
|
|
1402
1439
|
return {
|
|
1403
|
-
depositorBtcPubKey:
|
|
1404
|
-
btcPopSignature:
|
|
1405
|
-
unsignedPrePeginTx:
|
|
1406
|
-
depositorSignedPeginTx:
|
|
1440
|
+
depositorBtcPubKey: t(32),
|
|
1441
|
+
btcPopSignature: t(Ss),
|
|
1442
|
+
unsignedPrePeginTx: t(Cs),
|
|
1443
|
+
depositorSignedPeginTx: Hs(
|
|
1407
1444
|
s,
|
|
1408
|
-
|
|
1445
|
+
e
|
|
1409
1446
|
),
|
|
1410
|
-
hashlock:
|
|
1411
|
-
htlcVout:
|
|
1412
|
-
referralCode:
|
|
1413
|
-
depositorPayoutBtcAddress:
|
|
1414
|
-
depositorWotsPkHash:
|
|
1447
|
+
hashlock: t(32),
|
|
1448
|
+
htlcVout: e,
|
|
1449
|
+
referralCode: Ke,
|
|
1450
|
+
depositorPayoutBtcAddress: t(Is),
|
|
1451
|
+
depositorWotsPkHash: t(32)
|
|
1415
1452
|
};
|
|
1416
1453
|
}
|
|
1417
|
-
async function
|
|
1454
|
+
async function eo(s) {
|
|
1418
1455
|
const {
|
|
1419
|
-
publicClient:
|
|
1420
|
-
btcVaultRegistry:
|
|
1456
|
+
publicClient: e,
|
|
1457
|
+
btcVaultRegistry: t,
|
|
1421
1458
|
depositorEthAddress: o,
|
|
1422
1459
|
vaultProvider: i,
|
|
1423
1460
|
batchSize: n
|
|
@@ -1426,41 +1463,41 @@ async function Js(s) {
|
|
|
1426
1463
|
throw new Error(
|
|
1427
1464
|
`estimateSubmitPeginRequestBatchGas requires batchSize >= 1 (received ${n})`
|
|
1428
1465
|
);
|
|
1429
|
-
const a = await
|
|
1430
|
-
address:
|
|
1466
|
+
const a = await e.readContract({
|
|
1467
|
+
address: t,
|
|
1431
1468
|
abi: H,
|
|
1432
1469
|
functionName: "getPegInFee",
|
|
1433
1470
|
args: [i]
|
|
1434
1471
|
}) * BigInt(n), c = Array.from(
|
|
1435
1472
|
{ length: n },
|
|
1436
|
-
(
|
|
1437
|
-
),
|
|
1473
|
+
(d, g) => Rs(o, g)
|
|
1474
|
+
), h = ee({
|
|
1438
1475
|
abi: H,
|
|
1439
1476
|
functionName: "submitPeginRequestBatch",
|
|
1440
1477
|
args: [
|
|
1441
1478
|
o,
|
|
1442
1479
|
i,
|
|
1443
|
-
|
|
1480
|
+
He,
|
|
1444
1481
|
c
|
|
1445
1482
|
]
|
|
1446
1483
|
});
|
|
1447
|
-
return
|
|
1448
|
-
to:
|
|
1449
|
-
data:
|
|
1484
|
+
return e.estimateGas({
|
|
1485
|
+
to: t,
|
|
1486
|
+
data: h,
|
|
1450
1487
|
value: a,
|
|
1451
1488
|
account: o
|
|
1452
1489
|
});
|
|
1453
1490
|
}
|
|
1454
1491
|
export {
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1492
|
+
oe as C,
|
|
1493
|
+
He as M,
|
|
1494
|
+
Js as P,
|
|
1458
1495
|
Y as a,
|
|
1459
|
-
|
|
1460
|
-
|
|
1496
|
+
Vt as b,
|
|
1497
|
+
ps as c,
|
|
1461
1498
|
ds as d,
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1499
|
+
eo as e,
|
|
1500
|
+
Nt as f,
|
|
1501
|
+
fs as g
|
|
1465
1502
|
};
|
|
1466
|
-
//# sourceMappingURL=PeginManager-
|
|
1503
|
+
//# sourceMappingURL=PeginManager-DSFecw-w.js.map
|