@babylonlabs-io/ts-sdk 0.3.0 → 0.4.1-rc.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/{PayoutManager-BkOfdb2_.js → PayoutManager-B8vLG1dE.js} +414 -373
- package/dist/PayoutManager-B8vLG1dE.js.map +1 -0
- package/dist/PayoutManager-Shw7TY5P.cjs +2 -0
- package/dist/PayoutManager-Shw7TY5P.cjs.map +1 -0
- package/dist/challengeAssert-ClJYoKxJ.cjs +2 -0
- package/dist/challengeAssert-ClJYoKxJ.cjs.map +1 -0
- package/dist/challengeAssert-ZXE00zkT.js +617 -0
- package/dist/challengeAssert-ZXE00zkT.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -63
- package/dist/index.js.map +1 -1
- package/dist/tbv/core/contracts/abis/BTCVaultsManager.abi.d.ts +50 -4
- package/dist/tbv/core/contracts/abis/BTCVaultsManager.abi.d.ts.map +1 -1
- package/dist/tbv/core/index.cjs +1 -1
- package/dist/tbv/core/index.js +65 -60
- package/dist/tbv/core/managers/PeginManager.d.ts +92 -49
- package/dist/tbv/core/managers/PeginManager.d.ts.map +1 -1
- package/dist/tbv/core/managers/__tests__/PeginManager.test.d.ts +1 -1
- package/dist/tbv/core/managers/index.d.ts +4 -4
- package/dist/tbv/core/managers/index.d.ts.map +1 -1
- package/dist/tbv/core/primitives/__tests__/challengers.test.d.ts +2 -0
- package/dist/tbv/core/primitives/__tests__/challengers.test.d.ts.map +1 -0
- package/dist/tbv/core/primitives/challengers.d.ts +23 -0
- package/dist/tbv/core/primitives/challengers.d.ts.map +1 -0
- package/dist/tbv/core/primitives/index.cjs +1 -1
- package/dist/tbv/core/primitives/index.d.ts +9 -3
- package/dist/tbv/core/primitives/index.d.ts.map +1 -1
- package/dist/tbv/core/primitives/index.js +23 -18
- package/dist/tbv/core/primitives/psbt/__tests__/pegin.test.d.ts +1 -1
- package/dist/tbv/core/primitives/psbt/index.d.ts +8 -3
- package/dist/tbv/core/primitives/psbt/index.d.ts.map +1 -1
- package/dist/tbv/core/primitives/psbt/pegin.d.ts +76 -59
- package/dist/tbv/core/primitives/psbt/pegin.d.ts.map +1 -1
- package/dist/tbv/core/primitives/psbt/peginInput.d.ts +69 -0
- package/dist/tbv/core/primitives/psbt/peginInput.d.ts.map +1 -0
- package/dist/tbv/core/primitives/utils/bitcoin.d.ts +11 -0
- package/dist/tbv/core/primitives/utils/bitcoin.d.ts.map +1 -1
- package/dist/tbv/core/primitives/utils/index.d.ts +1 -1
- package/dist/tbv/core/primitives/utils/index.d.ts.map +1 -1
- package/dist/tbv/index.cjs +1 -1
- package/dist/tbv/index.js +65 -60
- package/dist/tbv/integrations/aave/clients/abis/AaveIntegrationController.abi.json.d.ts +16 -1
- package/dist/tbv/integrations/aave/index.cjs +1 -1
- package/dist/tbv/integrations/aave/index.cjs.map +1 -1
- package/dist/tbv/integrations/aave/index.js +3 -3
- package/package.json +20 -20
- package/LICENSE +0 -169
- package/dist/PayoutManager-BkOfdb2_.js.map +0 -1
- package/dist/PayoutManager-DZ7EIcAJ.cjs +0 -2
- package/dist/PayoutManager-DZ7EIcAJ.cjs.map +0 -1
- package/dist/challengeAssert-34HqeVFH.cjs +0 -2
- package/dist/challengeAssert-34HqeVFH.cjs.map +0 -1
- package/dist/challengeAssert-DVErOd8l.js +0 -423
- package/dist/challengeAssert-DVErOd8l.js.map +0 -1
|
@@ -1,196 +1,148 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import * as
|
|
5
|
-
import { script as
|
|
6
|
-
import { Buffer as
|
|
7
|
-
import {
|
|
8
|
-
import { createPublicClient as
|
|
1
|
+
var q = Object.defineProperty;
|
|
2
|
+
var _ = (n, t, e) => t in n ? q(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
|
|
3
|
+
var H = (n, t, e) => _(n, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import * as L from "bitcoinjs-lib";
|
|
5
|
+
import { script as j, Transaction as S, address as J, Psbt as C } from "bitcoinjs-lib";
|
|
6
|
+
import { Buffer as f } from "buffer";
|
|
7
|
+
import { P as Z, w as G, D, M as W, B as Q, T as Y, z as U, s as k, b as tt, y as et, a as nt, d as st, e as rt, q as I, o as at, v as V, f as M, g as R } from "./challengeAssert-ZXE00zkT.js";
|
|
8
|
+
import { createPublicClient as K, http as N, encodeFunctionData as ot, zeroAddress as it } from "viem";
|
|
9
9
|
import "@babylonlabs-io/babylon-tbv-rust-wasm";
|
|
10
|
-
|
|
11
|
-
const Z = 58, V = 43, G = 11, N = 546, H = BigInt(N), Q = 30, tt = 2, mt = 1.1;
|
|
12
|
-
function et(n) {
|
|
13
|
-
return n <= tt ? Q : 0;
|
|
14
|
-
}
|
|
15
|
-
const wt = 5;
|
|
16
|
-
function nt(n, t, e) {
|
|
10
|
+
function ct(n, t, e) {
|
|
17
11
|
if (n.length === 0)
|
|
18
12
|
throw new Error("Insufficient funds: no UTXOs available");
|
|
19
|
-
const s = n.filter((
|
|
20
|
-
const
|
|
21
|
-
return !!
|
|
13
|
+
const s = n.filter((a) => {
|
|
14
|
+
const u = f.from(a.scriptPubKey, "hex");
|
|
15
|
+
return !!j.decompile(u);
|
|
22
16
|
});
|
|
23
17
|
if (s.length === 0)
|
|
24
18
|
throw new Error(
|
|
25
19
|
"Insufficient funds: no valid UTXOs available (all have invalid scripts)"
|
|
26
20
|
);
|
|
27
|
-
const
|
|
28
|
-
let
|
|
29
|
-
for (const
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
if (i = BigInt(Math.ceil(
|
|
33
|
-
const
|
|
34
|
-
Math.ceil(
|
|
21
|
+
const o = [...s].sort((a, u) => u.value - a.value), r = [];
|
|
22
|
+
let c = 0n, i = 0n;
|
|
23
|
+
for (const a of o) {
|
|
24
|
+
r.push(a), c += BigInt(a.value);
|
|
25
|
+
const u = r.length * Z, l = 2 * W, p = u + l + Y;
|
|
26
|
+
if (i = BigInt(Math.ceil(p * e)) + BigInt(G(e)), c - t - i > D) {
|
|
27
|
+
const h = BigInt(
|
|
28
|
+
Math.ceil(W * e)
|
|
35
29
|
);
|
|
36
|
-
i +=
|
|
30
|
+
i += h;
|
|
37
31
|
}
|
|
38
|
-
if (
|
|
39
|
-
const
|
|
32
|
+
if (c >= t + i) {
|
|
33
|
+
const h = c - t - i;
|
|
40
34
|
return {
|
|
41
|
-
selectedUTXOs:
|
|
42
|
-
totalValue:
|
|
35
|
+
selectedUTXOs: r,
|
|
36
|
+
totalValue: c,
|
|
43
37
|
fee: i,
|
|
44
|
-
changeAmount:
|
|
38
|
+
changeAmount: h
|
|
45
39
|
};
|
|
46
40
|
}
|
|
47
41
|
}
|
|
48
42
|
throw new Error(
|
|
49
|
-
`Insufficient funds: need ${t + i} sats (${t} pegin + ${i} fee), have ${
|
|
43
|
+
`Insufficient funds: need ${t + i} sats (${t} pegin + ${i} fee), have ${c} sats`
|
|
50
44
|
);
|
|
51
45
|
}
|
|
52
|
-
function
|
|
53
|
-
return n >
|
|
46
|
+
function wt(n) {
|
|
47
|
+
return n > D;
|
|
54
48
|
}
|
|
55
|
-
function
|
|
56
|
-
return
|
|
49
|
+
function Tt() {
|
|
50
|
+
return Q;
|
|
57
51
|
}
|
|
58
|
-
function
|
|
59
|
-
const e = n.substring(8, 12) === "0001" ? 12 : 8, s = parseInt(
|
|
60
|
-
n.substring(e, e + 2),
|
|
61
|
-
16
|
|
62
|
-
), a = parseInt(
|
|
63
|
-
n.substring(e + 2, e + 4),
|
|
64
|
-
16
|
|
65
|
-
);
|
|
66
|
-
if (s !== 0)
|
|
67
|
-
throw new Error(`Expected 0 inputs from WASM, got ${s}`);
|
|
68
|
-
if (a === 0)
|
|
69
|
-
throw new Error("Expected at least 1 output from WASM, got 0");
|
|
70
|
-
const o = p.from(n.substring(0, 8), "hex").readUInt32LE(0), u = p.from(
|
|
71
|
-
n.substring(n.length - 8),
|
|
72
|
-
"hex"
|
|
73
|
-
).readUInt32LE(0), i = [];
|
|
74
|
-
let r = e + 4;
|
|
75
|
-
for (let c = 0; c < a; c++) {
|
|
76
|
-
const l = n.substring(r, r + 16), d = Number(p.from(l, "hex").readBigUInt64LE(0));
|
|
77
|
-
r += 16;
|
|
78
|
-
const f = parseInt(n.substring(r, r + 2), 16);
|
|
79
|
-
r += 2;
|
|
80
|
-
const g = n.substring(r, r + f * 2), b = p.from(g, "hex");
|
|
81
|
-
r += f * 2, i.push({ value: d, script: b });
|
|
82
|
-
}
|
|
83
|
-
return { version: o, locktime: u, outputs: i };
|
|
84
|
-
}
|
|
85
|
-
function rt(n) {
|
|
86
|
-
const { unfundedTxHex: t, selectedUTXOs: e, changeAddress: s, changeAmount: a, network: o } = n, { version: u, locktime: i, outputs: r } = st(t), c = new S.Transaction();
|
|
87
|
-
c.version = u, c.locktime = i;
|
|
88
|
-
for (const l of e) {
|
|
89
|
-
const d = p.from(l.txid, "hex").reverse();
|
|
90
|
-
c.addInput(d, l.vout);
|
|
91
|
-
}
|
|
92
|
-
for (const l of r)
|
|
93
|
-
c.addOutput(l.script, l.value);
|
|
94
|
-
if (a > H) {
|
|
95
|
-
const l = S.address.toOutputScript(s, o);
|
|
96
|
-
c.addOutput(l, Number(a));
|
|
97
|
-
}
|
|
98
|
-
return c.toHex();
|
|
99
|
-
}
|
|
100
|
-
function R(n) {
|
|
52
|
+
function X(n) {
|
|
101
53
|
const t = n.startsWith("0x") ? n.slice(2) : n;
|
|
102
|
-
return `0x${
|
|
54
|
+
return `0x${S.fromHex(t).getId()}`;
|
|
103
55
|
}
|
|
104
|
-
function
|
|
56
|
+
function vt(n, t, e) {
|
|
105
57
|
if (n.length === 0)
|
|
106
58
|
throw new Error("No input UTXOs provided for split transaction");
|
|
107
59
|
if (t.length === 0)
|
|
108
60
|
throw new Error("No outputs specified for split transaction");
|
|
109
|
-
for (const
|
|
110
|
-
if (
|
|
61
|
+
for (const a of t)
|
|
62
|
+
if (a.amount <= 0n)
|
|
111
63
|
throw new Error(
|
|
112
|
-
`Invalid output amount for ${
|
|
64
|
+
`Invalid output amount for ${a.address}: ${a.amount} satoshis. Amount must be greater than zero.`
|
|
113
65
|
);
|
|
114
|
-
const s =
|
|
115
|
-
|
|
116
|
-
for (const
|
|
117
|
-
const
|
|
118
|
-
|
|
66
|
+
const s = U(e), o = new S();
|
|
67
|
+
o.version = 2;
|
|
68
|
+
for (const a of n) {
|
|
69
|
+
const u = f.from(a.txid, "hex").reverse();
|
|
70
|
+
o.addInput(u, a.vout);
|
|
119
71
|
}
|
|
120
|
-
const
|
|
121
|
-
for (let
|
|
122
|
-
const
|
|
72
|
+
const r = [];
|
|
73
|
+
for (let a = 0; a < t.length; a++) {
|
|
74
|
+
const u = t[a];
|
|
123
75
|
let l;
|
|
124
76
|
try {
|
|
125
|
-
l =
|
|
126
|
-
} catch (
|
|
77
|
+
l = J.toOutputScript(u.address, s);
|
|
78
|
+
} catch (p) {
|
|
127
79
|
throw new Error(
|
|
128
|
-
`Failed to decode address "${
|
|
80
|
+
`Failed to decode address "${u.address}": ${p instanceof Error ? p.message : String(p)}`
|
|
129
81
|
);
|
|
130
82
|
}
|
|
131
|
-
|
|
83
|
+
o.addOutput(l, Number(u.amount)), r.push({
|
|
132
84
|
txid: "",
|
|
133
85
|
// Will be set after txid calculation
|
|
134
|
-
vout:
|
|
135
|
-
value: Number(
|
|
86
|
+
vout: a,
|
|
87
|
+
value: Number(u.amount),
|
|
136
88
|
scriptPubKey: l.toString("hex")
|
|
137
89
|
});
|
|
138
90
|
}
|
|
139
|
-
const
|
|
140
|
-
for (const
|
|
141
|
-
|
|
91
|
+
const c = o.toHex(), i = o.getId();
|
|
92
|
+
for (const a of r)
|
|
93
|
+
a.txid = i;
|
|
142
94
|
return {
|
|
143
|
-
txHex:
|
|
95
|
+
txHex: c,
|
|
144
96
|
txid: i,
|
|
145
|
-
outputs:
|
|
97
|
+
outputs: r
|
|
146
98
|
};
|
|
147
99
|
}
|
|
148
|
-
function
|
|
149
|
-
const s =
|
|
150
|
-
if (
|
|
100
|
+
function kt(n, t, e) {
|
|
101
|
+
const s = S.fromHex(n), o = new C();
|
|
102
|
+
if (o.setVersion(s.version), o.setLocktime(s.locktime), !f.isBuffer(e) || e.length !== 32)
|
|
151
103
|
throw new Error(
|
|
152
|
-
`Invalid publicKeyNoCoord: expected 32-byte Buffer (x-only pubkey), got ${
|
|
104
|
+
`Invalid publicKeyNoCoord: expected 32-byte Buffer (x-only pubkey), got ${f.isBuffer(e) ? `${e.length}-byte Buffer` : typeof e}`
|
|
153
105
|
);
|
|
154
106
|
if (t.length !== s.ins.length)
|
|
155
107
|
throw new Error(
|
|
156
108
|
`UTXO count mismatch: transaction has ${s.ins.length} input${s.ins.length !== 1 ? "s" : ""}, but ${t.length} UTXO${t.length !== 1 ? "s were" : " was"} provided`
|
|
157
109
|
);
|
|
158
|
-
for (let
|
|
159
|
-
const
|
|
110
|
+
for (let r = 0; r < s.ins.length; r++) {
|
|
111
|
+
const c = s.ins[r], i = t[r];
|
|
160
112
|
if (!i)
|
|
161
|
-
throw new Error(`Missing UTXO data for input ${
|
|
162
|
-
const
|
|
163
|
-
if (i.txid !==
|
|
113
|
+
throw new Error(`Missing UTXO data for input ${r}`);
|
|
114
|
+
const a = f.from(c.hash).reverse().toString("hex"), u = c.index;
|
|
115
|
+
if (i.txid !== a || i.vout !== u)
|
|
164
116
|
throw new Error(
|
|
165
|
-
`Input ${
|
|
117
|
+
`Input ${r} outpoint mismatch: transaction expects ${a}:${u}, but UTXO ${i.txid}:${i.vout} was provided. Ensure inputs array matches the order used in createSplitTransaction().`
|
|
166
118
|
);
|
|
167
|
-
const l =
|
|
119
|
+
const l = f.from(i.scriptPubKey, "hex");
|
|
168
120
|
if (!(l.length === 34 && l[0] === 81 && // OP_1 (witness version 1)
|
|
169
121
|
l[1] === 32))
|
|
170
122
|
throw new Error(
|
|
171
|
-
`Input ${
|
|
123
|
+
`Input ${r} must be P2TR (Taproot). createSplitTransactionPsbt() requires P2TR inputs because it uses tapInternalKey for Taproot signing. ScriptPubKey: ${i.scriptPubKey.substring(0, 20)}...`
|
|
172
124
|
);
|
|
173
|
-
const
|
|
174
|
-
script:
|
|
125
|
+
const y = {
|
|
126
|
+
script: f.from(i.scriptPubKey, "hex"),
|
|
175
127
|
value: i.value
|
|
176
128
|
};
|
|
177
|
-
|
|
178
|
-
hash:
|
|
179
|
-
index:
|
|
180
|
-
sequence:
|
|
181
|
-
witnessUtxo:
|
|
129
|
+
o.addInput({
|
|
130
|
+
hash: c.hash,
|
|
131
|
+
index: c.index,
|
|
132
|
+
sequence: c.sequence,
|
|
133
|
+
witnessUtxo: y,
|
|
182
134
|
tapInternalKey: e
|
|
183
135
|
});
|
|
184
136
|
}
|
|
185
|
-
for (const
|
|
186
|
-
|
|
187
|
-
script:
|
|
188
|
-
value:
|
|
137
|
+
for (const r of s.outs)
|
|
138
|
+
o.addOutput({
|
|
139
|
+
script: r.script,
|
|
140
|
+
value: r.value
|
|
189
141
|
});
|
|
190
|
-
return
|
|
142
|
+
return o.toHex();
|
|
191
143
|
}
|
|
192
|
-
var
|
|
193
|
-
function
|
|
144
|
+
var B = /* @__PURE__ */ ((n) => (n.P2PKH = "P2PKH", n.P2SH = "P2SH", n.P2WPKH = "P2WPKH", n.P2WSH = "P2WSH", n.P2TR = "P2TR", n.UNKNOWN = "UNKNOWN", n))(B || {});
|
|
145
|
+
function ut(n) {
|
|
194
146
|
const t = n.length;
|
|
195
147
|
return t === 25 && n[0] === 118 && // OP_DUP
|
|
196
148
|
n[1] === 169 && // OP_HASH160
|
|
@@ -203,17 +155,17 @@ function ot(n) {
|
|
|
203
155
|
n[1] === 32 ? "P2WSH" : t === 34 && n[0] === 81 && // OP_1
|
|
204
156
|
n[1] === 32 ? "P2TR" : "UNKNOWN";
|
|
205
157
|
}
|
|
206
|
-
function
|
|
207
|
-
const e =
|
|
158
|
+
function lt(n, t) {
|
|
159
|
+
const e = f.from(n.scriptPubKey, "hex"), s = ut(e);
|
|
208
160
|
switch (s) {
|
|
209
|
-
case
|
|
161
|
+
case B.P2WPKH:
|
|
210
162
|
return {
|
|
211
163
|
witnessUtxo: {
|
|
212
164
|
script: e,
|
|
213
165
|
value: n.value
|
|
214
166
|
}
|
|
215
167
|
};
|
|
216
|
-
case
|
|
168
|
+
case B.P2WSH: {
|
|
217
169
|
if (!n.witnessScript)
|
|
218
170
|
throw new Error("Missing witnessScript for P2WSH input");
|
|
219
171
|
return {
|
|
@@ -221,10 +173,10 @@ function at(n, t) {
|
|
|
221
173
|
script: e,
|
|
222
174
|
value: n.value
|
|
223
175
|
},
|
|
224
|
-
witnessScript:
|
|
176
|
+
witnessScript: f.from(n.witnessScript, "hex")
|
|
225
177
|
};
|
|
226
178
|
}
|
|
227
|
-
case
|
|
179
|
+
case B.P2TR: {
|
|
228
180
|
if (t && t.length !== 32)
|
|
229
181
|
throw new Error(
|
|
230
182
|
`Invalid tapInternalKey length: expected 32 bytes, got ${t.length}`
|
|
@@ -242,18 +194,18 @@ function at(n, t) {
|
|
|
242
194
|
throw new Error(`Unsupported script type: ${s}`);
|
|
243
195
|
}
|
|
244
196
|
}
|
|
245
|
-
const
|
|
197
|
+
const dt = {
|
|
246
198
|
mainnet: "https://mempool.space/api",
|
|
247
199
|
testnet: "https://mempool.space/testnet/api",
|
|
248
200
|
signet: "https://mempool.space/signet/api"
|
|
249
201
|
};
|
|
250
|
-
async function
|
|
202
|
+
async function E(n, t) {
|
|
251
203
|
try {
|
|
252
204
|
const e = await fetch(n, t);
|
|
253
205
|
if (!e.ok) {
|
|
254
|
-
const
|
|
206
|
+
const o = await e.text();
|
|
255
207
|
throw new Error(
|
|
256
|
-
`Mempool API error (${e.status}): ${
|
|
208
|
+
`Mempool API error (${e.status}): ${o || e.statusText}`
|
|
257
209
|
);
|
|
258
210
|
}
|
|
259
211
|
const s = e.headers.get("content-type");
|
|
@@ -262,7 +214,7 @@ async function k(n, t) {
|
|
|
262
214
|
throw e instanceof Error ? new Error(`Failed to fetch from mempool API: ${e.message}`) : new Error("Failed to fetch from mempool API: Unknown error");
|
|
263
215
|
}
|
|
264
216
|
}
|
|
265
|
-
async function
|
|
217
|
+
async function pt(n, t) {
|
|
266
218
|
try {
|
|
267
219
|
const e = await fetch(`${t}/tx`, {
|
|
268
220
|
method: "POST",
|
|
@@ -272,15 +224,15 @@ async function ct(n, t) {
|
|
|
272
224
|
}
|
|
273
225
|
});
|
|
274
226
|
if (!e.ok) {
|
|
275
|
-
const
|
|
276
|
-
let
|
|
227
|
+
const o = await e.text();
|
|
228
|
+
let r;
|
|
277
229
|
try {
|
|
278
|
-
|
|
230
|
+
r = JSON.parse(o).message;
|
|
279
231
|
} catch {
|
|
280
|
-
|
|
232
|
+
r = o;
|
|
281
233
|
}
|
|
282
234
|
throw new Error(
|
|
283
|
-
|
|
235
|
+
r || `Failed to broadcast transaction: ${e.statusText}`
|
|
284
236
|
);
|
|
285
237
|
}
|
|
286
238
|
return await e.text();
|
|
@@ -288,10 +240,10 @@ async function ct(n, t) {
|
|
|
288
240
|
throw e instanceof Error ? new Error(`Failed to broadcast BTC transaction: ${e.message}`) : new Error("Failed to broadcast BTC transaction: Unknown error");
|
|
289
241
|
}
|
|
290
242
|
}
|
|
291
|
-
async function
|
|
292
|
-
return
|
|
243
|
+
async function ht(n, t) {
|
|
244
|
+
return E(`${t}/tx/${n}`);
|
|
293
245
|
}
|
|
294
|
-
async function
|
|
246
|
+
async function Bt(n, t) {
|
|
295
247
|
try {
|
|
296
248
|
const e = await fetch(`${t}/tx/${n}/hex`);
|
|
297
249
|
if (!e.ok) {
|
|
@@ -305,33 +257,33 @@ async function kt(n, t) {
|
|
|
305
257
|
throw e instanceof Error ? new Error(`Failed to get transaction hex for ${n}: ${e.message}`) : new Error(`Failed to get transaction hex for ${n}: Unknown error`);
|
|
306
258
|
}
|
|
307
259
|
}
|
|
308
|
-
async function
|
|
309
|
-
const s = await
|
|
260
|
+
async function gt(n, t, e) {
|
|
261
|
+
const s = await ht(n, e);
|
|
310
262
|
if (t >= s.vout.length)
|
|
311
263
|
throw new Error(
|
|
312
264
|
`Invalid vout ${t} for transaction ${n} (has ${s.vout.length} outputs)`
|
|
313
265
|
);
|
|
314
|
-
const
|
|
266
|
+
const o = s.vout[t];
|
|
315
267
|
return {
|
|
316
268
|
txid: n,
|
|
317
269
|
vout: t,
|
|
318
|
-
value:
|
|
319
|
-
scriptPubKey:
|
|
270
|
+
value: o.value,
|
|
271
|
+
scriptPubKey: o.scriptpubkey
|
|
320
272
|
};
|
|
321
273
|
}
|
|
322
274
|
async function Et(n, t) {
|
|
323
275
|
try {
|
|
324
|
-
const e = await
|
|
276
|
+
const e = await E(`${t}/address/${n}/utxo`), s = await E(`${t}/v1/validate-address/${n}`);
|
|
325
277
|
if (!s.isvalid)
|
|
326
278
|
throw new Error(
|
|
327
279
|
`Invalid Bitcoin address: ${n}. Mempool API validation failed.`
|
|
328
280
|
);
|
|
329
|
-
return e.sort((
|
|
330
|
-
txid:
|
|
331
|
-
vout:
|
|
332
|
-
value:
|
|
281
|
+
return e.sort((r, c) => c.value - r.value).map((r) => ({
|
|
282
|
+
txid: r.txid,
|
|
283
|
+
vout: r.vout,
|
|
284
|
+
value: r.value,
|
|
333
285
|
scriptPubKey: s.scriptPubKey,
|
|
334
|
-
confirmed:
|
|
286
|
+
confirmed: r.status.confirmed
|
|
335
287
|
}));
|
|
336
288
|
} catch (e) {
|
|
337
289
|
throw e instanceof Error ? new Error(
|
|
@@ -341,13 +293,13 @@ async function Et(n, t) {
|
|
|
341
293
|
);
|
|
342
294
|
}
|
|
343
295
|
}
|
|
344
|
-
function
|
|
345
|
-
return
|
|
296
|
+
function St(n) {
|
|
297
|
+
return dt[n];
|
|
346
298
|
}
|
|
347
|
-
async function
|
|
348
|
-
return
|
|
299
|
+
async function Ht(n, t) {
|
|
300
|
+
return E(`${t}/address/${n}/txs`);
|
|
349
301
|
}
|
|
350
|
-
async function
|
|
302
|
+
async function It(n) {
|
|
351
303
|
const t = await fetch(`${n}/v1/fees/recommended`);
|
|
352
304
|
if (!t.ok)
|
|
353
305
|
throw new Error(
|
|
@@ -360,7 +312,7 @@ async function St(n) {
|
|
|
360
312
|
);
|
|
361
313
|
return e;
|
|
362
314
|
}
|
|
363
|
-
const
|
|
315
|
+
const $ = [
|
|
364
316
|
{
|
|
365
317
|
type: "function",
|
|
366
318
|
name: "submitPeginRequest",
|
|
@@ -381,7 +333,12 @@ const B = [
|
|
|
381
333
|
internalType: "bytes"
|
|
382
334
|
},
|
|
383
335
|
{
|
|
384
|
-
name: "
|
|
336
|
+
name: "unsignedPrePeginTx",
|
|
337
|
+
type: "bytes",
|
|
338
|
+
internalType: "bytes"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
name: "depositorSignedPeginTx",
|
|
385
342
|
type: "bytes",
|
|
386
343
|
internalType: "bytes"
|
|
387
344
|
},
|
|
@@ -390,6 +347,11 @@ const B = [
|
|
|
390
347
|
type: "address",
|
|
391
348
|
internalType: "address"
|
|
392
349
|
},
|
|
350
|
+
{
|
|
351
|
+
name: "hashlock",
|
|
352
|
+
type: "bytes32",
|
|
353
|
+
internalType: "bytes32"
|
|
354
|
+
},
|
|
393
355
|
{
|
|
394
356
|
name: "depositorPayoutBtcAddress",
|
|
395
357
|
type: "bytes",
|
|
@@ -430,7 +392,12 @@ const B = [
|
|
|
430
392
|
internalType: "bytes"
|
|
431
393
|
},
|
|
432
394
|
{
|
|
433
|
-
name: "
|
|
395
|
+
name: "unsignedPrePeginTx",
|
|
396
|
+
type: "bytes",
|
|
397
|
+
internalType: "bytes"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
name: "depositorSignedPeginTx",
|
|
434
401
|
type: "bytes",
|
|
435
402
|
internalType: "bytes"
|
|
436
403
|
},
|
|
@@ -439,6 +406,11 @@ const B = [
|
|
|
439
406
|
type: "address",
|
|
440
407
|
internalType: "address"
|
|
441
408
|
},
|
|
409
|
+
{
|
|
410
|
+
name: "hashlock",
|
|
411
|
+
type: "bytes32",
|
|
412
|
+
internalType: "bytes32"
|
|
413
|
+
},
|
|
442
414
|
{
|
|
443
415
|
name: "referralCode",
|
|
444
416
|
type: "uint32",
|
|
@@ -464,6 +436,24 @@ const B = [
|
|
|
464
436
|
],
|
|
465
437
|
stateMutability: "payable"
|
|
466
438
|
},
|
|
439
|
+
{
|
|
440
|
+
type: "function",
|
|
441
|
+
name: "activateVaultWithSecret",
|
|
442
|
+
inputs: [
|
|
443
|
+
{
|
|
444
|
+
name: "vaultId",
|
|
445
|
+
type: "bytes32",
|
|
446
|
+
internalType: "bytes32"
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
name: "s",
|
|
450
|
+
type: "bytes32",
|
|
451
|
+
internalType: "bytes32"
|
|
452
|
+
}
|
|
453
|
+
],
|
|
454
|
+
outputs: [],
|
|
455
|
+
stateMutability: "nonpayable"
|
|
456
|
+
},
|
|
467
457
|
{
|
|
468
458
|
type: "function",
|
|
469
459
|
name: "getPegInFee",
|
|
@@ -501,7 +491,7 @@ const B = [
|
|
|
501
491
|
components: [
|
|
502
492
|
{ name: "depositor", type: "address", internalType: "address" },
|
|
503
493
|
{ name: "depositorBtcPubKey", type: "bytes32", internalType: "bytes32" },
|
|
504
|
-
{ name: "
|
|
494
|
+
{ name: "depositorSignedPeginTx", type: "bytes", internalType: "bytes" },
|
|
505
495
|
{ name: "amount", type: "uint256", internalType: "uint256" },
|
|
506
496
|
{ name: "vaultProvider", type: "address", internalType: "address" },
|
|
507
497
|
{ name: "status", type: "uint8", internalType: "enum IBTCVaultsManager.BTCVaultStatus" },
|
|
@@ -509,9 +499,11 @@ const B = [
|
|
|
509
499
|
{ name: "universalChallengersVersion", type: "uint16", internalType: "uint16" },
|
|
510
500
|
{ name: "appVaultKeepersVersion", type: "uint16", internalType: "uint16" },
|
|
511
501
|
{ name: "offchainParamsVersion", type: "uint16", internalType: "uint16" },
|
|
502
|
+
{ name: "vkVersion", type: "uint16", internalType: "uint16" },
|
|
512
503
|
{ name: "createdAt", type: "uint256", internalType: "uint256" },
|
|
513
504
|
{ name: "verifiedAt", type: "uint256", internalType: "uint256" },
|
|
514
|
-
{ name: "depositorLamportPkHash", type: "bytes32", internalType: "bytes32" }
|
|
505
|
+
{ name: "depositorLamportPkHash", type: "bytes32", internalType: "bytes32" },
|
|
506
|
+
{ name: "hashlock", type: "bytes32", internalType: "bytes32" }
|
|
515
507
|
]
|
|
516
508
|
}
|
|
517
509
|
],
|
|
@@ -532,6 +524,16 @@ const B = [
|
|
|
532
524
|
internalType: "uint256"
|
|
533
525
|
}
|
|
534
526
|
]
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
type: "error",
|
|
530
|
+
name: "InvalidSecret",
|
|
531
|
+
inputs: []
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
type: "error",
|
|
535
|
+
name: "ActivationDeadlineExpired",
|
|
536
|
+
inputs: []
|
|
535
537
|
}
|
|
536
538
|
], x = {
|
|
537
539
|
// VaultAlreadyExists()
|
|
@@ -563,7 +565,7 @@ const B = [
|
|
|
563
565
|
// InvalidPeginFee(uint256,uint256)
|
|
564
566
|
"0x979f4518": "Invalid pegin fee: The ETH fee sent does not match the required amount. This may indicate a fee rate change during the transaction."
|
|
565
567
|
};
|
|
566
|
-
function
|
|
568
|
+
function O(n) {
|
|
567
569
|
if (!n || typeof n != "object") return;
|
|
568
570
|
const t = n;
|
|
569
571
|
if (typeof t.data == "string" && t.data.startsWith("0x"))
|
|
@@ -571,37 +573,37 @@ function U(n) {
|
|
|
571
573
|
if (typeof t.details == "string" && t.details.startsWith("0x"))
|
|
572
574
|
return t.details;
|
|
573
575
|
let e = t.cause, s = 0;
|
|
574
|
-
const
|
|
575
|
-
for (; e && typeof e == "object" && s <
|
|
576
|
+
const o = 5;
|
|
577
|
+
for (; e && typeof e == "object" && s < o; ) {
|
|
576
578
|
const i = e;
|
|
577
579
|
if (typeof i.data == "string" && i.data.startsWith("0x"))
|
|
578
580
|
return i.data;
|
|
579
581
|
e = i.cause, s++;
|
|
580
582
|
}
|
|
581
|
-
const
|
|
582
|
-
if (
|
|
583
|
-
return
|
|
583
|
+
const c = (typeof t.message == "string" ? t.message : "").match(/\b(0x[a-fA-F0-9]{8})\b/);
|
|
584
|
+
if (c)
|
|
585
|
+
return c[1];
|
|
584
586
|
}
|
|
585
587
|
function $t(n) {
|
|
586
|
-
const t =
|
|
588
|
+
const t = O(n);
|
|
587
589
|
if (t) {
|
|
588
590
|
const e = t.substring(0, 10);
|
|
589
591
|
return x[t] ?? x[e];
|
|
590
592
|
}
|
|
591
593
|
}
|
|
592
594
|
function Ct(n) {
|
|
593
|
-
const t =
|
|
595
|
+
const t = O(n);
|
|
594
596
|
if (t === void 0) return !1;
|
|
595
597
|
const e = t.substring(0, 10);
|
|
596
598
|
return t in x || e in x;
|
|
597
599
|
}
|
|
598
|
-
function
|
|
600
|
+
function z(n) {
|
|
599
601
|
console.error("[Contract Error] Raw error:", n);
|
|
600
|
-
const t =
|
|
602
|
+
const t = O(n);
|
|
601
603
|
if (console.error("[Contract Error] Extracted error data:", t), t) {
|
|
602
|
-
const s = t.substring(0, 10),
|
|
603
|
-
if (
|
|
604
|
-
throw console.error("[Contract Error] Known error:",
|
|
604
|
+
const s = t.substring(0, 10), o = x[t] ?? x[s];
|
|
605
|
+
if (o)
|
|
606
|
+
throw console.error("[Contract Error] Known error:", o), new Error(o);
|
|
605
607
|
}
|
|
606
608
|
const e = (n == null ? void 0 : n.message) || "";
|
|
607
609
|
if (e.includes("gas limit too high") || e.includes("21000000") || e.includes("Internal JSON-RPC error")) {
|
|
@@ -617,61 +619,102 @@ function K(n) {
|
|
|
617
619
|
}
|
|
618
620
|
throw n instanceof Error ? (console.error("[Contract Error] Unhandled error:", n.message), n) : new Error(`Contract call failed: ${String(n)}`);
|
|
619
621
|
}
|
|
620
|
-
class
|
|
622
|
+
class Ut {
|
|
621
623
|
/**
|
|
622
624
|
* Creates a new PeginManager instance.
|
|
623
625
|
*
|
|
624
626
|
* @param config - Manager configuration including wallets and contract addresses
|
|
625
627
|
*/
|
|
626
628
|
constructor(t) {
|
|
627
|
-
|
|
629
|
+
H(this, "config");
|
|
628
630
|
this.config = t;
|
|
629
631
|
}
|
|
630
632
|
/**
|
|
631
|
-
* Prepares
|
|
633
|
+
* Prepares an atomic swap peg-in by building the Pre-PegIn HTLC transaction,
|
|
634
|
+
* funding it, constructing the PegIn transaction, and signing the PegIn input.
|
|
632
635
|
*
|
|
633
636
|
* This method orchestrates the following steps:
|
|
634
637
|
* 1. Get depositor BTC public key from wallet
|
|
635
|
-
* 2. Build unfunded
|
|
636
|
-
* 3. Select UTXOs
|
|
637
|
-
* 4. Fund
|
|
638
|
+
* 2. Build unfunded Pre-PegIn transaction (HTLC output) using primitives
|
|
639
|
+
* 3. Select UTXOs to cover the HTLC value
|
|
640
|
+
* 4. Fund the Pre-PegIn transaction
|
|
641
|
+
* 5. Derive the PegIn transaction from the funded Pre-PegIn txid
|
|
642
|
+
* 6. Build PSBT for signing the PegIn input (HTLC leaf 0)
|
|
643
|
+
* 7. Sign via BTC wallet and extract depositor signature
|
|
638
644
|
*
|
|
639
|
-
* The returned
|
|
640
|
-
*
|
|
645
|
+
* The returned `fundedPrePeginTxHex` is funded but unsigned (inputs unsigned).
|
|
646
|
+
* Use `signAndBroadcast()` AFTER registering on Ethereum to broadcast it.
|
|
641
647
|
*
|
|
642
|
-
* @param params -
|
|
643
|
-
* @returns
|
|
648
|
+
* @param params - Atomic pegin parameters including amount, HTLC params, UTXOs
|
|
649
|
+
* @returns Atomic pegin result with funded Pre-PegIn tx, signed PegIn input, and signatures
|
|
644
650
|
* @throws Error if wallet operations fail or insufficient funds
|
|
645
651
|
*/
|
|
646
|
-
async
|
|
647
|
-
const e = await this.config.btcWallet.getPublicKeyHex(), s = e.length === 66 ? e.slice(2) : e,
|
|
652
|
+
async prepareAtomicPegin(t) {
|
|
653
|
+
const e = await this.config.btcWallet.getPublicKeyHex(), s = e.length === 66 ? e.slice(2) : e, o = k(t.vaultProviderBtcPubkey), r = t.vaultKeeperBtcPubkeys.map(k), c = t.universalChallengerBtcPubkeys.map(k), i = r.length, a = {
|
|
648
654
|
depositorPubkey: s,
|
|
649
|
-
vaultProviderPubkey:
|
|
650
|
-
vaultKeeperPubkeys:
|
|
651
|
-
universalChallengerPubkeys:
|
|
652
|
-
|
|
655
|
+
vaultProviderPubkey: o,
|
|
656
|
+
vaultKeeperPubkeys: r,
|
|
657
|
+
universalChallengerPubkeys: c,
|
|
658
|
+
hashH: t.hashH,
|
|
659
|
+
timelockRefund: t.timelockRefund,
|
|
653
660
|
pegInAmount: t.amount,
|
|
654
|
-
|
|
661
|
+
feeRate: t.protocolFeeRate,
|
|
662
|
+
numLocalChallengers: i,
|
|
663
|
+
councilQuorum: t.councilQuorum,
|
|
664
|
+
councilSize: t.councilSize,
|
|
655
665
|
network: this.config.btcNetwork
|
|
656
|
-
}
|
|
657
|
-
t.availableUTXOs,
|
|
658
|
-
|
|
659
|
-
t.
|
|
660
|
-
),
|
|
661
|
-
unfundedTxHex:
|
|
662
|
-
selectedUTXOs:
|
|
666
|
+
}, u = await tt(a), l = ct(
|
|
667
|
+
[...t.availableUTXOs],
|
|
668
|
+
u.totalOutputValue,
|
|
669
|
+
t.mempoolFeeRate
|
|
670
|
+
), p = U(this.config.btcNetwork), y = et({
|
|
671
|
+
unfundedTxHex: u.psbtHex,
|
|
672
|
+
selectedUTXOs: l.selectedUTXOs,
|
|
663
673
|
changeAddress: t.changeAddress,
|
|
664
|
-
changeAmount:
|
|
665
|
-
network:
|
|
666
|
-
}),
|
|
674
|
+
changeAmount: l.changeAmount,
|
|
675
|
+
network: p
|
|
676
|
+
}), h = k(X(y)), b = await nt({
|
|
677
|
+
prePeginParams: a,
|
|
678
|
+
timelockPegin: t.timelockPegin,
|
|
679
|
+
fundedPrePeginTxid: h
|
|
680
|
+
}), m = await st({
|
|
681
|
+
peginTxHex: b.txHex,
|
|
682
|
+
fundedPrePeginTxHex: y,
|
|
683
|
+
depositorPubkey: s,
|
|
684
|
+
vaultProviderPubkey: o,
|
|
685
|
+
vaultKeeperPubkeys: r,
|
|
686
|
+
universalChallengerPubkeys: c,
|
|
687
|
+
hashH: t.hashH,
|
|
688
|
+
timelockRefund: t.timelockRefund,
|
|
689
|
+
network: this.config.btcNetwork
|
|
690
|
+
}), d = await this.config.btcWallet.signPsbt(
|
|
691
|
+
m.psbtHex,
|
|
692
|
+
{
|
|
693
|
+
autoFinalized: !1,
|
|
694
|
+
signInputs: [
|
|
695
|
+
{
|
|
696
|
+
index: 0,
|
|
697
|
+
publicKey: e,
|
|
698
|
+
disableTweakSigner: !0
|
|
699
|
+
}
|
|
700
|
+
]
|
|
701
|
+
}
|
|
702
|
+
), g = rt(
|
|
703
|
+
d,
|
|
704
|
+
s
|
|
705
|
+
);
|
|
667
706
|
return {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
707
|
+
fundedPrePeginTxHex: y,
|
|
708
|
+
htlcValue: u.htlcValue,
|
|
709
|
+
signedPeginInputPsbtHex: d,
|
|
710
|
+
peginInputSignature: g,
|
|
711
|
+
vaultScriptPubKey: b.vaultScriptPubKey,
|
|
712
|
+
peginTxHex: b.txHex,
|
|
713
|
+
prePeginTxid: h,
|
|
714
|
+
peginTxid: b.txid,
|
|
715
|
+
selectedUTXOs: l.selectedUTXOs,
|
|
716
|
+
fee: l.fee,
|
|
717
|
+
changeAmount: l.changeAmount
|
|
675
718
|
};
|
|
676
719
|
}
|
|
677
720
|
/**
|
|
@@ -690,57 +733,63 @@ class Ht {
|
|
|
690
733
|
* @throws Error if signing or broadcasting fails
|
|
691
734
|
*/
|
|
692
735
|
async signAndBroadcast(t) {
|
|
693
|
-
const {
|
|
694
|
-
if (
|
|
736
|
+
const { fundedPrePeginTxHex: e, depositorBtcPubkey: s } = t, o = e.startsWith("0x") ? e.slice(2) : e, r = S.fromHex(o);
|
|
737
|
+
if (r.ins.length === 0)
|
|
695
738
|
throw new Error("Transaction has no inputs");
|
|
696
|
-
const
|
|
697
|
-
|
|
739
|
+
const c = new C();
|
|
740
|
+
c.setVersion(r.version), c.setLocktime(r.locktime);
|
|
698
741
|
const i = s.startsWith("0x") ? s.slice(2) : s;
|
|
699
742
|
if (i.length !== 64 || !/^[0-9a-fA-F]+$/.test(i))
|
|
700
743
|
throw new Error(
|
|
701
744
|
"Invalid depositorBtcPubkey: expected 64 hex characters (x-only pubkey)"
|
|
702
745
|
);
|
|
703
|
-
const
|
|
704
|
-
if (
|
|
746
|
+
const a = f.from(i, "hex");
|
|
747
|
+
if (a.length !== 32)
|
|
705
748
|
throw new Error(
|
|
706
|
-
`Invalid depositorBtcPubkey length: expected 32 bytes, got ${
|
|
749
|
+
`Invalid depositorBtcPubkey length: expected 32 bytes, got ${a.length}`
|
|
707
750
|
);
|
|
708
|
-
const
|
|
709
|
-
const
|
|
710
|
-
return
|
|
711
|
-
input:
|
|
712
|
-
utxoData:
|
|
713
|
-
txid:
|
|
714
|
-
vout:
|
|
751
|
+
const u = this.config.mempoolApiUrl, l = r.ins.map((d) => {
|
|
752
|
+
const g = f.from(d.hash).reverse().toString("hex"), P = d.index;
|
|
753
|
+
return gt(g, P, u).then((w) => ({
|
|
754
|
+
input: d,
|
|
755
|
+
utxoData: w,
|
|
756
|
+
txid: g,
|
|
757
|
+
vout: P
|
|
715
758
|
}));
|
|
716
|
-
}),
|
|
717
|
-
for (const { input:
|
|
718
|
-
const
|
|
759
|
+
}), p = await Promise.all(l);
|
|
760
|
+
for (const { input: d, utxoData: g, txid: P, vout: w } of p) {
|
|
761
|
+
const T = lt(
|
|
719
762
|
{
|
|
720
|
-
value:
|
|
721
|
-
scriptPubKey:
|
|
763
|
+
value: g.value,
|
|
764
|
+
scriptPubKey: g.scriptPubKey
|
|
722
765
|
},
|
|
723
|
-
|
|
766
|
+
a
|
|
724
767
|
);
|
|
725
|
-
|
|
726
|
-
hash:
|
|
727
|
-
index:
|
|
728
|
-
sequence:
|
|
729
|
-
...
|
|
768
|
+
c.addInput({
|
|
769
|
+
hash: d.hash,
|
|
770
|
+
index: d.index,
|
|
771
|
+
sequence: d.sequence,
|
|
772
|
+
...T
|
|
730
773
|
});
|
|
731
774
|
}
|
|
732
|
-
for (const
|
|
733
|
-
|
|
734
|
-
script:
|
|
735
|
-
value:
|
|
775
|
+
for (const d of r.outs)
|
|
776
|
+
c.addOutput({
|
|
777
|
+
script: d.script,
|
|
778
|
+
value: d.value
|
|
736
779
|
});
|
|
737
|
-
const
|
|
780
|
+
const y = await this.config.btcWallet.signPsbt(c.toHex()), h = C.fromHex(y);
|
|
738
781
|
try {
|
|
739
|
-
|
|
740
|
-
} catch {
|
|
782
|
+
h.finalizeAllInputs();
|
|
783
|
+
} catch (d) {
|
|
784
|
+
if (!h.data.inputs.every(
|
|
785
|
+
(P) => P.finalScriptWitness || P.finalScriptSig
|
|
786
|
+
))
|
|
787
|
+
throw new Error(
|
|
788
|
+
`PSBT finalization failed and wallet did not auto-finalize: ${d}`
|
|
789
|
+
);
|
|
741
790
|
}
|
|
742
|
-
const b =
|
|
743
|
-
return await
|
|
791
|
+
const b = h.extractTransaction().toHex();
|
|
792
|
+
return await pt(b, u);
|
|
744
793
|
}
|
|
745
794
|
/**
|
|
746
795
|
* Registers a peg-in on Ethereum by calling the BTCVaultsManager contract.
|
|
@@ -762,83 +811,87 @@ class Ht {
|
|
|
762
811
|
async registerPeginOnChain(t) {
|
|
763
812
|
const {
|
|
764
813
|
depositorBtcPubkey: e,
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
814
|
+
unsignedPrePeginTx: s,
|
|
815
|
+
depositorSignedPeginTx: o,
|
|
816
|
+
vaultProvider: r,
|
|
817
|
+
hashlock: c,
|
|
818
|
+
onPopSigned: i,
|
|
819
|
+
depositorPayoutBtcAddress: a,
|
|
820
|
+
depositorLamportPkHash: u,
|
|
821
|
+
preSignedBtcPopSignature: l
|
|
771
822
|
} = t;
|
|
772
823
|
if (!this.config.ethWallet.account)
|
|
773
824
|
throw new Error("Ethereum wallet account not found");
|
|
774
|
-
const
|
|
775
|
-
|
|
776
|
-
|
|
825
|
+
const p = this.config.ethWallet.account.address, y = await this.resolvePopSignature(
|
|
826
|
+
p,
|
|
827
|
+
l
|
|
777
828
|
);
|
|
778
|
-
|
|
779
|
-
const
|
|
780
|
-
|
|
781
|
-
),
|
|
782
|
-
if (await this.checkVaultExists(
|
|
829
|
+
i && await i();
|
|
830
|
+
const h = I(e), b = I(s), m = I(o), d = await this.resolvePayoutScriptPubKey(
|
|
831
|
+
a
|
|
832
|
+
), g = X(m);
|
|
833
|
+
if (await this.checkVaultExists(g))
|
|
783
834
|
throw new Error(
|
|
784
|
-
`Vault already exists for this transaction (ID: ${
|
|
835
|
+
`Vault already exists for this transaction (ID: ${g}). Vault IDs are deterministically derived from the unsigned Bitcoin transaction, so using the same UTXOs and amount will always produce the same vault. To create a new vault, please use different UTXOs or a different amount to generate a unique transaction.`
|
|
785
836
|
);
|
|
786
|
-
const
|
|
837
|
+
const w = K({
|
|
787
838
|
chain: this.config.ethChain,
|
|
788
|
-
transport:
|
|
839
|
+
transport: N()
|
|
789
840
|
});
|
|
790
|
-
let
|
|
841
|
+
let T;
|
|
791
842
|
try {
|
|
792
|
-
|
|
843
|
+
T = await w.readContract({
|
|
793
844
|
address: this.config.vaultContracts.btcVaultsManager,
|
|
794
|
-
abi:
|
|
845
|
+
abi: $,
|
|
795
846
|
functionName: "getPegInFee",
|
|
796
|
-
args: [
|
|
847
|
+
args: [r]
|
|
797
848
|
});
|
|
798
849
|
} catch {
|
|
799
850
|
throw new Error(
|
|
800
851
|
"Failed to query pegin fee from the contract. Please check your network connection and that the contract address is correct."
|
|
801
852
|
);
|
|
802
853
|
}
|
|
803
|
-
const
|
|
804
|
-
abi:
|
|
854
|
+
const F = ot({
|
|
855
|
+
abi: $,
|
|
805
856
|
functionName: "submitPeginRequest",
|
|
806
857
|
args: [
|
|
858
|
+
p,
|
|
859
|
+
h,
|
|
860
|
+
y,
|
|
861
|
+
b,
|
|
862
|
+
m,
|
|
863
|
+
r,
|
|
807
864
|
c,
|
|
808
865
|
d,
|
|
809
|
-
|
|
810
|
-
f,
|
|
811
|
-
a,
|
|
812
|
-
g,
|
|
813
|
-
i
|
|
866
|
+
u
|
|
814
867
|
]
|
|
815
868
|
});
|
|
816
|
-
let
|
|
869
|
+
let A;
|
|
817
870
|
try {
|
|
818
|
-
|
|
871
|
+
A = await w.estimateGas({
|
|
819
872
|
to: this.config.vaultContracts.btcVaultsManager,
|
|
820
|
-
data:
|
|
821
|
-
value:
|
|
873
|
+
data: F,
|
|
874
|
+
value: T,
|
|
822
875
|
account: this.config.ethWallet.account.address
|
|
823
876
|
});
|
|
824
|
-
} catch (
|
|
825
|
-
|
|
877
|
+
} catch (v) {
|
|
878
|
+
z(v);
|
|
826
879
|
}
|
|
827
880
|
try {
|
|
828
881
|
return {
|
|
829
882
|
ethTxHash: await this.config.ethWallet.sendTransaction({
|
|
830
883
|
to: this.config.vaultContracts.btcVaultsManager,
|
|
831
|
-
data:
|
|
832
|
-
value:
|
|
884
|
+
data: F,
|
|
885
|
+
value: T,
|
|
833
886
|
account: this.config.ethWallet.account,
|
|
834
887
|
chain: this.config.ethChain,
|
|
835
|
-
gas:
|
|
888
|
+
gas: A
|
|
836
889
|
}),
|
|
837
|
-
vaultId:
|
|
838
|
-
btcPopSignature:
|
|
890
|
+
vaultId: g,
|
|
891
|
+
btcPopSignature: y
|
|
839
892
|
};
|
|
840
|
-
} catch (
|
|
841
|
-
|
|
893
|
+
} catch (v) {
|
|
894
|
+
z(v);
|
|
842
895
|
}
|
|
843
896
|
}
|
|
844
897
|
/**
|
|
@@ -849,15 +902,15 @@ class Ht {
|
|
|
849
902
|
*/
|
|
850
903
|
async checkVaultExists(t) {
|
|
851
904
|
try {
|
|
852
|
-
return (await
|
|
905
|
+
return (await K({
|
|
853
906
|
chain: this.config.ethChain,
|
|
854
|
-
transport:
|
|
907
|
+
transport: N()
|
|
855
908
|
}).readContract({
|
|
856
909
|
address: this.config.vaultContracts.btcVaultsManager,
|
|
857
|
-
abi:
|
|
910
|
+
abi: $,
|
|
858
911
|
functionName: "getBTCVault",
|
|
859
912
|
args: [t]
|
|
860
|
-
})).depositor !==
|
|
913
|
+
})).depositor !== it;
|
|
861
914
|
} catch {
|
|
862
915
|
return !1;
|
|
863
916
|
}
|
|
@@ -875,19 +928,19 @@ class Ht {
|
|
|
875
928
|
e = t;
|
|
876
929
|
else {
|
|
877
930
|
e = await this.config.btcWallet.getAddress();
|
|
878
|
-
const
|
|
879
|
-
if (!
|
|
931
|
+
const o = await this.config.btcWallet.getPublicKeyHex();
|
|
932
|
+
if (!at(
|
|
880
933
|
e,
|
|
881
|
-
|
|
934
|
+
o,
|
|
882
935
|
this.config.btcNetwork
|
|
883
936
|
))
|
|
884
937
|
throw new Error(
|
|
885
938
|
"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)."
|
|
886
939
|
);
|
|
887
940
|
}
|
|
888
|
-
const s =
|
|
941
|
+
const s = U(this.config.btcNetwork);
|
|
889
942
|
try {
|
|
890
|
-
return `0x${
|
|
943
|
+
return `0x${L.address.toOutputScript(e, s).toString("hex")}`;
|
|
891
944
|
} catch {
|
|
892
945
|
throw new Error(
|
|
893
946
|
`Invalid BTC payout address: "${e}". Please provide a valid Bitcoin address for the ${this.config.btcNetwork} network.`
|
|
@@ -903,11 +956,11 @@ class Ht {
|
|
|
903
956
|
async resolvePopSignature(t, e) {
|
|
904
957
|
if (e)
|
|
905
958
|
return e;
|
|
906
|
-
const s = this.config.vaultContracts.btcVaultsManager,
|
|
907
|
-
|
|
959
|
+
const s = this.config.vaultContracts.btcVaultsManager, o = `${t.toLowerCase()}:${this.config.ethChain.id}:pegin:${s.toLowerCase()}`, r = await this.config.btcWallet.signMessage(
|
|
960
|
+
o,
|
|
908
961
|
"bip322-simple"
|
|
909
962
|
);
|
|
910
|
-
return
|
|
963
|
+
return r.startsWith("0x") ? r : `0x${f.from(r, "base64").toString("hex")}`;
|
|
911
964
|
}
|
|
912
965
|
/**
|
|
913
966
|
* Gets the configured Bitcoin network.
|
|
@@ -926,14 +979,14 @@ class Ht {
|
|
|
926
979
|
return this.config.vaultContracts.btcVaultsManager;
|
|
927
980
|
}
|
|
928
981
|
}
|
|
929
|
-
class
|
|
982
|
+
class Ot {
|
|
930
983
|
/**
|
|
931
984
|
* Creates a new PayoutManager instance.
|
|
932
985
|
*
|
|
933
986
|
* @param config - Manager configuration including wallet
|
|
934
987
|
*/
|
|
935
988
|
constructor(t) {
|
|
936
|
-
|
|
989
|
+
H(this, "config");
|
|
937
990
|
this.config = t;
|
|
938
991
|
}
|
|
939
992
|
/**
|
|
@@ -959,10 +1012,10 @@ class Ut {
|
|
|
959
1012
|
* @throws Error if wallet operations fail or signature extraction fails
|
|
960
1013
|
*/
|
|
961
1014
|
async signPayoutTransaction(t) {
|
|
962
|
-
const e = await this.config.btcWallet.getPublicKeyHex(), { depositorPubkey: s } =
|
|
1015
|
+
const e = await this.config.btcWallet.getPublicKeyHex(), { depositorPubkey: s } = V(
|
|
963
1016
|
e,
|
|
964
1017
|
t.depositorBtcPubkey
|
|
965
|
-
),
|
|
1018
|
+
), o = await M({
|
|
966
1019
|
payoutTxHex: t.payoutTxHex,
|
|
967
1020
|
peginTxHex: t.peginTxHex,
|
|
968
1021
|
assertTxHex: t.assertTxHex,
|
|
@@ -972,8 +1025,8 @@ class Ut {
|
|
|
972
1025
|
universalChallengerBtcPubkeys: t.universalChallengerBtcPubkeys,
|
|
973
1026
|
timelockPegin: t.timelockPegin,
|
|
974
1027
|
network: this.config.network
|
|
975
|
-
}),
|
|
976
|
-
|
|
1028
|
+
}), r = await this.config.btcWallet.signPsbt(
|
|
1029
|
+
o.psbtHex,
|
|
977
1030
|
{
|
|
978
1031
|
autoFinalized: !1,
|
|
979
1032
|
signInputs: [
|
|
@@ -986,7 +1039,7 @@ class Ut {
|
|
|
986
1039
|
}
|
|
987
1040
|
);
|
|
988
1041
|
return {
|
|
989
|
-
signature:
|
|
1042
|
+
signature: R(r, s),
|
|
990
1043
|
depositorBtcPubkey: s
|
|
991
1044
|
};
|
|
992
1045
|
}
|
|
@@ -1020,25 +1073,25 @@ class Ut {
|
|
|
1020
1073
|
throw new Error(
|
|
1021
1074
|
"Wallet does not support batch signing (signPsbts method not available)"
|
|
1022
1075
|
);
|
|
1023
|
-
const e = await this.config.btcWallet.getPublicKeyHex(), s = [],
|
|
1024
|
-
for (const
|
|
1025
|
-
const { depositorPubkey:
|
|
1076
|
+
const e = await this.config.btcWallet.getPublicKeyHex(), s = [], o = [], r = [];
|
|
1077
|
+
for (const a of t) {
|
|
1078
|
+
const { depositorPubkey: u } = V(
|
|
1026
1079
|
e,
|
|
1027
|
-
|
|
1080
|
+
a.depositorBtcPubkey
|
|
1028
1081
|
);
|
|
1029
|
-
|
|
1030
|
-
const l = await
|
|
1031
|
-
payoutTxHex:
|
|
1032
|
-
peginTxHex:
|
|
1033
|
-
assertTxHex:
|
|
1034
|
-
depositorBtcPubkey:
|
|
1035
|
-
vaultProviderBtcPubkey:
|
|
1036
|
-
vaultKeeperBtcPubkeys:
|
|
1037
|
-
universalChallengerBtcPubkeys:
|
|
1038
|
-
timelockPegin:
|
|
1082
|
+
r.push(u);
|
|
1083
|
+
const l = await M({
|
|
1084
|
+
payoutTxHex: a.payoutTxHex,
|
|
1085
|
+
peginTxHex: a.peginTxHex,
|
|
1086
|
+
assertTxHex: a.assertTxHex,
|
|
1087
|
+
depositorBtcPubkey: u,
|
|
1088
|
+
vaultProviderBtcPubkey: a.vaultProviderBtcPubkey,
|
|
1089
|
+
vaultKeeperBtcPubkeys: a.vaultKeeperBtcPubkeys,
|
|
1090
|
+
universalChallengerBtcPubkeys: a.universalChallengerBtcPubkeys,
|
|
1091
|
+
timelockPegin: a.timelockPegin,
|
|
1039
1092
|
network: this.config.network
|
|
1040
1093
|
});
|
|
1041
|
-
s.push(l.psbtHex),
|
|
1094
|
+
s.push(l.psbtHex), o.push({
|
|
1042
1095
|
autoFinalized: !1,
|
|
1043
1096
|
signInputs: [
|
|
1044
1097
|
{
|
|
@@ -1049,66 +1102,54 @@ class Ut {
|
|
|
1049
1102
|
]
|
|
1050
1103
|
});
|
|
1051
1104
|
}
|
|
1052
|
-
const
|
|
1105
|
+
const c = await this.config.btcWallet.signPsbts(
|
|
1053
1106
|
s,
|
|
1054
|
-
|
|
1107
|
+
o
|
|
1055
1108
|
);
|
|
1056
|
-
if (
|
|
1109
|
+
if (c.length !== t.length)
|
|
1057
1110
|
throw new Error(
|
|
1058
|
-
`Expected ${t.length} signed PSBTs but received ${
|
|
1111
|
+
`Expected ${t.length} signed PSBTs but received ${c.length}`
|
|
1059
1112
|
);
|
|
1060
1113
|
const i = [];
|
|
1061
|
-
for (let
|
|
1062
|
-
const
|
|
1063
|
-
|
|
1064
|
-
|
|
1114
|
+
for (let a = 0; a < t.length; a++) {
|
|
1115
|
+
const u = r[a], l = R(
|
|
1116
|
+
c[a],
|
|
1117
|
+
u
|
|
1065
1118
|
);
|
|
1066
1119
|
i.push({
|
|
1067
1120
|
payoutSignature: l,
|
|
1068
|
-
depositorBtcPubkey:
|
|
1121
|
+
depositorBtcPubkey: u
|
|
1069
1122
|
});
|
|
1070
1123
|
}
|
|
1071
1124
|
return i;
|
|
1072
1125
|
}
|
|
1073
1126
|
}
|
|
1074
1127
|
export {
|
|
1075
|
-
|
|
1076
|
-
N as B,
|
|
1128
|
+
B,
|
|
1077
1129
|
x as C,
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
st as p,
|
|
1103
|
-
kt as q,
|
|
1104
|
-
et as r,
|
|
1105
|
-
nt as s,
|
|
1106
|
-
ut as t,
|
|
1107
|
-
lt as u,
|
|
1108
|
-
it as v,
|
|
1109
|
-
ct as w,
|
|
1110
|
-
B as x,
|
|
1111
|
-
U as y,
|
|
1112
|
-
$t as z
|
|
1130
|
+
dt as M,
|
|
1131
|
+
Ut as P,
|
|
1132
|
+
wt as a,
|
|
1133
|
+
vt as b,
|
|
1134
|
+
X as c,
|
|
1135
|
+
kt as d,
|
|
1136
|
+
ut as e,
|
|
1137
|
+
lt as f,
|
|
1138
|
+
Tt as g,
|
|
1139
|
+
Ot as h,
|
|
1140
|
+
Ht as i,
|
|
1141
|
+
Et as j,
|
|
1142
|
+
St as k,
|
|
1143
|
+
It as l,
|
|
1144
|
+
Bt as m,
|
|
1145
|
+
ht as n,
|
|
1146
|
+
gt as o,
|
|
1147
|
+
pt as p,
|
|
1148
|
+
$ as q,
|
|
1149
|
+
O as r,
|
|
1150
|
+
ct as s,
|
|
1151
|
+
$t as t,
|
|
1152
|
+
Ct as u,
|
|
1153
|
+
z as v
|
|
1113
1154
|
};
|
|
1114
|
-
//# sourceMappingURL=PayoutManager-
|
|
1155
|
+
//# sourceMappingURL=PayoutManager-B8vLG1dE.js.map
|