@babylonlabs-io/ts-sdk 5.1.0 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PayoutManager-BHeiLQ1j.js → PayoutManager-3-MzBVLj.js} +2 -2
- package/dist/{PayoutManager-BHeiLQ1j.js.map → PayoutManager-3-MzBVLj.js.map} +1 -1
- package/dist/{PayoutManager-B5nR0x1t.cjs → PayoutManager-PQqeqX41.cjs} +2 -2
- package/dist/{PayoutManager-B5nR0x1t.cjs.map → PayoutManager-PQqeqX41.cjs.map} +1 -1
- package/dist/{PeginManager-6ghglb4r.cjs → PeginManager-D_ZUfbIy.cjs} +2 -2
- package/dist/{PeginManager-6ghglb4r.cjs.map → PeginManager-D_ZUfbIy.cjs.map} +1 -1
- package/dist/{PeginManager-CXNqbgA4.js → PeginManager-m3IlM4wS.js} +4 -4
- package/dist/{PeginManager-CXNqbgA4.js.map → PeginManager-m3IlM4wS.js.map} +1 -1
- package/dist/{buildAndBroadcastReclaim-Cf05JFP-.cjs → buildAndBroadcastReclaim-CMjlyooo.cjs} +2 -2
- package/dist/{buildAndBroadcastReclaim-Cf05JFP-.cjs.map → buildAndBroadcastReclaim-CMjlyooo.cjs.map} +1 -1
- package/dist/{buildAndBroadcastReclaim-Acz637Vf.js → buildAndBroadcastReclaim-D8l-QJWo.js} +793 -772
- package/dist/{buildAndBroadcastReclaim-Acz637Vf.js.map → buildAndBroadcastReclaim-D8l-QJWo.js.map} +1 -1
- package/dist/{challengeAssert-CuX_8Twt.cjs → challengeAssert-DlzX_kjF.cjs} +2 -2
- package/dist/{challengeAssert-CuX_8Twt.cjs.map → challengeAssert-DlzX_kjF.cjs.map} +1 -1
- package/dist/{challengeAssert-D_lRvsO0.js → challengeAssert-hpOHGPXX.js} +2 -2
- package/dist/{challengeAssert-D_lRvsO0.js.map → challengeAssert-hpOHGPXX.js.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +312 -309
- package/dist/index.js.map +1 -1
- package/dist/peginState-B4t_PDgj.cjs.map +1 -1
- package/dist/peginState-CXdbSit3.js.map +1 -1
- package/dist/tbv/core/index.cjs +1 -1
- package/dist/tbv/core/index.js +306 -303
- package/dist/tbv/core/index.js.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/primitives/index.cjs +1 -1
- package/dist/tbv/core/primitives/index.d.ts +5 -0
- package/dist/tbv/core/primitives/index.d.ts.map +1 -1
- package/dist/tbv/core/primitives/index.js +31 -29
- package/dist/tbv/core/primitives/index.js.map +1 -1
- package/dist/tbv/core/primitives/psbt/__tests__/signetPeginHashlockSpend.fixture.d.ts +19 -0
- package/dist/tbv/core/primitives/psbt/__tests__/signetPeginHashlockSpend.fixture.d.ts.map +1 -0
- package/dist/tbv/core/primitives/psbt/__tests__/verifyPeginHashlockSpend.test.d.ts +9 -0
- package/dist/tbv/core/primitives/psbt/__tests__/verifyPeginHashlockSpend.test.d.ts.map +1 -0
- package/dist/tbv/core/primitives/psbt/verifyPeginHashlockSpend.d.ts +73 -0
- package/dist/tbv/core/primitives/psbt/verifyPeginHashlockSpend.d.ts.map +1 -0
- package/dist/tbv/core/recovery/reconstructPeginParams.d.ts +6 -0
- package/dist/tbv/core/recovery/reconstructPeginParams.d.ts.map +1 -1
- package/dist/tbv/core/recovery/toRefundInputs.d.ts +0 -2
- package/dist/tbv/core/recovery/toRefundInputs.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/peginState.d.ts +16 -5
- package/dist/tbv/core/services/deposit/peginState.d.ts.map +1 -1
- package/dist/tbv/core/services/index.cjs +1 -1
- package/dist/tbv/core/services/index.js +74 -73
- package/dist/tbv/core/services/refund/buildAndBroadcastRefund.d.ts +6 -2
- package/dist/tbv/core/services/refund/buildAndBroadcastRefund.d.ts.map +1 -1
- package/dist/tbv/core/services/refund/errors.d.ts +15 -0
- package/dist/tbv/core/services/refund/errors.d.ts.map +1 -1
- package/dist/tbv/core/services/refund/index.d.ts +1 -1
- package/dist/tbv/core/services/refund/index.d.ts.map +1 -1
- package/dist/tbv/index.cjs +1 -1
- package/dist/tbv/index.js +306 -303
- package/dist/tbv/index.js.map +1 -1
- package/dist/{toRefundInputs-DwXpKQxN.js → toRefundInputs-D5tx3eeA.js} +152 -152
- package/dist/{toRefundInputs-DwXpKQxN.js.map → toRefundInputs-D5tx3eeA.js.map} +1 -1
- package/dist/{toRefundInputs-BzyN0zvj.cjs → toRefundInputs-Df6eRITl.cjs} +2 -2
- package/dist/{toRefundInputs-BzyN0zvj.cjs.map → toRefundInputs-Df6eRITl.cjs.map} +1 -1
- package/dist/{verifyKeyPathSchnorrSignature-BVrAmVL3.cjs → verifyKeyPathSchnorrSignature-B7Za6aa1.cjs} +2 -2
- package/dist/{verifyKeyPathSchnorrSignature-BVrAmVL3.cjs.map → verifyKeyPathSchnorrSignature-B7Za6aa1.cjs.map} +1 -1
- package/dist/{verifyKeyPathSchnorrSignature-CIE3jlVt.js → verifyKeyPathSchnorrSignature-dw7xhm5Y.js} +2 -2
- package/dist/{verifyKeyPathSchnorrSignature-CIE3jlVt.js.map → verifyKeyPathSchnorrSignature-dw7xhm5Y.js.map} +1 -1
- package/dist/verifyPeginHashlockSpend-CdTFR2K6.js +167 -0
- package/dist/verifyPeginHashlockSpend-CdTFR2K6.js.map +1 -0
- package/dist/verifyPeginHashlockSpend-CisfqMuT.cjs +2 -0
- package/dist/verifyPeginHashlockSpend-CisfqMuT.cjs.map +1 -0
- package/dist/{verifyScriptPathSchnorrSignature-DLNGgm4j.js → verifyScriptPathSchnorrSignature-BVGPEZXW.js} +9 -8
- package/dist/{verifyScriptPathSchnorrSignature-DLNGgm4j.js.map → verifyScriptPathSchnorrSignature-BVGPEZXW.js.map} +1 -1
- package/dist/{verifyScriptPathSchnorrSignature-BHskbJJx.cjs → verifyScriptPathSchnorrSignature-p3sVoWQi.cjs} +2 -2
- package/dist/{verifyScriptPathSchnorrSignature-BHskbJJx.cjs.map → verifyScriptPathSchnorrSignature-p3sVoWQi.cjs.map} +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import * as N from "@bitcoin-js/tiny-secp256k1-asmjs";
|
|
2
|
+
import { Transaction as O, crypto as b, script as C, opcodes as i } from "bitcoinjs-lib";
|
|
3
|
+
import { Buffer as _ } from "buffer";
|
|
4
|
+
import { s as m, T as k } from "./bitcoin-C-TuHb-v.js";
|
|
5
|
+
import { l as B, m as F } from "./verifyScriptPathSchnorrSignature-BVGPEZXW.js";
|
|
6
|
+
const L = 32, E = 32, A = 64, U = 65, w = /* @__PURE__ */ new Set([
|
|
7
|
+
1,
|
|
8
|
+
2,
|
|
9
|
+
3,
|
|
10
|
+
129,
|
|
11
|
+
130,
|
|
12
|
+
131
|
|
13
|
+
]), X = 0, D = 80, R = 2, q = 3, Q = 2, W = 80, z = 16, H = (e) => m(e).toLowerCase(), r = (e) => ({
|
|
14
|
+
valid: !1,
|
|
15
|
+
reason: e
|
|
16
|
+
});
|
|
17
|
+
function g(e, t) {
|
|
18
|
+
return _.isBuffer(e) && e.length === t;
|
|
19
|
+
}
|
|
20
|
+
function Z(e) {
|
|
21
|
+
if (typeof e == "number") {
|
|
22
|
+
const t = e - W;
|
|
23
|
+
return t >= 1 && t <= z ? t : void 0;
|
|
24
|
+
}
|
|
25
|
+
if (_.isBuffer(e))
|
|
26
|
+
try {
|
|
27
|
+
return C.number.decode(e);
|
|
28
|
+
} catch {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function j(e) {
|
|
33
|
+
const t = C.decompile(e);
|
|
34
|
+
if (!t || !_.from(C.compile(t)).equals(e))
|
|
35
|
+
return;
|
|
36
|
+
let c = 0;
|
|
37
|
+
const o = () => t[c++];
|
|
38
|
+
if (o() !== i.OP_SIZE) return;
|
|
39
|
+
const l = o();
|
|
40
|
+
if (!g(l, 1) || l[0] !== L || o() !== i.OP_EQUALVERIFY || o() !== i.OP_SHA256) return;
|
|
41
|
+
const f = o();
|
|
42
|
+
if (!g(f, L) || o() !== i.OP_EQUALVERIFY) return;
|
|
43
|
+
const n = o();
|
|
44
|
+
if (!g(n, E) || o() !== i.OP_CHECKSIGVERIFY) return;
|
|
45
|
+
const v = o();
|
|
46
|
+
if (!g(v, E) || o() !== i.OP_CHECKSIGVERIFY) return;
|
|
47
|
+
const P = [];
|
|
48
|
+
for (; ; ) {
|
|
49
|
+
const a = o();
|
|
50
|
+
if (!g(a, E) || o() !== i.OP_CHECKSIG) return;
|
|
51
|
+
const d = [a];
|
|
52
|
+
for (; ; ) {
|
|
53
|
+
const S = t[c];
|
|
54
|
+
if (!g(S, E) || t[c + 1] !== i.OP_CHECKSIGADD)
|
|
55
|
+
break;
|
|
56
|
+
d.push(S), c += 2;
|
|
57
|
+
}
|
|
58
|
+
const h = Z(o());
|
|
59
|
+
if (h === void 0 || h < 1 || h > d.length)
|
|
60
|
+
return;
|
|
61
|
+
P.push({ keys: d, threshold: h });
|
|
62
|
+
const s = o();
|
|
63
|
+
if (s === i.OP_NUMEQUAL) break;
|
|
64
|
+
if (s !== i.OP_NUMEQUALVERIFY || P.length === Q) return;
|
|
65
|
+
}
|
|
66
|
+
if (c === t.length)
|
|
67
|
+
return { hashlock: f, depositorKey: n, vaultProviderKey: v, groups: P };
|
|
68
|
+
}
|
|
69
|
+
function re(e) {
|
|
70
|
+
let t, c;
|
|
71
|
+
try {
|
|
72
|
+
t = O.fromHex(m(e.peginTxHex)), c = O.fromHex(m(e.prePeginTxHex));
|
|
73
|
+
} catch {
|
|
74
|
+
return r("a served transaction does not parse");
|
|
75
|
+
}
|
|
76
|
+
if (H(t.getId()) !== H(e.peginTxid))
|
|
77
|
+
return r("the served PegIn is not the on-chain signed PegIn");
|
|
78
|
+
const o = H(e.prePeginTxid);
|
|
79
|
+
if (H(c.getId()) !== o)
|
|
80
|
+
return r("the served Pre-PegIn is not the registered one");
|
|
81
|
+
if (t.ins.length !== 1)
|
|
82
|
+
return r("the PegIn does not have exactly one input");
|
|
83
|
+
const [l] = t.ins;
|
|
84
|
+
if (l.index !== e.htlcVout || _.from(l.hash).reverse().toString("hex") !== o)
|
|
85
|
+
return r("the PegIn does not spend the vault's HTLC output");
|
|
86
|
+
const f = c.outs[e.htlcVout];
|
|
87
|
+
if (!f)
|
|
88
|
+
return r("the Pre-PegIn has no output at the HTLC index");
|
|
89
|
+
const n = l.witness;
|
|
90
|
+
if (n.length < R)
|
|
91
|
+
return r("the HTLC input has no script-path witness");
|
|
92
|
+
const v = n[n.length - 1];
|
|
93
|
+
if (v.length > 0 && v[0] === D)
|
|
94
|
+
return r("the HTLC input's witness carries an annex");
|
|
95
|
+
const P = n[n.length - 1], a = n[n.length - 2], d = n.slice(0, n.length - R);
|
|
96
|
+
let h;
|
|
97
|
+
try {
|
|
98
|
+
h = B({
|
|
99
|
+
leafVersion: k,
|
|
100
|
+
script: a,
|
|
101
|
+
controlBlock: P
|
|
102
|
+
});
|
|
103
|
+
} catch {
|
|
104
|
+
return r("the control block is malformed");
|
|
105
|
+
}
|
|
106
|
+
if (!h.equals(f.script))
|
|
107
|
+
return r("the leaf is not committed to the vault's HTLC output");
|
|
108
|
+
const s = j(a);
|
|
109
|
+
if (!s)
|
|
110
|
+
return r("the spent leaf is not the hashlock leaf");
|
|
111
|
+
if (!s.hashlock.equals(_.from(m(e.hashlock), "hex")))
|
|
112
|
+
return r("the leaf's hashlock is not the vault's");
|
|
113
|
+
const S = s.groups.reduce((u, p) => u + p.keys.length, 0);
|
|
114
|
+
if (d.length !== q + S)
|
|
115
|
+
return r("the witness does not hold one item per check of the leaf");
|
|
116
|
+
const [x, K, Y, ...G] = [
|
|
117
|
+
...d
|
|
118
|
+
].reverse();
|
|
119
|
+
if (x.length !== L || !b.sha256(x).equals(s.hashlock))
|
|
120
|
+
return r("the witness does not open the hashlock");
|
|
121
|
+
const V = F(k, a), y = (u, p) => {
|
|
122
|
+
let T = X;
|
|
123
|
+
if (u.length === U) {
|
|
124
|
+
if (T = u[A], !w.has(T)) return !1;
|
|
125
|
+
} else if (u.length !== A)
|
|
126
|
+
return !1;
|
|
127
|
+
try {
|
|
128
|
+
const I = t.hashForWitnessV1(
|
|
129
|
+
0,
|
|
130
|
+
[f.script],
|
|
131
|
+
[f.value],
|
|
132
|
+
T,
|
|
133
|
+
V
|
|
134
|
+
);
|
|
135
|
+
return N.verifySchnorr(
|
|
136
|
+
I,
|
|
137
|
+
p,
|
|
138
|
+
u.subarray(0, A)
|
|
139
|
+
);
|
|
140
|
+
} catch {
|
|
141
|
+
return !1;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
if (!y(K, s.depositorKey))
|
|
145
|
+
return r("the depositor's signature does not verify");
|
|
146
|
+
if (!y(Y, s.vaultProviderKey))
|
|
147
|
+
return r("the vault provider's signature does not verify");
|
|
148
|
+
let M = 0;
|
|
149
|
+
for (const u of s.groups) {
|
|
150
|
+
let p = 0;
|
|
151
|
+
for (const T of u.keys) {
|
|
152
|
+
const I = G[M++];
|
|
153
|
+
if (I.length !== 0) {
|
|
154
|
+
if (!y(I, T))
|
|
155
|
+
return r("a multisig signature does not verify");
|
|
156
|
+
p += 1;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (p !== u.threshold)
|
|
160
|
+
return r("a multisig block is short of its threshold");
|
|
161
|
+
}
|
|
162
|
+
return { valid: !0 };
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
re as v
|
|
166
|
+
};
|
|
167
|
+
//# sourceMappingURL=verifyPeginHashlockSpend-CdTFR2K6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyPeginHashlockSpend-CdTFR2K6.js","sources":["../src/tbv/core/primitives/psbt/verifyPeginHashlockSpend.ts"],"sourcesContent":["/**\n * Consensus check of a PegIn's spend of its vault's Pre-PegIn HTLC through the\n * hashlock leaf.\n *\n * A Bitcoin API is not trusted to say that a vault's PegIn swept its HTLC. It\n * can name the PegIn's public txid as the HTLC's spender, and serve back the\n * depositor-signed PegIn the registry publishes: a txid does not commit to the\n * witness. Finding the hashlock preimage in a served witness is not enough\n * either — a secret disclosed in a reverted activation's calldata can be copied\n * into a witness whose signatures are garbage. This check verifies the witness\n * the way Bitcoin would:\n *\n * - the Pre-PegIn is the registered one (its txid), so the HTLC output's script\n * and value are authentic;\n * - the leaf script and control block commit to that output (BIP-341);\n * - the leaf is the hashlock leaf, its preimage opens the registered hashlock,\n * and every signature it requires verifies against the PegIn's script-path\n * sighash (BIP-342).\n *\n * A PegIn that passes is a valid spend of the HTLC: while the HTLC is unspent,\n * its holder can broadcast it to sweep the HTLC. It proves that much — not that\n * it was broadcast, nor that the HTLC is still unspent (the depositor's refund\n * may have taken it). The participants' PegIn input signatures are public —\n * the registry serves them\n * (vault-contracts-aave-v4@f5ef5633:src/protocol/BTCVaultRegistry.sol:918-925,\n * `getPeginInputSignaturesForVault`) and the depositor's is in the signed\n * PegIn — so the secret is the one ingredient that is not. Until it is public\n * no one can produce a passing PegIn; once it is, anyone can.\n *\n * The leaf (btc-vault@1d841f73:crates/vault/src/connectors/prepegin_htlc.rs:88-126,\n * multisig blocks from crates/vault/src/connectors/script_utils.rs:29-78):\n *\n * OP_SIZE <32> OP_EQUALVERIFY OP_SHA256 <h> OP_EQUALVERIFY\n * <D> OP_CHECKSIGVERIFY <VP> OP_CHECKSIGVERIFY\n * <VK_1> OP_CHECKSIG <VK_2..N> OP_CHECKSIGADD <N> OP_NUMEQUALVERIFY\n * <UC_1> OP_CHECKSIG <UC_2..M> OP_CHECKSIGADD <M> OP_NUMEQUAL\n *\n * With no universal challengers the keeper block ends in `OP_NUMEQUAL`. The\n * witness is the evaluation order reversed:\n * `[UC_M..UC_1, VK_N..VK_1, VP, D, preimage, script, control block]`\n * (btc-vault@1d841f73:crates/vault/src/sign.rs:718-761).\n *\n * @module primitives/psbt/verifyPeginHashlockSpend\n */\n\nimport * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport {\n crypto as bcrypto,\n script as bscript,\n opcodes,\n Transaction,\n} from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\nimport { stripHexPrefix, TAPSCRIPT_LEAF_VERSION } from \"../utils/bitcoin\";\nimport {\n computeTapLeafHash,\n computeTaprootScriptPubKey,\n} from \"../utils/taproot\";\n\n/** The hashlock leaf enforces `OP_SIZE <32> OP_EQUALVERIFY` on the preimage. */\nconst PREIMAGE_BYTES = 32;\n/** BIP-340 x-only public key. */\nconst X_ONLY_KEY_BYTES = 32;\n/** BIP-340 signature; a 65th byte carries an explicit sighash type (BIP-341). */\nconst SCHNORR_SIG_BYTES = 64;\nconst SCHNORR_SIG_WITH_HASH_TYPE_BYTES = 65;\n/**\n * The explicit sighash types BIP-341 accepts — ALL, NONE, SINGLE, each alone or\n * with ANYONECANPAY (0x80); `SIGHASH_DEFAULT` (0x00) is only implicit. Literal\n * values, so this module reads nothing from bitcoinjs at import time.\n */\nconst EXPLICIT_TAPROOT_HASH_TYPES = new Set([\n 0x01, 0x02, 0x03, 0x81, 0x82, 0x83,\n]);\n/** BIP-341 `SIGHASH_DEFAULT`: the type of a 64-byte signature. */\nconst SIGHASH_DEFAULT = 0x00;\n/** BIP-341: a last witness item starting with this byte is an annex. */\nconst ANNEX_TAG = 0x50;\n/** Script and control block follow the stack items in a script-path witness. */\nconst SCRIPT_PATH_TRAILER_ITEMS = 2;\n/** The preimage, the depositor's and the vault provider's signatures. */\nconst FIXED_STACK_ITEMS = 3;\n/** Keepers, then — when the vault has any — universal challengers. */\nconst MAX_MULTISIG_GROUPS = 2;\n/** `OP_1`..`OP_16` (0x51..0x60) push 1..16: the value is the opcode less `OP_RESERVED` (0x50). */\nconst SMALL_INT_OPCODE_BASE = 0x50;\nconst SMALL_INT_MAX = 16;\n\n/** The on-chain facts a served PegIn and Pre-PegIn are checked against. */\nexport interface VerifyPeginHashlockSpendParams {\n /** The PegIn as a Bitcoin API served it, witness included. */\n peginTxHex: string;\n /** The vault's Pre-PegIn as a Bitcoin API served it; authenticated by its txid. */\n prePeginTxHex: string;\n /** Txid of the vault's on-chain signed PegIn. */\n peginTxid: string;\n /** The vault's registered Pre-PegIn txid. */\n prePeginTxid: string;\n /** The vault's registered HTLC output index in the Pre-PegIn. */\n htlcVout: number;\n /** The vault's registered hashlock, `sha256(secret)`. */\n hashlock: string;\n}\n\n/** Whether the PegIn validly spends the HTLC; a refusal names its reason. */\nexport type PeginHashlockSpendVerdict =\n | { valid: true }\n | { valid: false; reason: string };\n\ninterface MultisigGroup {\n keys: Buffer[];\n threshold: number;\n}\n\ninterface HashlockLeaf {\n hashlock: Buffer;\n depositorKey: Buffer;\n vaultProviderKey: Buffer;\n /** In evaluation order: keepers, then universal challengers. */\n groups: MultisigGroup[];\n}\n\nconst canonicalTxid = (txid: string): string =>\n stripHexPrefix(txid).toLowerCase();\n\nconst refuse = (reason: string): PeginHashlockSpendVerdict => ({\n valid: false,\n reason,\n});\n\nfunction isPush(\n chunk: number | Buffer | undefined,\n length: number,\n): chunk is Buffer {\n return Buffer.isBuffer(chunk) && chunk.length === length;\n}\n\n/** A threshold pushed as `OP_1`..`OP_16` or as a minimal script number. */\nfunction decodeThreshold(\n chunk: number | Buffer | undefined,\n): number | undefined {\n if (typeof chunk === \"number\") {\n const value = chunk - SMALL_INT_OPCODE_BASE;\n return value >= 1 && value <= SMALL_INT_MAX ? value : undefined;\n }\n if (!Buffer.isBuffer(chunk)) return undefined;\n try {\n return bscript.number.decode(chunk);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Parse the hashlock leaf, or `undefined` for any other script. The script must\n * be minimally encoded — decompiling and recompiling it must give back the same\n * bytes — so the parse describes exactly the bytes that will execute.\n */\nfunction parseHashlockLeaf(leafScript: Buffer): HashlockLeaf | undefined {\n const chunks = bscript.decompile(leafScript);\n if (!chunks || !Buffer.from(bscript.compile(chunks)).equals(leafScript)) {\n return undefined;\n }\n let i = 0;\n const next = () => chunks[i++];\n\n if (next() !== opcodes.OP_SIZE) return undefined;\n const size = next();\n if (!isPush(size, 1) || size[0] !== PREIMAGE_BYTES) return undefined;\n if (next() !== opcodes.OP_EQUALVERIFY) return undefined;\n if (next() !== opcodes.OP_SHA256) return undefined;\n const hashlock = next();\n if (!isPush(hashlock, PREIMAGE_BYTES)) return undefined;\n if (next() !== opcodes.OP_EQUALVERIFY) return undefined;\n const depositorKey = next();\n if (!isPush(depositorKey, X_ONLY_KEY_BYTES)) return undefined;\n if (next() !== opcodes.OP_CHECKSIGVERIFY) return undefined;\n const vaultProviderKey = next();\n if (!isPush(vaultProviderKey, X_ONLY_KEY_BYTES)) return undefined;\n if (next() !== opcodes.OP_CHECKSIGVERIFY) return undefined;\n\n const groups: MultisigGroup[] = [];\n for (;;) {\n const firstKey = next();\n if (!isPush(firstKey, X_ONLY_KEY_BYTES)) return undefined;\n if (next() !== opcodes.OP_CHECKSIG) return undefined;\n const keys = [firstKey];\n for (;;) {\n const key = chunks[i];\n if (\n !isPush(key, X_ONLY_KEY_BYTES) ||\n chunks[i + 1] !== opcodes.OP_CHECKSIGADD\n ) {\n break;\n }\n keys.push(key);\n i += 2;\n }\n const threshold = decodeThreshold(next());\n if (threshold === undefined || threshold < 1 || threshold > keys.length) {\n return undefined;\n }\n groups.push({ keys, threshold });\n const close = next();\n if (close === opcodes.OP_NUMEQUAL) break;\n if (close !== opcodes.OP_NUMEQUALVERIFY) return undefined;\n if (groups.length === MAX_MULTISIG_GROUPS) return undefined;\n }\n if (i !== chunks.length) return undefined;\n\n return { hashlock, depositorKey, vaultProviderKey, groups };\n}\n\n/**\n * Verify a served PegIn spends the vault's HTLC through the hashlock leaf with\n * a witness Bitcoin would accept. Never throws on malformed input: anything that\n * is not such a spend is a refusal.\n */\nexport function verifyPeginHashlockSpend(\n params: VerifyPeginHashlockSpendParams,\n): PeginHashlockSpendVerdict {\n let pegin: Transaction;\n let prePegin: Transaction;\n try {\n pegin = Transaction.fromHex(stripHexPrefix(params.peginTxHex));\n prePegin = Transaction.fromHex(stripHexPrefix(params.prePeginTxHex));\n } catch {\n return refuse(\"a served transaction does not parse\");\n }\n\n if (canonicalTxid(pegin.getId()) !== canonicalTxid(params.peginTxid)) {\n return refuse(\"the served PegIn is not the on-chain signed PegIn\");\n }\n const prePeginTxid = canonicalTxid(params.prePeginTxid);\n if (canonicalTxid(prePegin.getId()) !== prePeginTxid) {\n return refuse(\"the served Pre-PegIn is not the registered one\");\n }\n\n // The protocol's PegIn has a single input. With more, the sighash would also\n // commit to prevouts this check cannot authenticate.\n if (pegin.ins.length !== 1) {\n return refuse(\"the PegIn does not have exactly one input\");\n }\n const [input] = pegin.ins;\n if (\n input.index !== params.htlcVout ||\n Buffer.from(input.hash).reverse().toString(\"hex\") !== prePeginTxid\n ) {\n return refuse(\"the PegIn does not spend the vault's HTLC output\");\n }\n const htlcOutput = prePegin.outs[params.htlcVout];\n if (!htlcOutput) {\n return refuse(\"the Pre-PegIn has no output at the HTLC index\");\n }\n\n const witness = input.witness;\n if (witness.length < SCRIPT_PATH_TRAILER_ITEMS) {\n return refuse(\"the HTLC input has no script-path witness\");\n }\n const lastItem = witness[witness.length - 1];\n if (lastItem.length > 0 && lastItem[0] === ANNEX_TAG) {\n return refuse(\"the HTLC input's witness carries an annex\");\n }\n const controlBlock = witness[witness.length - 1];\n const leafScript = witness[witness.length - 2];\n const stack = witness.slice(0, witness.length - SCRIPT_PATH_TRAILER_ITEMS);\n\n let committedScriptPubKey: Buffer;\n try {\n committedScriptPubKey = computeTaprootScriptPubKey({\n leafVersion: TAPSCRIPT_LEAF_VERSION,\n script: leafScript,\n controlBlock,\n });\n } catch {\n return refuse(\"the control block is malformed\");\n }\n if (!committedScriptPubKey.equals(htlcOutput.script)) {\n return refuse(\"the leaf is not committed to the vault's HTLC output\");\n }\n\n const leaf = parseHashlockLeaf(leafScript);\n if (!leaf) {\n return refuse(\"the spent leaf is not the hashlock leaf\");\n }\n if (\n !leaf.hashlock.equals(Buffer.from(stripHexPrefix(params.hashlock), \"hex\"))\n ) {\n return refuse(\"the leaf's hashlock is not the vault's\");\n }\n\n // Tapscript's clean-stack rule: the leaf consumes every item, so the witness\n // holds exactly one per check.\n const keyCount = leaf.groups.reduce((n, group) => n + group.keys.length, 0);\n if (stack.length !== FIXED_STACK_ITEMS + keyCount) {\n return refuse(\"the witness does not hold one item per check of the leaf\");\n }\n const [preimage, depositorSig, vaultProviderSig, ...groupSigs] = [\n ...stack,\n ].reverse();\n\n if (\n preimage.length !== PREIMAGE_BYTES ||\n !bcrypto.sha256(preimage).equals(leaf.hashlock)\n ) {\n return refuse(\"the witness does not open the hashlock\");\n }\n\n const leafHash = computeTapLeafHash(TAPSCRIPT_LEAF_VERSION, leafScript);\n const signatureVerifies = (signature: Buffer, key: Buffer): boolean => {\n let hashType = SIGHASH_DEFAULT;\n if (signature.length === SCHNORR_SIG_WITH_HASH_TYPE_BYTES) {\n hashType = signature[SCHNORR_SIG_BYTES];\n if (!EXPLICIT_TAPROOT_HASH_TYPES.has(hashType)) return false;\n } else if (signature.length !== SCHNORR_SIG_BYTES) {\n return false;\n }\n try {\n const sighash = pegin.hashForWitnessV1(\n 0,\n [htlcOutput.script],\n [htlcOutput.value],\n hashType,\n leafHash,\n );\n return ecc.verifySchnorr(\n sighash,\n key,\n signature.subarray(0, SCHNORR_SIG_BYTES),\n );\n } catch {\n return false;\n }\n };\n\n // `OP_CHECKSIGVERIFY`: the signature must be present and valid.\n if (!signatureVerifies(depositorSig, leaf.depositorKey)) {\n return refuse(\"the depositor's signature does not verify\");\n }\n if (!signatureVerifies(vaultProviderSig, leaf.vaultProviderKey)) {\n return refuse(\"the vault provider's signature does not verify\");\n }\n\n // `OP_CHECKSIG` / `OP_CHECKSIGADD`: an empty signature counts nothing, and a\n // non-empty one that fails aborts the script (BIP-342).\n let offset = 0;\n for (const group of leaf.groups) {\n let valid = 0;\n for (const key of group.keys) {\n const signature = groupSigs[offset++];\n if (signature.length === 0) continue;\n if (!signatureVerifies(signature, key)) {\n return refuse(\"a multisig signature does not verify\");\n }\n valid += 1;\n }\n if (valid !== group.threshold) {\n return refuse(\"a multisig block is short of its threshold\");\n }\n }\n\n return { valid: true };\n}\n"],"names":["PREIMAGE_BYTES","X_ONLY_KEY_BYTES","SCHNORR_SIG_BYTES","SCHNORR_SIG_WITH_HASH_TYPE_BYTES","EXPLICIT_TAPROOT_HASH_TYPES","SIGHASH_DEFAULT","ANNEX_TAG","SCRIPT_PATH_TRAILER_ITEMS","FIXED_STACK_ITEMS","MAX_MULTISIG_GROUPS","SMALL_INT_OPCODE_BASE","SMALL_INT_MAX","canonicalTxid","txid","stripHexPrefix","refuse","reason","isPush","chunk","length","Buffer","decodeThreshold","value","bscript","parseHashlockLeaf","leafScript","chunks","i","next","opcodes","size","hashlock","depositorKey","vaultProviderKey","groups","firstKey","keys","key","threshold","close","verifyPeginHashlockSpend","params","pegin","prePegin","Transaction","prePeginTxid","input","htlcOutput","witness","lastItem","controlBlock","stack","committedScriptPubKey","computeTaprootScriptPubKey","TAPSCRIPT_LEAF_VERSION","leaf","keyCount","n","group","preimage","depositorSig","vaultProviderSig","groupSigs","bcrypto","leafHash","computeTapLeafHash","signatureVerifies","signature","hashType","sighash","ecc","offset","valid"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const Y=require("@bitcoin-js/tiny-secp256k1-asmjs"),n=require("bitcoinjs-lib"),T=require("buffer"),v=require("./bitcoin-D-O2GjbC.cjs"),L=require("./verifyScriptPathSchnorrSignature-p3sVoWQi.cjs");function N(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const s in e)if(s!=="default"){const r=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,r.get?r:{enumerable:!0,get:()=>e[s]})}}return t.default=e,Object.freeze(t)}const V=N(Y),x=32,H=32,O=64,G=65,M=new Set([1,2,3,129,130,131]),F=0,q=80,k=2,w=3,U=2,D=80,X=16,y=e=>v.stripHexPrefix(e).toLowerCase(),o=e=>({valid:!1,reason:e});function g(e,t){return T.Buffer.isBuffer(e)&&e.length===t}function j(e){if(typeof e=="number"){const t=e-D;return t>=1&&t<=X?t:void 0}if(T.Buffer.isBuffer(e))try{return n.script.number.decode(e)}catch{return}}function Q(e){const t=n.script.decompile(e);if(!t||!T.Buffer.from(n.script.compile(t)).equals(e))return;let s=0;const r=()=>t[s++];if(r()!==n.opcodes.OP_SIZE)return;const l=r();if(!g(l,1)||l[0]!==x||r()!==n.opcodes.OP_EQUALVERIFY||r()!==n.opcodes.OP_SHA256)return;const f=r();if(!g(f,x)||r()!==n.opcodes.OP_EQUALVERIFY)return;const i=r();if(!g(i,H)||r()!==n.opcodes.OP_CHECKSIGVERIFY)return;const P=r();if(!g(P,H)||r()!==n.opcodes.OP_CHECKSIGVERIFY)return;const S=[];for(;;){const a=r();if(!g(a,H)||r()!==n.opcodes.OP_CHECKSIG)return;const d=[a];for(;;){const I=t[s];if(!g(I,H)||t[s+1]!==n.opcodes.OP_CHECKSIGADD)break;d.push(I),s+=2}const h=j(r());if(h===void 0||h<1||h>d.length)return;S.push({keys:d,threshold:h});const c=r();if(c===n.opcodes.OP_NUMEQUAL)break;if(c!==n.opcodes.OP_NUMEQUALVERIFY||S.length===U)return}if(s===t.length)return{hashlock:f,depositorKey:i,vaultProviderKey:P,groups:S}}function z(e){let t,s;try{t=n.Transaction.fromHex(v.stripHexPrefix(e.peginTxHex)),s=n.Transaction.fromHex(v.stripHexPrefix(e.prePeginTxHex))}catch{return o("a served transaction does not parse")}if(y(t.getId())!==y(e.peginTxid))return o("the served PegIn is not the on-chain signed PegIn");const r=y(e.prePeginTxid);if(y(s.getId())!==r)return o("the served Pre-PegIn is not the registered one");if(t.ins.length!==1)return o("the PegIn does not have exactly one input");const[l]=t.ins;if(l.index!==e.htlcVout||T.Buffer.from(l.hash).reverse().toString("hex")!==r)return o("the PegIn does not spend the vault's HTLC output");const f=s.outs[e.htlcVout];if(!f)return o("the Pre-PegIn has no output at the HTLC index");const i=l.witness;if(i.length<k)return o("the HTLC input has no script-path witness");const P=i[i.length-1];if(P.length>0&&P[0]===q)return o("the HTLC input's witness carries an annex");const S=i[i.length-1],a=i[i.length-2],d=i.slice(0,i.length-k);let h;try{h=L.computeTaprootScriptPubKey({leafVersion:v.TAPSCRIPT_LEAF_VERSION,script:a,controlBlock:S})}catch{return o("the control block is malformed")}if(!h.equals(f.script))return o("the leaf is not committed to the vault's HTLC output");const c=Q(a);if(!c)return o("the spent leaf is not the hashlock leaf");if(!c.hashlock.equals(T.Buffer.from(v.stripHexPrefix(e.hashlock),"hex")))return o("the leaf's hashlock is not the vault's");const I=c.groups.reduce((u,p)=>u+p.keys.length,0);if(d.length!==w+I)return o("the witness does not hold one item per check of the leaf");const[C,m,R,...b]=[...d].reverse();if(C.length!==x||!n.crypto.sha256(C).equals(c.hashlock))return o("the witness does not open the hashlock");const B=L.computeTapLeafHash(v.TAPSCRIPT_LEAF_VERSION,a),A=(u,p)=>{let _=F;if(u.length===G){if(_=u[O],!M.has(_))return!1}else if(u.length!==O)return!1;try{const E=t.hashForWitnessV1(0,[f.script],[f.value],_,B);return V.verifySchnorr(E,p,u.subarray(0,O))}catch{return!1}};if(!A(m,c.depositorKey))return o("the depositor's signature does not verify");if(!A(R,c.vaultProviderKey))return o("the vault provider's signature does not verify");let K=0;for(const u of c.groups){let p=0;for(const _ of u.keys){const E=b[K++];if(E.length!==0){if(!A(E,_))return o("a multisig signature does not verify");p+=1}}if(p!==u.threshold)return o("a multisig block is short of its threshold")}return{valid:!0}}exports.verifyPeginHashlockSpend=z;
|
|
2
|
+
//# sourceMappingURL=verifyPeginHashlockSpend-CisfqMuT.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyPeginHashlockSpend-CisfqMuT.cjs","sources":["../src/tbv/core/primitives/psbt/verifyPeginHashlockSpend.ts"],"sourcesContent":["/**\n * Consensus check of a PegIn's spend of its vault's Pre-PegIn HTLC through the\n * hashlock leaf.\n *\n * A Bitcoin API is not trusted to say that a vault's PegIn swept its HTLC. It\n * can name the PegIn's public txid as the HTLC's spender, and serve back the\n * depositor-signed PegIn the registry publishes: a txid does not commit to the\n * witness. Finding the hashlock preimage in a served witness is not enough\n * either — a secret disclosed in a reverted activation's calldata can be copied\n * into a witness whose signatures are garbage. This check verifies the witness\n * the way Bitcoin would:\n *\n * - the Pre-PegIn is the registered one (its txid), so the HTLC output's script\n * and value are authentic;\n * - the leaf script and control block commit to that output (BIP-341);\n * - the leaf is the hashlock leaf, its preimage opens the registered hashlock,\n * and every signature it requires verifies against the PegIn's script-path\n * sighash (BIP-342).\n *\n * A PegIn that passes is a valid spend of the HTLC: while the HTLC is unspent,\n * its holder can broadcast it to sweep the HTLC. It proves that much — not that\n * it was broadcast, nor that the HTLC is still unspent (the depositor's refund\n * may have taken it). The participants' PegIn input signatures are public —\n * the registry serves them\n * (vault-contracts-aave-v4@f5ef5633:src/protocol/BTCVaultRegistry.sol:918-925,\n * `getPeginInputSignaturesForVault`) and the depositor's is in the signed\n * PegIn — so the secret is the one ingredient that is not. Until it is public\n * no one can produce a passing PegIn; once it is, anyone can.\n *\n * The leaf (btc-vault@1d841f73:crates/vault/src/connectors/prepegin_htlc.rs:88-126,\n * multisig blocks from crates/vault/src/connectors/script_utils.rs:29-78):\n *\n * OP_SIZE <32> OP_EQUALVERIFY OP_SHA256 <h> OP_EQUALVERIFY\n * <D> OP_CHECKSIGVERIFY <VP> OP_CHECKSIGVERIFY\n * <VK_1> OP_CHECKSIG <VK_2..N> OP_CHECKSIGADD <N> OP_NUMEQUALVERIFY\n * <UC_1> OP_CHECKSIG <UC_2..M> OP_CHECKSIGADD <M> OP_NUMEQUAL\n *\n * With no universal challengers the keeper block ends in `OP_NUMEQUAL`. The\n * witness is the evaluation order reversed:\n * `[UC_M..UC_1, VK_N..VK_1, VP, D, preimage, script, control block]`\n * (btc-vault@1d841f73:crates/vault/src/sign.rs:718-761).\n *\n * @module primitives/psbt/verifyPeginHashlockSpend\n */\n\nimport * as ecc from \"@bitcoin-js/tiny-secp256k1-asmjs\";\nimport {\n crypto as bcrypto,\n script as bscript,\n opcodes,\n Transaction,\n} from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\nimport { stripHexPrefix, TAPSCRIPT_LEAF_VERSION } from \"../utils/bitcoin\";\nimport {\n computeTapLeafHash,\n computeTaprootScriptPubKey,\n} from \"../utils/taproot\";\n\n/** The hashlock leaf enforces `OP_SIZE <32> OP_EQUALVERIFY` on the preimage. */\nconst PREIMAGE_BYTES = 32;\n/** BIP-340 x-only public key. */\nconst X_ONLY_KEY_BYTES = 32;\n/** BIP-340 signature; a 65th byte carries an explicit sighash type (BIP-341). */\nconst SCHNORR_SIG_BYTES = 64;\nconst SCHNORR_SIG_WITH_HASH_TYPE_BYTES = 65;\n/**\n * The explicit sighash types BIP-341 accepts — ALL, NONE, SINGLE, each alone or\n * with ANYONECANPAY (0x80); `SIGHASH_DEFAULT` (0x00) is only implicit. Literal\n * values, so this module reads nothing from bitcoinjs at import time.\n */\nconst EXPLICIT_TAPROOT_HASH_TYPES = new Set([\n 0x01, 0x02, 0x03, 0x81, 0x82, 0x83,\n]);\n/** BIP-341 `SIGHASH_DEFAULT`: the type of a 64-byte signature. */\nconst SIGHASH_DEFAULT = 0x00;\n/** BIP-341: a last witness item starting with this byte is an annex. */\nconst ANNEX_TAG = 0x50;\n/** Script and control block follow the stack items in a script-path witness. */\nconst SCRIPT_PATH_TRAILER_ITEMS = 2;\n/** The preimage, the depositor's and the vault provider's signatures. */\nconst FIXED_STACK_ITEMS = 3;\n/** Keepers, then — when the vault has any — universal challengers. */\nconst MAX_MULTISIG_GROUPS = 2;\n/** `OP_1`..`OP_16` (0x51..0x60) push 1..16: the value is the opcode less `OP_RESERVED` (0x50). */\nconst SMALL_INT_OPCODE_BASE = 0x50;\nconst SMALL_INT_MAX = 16;\n\n/** The on-chain facts a served PegIn and Pre-PegIn are checked against. */\nexport interface VerifyPeginHashlockSpendParams {\n /** The PegIn as a Bitcoin API served it, witness included. */\n peginTxHex: string;\n /** The vault's Pre-PegIn as a Bitcoin API served it; authenticated by its txid. */\n prePeginTxHex: string;\n /** Txid of the vault's on-chain signed PegIn. */\n peginTxid: string;\n /** The vault's registered Pre-PegIn txid. */\n prePeginTxid: string;\n /** The vault's registered HTLC output index in the Pre-PegIn. */\n htlcVout: number;\n /** The vault's registered hashlock, `sha256(secret)`. */\n hashlock: string;\n}\n\n/** Whether the PegIn validly spends the HTLC; a refusal names its reason. */\nexport type PeginHashlockSpendVerdict =\n | { valid: true }\n | { valid: false; reason: string };\n\ninterface MultisigGroup {\n keys: Buffer[];\n threshold: number;\n}\n\ninterface HashlockLeaf {\n hashlock: Buffer;\n depositorKey: Buffer;\n vaultProviderKey: Buffer;\n /** In evaluation order: keepers, then universal challengers. */\n groups: MultisigGroup[];\n}\n\nconst canonicalTxid = (txid: string): string =>\n stripHexPrefix(txid).toLowerCase();\n\nconst refuse = (reason: string): PeginHashlockSpendVerdict => ({\n valid: false,\n reason,\n});\n\nfunction isPush(\n chunk: number | Buffer | undefined,\n length: number,\n): chunk is Buffer {\n return Buffer.isBuffer(chunk) && chunk.length === length;\n}\n\n/** A threshold pushed as `OP_1`..`OP_16` or as a minimal script number. */\nfunction decodeThreshold(\n chunk: number | Buffer | undefined,\n): number | undefined {\n if (typeof chunk === \"number\") {\n const value = chunk - SMALL_INT_OPCODE_BASE;\n return value >= 1 && value <= SMALL_INT_MAX ? value : undefined;\n }\n if (!Buffer.isBuffer(chunk)) return undefined;\n try {\n return bscript.number.decode(chunk);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Parse the hashlock leaf, or `undefined` for any other script. The script must\n * be minimally encoded — decompiling and recompiling it must give back the same\n * bytes — so the parse describes exactly the bytes that will execute.\n */\nfunction parseHashlockLeaf(leafScript: Buffer): HashlockLeaf | undefined {\n const chunks = bscript.decompile(leafScript);\n if (!chunks || !Buffer.from(bscript.compile(chunks)).equals(leafScript)) {\n return undefined;\n }\n let i = 0;\n const next = () => chunks[i++];\n\n if (next() !== opcodes.OP_SIZE) return undefined;\n const size = next();\n if (!isPush(size, 1) || size[0] !== PREIMAGE_BYTES) return undefined;\n if (next() !== opcodes.OP_EQUALVERIFY) return undefined;\n if (next() !== opcodes.OP_SHA256) return undefined;\n const hashlock = next();\n if (!isPush(hashlock, PREIMAGE_BYTES)) return undefined;\n if (next() !== opcodes.OP_EQUALVERIFY) return undefined;\n const depositorKey = next();\n if (!isPush(depositorKey, X_ONLY_KEY_BYTES)) return undefined;\n if (next() !== opcodes.OP_CHECKSIGVERIFY) return undefined;\n const vaultProviderKey = next();\n if (!isPush(vaultProviderKey, X_ONLY_KEY_BYTES)) return undefined;\n if (next() !== opcodes.OP_CHECKSIGVERIFY) return undefined;\n\n const groups: MultisigGroup[] = [];\n for (;;) {\n const firstKey = next();\n if (!isPush(firstKey, X_ONLY_KEY_BYTES)) return undefined;\n if (next() !== opcodes.OP_CHECKSIG) return undefined;\n const keys = [firstKey];\n for (;;) {\n const key = chunks[i];\n if (\n !isPush(key, X_ONLY_KEY_BYTES) ||\n chunks[i + 1] !== opcodes.OP_CHECKSIGADD\n ) {\n break;\n }\n keys.push(key);\n i += 2;\n }\n const threshold = decodeThreshold(next());\n if (threshold === undefined || threshold < 1 || threshold > keys.length) {\n return undefined;\n }\n groups.push({ keys, threshold });\n const close = next();\n if (close === opcodes.OP_NUMEQUAL) break;\n if (close !== opcodes.OP_NUMEQUALVERIFY) return undefined;\n if (groups.length === MAX_MULTISIG_GROUPS) return undefined;\n }\n if (i !== chunks.length) return undefined;\n\n return { hashlock, depositorKey, vaultProviderKey, groups };\n}\n\n/**\n * Verify a served PegIn spends the vault's HTLC through the hashlock leaf with\n * a witness Bitcoin would accept. Never throws on malformed input: anything that\n * is not such a spend is a refusal.\n */\nexport function verifyPeginHashlockSpend(\n params: VerifyPeginHashlockSpendParams,\n): PeginHashlockSpendVerdict {\n let pegin: Transaction;\n let prePegin: Transaction;\n try {\n pegin = Transaction.fromHex(stripHexPrefix(params.peginTxHex));\n prePegin = Transaction.fromHex(stripHexPrefix(params.prePeginTxHex));\n } catch {\n return refuse(\"a served transaction does not parse\");\n }\n\n if (canonicalTxid(pegin.getId()) !== canonicalTxid(params.peginTxid)) {\n return refuse(\"the served PegIn is not the on-chain signed PegIn\");\n }\n const prePeginTxid = canonicalTxid(params.prePeginTxid);\n if (canonicalTxid(prePegin.getId()) !== prePeginTxid) {\n return refuse(\"the served Pre-PegIn is not the registered one\");\n }\n\n // The protocol's PegIn has a single input. With more, the sighash would also\n // commit to prevouts this check cannot authenticate.\n if (pegin.ins.length !== 1) {\n return refuse(\"the PegIn does not have exactly one input\");\n }\n const [input] = pegin.ins;\n if (\n input.index !== params.htlcVout ||\n Buffer.from(input.hash).reverse().toString(\"hex\") !== prePeginTxid\n ) {\n return refuse(\"the PegIn does not spend the vault's HTLC output\");\n }\n const htlcOutput = prePegin.outs[params.htlcVout];\n if (!htlcOutput) {\n return refuse(\"the Pre-PegIn has no output at the HTLC index\");\n }\n\n const witness = input.witness;\n if (witness.length < SCRIPT_PATH_TRAILER_ITEMS) {\n return refuse(\"the HTLC input has no script-path witness\");\n }\n const lastItem = witness[witness.length - 1];\n if (lastItem.length > 0 && lastItem[0] === ANNEX_TAG) {\n return refuse(\"the HTLC input's witness carries an annex\");\n }\n const controlBlock = witness[witness.length - 1];\n const leafScript = witness[witness.length - 2];\n const stack = witness.slice(0, witness.length - SCRIPT_PATH_TRAILER_ITEMS);\n\n let committedScriptPubKey: Buffer;\n try {\n committedScriptPubKey = computeTaprootScriptPubKey({\n leafVersion: TAPSCRIPT_LEAF_VERSION,\n script: leafScript,\n controlBlock,\n });\n } catch {\n return refuse(\"the control block is malformed\");\n }\n if (!committedScriptPubKey.equals(htlcOutput.script)) {\n return refuse(\"the leaf is not committed to the vault's HTLC output\");\n }\n\n const leaf = parseHashlockLeaf(leafScript);\n if (!leaf) {\n return refuse(\"the spent leaf is not the hashlock leaf\");\n }\n if (\n !leaf.hashlock.equals(Buffer.from(stripHexPrefix(params.hashlock), \"hex\"))\n ) {\n return refuse(\"the leaf's hashlock is not the vault's\");\n }\n\n // Tapscript's clean-stack rule: the leaf consumes every item, so the witness\n // holds exactly one per check.\n const keyCount = leaf.groups.reduce((n, group) => n + group.keys.length, 0);\n if (stack.length !== FIXED_STACK_ITEMS + keyCount) {\n return refuse(\"the witness does not hold one item per check of the leaf\");\n }\n const [preimage, depositorSig, vaultProviderSig, ...groupSigs] = [\n ...stack,\n ].reverse();\n\n if (\n preimage.length !== PREIMAGE_BYTES ||\n !bcrypto.sha256(preimage).equals(leaf.hashlock)\n ) {\n return refuse(\"the witness does not open the hashlock\");\n }\n\n const leafHash = computeTapLeafHash(TAPSCRIPT_LEAF_VERSION, leafScript);\n const signatureVerifies = (signature: Buffer, key: Buffer): boolean => {\n let hashType = SIGHASH_DEFAULT;\n if (signature.length === SCHNORR_SIG_WITH_HASH_TYPE_BYTES) {\n hashType = signature[SCHNORR_SIG_BYTES];\n if (!EXPLICIT_TAPROOT_HASH_TYPES.has(hashType)) return false;\n } else if (signature.length !== SCHNORR_SIG_BYTES) {\n return false;\n }\n try {\n const sighash = pegin.hashForWitnessV1(\n 0,\n [htlcOutput.script],\n [htlcOutput.value],\n hashType,\n leafHash,\n );\n return ecc.verifySchnorr(\n sighash,\n key,\n signature.subarray(0, SCHNORR_SIG_BYTES),\n );\n } catch {\n return false;\n }\n };\n\n // `OP_CHECKSIGVERIFY`: the signature must be present and valid.\n if (!signatureVerifies(depositorSig, leaf.depositorKey)) {\n return refuse(\"the depositor's signature does not verify\");\n }\n if (!signatureVerifies(vaultProviderSig, leaf.vaultProviderKey)) {\n return refuse(\"the vault provider's signature does not verify\");\n }\n\n // `OP_CHECKSIG` / `OP_CHECKSIGADD`: an empty signature counts nothing, and a\n // non-empty one that fails aborts the script (BIP-342).\n let offset = 0;\n for (const group of leaf.groups) {\n let valid = 0;\n for (const key of group.keys) {\n const signature = groupSigs[offset++];\n if (signature.length === 0) continue;\n if (!signatureVerifies(signature, key)) {\n return refuse(\"a multisig signature does not verify\");\n }\n valid += 1;\n }\n if (valid !== group.threshold) {\n return refuse(\"a multisig block is short of its threshold\");\n }\n }\n\n return { valid: true };\n}\n"],"names":["PREIMAGE_BYTES","X_ONLY_KEY_BYTES","SCHNORR_SIG_BYTES","SCHNORR_SIG_WITH_HASH_TYPE_BYTES","EXPLICIT_TAPROOT_HASH_TYPES","SIGHASH_DEFAULT","ANNEX_TAG","SCRIPT_PATH_TRAILER_ITEMS","FIXED_STACK_ITEMS","MAX_MULTISIG_GROUPS","SMALL_INT_OPCODE_BASE","SMALL_INT_MAX","canonicalTxid","txid","stripHexPrefix","refuse","reason","isPush","chunk","length","Buffer","decodeThreshold","value","bscript","parseHashlockLeaf","leafScript","chunks","i","next","opcodes","size","hashlock","depositorKey","vaultProviderKey","groups","firstKey","keys","key","threshold","close","verifyPeginHashlockSpend","params","pegin","prePegin","Transaction","prePeginTxid","input","htlcOutput","witness","lastItem","controlBlock","stack","committedScriptPubKey","computeTaprootScriptPubKey","TAPSCRIPT_LEAF_VERSION","leaf","keyCount","n","group","preimage","depositorSig","vaultProviderSig","groupSigs","bcrypto","leafHash","computeTapLeafHash","signatureVerifies","signature","hashType","sighash","ecc","offset","valid"],"mappings":"2eA6DMA,EAAiB,GAEjBC,EAAmB,GAEnBC,EAAoB,GACpBC,EAAmC,GAMnCC,MAAkC,IAAI,CAC1C,EAAM,EAAM,EAAM,IAAM,IAAM,GAChC,CAAC,EAEKC,EAAkB,EAElBC,EAAY,GAEZC,EAA4B,EAE5BC,EAAoB,EAEpBC,EAAsB,EAEtBC,EAAwB,GACxBC,EAAgB,GAoChBC,EAAiBC,GACrBC,EAAAA,eAAeD,CAAI,EAAE,YAAA,EAEjBE,EAAUC,IAA+C,CAC7D,MAAO,GACP,OAAAA,CACF,GAEA,SAASC,EACPC,EACAC,EACiB,CACjB,OAAOC,EAAAA,OAAO,SAASF,CAAK,GAAKA,EAAM,SAAWC,CACpD,CAGA,SAASE,EACPH,EACoB,CACpB,GAAI,OAAOA,GAAU,SAAU,CAC7B,MAAMI,EAAQJ,EAAQR,EACtB,OAAOY,GAAS,GAAKA,GAASX,EAAgBW,EAAQ,MACxD,CACA,GAAKF,EAAAA,OAAO,SAASF,CAAK,EAC1B,GAAI,CACF,OAAOK,SAAQ,OAAO,OAAOL,CAAK,CACpC,MAAQ,CACN,MACF,CACF,CAOA,SAASM,EAAkBC,EAA8C,CACvE,MAAMC,EAASH,EAAAA,OAAQ,UAAUE,CAAU,EAC3C,GAAI,CAACC,GAAU,CAACN,EAAAA,OAAO,KAAKG,EAAAA,OAAQ,QAAQG,CAAM,CAAC,EAAE,OAAOD,CAAU,EACpE,OAEF,IAAIE,EAAI,EACR,MAAMC,EAAO,IAAMF,EAAOC,GAAG,EAE7B,GAAIC,EAAA,IAAWC,UAAQ,QAAS,OAChC,MAAMC,EAAOF,EAAA,EAGb,GAFI,CAACX,EAAOa,EAAM,CAAC,GAAKA,EAAK,CAAC,IAAM9B,GAChC4B,EAAA,IAAWC,UAAQ,gBACnBD,EAAA,IAAWC,UAAQ,UAAW,OAClC,MAAME,EAAWH,EAAA,EAEjB,GADI,CAACX,EAAOc,EAAU/B,CAAc,GAChC4B,EAAA,IAAWC,UAAQ,eAAgB,OACvC,MAAMG,EAAeJ,EAAA,EAErB,GADI,CAACX,EAAOe,EAAc/B,CAAgB,GACtC2B,EAAA,IAAWC,UAAQ,kBAAmB,OAC1C,MAAMI,EAAmBL,EAAA,EAEzB,GADI,CAACX,EAAOgB,EAAkBhC,CAAgB,GAC1C2B,EAAA,IAAWC,UAAQ,kBAAmB,OAE1C,MAAMK,EAA0B,CAAA,EAChC,OAAS,CACP,MAAMC,EAAWP,EAAA,EAEjB,GADI,CAACX,EAAOkB,EAAUlC,CAAgB,GAClC2B,EAAA,IAAWC,UAAQ,YAAa,OACpC,MAAMO,EAAO,CAACD,CAAQ,EACtB,OAAS,CACP,MAAME,EAAMX,EAAOC,CAAC,EACpB,GACE,CAACV,EAAOoB,EAAKpC,CAAgB,GAC7ByB,EAAOC,EAAI,CAAC,IAAME,EAAAA,QAAQ,eAE1B,MAEFO,EAAK,KAAKC,CAAG,EACbV,GAAK,CACP,CACA,MAAMW,EAAYjB,EAAgBO,GAAM,EACxC,GAAIU,IAAc,QAAaA,EAAY,GAAKA,EAAYF,EAAK,OAC/D,OAEFF,EAAO,KAAK,CAAE,KAAAE,EAAM,UAAAE,CAAA,CAAW,EAC/B,MAAMC,EAAQX,EAAA,EACd,GAAIW,IAAUV,EAAAA,QAAQ,YAAa,MAEnC,GADIU,IAAUV,EAAAA,QAAQ,mBAClBK,EAAO,SAAWzB,EAAqB,MAC7C,CACA,GAAIkB,IAAMD,EAAO,OAEjB,MAAO,CAAE,SAAAK,EAAU,aAAAC,EAAc,iBAAAC,EAAkB,OAAAC,CAAA,CACrD,CAOO,SAASM,EACdC,EAC2B,CAC3B,IAAIC,EACAC,EACJ,GAAI,CACFD,EAAQE,EAAAA,YAAY,QAAQ9B,EAAAA,eAAe2B,EAAO,UAAU,CAAC,EAC7DE,EAAWC,EAAAA,YAAY,QAAQ9B,EAAAA,eAAe2B,EAAO,aAAa,CAAC,CACrE,MAAQ,CACN,OAAO1B,EAAO,qCAAqC,CACrD,CAEA,GAAIH,EAAc8B,EAAM,MAAA,CAAO,IAAM9B,EAAc6B,EAAO,SAAS,EACjE,OAAO1B,EAAO,mDAAmD,EAEnE,MAAM8B,EAAejC,EAAc6B,EAAO,YAAY,EACtD,GAAI7B,EAAc+B,EAAS,MAAA,CAAO,IAAME,EACtC,OAAO9B,EAAO,gDAAgD,EAKhE,GAAI2B,EAAM,IAAI,SAAW,EACvB,OAAO3B,EAAO,2CAA2C,EAE3D,KAAM,CAAC+B,CAAK,EAAIJ,EAAM,IACtB,GACEI,EAAM,QAAUL,EAAO,UACvBrB,EAAAA,OAAO,KAAK0B,EAAM,IAAI,EAAE,QAAA,EAAU,SAAS,KAAK,IAAMD,EAEtD,OAAO9B,EAAO,kDAAkD,EAElE,MAAMgC,EAAaJ,EAAS,KAAKF,EAAO,QAAQ,EAChD,GAAI,CAACM,EACH,OAAOhC,EAAO,+CAA+C,EAG/D,MAAMiC,EAAUF,EAAM,QACtB,GAAIE,EAAQ,OAASzC,EACnB,OAAOQ,EAAO,2CAA2C,EAE3D,MAAMkC,EAAWD,EAAQA,EAAQ,OAAS,CAAC,EAC3C,GAAIC,EAAS,OAAS,GAAKA,EAAS,CAAC,IAAM3C,EACzC,OAAOS,EAAO,2CAA2C,EAE3D,MAAMmC,EAAeF,EAAQA,EAAQ,OAAS,CAAC,EACzCvB,EAAauB,EAAQA,EAAQ,OAAS,CAAC,EACvCG,EAAQH,EAAQ,MAAM,EAAGA,EAAQ,OAASzC,CAAyB,EAEzE,IAAI6C,EACJ,GAAI,CACFA,EAAwBC,EAAAA,2BAA2B,CACjD,YAAaC,EAAAA,uBACb,OAAQ7B,EACR,aAAAyB,CAAA,CACD,CACH,MAAQ,CACN,OAAOnC,EAAO,gCAAgC,CAChD,CACA,GAAI,CAACqC,EAAsB,OAAOL,EAAW,MAAM,EACjD,OAAOhC,EAAO,sDAAsD,EAGtE,MAAMwC,EAAO/B,EAAkBC,CAAU,EACzC,GAAI,CAAC8B,EACH,OAAOxC,EAAO,yCAAyC,EAEzD,GACE,CAACwC,EAAK,SAAS,OAAOnC,EAAAA,OAAO,KAAKN,EAAAA,eAAe2B,EAAO,QAAQ,EAAG,KAAK,CAAC,EAEzE,OAAO1B,EAAO,wCAAwC,EAKxD,MAAMyC,EAAWD,EAAK,OAAO,OAAO,CAACE,EAAGC,IAAUD,EAAIC,EAAM,KAAK,OAAQ,CAAC,EAC1E,GAAIP,EAAM,SAAW3C,EAAoBgD,EACvC,OAAOzC,EAAO,0DAA0D,EAE1E,KAAM,CAAC4C,EAAUC,EAAcC,EAAkB,GAAGC,CAAS,EAAI,CAC/D,GAAGX,CAAA,EACH,QAAA,EAEF,GACEQ,EAAS,SAAW3D,GACpB,CAAC+D,EAAAA,OAAQ,OAAOJ,CAAQ,EAAE,OAAOJ,EAAK,QAAQ,EAE9C,OAAOxC,EAAO,wCAAwC,EAGxD,MAAMiD,EAAWC,EAAAA,mBAAmBX,EAAAA,uBAAwB7B,CAAU,EAChEyC,EAAoB,CAACC,EAAmB9B,IAAyB,CACrE,IAAI+B,EAAW/D,EACf,GAAI8D,EAAU,SAAWhE,GAEvB,GADAiE,EAAWD,EAAUjE,CAAiB,EAClC,CAACE,EAA4B,IAAIgE,CAAQ,EAAG,MAAO,WAC9CD,EAAU,SAAWjE,EAC9B,MAAO,GAET,GAAI,CACF,MAAMmE,EAAU3B,EAAM,iBACpB,EACA,CAACK,EAAW,MAAM,EAClB,CAACA,EAAW,KAAK,EACjBqB,EACAJ,CAAA,EAEF,OAAOM,EAAI,cACTD,EACAhC,EACA8B,EAAU,SAAS,EAAGjE,CAAiB,CAAA,CAE3C,MAAQ,CACN,MAAO,EACT,CACF,EAGA,GAAI,CAACgE,EAAkBN,EAAcL,EAAK,YAAY,EACpD,OAAOxC,EAAO,2CAA2C,EAE3D,GAAI,CAACmD,EAAkBL,EAAkBN,EAAK,gBAAgB,EAC5D,OAAOxC,EAAO,gDAAgD,EAKhE,IAAIwD,EAAS,EACb,UAAWb,KAASH,EAAK,OAAQ,CAC/B,IAAIiB,EAAQ,EACZ,UAAWnC,KAAOqB,EAAM,KAAM,CAC5B,MAAMS,EAAYL,EAAUS,GAAQ,EACpC,GAAIJ,EAAU,SAAW,EACzB,IAAI,CAACD,EAAkBC,EAAW9B,CAAG,EACnC,OAAOtB,EAAO,sCAAsC,EAEtDyD,GAAS,EACX,CACA,GAAIA,IAAUd,EAAM,UAClB,OAAO3C,EAAO,4CAA4C,CAE9D,CAEA,MAAO,CAAE,MAAO,EAAA,CAClB"}
|
|
@@ -1182,13 +1182,14 @@ export {
|
|
|
1182
1182
|
no as i,
|
|
1183
1183
|
ro as j,
|
|
1184
1184
|
lt as k,
|
|
1185
|
-
|
|
1185
|
+
$t as l,
|
|
1186
1186
|
Ae as m,
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1187
|
+
et as n,
|
|
1188
|
+
_e as o,
|
|
1189
|
+
nt as p,
|
|
1190
|
+
kt as q,
|
|
1191
|
+
It as r,
|
|
1192
|
+
Qe as s,
|
|
1193
|
+
ge as t
|
|
1193
1194
|
};
|
|
1194
|
-
//# sourceMappingURL=verifyScriptPathSchnorrSignature-
|
|
1195
|
+
//# sourceMappingURL=verifyScriptPathSchnorrSignature-BVGPEZXW.js.map
|