@toon-protocol/client-mcp 0.19.0 → 0.20.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/app/index.html +69 -69
- package/dist/{chunk-VA7XC4FD.js → chunk-3DDN4CJQ.js} +17 -1
- package/dist/{chunk-VA7XC4FD.js.map → chunk-3DDN4CJQ.js.map} +1 -1
- package/dist/{chunk-ITONR5ML.js → chunk-5SFBB4PJ.js} +46 -12
- package/dist/chunk-5SFBB4PJ.js.map +1 -0
- package/dist/{chunk-LR7W2ISE.js → chunk-HMD5EVQI.js} +11 -2
- package/dist/{chunk-LR7W2ISE.js.map → chunk-HMD5EVQI.js.map} +1 -1
- package/dist/{chunk-OGMD7Z2F.js → chunk-HSSJFB3I.js} +1018 -181
- package/dist/chunk-HSSJFB3I.js.map +1 -0
- package/dist/{chunk-3PGURFAM.js → chunk-KYQUVXEY.js} +2 -2
- package/dist/{chunk-XQUUFAIM.js → chunk-LN2OF264.js} +4 -2
- package/dist/{chunk-CTDRHEDX.js → chunk-SLMGETW7.js} +2 -2
- package/dist/{chunk-CTDRHEDX.js.map → chunk-SLMGETW7.js.map} +1 -1
- package/dist/{chunk-32QD72IL.js → chunk-T3WCTWRP.js} +2 -2
- package/dist/daemon.js +7 -7
- package/dist/{ed25519-U4PTEOFD.js → ed25519-VBPL32VX.js} +2 -2
- package/dist/{hmac-CMZORX4Y.js → hmac-GNBDA4UC.js} +3 -3
- package/dist/index.js +8 -8
- package/dist/mcp.js +7 -7
- package/dist/{node-WPA2UDEH-72L4MKGB.js → node-WPA2UDEH-SRYDHHAV.js} +3 -3
- package/dist/{node-WPA2UDEH-72L4MKGB.js.map → node-WPA2UDEH-SRYDHHAV.js.map} +1 -1
- package/dist/{sha512-4LOCATJH.js → sha512-D7TTPT7I.js} +3 -3
- package/package.json +7 -7
- package/dist/chunk-ITONR5ML.js.map +0 -1
- package/dist/chunk-OGMD7Z2F.js.map +0 -1
- /package/dist/{chunk-3PGURFAM.js.map → chunk-KYQUVXEY.js.map} +0 -0
- /package/dist/{chunk-XQUUFAIM.js.map → chunk-LN2OF264.js.map} +0 -0
- /package/dist/{chunk-32QD72IL.js.map → chunk-T3WCTWRP.js.map} +0 -0
- /package/dist/{ed25519-U4PTEOFD.js.map → ed25519-VBPL32VX.js.map} +0 -0
- /package/dist/{hmac-CMZORX4Y.js.map → hmac-GNBDA4UC.js.map} +0 -0
- /package/dist/{sha512-4LOCATJH.js.map → sha512-D7TTPT7I.js.map} +0 -0
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
__require
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SLMGETW7.js";
|
|
5
5
|
import {
|
|
6
6
|
HashMD,
|
|
7
|
+
rotlBH as rotlBH2,
|
|
8
|
+
rotlBL as rotlBL2,
|
|
9
|
+
rotlSH as rotlSH2,
|
|
10
|
+
rotlSL as rotlSL2,
|
|
7
11
|
sha256 as sha2562,
|
|
8
|
-
sha512
|
|
9
|
-
|
|
12
|
+
sha512,
|
|
13
|
+
split as split2
|
|
14
|
+
} from "./chunk-HMD5EVQI.js";
|
|
10
15
|
import {
|
|
11
16
|
hmac
|
|
12
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-T3WCTWRP.js";
|
|
13
18
|
import {
|
|
19
|
+
Hash,
|
|
14
20
|
abytes as abytes3,
|
|
21
|
+
aexists as aexists2,
|
|
15
22
|
ahash as ahash2,
|
|
16
23
|
anumber as anumber2,
|
|
24
|
+
aoutput as aoutput2,
|
|
17
25
|
bytesToHex as bytesToHex3,
|
|
18
26
|
checkOpts,
|
|
19
27
|
clean as clean2,
|
|
@@ -23,10 +31,13 @@ import {
|
|
|
23
31
|
hexToBytes as hexToBytes3,
|
|
24
32
|
isBytes as isBytes2,
|
|
25
33
|
kdfInputToBytes,
|
|
26
|
-
randomBytes as
|
|
34
|
+
randomBytes as randomBytes3,
|
|
27
35
|
rotl,
|
|
36
|
+
swap32IfBE as swap32IfBE2,
|
|
37
|
+
toBytes,
|
|
38
|
+
u32 as u322,
|
|
28
39
|
utf8ToBytes
|
|
29
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-3DDN4CJQ.js";
|
|
30
41
|
import {
|
|
31
42
|
Field,
|
|
32
43
|
aInRange,
|
|
@@ -39,6 +50,7 @@ import {
|
|
|
39
50
|
anumber,
|
|
40
51
|
aoutput,
|
|
41
52
|
asafenumber,
|
|
53
|
+
asciiToBytes,
|
|
42
54
|
bitLen,
|
|
43
55
|
bitMask,
|
|
44
56
|
bytesToHex,
|
|
@@ -62,6 +74,7 @@ import {
|
|
|
62
74
|
numberToHexUnpadded,
|
|
63
75
|
pow2,
|
|
64
76
|
randomBytes,
|
|
77
|
+
randomBytes2,
|
|
65
78
|
rotlBH,
|
|
66
79
|
rotlBL,
|
|
67
80
|
rotlSH,
|
|
@@ -72,13 +85,13 @@ import {
|
|
|
72
85
|
u32,
|
|
73
86
|
validateObject,
|
|
74
87
|
wNAF
|
|
75
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-LN2OF264.js";
|
|
76
89
|
import {
|
|
77
90
|
createBase58check,
|
|
78
91
|
utils
|
|
79
92
|
} from "./chunk-NL7NYWPC.js";
|
|
80
93
|
|
|
81
|
-
// ../../node_modules/.pnpm/@toon-protocol+core@
|
|
94
|
+
// ../../node_modules/.pnpm/@toon-protocol+core@3.0.0_typescript@5.9.3/node_modules/@toon-protocol/core/dist/chunk-5WT7ISKC.js
|
|
82
95
|
import { encode } from "@toon-format/toon";
|
|
83
96
|
import { decode } from "@toon-format/toon";
|
|
84
97
|
import { decode as decode2 } from "@toon-format/toon";
|
|
@@ -194,7 +207,7 @@ function decodeEventFromToon(data) {
|
|
|
194
207
|
}
|
|
195
208
|
}
|
|
196
209
|
|
|
197
|
-
// ../../node_modules/.pnpm/@toon-protocol+core@
|
|
210
|
+
// ../../node_modules/.pnpm/@toon-protocol+core@3.0.0_typescript@5.9.3/node_modules/@toon-protocol/core/dist/index.js
|
|
198
211
|
import { finalizeEvent } from "nostr-tools/pure";
|
|
199
212
|
import { finalizeEvent as finalizeEvent2 } from "nostr-tools/pure";
|
|
200
213
|
import { finalizeEvent as finalizeEvent3 } from "nostr-tools/pure";
|
|
@@ -411,7 +424,7 @@ var Keccak = class _Keccak {
|
|
|
411
424
|
var genKeccak = (suffix, blockLen, outputLen, info = {}) => createHasher(() => new Keccak(blockLen, suffix, outputLen), info);
|
|
412
425
|
var keccak_256 = /* @__PURE__ */ genKeccak(1, 136, 32);
|
|
413
426
|
|
|
414
|
-
// ../../node_modules/.pnpm/@toon-protocol+core@
|
|
427
|
+
// ../../node_modules/.pnpm/@toon-protocol+core@3.0.0_typescript@5.9.3/node_modules/@toon-protocol/core/dist/index.js
|
|
415
428
|
import { SimplePool as SimplePool3 } from "nostr-tools/pool";
|
|
416
429
|
import { getPublicKey as getPublicKey3 } from "nostr-tools/pure";
|
|
417
430
|
import WebSocket22 from "ws";
|
|
@@ -494,7 +507,7 @@ var hmac2 = /* @__PURE__ */ (() => {
|
|
|
494
507
|
})();
|
|
495
508
|
|
|
496
509
|
// ../../node_modules/.pnpm/@noble+curves@2.2.0/node_modules/@noble/curves/abstract/weierstrass.js
|
|
497
|
-
var divNearest = (
|
|
510
|
+
var divNearest = (num2, den) => (num2 + (num2 >= 0 ? den : -den) / _2n2) / den;
|
|
498
511
|
function _splitEndoScalar(k, basis, n) {
|
|
499
512
|
aInRange("scalar", k, _0n2, n);
|
|
500
513
|
const [[a1, b1], [a2, b2]] = basis;
|
|
@@ -600,12 +613,12 @@ var DER = {
|
|
|
600
613
|
// - add zero byte if exists
|
|
601
614
|
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
|
602
615
|
_int: {
|
|
603
|
-
encode(
|
|
616
|
+
encode(num2) {
|
|
604
617
|
const { Err: E } = DER;
|
|
605
|
-
abignumber(
|
|
606
|
-
if (
|
|
618
|
+
abignumber(num2);
|
|
619
|
+
if (num2 < _0n2)
|
|
607
620
|
throw new E("integer: negative integers are not allowed");
|
|
608
|
-
let hex = numberToHexUnpadded(
|
|
621
|
+
let hex = numberToHexUnpadded(num2);
|
|
609
622
|
if (Number.parseInt(hex[0], 16) & 8)
|
|
610
623
|
hex = "00" + hex;
|
|
611
624
|
if (hex.length & 1)
|
|
@@ -676,7 +689,7 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
676
689
|
if (!Fp.isOdd)
|
|
677
690
|
throw new Error("compression is not supported: Field does not have .isOdd()");
|
|
678
691
|
}
|
|
679
|
-
function
|
|
692
|
+
function pointToBytes2(_c, point, isCompressed) {
|
|
680
693
|
if (allowInfinityPoint && point.is0())
|
|
681
694
|
return Uint8Array.of(0);
|
|
682
695
|
const { x, y } = point.toAffine();
|
|
@@ -727,7 +740,7 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
727
740
|
throw new Error(`bad point: got length ${length}, expected compressed=${comp} or uncompressed=${uncomp}`);
|
|
728
741
|
}
|
|
729
742
|
}
|
|
730
|
-
const encodePoint = extraOpts.toBytes === void 0 ?
|
|
743
|
+
const encodePoint = extraOpts.toBytes === void 0 ? pointToBytes2 : extraOpts.toBytes;
|
|
731
744
|
const decodePoint = extraOpts.fromBytes === void 0 ? pointFromBytes : extraOpts.fromBytes;
|
|
732
745
|
function weierstrassEquation(x) {
|
|
733
746
|
const x2 = Fp.sqr(x);
|
|
@@ -1100,14 +1113,14 @@ function getWLengths(Fp, Fn) {
|
|
|
1100
1113
|
}
|
|
1101
1114
|
function ecdh(Point2, ecdhOpts = {}) {
|
|
1102
1115
|
const { Fn } = Point2;
|
|
1103
|
-
const randomBytes_ = ecdhOpts.randomBytes === void 0 ?
|
|
1116
|
+
const randomBytes_ = ecdhOpts.randomBytes === void 0 ? randomBytes2 : ecdhOpts.randomBytes;
|
|
1104
1117
|
const lengths = Object.assign(getWLengths(Point2.Fp, Fn), {
|
|
1105
1118
|
seed: Math.max(getMinHashLength(Fn.ORDER), 16)
|
|
1106
1119
|
});
|
|
1107
1120
|
function isValidSecretKey(secretKey) {
|
|
1108
1121
|
try {
|
|
1109
|
-
const
|
|
1110
|
-
return Fn.isValidNot0(
|
|
1122
|
+
const num2 = Fn.fromBytes(secretKey);
|
|
1123
|
+
return Fn.isValidNot0(num2);
|
|
1111
1124
|
} catch (error) {
|
|
1112
1125
|
return false;
|
|
1113
1126
|
}
|
|
@@ -1174,7 +1187,7 @@ function ecdsa(Point2, hash, ecdsaOpts = {}) {
|
|
|
1174
1187
|
bits2int_modN: "function"
|
|
1175
1188
|
});
|
|
1176
1189
|
ecdsaOpts = Object.assign({}, ecdsaOpts);
|
|
1177
|
-
const
|
|
1190
|
+
const randomBytes4 = ecdsaOpts.randomBytes === void 0 ? randomBytes2 : ecdsaOpts.randomBytes;
|
|
1178
1191
|
const hmac3 = ecdsaOpts.hmac === void 0 ? (key2, msg) => hmac2(hash_, key2, msg) : ecdsaOpts.hmac;
|
|
1179
1192
|
const { Fp, Fn } = Point2;
|
|
1180
1193
|
const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;
|
|
@@ -1190,10 +1203,10 @@ function ecdsa(Point2, hash, ecdsaOpts = {}) {
|
|
|
1190
1203
|
const HALF = CURVE_ORDER >> _1n2;
|
|
1191
1204
|
return number > HALF;
|
|
1192
1205
|
}
|
|
1193
|
-
function validateRS(title,
|
|
1194
|
-
if (!Fn.isValidNot0(
|
|
1206
|
+
function validateRS(title, num2) {
|
|
1207
|
+
if (!Fn.isValidNot0(num2))
|
|
1195
1208
|
throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`);
|
|
1196
|
-
return
|
|
1209
|
+
return num2;
|
|
1197
1210
|
}
|
|
1198
1211
|
function assertRecoverableCurve() {
|
|
1199
1212
|
if (hasLargeRecoveryLifts)
|
|
@@ -1295,17 +1308,17 @@ function ecdsa(Point2, hash, ecdsaOpts = {}) {
|
|
|
1295
1308
|
const bits2int = ecdsaOpts.bits2int === void 0 ? function bits2int_def(bytes) {
|
|
1296
1309
|
if (bytes.length > 8192)
|
|
1297
1310
|
throw new Error("input is too large");
|
|
1298
|
-
const
|
|
1311
|
+
const num2 = bytesToNumberBE(bytes);
|
|
1299
1312
|
const delta = bytes.length * 8 - fnBits;
|
|
1300
|
-
return delta > 0 ?
|
|
1313
|
+
return delta > 0 ? num2 >> BigInt(delta) : num2;
|
|
1301
1314
|
} : ecdsaOpts.bits2int;
|
|
1302
1315
|
const bits2int_modN = ecdsaOpts.bits2int_modN === void 0 ? function bits2int_modN_def(bytes) {
|
|
1303
1316
|
return Fn.create(bits2int(bytes));
|
|
1304
1317
|
} : ecdsaOpts.bits2int_modN;
|
|
1305
1318
|
const ORDER_MASK = bitMask(fnBits);
|
|
1306
|
-
function int2octets(
|
|
1307
|
-
aInRange("num < 2^" + fnBits,
|
|
1308
|
-
return Fn.toBytes(
|
|
1319
|
+
function int2octets(num2) {
|
|
1320
|
+
aInRange("num < 2^" + fnBits, num2, _0n2, ORDER_MASK);
|
|
1321
|
+
return Fn.toBytes(num2);
|
|
1309
1322
|
}
|
|
1310
1323
|
function validateMsgAndHash(message, prehash) {
|
|
1311
1324
|
abytes2(message, void 0, "message");
|
|
@@ -1320,7 +1333,7 @@ function ecdsa(Point2, hash, ecdsaOpts = {}) {
|
|
|
1320
1333
|
throw new Error("invalid private key");
|
|
1321
1334
|
const seedArgs = [int2octets(d), int2octets(h1int)];
|
|
1322
1335
|
if (extraEntropy != null && extraEntropy !== false) {
|
|
1323
|
-
const e = extraEntropy === true ?
|
|
1336
|
+
const e = extraEntropy === true ? randomBytes4(lengths.secretKey) : extraEntropy;
|
|
1324
1337
|
seedArgs.push(abytes2(e, void 0, "extraEntropy"));
|
|
1325
1338
|
}
|
|
1326
1339
|
const seed = concatBytes(...seedArgs);
|
|
@@ -1418,6 +1431,7 @@ var secp256k1_ENDO = {
|
|
|
1418
1431
|
[BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"), BigInt("0x3086d221a7d46bcde86c90e49284eb15")]
|
|
1419
1432
|
]
|
|
1420
1433
|
};
|
|
1434
|
+
var _0n3 = /* @__PURE__ */ BigInt(0);
|
|
1421
1435
|
var _2n3 = /* @__PURE__ */ BigInt(2);
|
|
1422
1436
|
function sqrtMod(y) {
|
|
1423
1437
|
const P = secp256k1_CURVE.p;
|
|
@@ -1447,8 +1461,119 @@ var Pointk1 = /* @__PURE__ */ weierstrass(secp256k1_CURVE, {
|
|
|
1447
1461
|
endo: secp256k1_ENDO
|
|
1448
1462
|
});
|
|
1449
1463
|
var secp256k1 = /* @__PURE__ */ ecdsa(Pointk1, sha256);
|
|
1464
|
+
var TAGGED_HASH_PREFIXES = {};
|
|
1465
|
+
function taggedHash(tag, ...messages) {
|
|
1466
|
+
let tagP = TAGGED_HASH_PREFIXES[tag];
|
|
1467
|
+
if (tagP === void 0) {
|
|
1468
|
+
const tagH = sha256(asciiToBytes(tag));
|
|
1469
|
+
tagP = concatBytes(tagH, tagH);
|
|
1470
|
+
TAGGED_HASH_PREFIXES[tag] = tagP;
|
|
1471
|
+
}
|
|
1472
|
+
return sha256(concatBytes(tagP, ...messages));
|
|
1473
|
+
}
|
|
1474
|
+
var pointToBytes = (point) => point.toBytes(true).slice(1);
|
|
1475
|
+
var hasEven = (y) => y % _2n3 === _0n3;
|
|
1476
|
+
function schnorrGetExtPubKey(priv) {
|
|
1477
|
+
const { Fn, BASE } = Pointk1;
|
|
1478
|
+
const d_ = Fn.fromBytes(priv);
|
|
1479
|
+
const p = BASE.multiply(d_);
|
|
1480
|
+
const scalar = hasEven(p.y) ? d_ : Fn.neg(d_);
|
|
1481
|
+
return { scalar, bytes: pointToBytes(p) };
|
|
1482
|
+
}
|
|
1483
|
+
function lift_x(x) {
|
|
1484
|
+
const Fp = Fpk1;
|
|
1485
|
+
if (!Fp.isValidNot0(x))
|
|
1486
|
+
throw new Error("invalid x: Fail if x \u2265 p");
|
|
1487
|
+
const xx = Fp.create(x * x);
|
|
1488
|
+
const c = Fp.create(xx * x + BigInt(7));
|
|
1489
|
+
let y = Fp.sqrt(c);
|
|
1490
|
+
if (!hasEven(y))
|
|
1491
|
+
y = Fp.neg(y);
|
|
1492
|
+
const p = Pointk1.fromAffine({ x, y });
|
|
1493
|
+
p.assertValidity();
|
|
1494
|
+
return p;
|
|
1495
|
+
}
|
|
1496
|
+
var num = bytesToNumberBE;
|
|
1497
|
+
function challenge(...args) {
|
|
1498
|
+
return Pointk1.Fn.create(num(taggedHash("BIP0340/challenge", ...args)));
|
|
1499
|
+
}
|
|
1500
|
+
function schnorrGetPublicKey(secretKey) {
|
|
1501
|
+
return schnorrGetExtPubKey(secretKey).bytes;
|
|
1502
|
+
}
|
|
1503
|
+
function schnorrSign(message, secretKey, auxRand = randomBytes(32)) {
|
|
1504
|
+
const { Fn, BASE } = Pointk1;
|
|
1505
|
+
const m = abytes2(message, void 0, "message");
|
|
1506
|
+
const { bytes: px, scalar: d } = schnorrGetExtPubKey(secretKey);
|
|
1507
|
+
const a = abytes2(auxRand, 32, "auxRand");
|
|
1508
|
+
const t = Fn.toBytes(d ^ num(taggedHash("BIP0340/aux", a)));
|
|
1509
|
+
const rand = taggedHash("BIP0340/nonce", t, px, m);
|
|
1510
|
+
const k_ = Fn.create(num(rand));
|
|
1511
|
+
if (k_ === 0n)
|
|
1512
|
+
throw new Error("sign failed: k is zero");
|
|
1513
|
+
const p = BASE.multiply(k_);
|
|
1514
|
+
const k = hasEven(p.y) ? k_ : Fn.neg(k_);
|
|
1515
|
+
const rx = pointToBytes(p);
|
|
1516
|
+
const e = challenge(rx, px, m);
|
|
1517
|
+
const sig = new Uint8Array(64);
|
|
1518
|
+
sig.set(rx, 0);
|
|
1519
|
+
sig.set(Fn.toBytes(Fn.create(k + e * d)), 32);
|
|
1520
|
+
if (!schnorrVerify(sig, m, px))
|
|
1521
|
+
throw new Error("sign: Invalid signature produced");
|
|
1522
|
+
return sig;
|
|
1523
|
+
}
|
|
1524
|
+
function schnorrVerify(signature, message, publicKey) {
|
|
1525
|
+
const { Fp, Fn, BASE } = Pointk1;
|
|
1526
|
+
const sig = abytes2(signature, 64, "signature");
|
|
1527
|
+
const m = abytes2(message, void 0, "message");
|
|
1528
|
+
const pub = abytes2(publicKey, 32, "publicKey");
|
|
1529
|
+
try {
|
|
1530
|
+
const P = lift_x(num(pub));
|
|
1531
|
+
const r = num(sig.subarray(0, 32));
|
|
1532
|
+
if (!Fp.isValidNot0(r))
|
|
1533
|
+
return false;
|
|
1534
|
+
const s = num(sig.subarray(32, 64));
|
|
1535
|
+
if (!Fn.isValidNot0(s))
|
|
1536
|
+
return false;
|
|
1537
|
+
const e = challenge(Fn.toBytes(r), pointToBytes(P), m);
|
|
1538
|
+
const R = BASE.multiplyUnsafe(s).add(P.multiplyUnsafe(Fn.neg(e)));
|
|
1539
|
+
const { x, y } = R.toAffine();
|
|
1540
|
+
if (R.is0() || !hasEven(y) || x !== r)
|
|
1541
|
+
return false;
|
|
1542
|
+
return true;
|
|
1543
|
+
} catch (error) {
|
|
1544
|
+
return false;
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
var schnorr = /* @__PURE__ */ (() => {
|
|
1548
|
+
const size = 32;
|
|
1549
|
+
const seedLength = 48;
|
|
1550
|
+
const randomSecretKey = (seed) => {
|
|
1551
|
+
seed = seed === void 0 ? randomBytes(seedLength) : seed;
|
|
1552
|
+
return mapHashToField(seed, secp256k1_CURVE.n);
|
|
1553
|
+
};
|
|
1554
|
+
return Object.freeze({
|
|
1555
|
+
keygen: createKeygen(randomSecretKey, schnorrGetPublicKey),
|
|
1556
|
+
getPublicKey: schnorrGetPublicKey,
|
|
1557
|
+
sign: schnorrSign,
|
|
1558
|
+
verify: schnorrVerify,
|
|
1559
|
+
Point: Pointk1,
|
|
1560
|
+
utils: Object.freeze({
|
|
1561
|
+
randomSecretKey,
|
|
1562
|
+
taggedHash,
|
|
1563
|
+
lift_x,
|
|
1564
|
+
pointToBytes
|
|
1565
|
+
}),
|
|
1566
|
+
lengths: Object.freeze({
|
|
1567
|
+
secretKey: size,
|
|
1568
|
+
publicKey: size,
|
|
1569
|
+
publicKeyHasPrefix: false,
|
|
1570
|
+
signature: size * 2,
|
|
1571
|
+
seed: seedLength
|
|
1572
|
+
})
|
|
1573
|
+
});
|
|
1574
|
+
})();
|
|
1450
1575
|
|
|
1451
|
-
// ../../node_modules/.pnpm/@toon-protocol+core@
|
|
1576
|
+
// ../../node_modules/.pnpm/@toon-protocol+core@3.0.0_typescript@5.9.3/node_modules/@toon-protocol/core/dist/index.js
|
|
1452
1577
|
import { getPublicKey as getPublicKey5 } from "nostr-tools/pure";
|
|
1453
1578
|
var ILP_PEER_INFO_KIND = 10032;
|
|
1454
1579
|
var BLOB_STORAGE_REQUEST_KIND = 5094;
|
|
@@ -2152,15 +2277,71 @@ function concatBytes3(...parts) {
|
|
|
2152
2277
|
}
|
|
2153
2278
|
return out;
|
|
2154
2279
|
}
|
|
2155
|
-
|
|
2280
|
+
var EIP712_PREFIX = new Uint8Array([25, 1]);
|
|
2281
|
+
var EIP712DOMAIN_TYPEHASH = keccak_256(
|
|
2282
|
+
new TextEncoder().encode(
|
|
2283
|
+
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
|
|
2284
|
+
)
|
|
2285
|
+
);
|
|
2286
|
+
var DOMAIN_NAME_HASH = keccak_256(new TextEncoder().encode("RollingSwapChannel"));
|
|
2287
|
+
var DOMAIN_VERSION_HASH = keccak_256(new TextEncoder().encode("2"));
|
|
2288
|
+
var CLAIM_TYPEHASH = keccak_256(
|
|
2289
|
+
new TextEncoder().encode(
|
|
2290
|
+
"ClaimBalanceProof(bytes32 channelId,uint256 cumulativeAmount,uint256 nonce,address recipient)"
|
|
2291
|
+
)
|
|
2292
|
+
);
|
|
2293
|
+
var COOP_CLOSE_TYPEHASH = keccak_256(
|
|
2294
|
+
new TextEncoder().encode(
|
|
2295
|
+
"CooperativeClose(bytes32 channelId,uint256 cumulativeAmount,uint256 nonce)"
|
|
2296
|
+
)
|
|
2297
|
+
);
|
|
2298
|
+
function leftPad32(bytes) {
|
|
2299
|
+
if (bytes.length > 32) {
|
|
2300
|
+
throw new Error(`cannot left-pad ${bytes.length} bytes into 32`);
|
|
2301
|
+
}
|
|
2302
|
+
const out = new Uint8Array(32);
|
|
2303
|
+
out.set(bytes, 32 - bytes.length);
|
|
2304
|
+
return out;
|
|
2305
|
+
}
|
|
2306
|
+
function eip712DomainSeparatorEvm(chainId, verifyingContractBytes) {
|
|
2307
|
+
if (verifyingContractBytes.length !== 20) {
|
|
2308
|
+
throw new Error(
|
|
2309
|
+
`verifyingContract must be 20 bytes (got ${verifyingContractBytes.length})`
|
|
2310
|
+
);
|
|
2311
|
+
}
|
|
2156
2312
|
return keccak_256(
|
|
2157
2313
|
concatBytes3(
|
|
2314
|
+
EIP712DOMAIN_TYPEHASH,
|
|
2315
|
+
DOMAIN_NAME_HASH,
|
|
2316
|
+
DOMAIN_VERSION_HASH,
|
|
2317
|
+
bigintToBytes32BE(chainId),
|
|
2318
|
+
leftPad32(verifyingContractBytes)
|
|
2319
|
+
)
|
|
2320
|
+
);
|
|
2321
|
+
}
|
|
2322
|
+
function eip712Digest(domainSeparator, structHash) {
|
|
2323
|
+
return keccak_256(concatBytes3(EIP712_PREFIX, domainSeparator, structHash));
|
|
2324
|
+
}
|
|
2325
|
+
function balanceProofHashEvm(channelIdBytes, cumulativeAmount, nonce, recipientBytes, chainId, verifyingContractBytes) {
|
|
2326
|
+
if (channelIdBytes.length !== 32) {
|
|
2327
|
+
throw new Error(`channelId must be 32 bytes (got ${channelIdBytes.length})`);
|
|
2328
|
+
}
|
|
2329
|
+
if (recipientBytes.length !== 20) {
|
|
2330
|
+
throw new Error(`recipient must be 20 bytes (got ${recipientBytes.length})`);
|
|
2331
|
+
}
|
|
2332
|
+
const structHash = keccak_256(
|
|
2333
|
+
concatBytes3(
|
|
2334
|
+
CLAIM_TYPEHASH,
|
|
2158
2335
|
channelIdBytes,
|
|
2159
2336
|
bigintToBytes32BE(cumulativeAmount),
|
|
2160
2337
|
bigintToBytes32BE(nonce),
|
|
2161
|
-
recipientBytes
|
|
2338
|
+
leftPad32(recipientBytes)
|
|
2162
2339
|
)
|
|
2163
2340
|
);
|
|
2341
|
+
return eip712Digest(
|
|
2342
|
+
eip712DomainSeparatorEvm(chainId, verifyingContractBytes),
|
|
2343
|
+
structHash
|
|
2344
|
+
);
|
|
2164
2345
|
}
|
|
2165
2346
|
function balanceProofHashSolana(channelId, cumulativeAmount, nonce, recipient) {
|
|
2166
2347
|
return sha256(
|
|
@@ -3407,7 +3588,7 @@ function generateMnemonic(wordlist2, strength = 128) {
|
|
|
3407
3588
|
anumber2(strength);
|
|
3408
3589
|
if (strength % 32 !== 0 || strength > 256)
|
|
3409
3590
|
throw new TypeError("Invalid entropy");
|
|
3410
|
-
return entropyToMnemonic(
|
|
3591
|
+
return entropyToMnemonic(randomBytes3(strength / 8), wordlist2);
|
|
3411
3592
|
}
|
|
3412
3593
|
var calcChecksum = (entropy) => {
|
|
3413
3594
|
const bitsLeft = 8 - entropy.length / 4;
|
|
@@ -5497,7 +5678,7 @@ zone
|
|
|
5497
5678
|
zoo`.split("\n");
|
|
5498
5679
|
|
|
5499
5680
|
// ../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/esm/utils.js
|
|
5500
|
-
var
|
|
5681
|
+
var _0n4 = /* @__PURE__ */ BigInt(0);
|
|
5501
5682
|
var _1n3 = /* @__PURE__ */ BigInt(1);
|
|
5502
5683
|
function _abool2(value, title = "") {
|
|
5503
5684
|
if (typeof value !== "boolean") {
|
|
@@ -5518,14 +5699,14 @@ function _abytes2(value, length, title = "") {
|
|
|
5518
5699
|
}
|
|
5519
5700
|
return value;
|
|
5520
5701
|
}
|
|
5521
|
-
function numberToHexUnpadded2(
|
|
5522
|
-
const hex =
|
|
5702
|
+
function numberToHexUnpadded2(num2) {
|
|
5703
|
+
const hex = num2.toString(16);
|
|
5523
5704
|
return hex.length & 1 ? "0" + hex : hex;
|
|
5524
5705
|
}
|
|
5525
5706
|
function hexToNumber(hex) {
|
|
5526
5707
|
if (typeof hex !== "string")
|
|
5527
5708
|
throw new Error("hex string expected, got " + typeof hex);
|
|
5528
|
-
return hex === "" ?
|
|
5709
|
+
return hex === "" ? _0n4 : BigInt("0x" + hex);
|
|
5529
5710
|
}
|
|
5530
5711
|
function bytesToNumberBE2(bytes) {
|
|
5531
5712
|
return hexToNumber(bytesToHex3(bytes));
|
|
@@ -5558,7 +5739,7 @@ function ensureBytes(title, hex, expectedLength) {
|
|
|
5558
5739
|
throw new Error(title + " of length " + expectedLength + " expected, got " + len);
|
|
5559
5740
|
return res;
|
|
5560
5741
|
}
|
|
5561
|
-
var isPosBig = (n) => typeof n === "bigint" &&
|
|
5742
|
+
var isPosBig = (n) => typeof n === "bigint" && _0n4 <= n;
|
|
5562
5743
|
function inRange(n, min, max) {
|
|
5563
5744
|
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
5564
5745
|
}
|
|
@@ -5568,7 +5749,7 @@ function aInRange2(title, n, min, max) {
|
|
|
5568
5749
|
}
|
|
5569
5750
|
function bitLen2(n) {
|
|
5570
5751
|
let len;
|
|
5571
|
-
for (len = 0; n >
|
|
5752
|
+
for (len = 0; n > _0n4; n >>= _1n3, len += 1)
|
|
5572
5753
|
;
|
|
5573
5754
|
return len;
|
|
5574
5755
|
}
|
|
@@ -5599,7 +5780,7 @@ function createHmacDrbg2(hashLen, qByteLen, hmacFn) {
|
|
|
5599
5780
|
k = h(u8of(1), seed);
|
|
5600
5781
|
v = h();
|
|
5601
5782
|
};
|
|
5602
|
-
const
|
|
5783
|
+
const gen2 = () => {
|
|
5603
5784
|
if (i++ >= 1e3)
|
|
5604
5785
|
throw new Error("drbg: tried 1000 values");
|
|
5605
5786
|
let len = 0;
|
|
@@ -5616,7 +5797,7 @@ function createHmacDrbg2(hashLen, qByteLen, hmacFn) {
|
|
|
5616
5797
|
reset();
|
|
5617
5798
|
reseed(seed);
|
|
5618
5799
|
let res = void 0;
|
|
5619
|
-
while (!(res = pred(
|
|
5800
|
+
while (!(res = pred(gen2())))
|
|
5620
5801
|
reseed();
|
|
5621
5802
|
reset();
|
|
5622
5803
|
return res;
|
|
@@ -5650,7 +5831,7 @@ function memoized(fn) {
|
|
|
5650
5831
|
}
|
|
5651
5832
|
|
|
5652
5833
|
// ../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/esm/abstract/modular.js
|
|
5653
|
-
var
|
|
5834
|
+
var _0n5 = BigInt(0);
|
|
5654
5835
|
var _1n4 = BigInt(1);
|
|
5655
5836
|
var _2n4 = /* @__PURE__ */ BigInt(2);
|
|
5656
5837
|
var _3n2 = /* @__PURE__ */ BigInt(3);
|
|
@@ -5662,25 +5843,25 @@ var _9n = /* @__PURE__ */ BigInt(9);
|
|
|
5662
5843
|
var _16n = /* @__PURE__ */ BigInt(16);
|
|
5663
5844
|
function mod(a, b) {
|
|
5664
5845
|
const result = a % b;
|
|
5665
|
-
return result >=
|
|
5846
|
+
return result >= _0n5 ? result : b + result;
|
|
5666
5847
|
}
|
|
5667
5848
|
function pow22(x, power, modulo) {
|
|
5668
5849
|
let res = x;
|
|
5669
|
-
while (power-- >
|
|
5850
|
+
while (power-- > _0n5) {
|
|
5670
5851
|
res *= res;
|
|
5671
5852
|
res %= modulo;
|
|
5672
5853
|
}
|
|
5673
5854
|
return res;
|
|
5674
5855
|
}
|
|
5675
5856
|
function invert(number, modulo) {
|
|
5676
|
-
if (number ===
|
|
5857
|
+
if (number === _0n5)
|
|
5677
5858
|
throw new Error("invert: expected non-zero number");
|
|
5678
|
-
if (modulo <=
|
|
5859
|
+
if (modulo <= _0n5)
|
|
5679
5860
|
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
5680
5861
|
let a = mod(number, modulo);
|
|
5681
5862
|
let b = modulo;
|
|
5682
|
-
let x =
|
|
5683
|
-
while (a !==
|
|
5863
|
+
let x = _0n5, y = _1n4, u = _1n4, v = _0n5;
|
|
5864
|
+
while (a !== _0n5) {
|
|
5684
5865
|
const q = b / a;
|
|
5685
5866
|
const r = b % a;
|
|
5686
5867
|
const m = x - u * q;
|
|
@@ -5739,7 +5920,7 @@ function tonelliShanks(P) {
|
|
|
5739
5920
|
throw new Error("sqrt is not defined for small field");
|
|
5740
5921
|
let Q = P - _1n4;
|
|
5741
5922
|
let S = 0;
|
|
5742
|
-
while (Q % _2n4 ===
|
|
5923
|
+
while (Q % _2n4 === _0n5) {
|
|
5743
5924
|
Q /= _2n4;
|
|
5744
5925
|
S++;
|
|
5745
5926
|
}
|
|
@@ -5825,16 +6006,16 @@ function validateField2(field) {
|
|
|
5825
6006
|
_validateObject(field, opts);
|
|
5826
6007
|
return field;
|
|
5827
6008
|
}
|
|
5828
|
-
function FpPow(Fp,
|
|
5829
|
-
if (power <
|
|
6009
|
+
function FpPow(Fp, num2, power) {
|
|
6010
|
+
if (power < _0n5)
|
|
5830
6011
|
throw new Error("invalid exponent, negatives unsupported");
|
|
5831
|
-
if (power ===
|
|
6012
|
+
if (power === _0n5)
|
|
5832
6013
|
return Fp.ONE;
|
|
5833
6014
|
if (power === _1n4)
|
|
5834
|
-
return
|
|
6015
|
+
return num2;
|
|
5835
6016
|
let p = Fp.ONE;
|
|
5836
|
-
let d =
|
|
5837
|
-
while (power >
|
|
6017
|
+
let d = num2;
|
|
6018
|
+
while (power > _0n5) {
|
|
5838
6019
|
if (power & _1n4)
|
|
5839
6020
|
p = Fp.mul(p, d);
|
|
5840
6021
|
d = Fp.sqr(d);
|
|
@@ -5844,18 +6025,18 @@ function FpPow(Fp, num, power) {
|
|
|
5844
6025
|
}
|
|
5845
6026
|
function FpInvertBatch2(Fp, nums, passZero = false) {
|
|
5846
6027
|
const inverted = new Array(nums.length).fill(passZero ? Fp.ZERO : void 0);
|
|
5847
|
-
const multipliedAcc = nums.reduce((acc,
|
|
5848
|
-
if (Fp.is0(
|
|
6028
|
+
const multipliedAcc = nums.reduce((acc, num2, i) => {
|
|
6029
|
+
if (Fp.is0(num2))
|
|
5849
6030
|
return acc;
|
|
5850
6031
|
inverted[i] = acc;
|
|
5851
|
-
return Fp.mul(acc,
|
|
6032
|
+
return Fp.mul(acc, num2);
|
|
5852
6033
|
}, Fp.ONE);
|
|
5853
6034
|
const invertedAcc = Fp.inv(multipliedAcc);
|
|
5854
|
-
nums.reduceRight((acc,
|
|
5855
|
-
if (Fp.is0(
|
|
6035
|
+
nums.reduceRight((acc, num2, i) => {
|
|
6036
|
+
if (Fp.is0(num2))
|
|
5856
6037
|
return acc;
|
|
5857
6038
|
inverted[i] = Fp.mul(acc, inverted[i]);
|
|
5858
|
-
return Fp.mul(acc,
|
|
6039
|
+
return Fp.mul(acc, num2);
|
|
5859
6040
|
}, invertedAcc);
|
|
5860
6041
|
return inverted;
|
|
5861
6042
|
}
|
|
@@ -5877,7 +6058,7 @@ function nLength(n, nBitLength) {
|
|
|
5877
6058
|
return { nBitLength: _nBitLength, nByteLength };
|
|
5878
6059
|
}
|
|
5879
6060
|
function Field2(ORDER, bitLenOrOpts, isLE = false, opts = {}) {
|
|
5880
|
-
if (ORDER <=
|
|
6061
|
+
if (ORDER <= _0n5)
|
|
5881
6062
|
throw new Error("invalid field: expected ORDER > 0, got " + ORDER);
|
|
5882
6063
|
let _nbitLength = void 0;
|
|
5883
6064
|
let _sqrt = void 0;
|
|
@@ -5912,39 +6093,39 @@ function Field2(ORDER, bitLenOrOpts, isLE = false, opts = {}) {
|
|
|
5912
6093
|
BITS,
|
|
5913
6094
|
BYTES,
|
|
5914
6095
|
MASK: bitMask2(BITS),
|
|
5915
|
-
ZERO:
|
|
6096
|
+
ZERO: _0n5,
|
|
5916
6097
|
ONE: _1n4,
|
|
5917
6098
|
allowedLengths,
|
|
5918
|
-
create: (
|
|
5919
|
-
isValid: (
|
|
5920
|
-
if (typeof
|
|
5921
|
-
throw new Error("invalid field element: expected bigint, got " + typeof
|
|
5922
|
-
return
|
|
6099
|
+
create: (num2) => mod(num2, ORDER),
|
|
6100
|
+
isValid: (num2) => {
|
|
6101
|
+
if (typeof num2 !== "bigint")
|
|
6102
|
+
throw new Error("invalid field element: expected bigint, got " + typeof num2);
|
|
6103
|
+
return _0n5 <= num2 && num2 < ORDER;
|
|
5923
6104
|
},
|
|
5924
|
-
is0: (
|
|
6105
|
+
is0: (num2) => num2 === _0n5,
|
|
5925
6106
|
// is valid and invertible
|
|
5926
|
-
isValidNot0: (
|
|
5927
|
-
isOdd: (
|
|
5928
|
-
neg: (
|
|
6107
|
+
isValidNot0: (num2) => !f.is0(num2) && f.isValid(num2),
|
|
6108
|
+
isOdd: (num2) => (num2 & _1n4) === _1n4,
|
|
6109
|
+
neg: (num2) => mod(-num2, ORDER),
|
|
5929
6110
|
eql: (lhs, rhs) => lhs === rhs,
|
|
5930
|
-
sqr: (
|
|
6111
|
+
sqr: (num2) => mod(num2 * num2, ORDER),
|
|
5931
6112
|
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
|
5932
6113
|
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
|
5933
6114
|
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
|
5934
|
-
pow: (
|
|
6115
|
+
pow: (num2, power) => FpPow(f, num2, power),
|
|
5935
6116
|
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
|
5936
6117
|
// Same as above, but doesn't normalize
|
|
5937
|
-
sqrN: (
|
|
6118
|
+
sqrN: (num2) => num2 * num2,
|
|
5938
6119
|
addN: (lhs, rhs) => lhs + rhs,
|
|
5939
6120
|
subN: (lhs, rhs) => lhs - rhs,
|
|
5940
6121
|
mulN: (lhs, rhs) => lhs * rhs,
|
|
5941
|
-
inv: (
|
|
6122
|
+
inv: (num2) => invert(num2, ORDER),
|
|
5942
6123
|
sqrt: _sqrt || ((n) => {
|
|
5943
6124
|
if (!sqrtP)
|
|
5944
6125
|
sqrtP = FpSqrt(ORDER);
|
|
5945
6126
|
return sqrtP(f, n);
|
|
5946
6127
|
}),
|
|
5947
|
-
toBytes: (
|
|
6128
|
+
toBytes: (num2) => isLE ? numberToBytesLE(num2, BYTES) : numberToBytesBE(num2, BYTES),
|
|
5948
6129
|
fromBytes: (bytes, skipValidation = true) => {
|
|
5949
6130
|
if (allowedLengths) {
|
|
5950
6131
|
if (!allowedLengths.includes(bytes.length) || bytes.length > BYTES) {
|
|
@@ -5989,13 +6170,13 @@ function mapHashToField2(key2, fieldOrder, isLE = false) {
|
|
|
5989
6170
|
const minLen = getMinHashLength2(fieldOrder);
|
|
5990
6171
|
if (len < 16 || len < minLen || len > 1024)
|
|
5991
6172
|
throw new Error("expected " + minLen + "-1024 bytes of input, got " + len);
|
|
5992
|
-
const
|
|
5993
|
-
const reduced = mod(
|
|
6173
|
+
const num2 = isLE ? bytesToNumberLE(key2) : bytesToNumberBE2(key2);
|
|
6174
|
+
const reduced = mod(num2, fieldOrder - _1n4) + _1n4;
|
|
5994
6175
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
|
5995
6176
|
}
|
|
5996
6177
|
|
|
5997
6178
|
// ../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/esm/abstract/curve.js
|
|
5998
|
-
var
|
|
6179
|
+
var _0n6 = BigInt(0);
|
|
5999
6180
|
var _1n5 = BigInt(1);
|
|
6000
6181
|
function negateCt2(condition, item) {
|
|
6001
6182
|
const neg = item.negate();
|
|
@@ -6056,7 +6237,7 @@ function getW(P) {
|
|
|
6056
6237
|
return pointWindowSizes.get(P) || 1;
|
|
6057
6238
|
}
|
|
6058
6239
|
function assert0(n) {
|
|
6059
|
-
if (n !==
|
|
6240
|
+
if (n !== _0n6)
|
|
6060
6241
|
throw new Error("invalid wNAF");
|
|
6061
6242
|
}
|
|
6062
6243
|
var wNAF2 = class {
|
|
@@ -6070,7 +6251,7 @@ var wNAF2 = class {
|
|
|
6070
6251
|
// non-const time multiplication ladder
|
|
6071
6252
|
_unsafeLadder(elm, n, p = this.ZERO) {
|
|
6072
6253
|
let d = elm;
|
|
6073
|
-
while (n >
|
|
6254
|
+
while (n > _0n6) {
|
|
6074
6255
|
if (n & _1n5)
|
|
6075
6256
|
p = p.add(d);
|
|
6076
6257
|
d = d.double();
|
|
@@ -6138,7 +6319,7 @@ var wNAF2 = class {
|
|
|
6138
6319
|
wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
|
|
6139
6320
|
const wo = calcWOpts(W, this.bits);
|
|
6140
6321
|
for (let window2 = 0; window2 < wo.windows; window2++) {
|
|
6141
|
-
if (n ===
|
|
6322
|
+
if (n === _0n6)
|
|
6142
6323
|
break;
|
|
6143
6324
|
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window2, wo);
|
|
6144
6325
|
n = nextN;
|
|
@@ -6190,7 +6371,7 @@ function mulEndoUnsafe2(Point2, point, k1, k2) {
|
|
|
6190
6371
|
let acc = point;
|
|
6191
6372
|
let p1 = Point2.ZERO;
|
|
6192
6373
|
let p2 = Point2.ZERO;
|
|
6193
|
-
while (k1 >
|
|
6374
|
+
while (k1 > _0n6 || k2 > _0n6) {
|
|
6194
6375
|
if (k1 & _1n5)
|
|
6195
6376
|
p1 = p1.add(acc);
|
|
6196
6377
|
if (k2 & _1n5)
|
|
@@ -6257,7 +6438,7 @@ function _createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
|
6257
6438
|
throw new Error(`expected valid ${type} CURVE object`);
|
|
6258
6439
|
for (const p of ["p", "n", "h"]) {
|
|
6259
6440
|
const val = CURVE[p];
|
|
6260
|
-
if (!(typeof val === "bigint" && val >
|
|
6441
|
+
if (!(typeof val === "bigint" && val > _0n6))
|
|
6261
6442
|
throw new Error(`CURVE.${p} must be positive bigint`);
|
|
6262
6443
|
}
|
|
6263
6444
|
const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE);
|
|
@@ -6273,21 +6454,21 @@ function _createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
|
6273
6454
|
}
|
|
6274
6455
|
|
|
6275
6456
|
// ../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/esm/abstract/weierstrass.js
|
|
6276
|
-
var divNearest2 = (
|
|
6457
|
+
var divNearest2 = (num2, den) => (num2 + (num2 >= 0 ? den : -den) / _2n5) / den;
|
|
6277
6458
|
function _splitEndoScalar2(k, basis, n) {
|
|
6278
6459
|
const [[a1, b1], [a2, b2]] = basis;
|
|
6279
6460
|
const c1 = divNearest2(b2 * k, n);
|
|
6280
6461
|
const c2 = divNearest2(-b1 * k, n);
|
|
6281
6462
|
let k1 = k - c1 * a1 - c2 * a2;
|
|
6282
6463
|
let k2 = -c1 * b1 - c2 * b2;
|
|
6283
|
-
const k1neg = k1 <
|
|
6284
|
-
const k2neg = k2 <
|
|
6464
|
+
const k1neg = k1 < _0n7;
|
|
6465
|
+
const k2neg = k2 < _0n7;
|
|
6285
6466
|
if (k1neg)
|
|
6286
6467
|
k1 = -k1;
|
|
6287
6468
|
if (k2neg)
|
|
6288
6469
|
k2 = -k2;
|
|
6289
6470
|
const MAX_NUM = bitMask2(Math.ceil(bitLen2(n) / 2)) + _1n6;
|
|
6290
|
-
if (k1 <
|
|
6471
|
+
if (k1 < _0n7 || k1 >= MAX_NUM || k2 < _0n7 || k2 >= MAX_NUM) {
|
|
6291
6472
|
throw new Error("splitScalar (endomorphism): failed, k=" + k);
|
|
6292
6473
|
}
|
|
6293
6474
|
return { k1neg, k1, k2neg, k2 };
|
|
@@ -6373,11 +6554,11 @@ var DER2 = {
|
|
|
6373
6554
|
// - add zero byte if exists
|
|
6374
6555
|
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
|
6375
6556
|
_int: {
|
|
6376
|
-
encode(
|
|
6557
|
+
encode(num2) {
|
|
6377
6558
|
const { Err: E } = DER2;
|
|
6378
|
-
if (
|
|
6559
|
+
if (num2 < _0n7)
|
|
6379
6560
|
throw new E("integer: negative integers are not allowed");
|
|
6380
|
-
let hex = numberToHexUnpadded2(
|
|
6561
|
+
let hex = numberToHexUnpadded2(num2);
|
|
6381
6562
|
if (Number.parseInt(hex[0], 16) & 8)
|
|
6382
6563
|
hex = "00" + hex;
|
|
6383
6564
|
if (hex.length & 1)
|
|
@@ -6413,27 +6594,27 @@ var DER2 = {
|
|
|
6413
6594
|
return tlv.encode(48, seq);
|
|
6414
6595
|
}
|
|
6415
6596
|
};
|
|
6416
|
-
var
|
|
6597
|
+
var _0n7 = BigInt(0);
|
|
6417
6598
|
var _1n6 = BigInt(1);
|
|
6418
6599
|
var _2n5 = BigInt(2);
|
|
6419
6600
|
var _3n3 = BigInt(3);
|
|
6420
6601
|
var _4n3 = BigInt(4);
|
|
6421
6602
|
function _normFnElement(Fn, key2) {
|
|
6422
6603
|
const { BYTES: expected } = Fn;
|
|
6423
|
-
let
|
|
6604
|
+
let num2;
|
|
6424
6605
|
if (typeof key2 === "bigint") {
|
|
6425
|
-
|
|
6606
|
+
num2 = key2;
|
|
6426
6607
|
} else {
|
|
6427
6608
|
let bytes = ensureBytes("private key", key2);
|
|
6428
6609
|
try {
|
|
6429
|
-
|
|
6610
|
+
num2 = Fn.fromBytes(bytes);
|
|
6430
6611
|
} catch (error) {
|
|
6431
6612
|
throw new Error(`invalid private key: expected ui8a of size ${expected}, got ${typeof key2}`);
|
|
6432
6613
|
}
|
|
6433
6614
|
}
|
|
6434
|
-
if (!Fn.isValidNot0(
|
|
6615
|
+
if (!Fn.isValidNot0(num2))
|
|
6435
6616
|
throw new Error("invalid private key: out of range [1..N-1]");
|
|
6436
|
-
return
|
|
6617
|
+
return num2;
|
|
6437
6618
|
}
|
|
6438
6619
|
function weierstrassN(params, extraOpts = {}) {
|
|
6439
6620
|
const validated = _createCurveFields("weierstrass", params, extraOpts);
|
|
@@ -6460,7 +6641,7 @@ function weierstrassN(params, extraOpts = {}) {
|
|
|
6460
6641
|
if (!Fp.isOdd)
|
|
6461
6642
|
throw new Error("compression is not supported: Field does not have .isOdd()");
|
|
6462
6643
|
}
|
|
6463
|
-
function
|
|
6644
|
+
function pointToBytes2(_c, point, isCompressed) {
|
|
6464
6645
|
const { x, y } = point.toAffine();
|
|
6465
6646
|
const bx = Fp.toBytes(x);
|
|
6466
6647
|
_abool2(isCompressed, "isCompressed");
|
|
@@ -6507,7 +6688,7 @@ function weierstrassN(params, extraOpts = {}) {
|
|
|
6507
6688
|
throw new Error(`bad point: got length ${length}, expected compressed=${comp} or uncompressed=${uncomp}`);
|
|
6508
6689
|
}
|
|
6509
6690
|
}
|
|
6510
|
-
const encodePoint = extraOpts.toBytes ||
|
|
6691
|
+
const encodePoint = extraOpts.toBytes || pointToBytes2;
|
|
6511
6692
|
const decodePoint = extraOpts.fromBytes || pointFromBytes;
|
|
6512
6693
|
function weierstrassEquation(x) {
|
|
6513
6694
|
const x2 = Fp.sqr(x);
|
|
@@ -6787,7 +6968,7 @@ function weierstrassN(params, extraOpts = {}) {
|
|
|
6787
6968
|
const p = this;
|
|
6788
6969
|
if (!Fn.isValid(sc))
|
|
6789
6970
|
throw new Error("invalid scalar: out of range");
|
|
6790
|
-
if (sc ===
|
|
6971
|
+
if (sc === _0n7 || p.is0())
|
|
6791
6972
|
return Point2.ZERO;
|
|
6792
6973
|
if (sc === _1n6)
|
|
6793
6974
|
return p;
|
|
@@ -6895,7 +7076,7 @@ function getWLengths2(Fp, Fn) {
|
|
|
6895
7076
|
}
|
|
6896
7077
|
function ecdh2(Point2, ecdhOpts = {}) {
|
|
6897
7078
|
const { Fn } = Point2;
|
|
6898
|
-
const randomBytes_ = ecdhOpts.randomBytes ||
|
|
7079
|
+
const randomBytes_ = ecdhOpts.randomBytes || randomBytes3;
|
|
6899
7080
|
const lengths = Object.assign(getWLengths2(Point2.Fp, Fn), { seed: getMinHashLength2(Fn.ORDER) });
|
|
6900
7081
|
function isValidSecretKey(secretKey) {
|
|
6901
7082
|
try {
|
|
@@ -6970,7 +7151,7 @@ function ecdsa2(Point2, hash, ecdsaOpts = {}) {
|
|
|
6970
7151
|
bits2int: "function",
|
|
6971
7152
|
bits2int_modN: "function"
|
|
6972
7153
|
});
|
|
6973
|
-
const
|
|
7154
|
+
const randomBytes4 = ecdsaOpts.randomBytes || randomBytes3;
|
|
6974
7155
|
const hmac3 = ecdsaOpts.hmac || ((key2, ...msgs) => hmac(hash, key2, concatBytes2(...msgs)));
|
|
6975
7156
|
const { Fp, Fn } = Point2;
|
|
6976
7157
|
const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;
|
|
@@ -6987,10 +7168,10 @@ function ecdsa2(Point2, hash, ecdsaOpts = {}) {
|
|
|
6987
7168
|
const HALF = CURVE_ORDER >> _1n6;
|
|
6988
7169
|
return number > HALF;
|
|
6989
7170
|
}
|
|
6990
|
-
function validateRS(title,
|
|
6991
|
-
if (!Fn.isValidNot0(
|
|
7171
|
+
function validateRS(title, num2) {
|
|
7172
|
+
if (!Fn.isValidNot0(num2))
|
|
6992
7173
|
throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`);
|
|
6993
|
-
return
|
|
7174
|
+
return num2;
|
|
6994
7175
|
}
|
|
6995
7176
|
function validateSigLength(bytes, format) {
|
|
6996
7177
|
validateSigFormat2(format);
|
|
@@ -7100,17 +7281,17 @@ function ecdsa2(Point2, hash, ecdsaOpts = {}) {
|
|
|
7100
7281
|
const bits2int = ecdsaOpts.bits2int || function bits2int_def(bytes) {
|
|
7101
7282
|
if (bytes.length > 8192)
|
|
7102
7283
|
throw new Error("input is too large");
|
|
7103
|
-
const
|
|
7284
|
+
const num2 = bytesToNumberBE2(bytes);
|
|
7104
7285
|
const delta = bytes.length * 8 - fnBits;
|
|
7105
|
-
return delta > 0 ?
|
|
7286
|
+
return delta > 0 ? num2 >> BigInt(delta) : num2;
|
|
7106
7287
|
};
|
|
7107
7288
|
const bits2int_modN = ecdsaOpts.bits2int_modN || function bits2int_modN_def(bytes) {
|
|
7108
7289
|
return Fn.create(bits2int(bytes));
|
|
7109
7290
|
};
|
|
7110
7291
|
const ORDER_MASK = bitMask2(fnBits);
|
|
7111
|
-
function int2octets(
|
|
7112
|
-
aInRange2("num < 2^" + fnBits,
|
|
7113
|
-
return Fn.toBytes(
|
|
7292
|
+
function int2octets(num2) {
|
|
7293
|
+
aInRange2("num < 2^" + fnBits, num2, _0n7, ORDER_MASK);
|
|
7294
|
+
return Fn.toBytes(num2);
|
|
7114
7295
|
}
|
|
7115
7296
|
function validateMsgAndHash(message, prehash) {
|
|
7116
7297
|
_abytes2(message, void 0, "message");
|
|
@@ -7125,7 +7306,7 @@ function ecdsa2(Point2, hash, ecdsaOpts = {}) {
|
|
|
7125
7306
|
const d = _normFnElement(Fn, privateKey);
|
|
7126
7307
|
const seedArgs = [int2octets(d), int2octets(h1int)];
|
|
7127
7308
|
if (extraEntropy != null && extraEntropy !== false) {
|
|
7128
|
-
const e = extraEntropy === true ?
|
|
7309
|
+
const e = extraEntropy === true ? randomBytes4(lengths.secretKey) : extraEntropy;
|
|
7129
7310
|
seedArgs.push(ensureBytes("extraEntropy", e));
|
|
7130
7311
|
}
|
|
7131
7312
|
const seed = concatBytes2(...seedArgs);
|
|
@@ -7137,10 +7318,10 @@ function ecdsa2(Point2, hash, ecdsaOpts = {}) {
|
|
|
7137
7318
|
const ik = Fn.inv(k);
|
|
7138
7319
|
const q = Point2.BASE.multiply(k).toAffine();
|
|
7139
7320
|
const r = Fn.create(q.x);
|
|
7140
|
-
if (r ===
|
|
7321
|
+
if (r === _0n7)
|
|
7141
7322
|
return;
|
|
7142
7323
|
const s = Fn.create(ik * Fn.create(m + r * d));
|
|
7143
|
-
if (s ===
|
|
7324
|
+
if (s === _0n7)
|
|
7144
7325
|
return;
|
|
7145
7326
|
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n6);
|
|
7146
7327
|
let normS = s;
|
|
@@ -7461,10 +7642,10 @@ function bytesToNumber(bytes) {
|
|
|
7461
7642
|
const h = bytes.length === 0 ? "0" : bytesToHex3(bytes);
|
|
7462
7643
|
return BigInt("0x" + h);
|
|
7463
7644
|
}
|
|
7464
|
-
function numberToBytes(
|
|
7465
|
-
if (typeof
|
|
7645
|
+
function numberToBytes(num2) {
|
|
7646
|
+
if (typeof num2 !== "bigint")
|
|
7466
7647
|
throw new Error("bigint expected");
|
|
7467
|
-
return hexToBytes3(
|
|
7648
|
+
return hexToBytes3(num2.toString(16).padStart(64, "0"));
|
|
7468
7649
|
}
|
|
7469
7650
|
var MASTER_SECRET = utf8ToBytes("Bitcoin seed");
|
|
7470
7651
|
var BITCOIN_VERSIONS = { private: 76066276, public: 76067358 };
|
|
@@ -7712,7 +7893,7 @@ import { toHex as toHex3 } from "viem";
|
|
|
7712
7893
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
7713
7894
|
import { createPublicClient as createPublicClient2, http as http2, defineChain as defineChain2 } from "viem";
|
|
7714
7895
|
|
|
7715
|
-
// ../../node_modules/.pnpm/@toon-protocol+sdk@
|
|
7896
|
+
// ../../node_modules/.pnpm/@toon-protocol+sdk@3.0.0_mina-signer@3.1.0_typescript@5.9.3/node_modules/@toon-protocol/sdk/dist/chunk-RAZRWSJF.js
|
|
7716
7897
|
import { getPublicKey as getPublicKey6 } from "nostr-tools/pure";
|
|
7717
7898
|
import { generateSecretKey, getPublicKey as getPublicKey22 } from "nostr-tools/pure";
|
|
7718
7899
|
import { createRumor, createSeal, createWrap } from "nostr-tools/nip59";
|
|
@@ -7874,10 +8055,218 @@ function decryptFulfillClaim(params) {
|
|
|
7874
8055
|
}
|
|
7875
8056
|
}
|
|
7876
8057
|
}
|
|
8058
|
+
var STREAM_RECEIPT_VERSION = 1;
|
|
8059
|
+
var STREAM_RECEIPT_SIGNING_TAG = "toon.stream-receipt.v1";
|
|
8060
|
+
var STREAM_NONCE_REGEX = /^[0-9a-f]{32}$/;
|
|
8061
|
+
var SIG_REGEX = /^[0-9a-f]{128}$/;
|
|
8062
|
+
var HEX64_REGEX = /^[0-9a-f]{64}$/;
|
|
8063
|
+
var DECIMAL_UINT_REGEX = /^(0|[1-9]\d*)$/;
|
|
7877
8064
|
var RATE_REGEX2 = /^(0|[1-9]\d*)(\.\d+)?$/;
|
|
8065
|
+
function isValidStreamNonce(value) {
|
|
8066
|
+
return typeof value === "string" && STREAM_NONCE_REGEX.test(value);
|
|
8067
|
+
}
|
|
8068
|
+
function parseStreamReceipt(value) {
|
|
8069
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
8070
|
+
throw new Error("receipt must be an object");
|
|
8071
|
+
}
|
|
8072
|
+
const obj = value;
|
|
8073
|
+
if (obj["v"] !== STREAM_RECEIPT_VERSION) {
|
|
8074
|
+
throw new Error(
|
|
8075
|
+
`receipt.v must be ${STREAM_RECEIPT_VERSION}, got ${String(obj["v"])}`
|
|
8076
|
+
);
|
|
8077
|
+
}
|
|
8078
|
+
if (!isValidStreamNonce(obj["streamNonce"])) {
|
|
8079
|
+
throw new Error("receipt.streamNonce must be 32-char lowercase hex");
|
|
8080
|
+
}
|
|
8081
|
+
const seq = obj["seq"];
|
|
8082
|
+
if (typeof seq !== "number" || !Number.isSafeInteger(seq) || seq < 1) {
|
|
8083
|
+
throw new Error("receipt.seq must be a positive safe integer");
|
|
8084
|
+
}
|
|
8085
|
+
const cumulativeDelivered = obj["cumulativeDelivered"];
|
|
8086
|
+
if (typeof cumulativeDelivered !== "string" || !DECIMAL_UINT_REGEX.test(cumulativeDelivered)) {
|
|
8087
|
+
throw new Error(
|
|
8088
|
+
"receipt.cumulativeDelivered must be a non-negative integer decimal string"
|
|
8089
|
+
);
|
|
8090
|
+
}
|
|
8091
|
+
const rate = obj["rate"];
|
|
8092
|
+
if (typeof rate !== "string" || !RATE_REGEX2.test(rate) || /^0(\.0+)?$/.test(rate)) {
|
|
8093
|
+
throw new Error("receipt.rate must be a positive decimal string");
|
|
8094
|
+
}
|
|
8095
|
+
const rateTimestamp = obj["rateTimestamp"];
|
|
8096
|
+
if (typeof rateTimestamp !== "number" || !Number.isInteger(rateTimestamp) || rateTimestamp <= 0) {
|
|
8097
|
+
throw new Error(
|
|
8098
|
+
"receipt.rateTimestamp must be a positive integer (unix ms)"
|
|
8099
|
+
);
|
|
8100
|
+
}
|
|
8101
|
+
const sig = obj["sig"];
|
|
8102
|
+
if (typeof sig !== "string" || !SIG_REGEX.test(sig)) {
|
|
8103
|
+
throw new Error("receipt.sig must be 128-char lowercase hex");
|
|
8104
|
+
}
|
|
8105
|
+
return {
|
|
8106
|
+
v: STREAM_RECEIPT_VERSION,
|
|
8107
|
+
streamNonce: obj["streamNonce"],
|
|
8108
|
+
seq,
|
|
8109
|
+
cumulativeDelivered,
|
|
8110
|
+
rate,
|
|
8111
|
+
rateTimestamp,
|
|
8112
|
+
sig
|
|
8113
|
+
};
|
|
8114
|
+
}
|
|
8115
|
+
function encodeReceiptSigningPayload(fields) {
|
|
8116
|
+
if (!isValidStreamNonce(fields.streamNonce)) {
|
|
8117
|
+
throw new Error("streamNonce must be 32-char lowercase hex");
|
|
8118
|
+
}
|
|
8119
|
+
const tag = Buffer.from(STREAM_RECEIPT_SIGNING_TAG, "utf8");
|
|
8120
|
+
const cumulative = Buffer.from(fields.cumulativeDelivered, "utf8");
|
|
8121
|
+
const rate = Buffer.from(fields.rate, "utf8");
|
|
8122
|
+
const buf = Buffer.alloc(
|
|
8123
|
+
4 + tag.length + 1 + 16 + 8 + 4 + cumulative.length + 4 + rate.length + 8
|
|
8124
|
+
);
|
|
8125
|
+
let off = 0;
|
|
8126
|
+
buf.writeUInt32BE(tag.length, off);
|
|
8127
|
+
off += 4;
|
|
8128
|
+
tag.copy(buf, off);
|
|
8129
|
+
off += tag.length;
|
|
8130
|
+
buf.writeUInt8(fields.v, off);
|
|
8131
|
+
off += 1;
|
|
8132
|
+
Buffer.from(hexToBytes(fields.streamNonce)).copy(buf, off);
|
|
8133
|
+
off += 16;
|
|
8134
|
+
buf.writeBigUInt64BE(BigInt(fields.seq), off);
|
|
8135
|
+
off += 8;
|
|
8136
|
+
buf.writeUInt32BE(cumulative.length, off);
|
|
8137
|
+
off += 4;
|
|
8138
|
+
cumulative.copy(buf, off);
|
|
8139
|
+
off += cumulative.length;
|
|
8140
|
+
buf.writeUInt32BE(rate.length, off);
|
|
8141
|
+
off += 4;
|
|
8142
|
+
rate.copy(buf, off);
|
|
8143
|
+
off += rate.length;
|
|
8144
|
+
buf.writeBigUInt64BE(BigInt(fields.rateTimestamp), off);
|
|
8145
|
+
return new Uint8Array(buf);
|
|
8146
|
+
}
|
|
8147
|
+
function verifyStreamReceipt(receipt, makerPubkey) {
|
|
8148
|
+
if (typeof makerPubkey !== "string" || !HEX64_REGEX.test(makerPubkey)) {
|
|
8149
|
+
return false;
|
|
8150
|
+
}
|
|
8151
|
+
if (typeof receipt.sig !== "string" || !SIG_REGEX.test(receipt.sig)) {
|
|
8152
|
+
return false;
|
|
8153
|
+
}
|
|
8154
|
+
try {
|
|
8155
|
+
const { sig: _sig, ...fields } = receipt;
|
|
8156
|
+
const digest = sha256(encodeReceiptSigningPayload(fields));
|
|
8157
|
+
return schnorr.verify(
|
|
8158
|
+
hexToBytes(receipt.sig),
|
|
8159
|
+
digest,
|
|
8160
|
+
hexToBytes(makerPubkey)
|
|
8161
|
+
);
|
|
8162
|
+
} catch {
|
|
8163
|
+
return false;
|
|
8164
|
+
}
|
|
8165
|
+
}
|
|
8166
|
+
var ReceiptChainTracker = class {
|
|
8167
|
+
#streamNonce;
|
|
8168
|
+
#makerPubkey;
|
|
8169
|
+
/** Verified receipts, kept sorted by ascending seq. */
|
|
8170
|
+
#receipts = [];
|
|
8171
|
+
#seqs = /* @__PURE__ */ new Set();
|
|
8172
|
+
constructor(input) {
|
|
8173
|
+
if (!isValidStreamNonce(input.streamNonce)) {
|
|
8174
|
+
throw new Error("streamNonce must be 32-char lowercase hex");
|
|
8175
|
+
}
|
|
8176
|
+
if (typeof input.makerPubkey !== "string" || !HEX64_REGEX.test(input.makerPubkey)) {
|
|
8177
|
+
throw new Error("makerPubkey must be a 64-char lowercase hex string");
|
|
8178
|
+
}
|
|
8179
|
+
this.#streamNonce = input.streamNonce;
|
|
8180
|
+
this.#makerPubkey = input.makerPubkey;
|
|
8181
|
+
}
|
|
8182
|
+
get streamNonce() {
|
|
8183
|
+
return this.#streamNonce;
|
|
8184
|
+
}
|
|
8185
|
+
/** Number of verified receipts accumulated so far. */
|
|
8186
|
+
get size() {
|
|
8187
|
+
return this.#receipts.length;
|
|
8188
|
+
}
|
|
8189
|
+
/**
|
|
8190
|
+
* Verify + accumulate one receipt. On `{ok: false}` the receipt is NOT
|
|
8191
|
+
* added and the chain is unchanged.
|
|
8192
|
+
*/
|
|
8193
|
+
add(receipt) {
|
|
8194
|
+
if (receipt.streamNonce !== this.#streamNonce) {
|
|
8195
|
+
return {
|
|
8196
|
+
ok: false,
|
|
8197
|
+
code: "WRONG_STREAM_NONCE",
|
|
8198
|
+
message: `receipt streamNonce ${receipt.streamNonce} does not match session ${this.#streamNonce}`
|
|
8199
|
+
};
|
|
8200
|
+
}
|
|
8201
|
+
if (!verifyStreamReceipt(receipt, this.#makerPubkey)) {
|
|
8202
|
+
return {
|
|
8203
|
+
ok: false,
|
|
8204
|
+
code: "BAD_SIGNATURE",
|
|
8205
|
+
message: `receipt seq ${receipt.seq} signature does not verify against maker key ${this.#makerPubkey}`
|
|
8206
|
+
};
|
|
8207
|
+
}
|
|
8208
|
+
if (this.#seqs.has(receipt.seq)) {
|
|
8209
|
+
return {
|
|
8210
|
+
ok: false,
|
|
8211
|
+
code: "DUPLICATE_SEQ",
|
|
8212
|
+
message: `duplicate receipt seq ${receipt.seq}`
|
|
8213
|
+
};
|
|
8214
|
+
}
|
|
8215
|
+
let lo = 0;
|
|
8216
|
+
let hi = this.#receipts.length;
|
|
8217
|
+
while (lo < hi) {
|
|
8218
|
+
const mid = lo + hi >>> 1;
|
|
8219
|
+
const midReceipt = this.#receipts[mid];
|
|
8220
|
+
if (midReceipt.seq < receipt.seq) lo = mid + 1;
|
|
8221
|
+
else hi = mid;
|
|
8222
|
+
}
|
|
8223
|
+
const cumulative = BigInt(receipt.cumulativeDelivered);
|
|
8224
|
+
const lower = lo > 0 ? this.#receipts[lo - 1] : void 0;
|
|
8225
|
+
const higher = lo < this.#receipts.length ? this.#receipts[lo] : void 0;
|
|
8226
|
+
if (lower && BigInt(lower.cumulativeDelivered) > cumulative) {
|
|
8227
|
+
return {
|
|
8228
|
+
ok: false,
|
|
8229
|
+
code: "NON_MONOTONIC",
|
|
8230
|
+
message: `receipt seq ${receipt.seq} cumulativeDelivered ${receipt.cumulativeDelivered} is below seq ${lower.seq}'s ${lower.cumulativeDelivered}`
|
|
8231
|
+
};
|
|
8232
|
+
}
|
|
8233
|
+
if (higher && BigInt(higher.cumulativeDelivered) < cumulative) {
|
|
8234
|
+
return {
|
|
8235
|
+
ok: false,
|
|
8236
|
+
code: "NON_MONOTONIC",
|
|
8237
|
+
message: `receipt seq ${receipt.seq} cumulativeDelivered ${receipt.cumulativeDelivered} is above seq ${higher.seq}'s ${higher.cumulativeDelivered}`
|
|
8238
|
+
};
|
|
8239
|
+
}
|
|
8240
|
+
this.#receipts.splice(lo, 0, receipt);
|
|
8241
|
+
this.#seqs.add(receipt.seq);
|
|
8242
|
+
return { ok: true };
|
|
8243
|
+
}
|
|
8244
|
+
/**
|
|
8245
|
+
* Snapshot the accumulated chain: sorted receipts, the superseding latest,
|
|
8246
|
+
* the signed total delivered, and any `seq` holes in `[1, latest.seq]`.
|
|
8247
|
+
*/
|
|
8248
|
+
chain() {
|
|
8249
|
+
const receipts = [...this.#receipts];
|
|
8250
|
+
const latest = receipts[receipts.length - 1];
|
|
8251
|
+
const holes = [];
|
|
8252
|
+
if (latest) {
|
|
8253
|
+
for (let seq = 1; seq <= latest.seq; seq++) {
|
|
8254
|
+
if (!this.#seqs.has(seq)) holes.push(seq);
|
|
8255
|
+
}
|
|
8256
|
+
}
|
|
8257
|
+
return {
|
|
8258
|
+
streamNonce: this.#streamNonce,
|
|
8259
|
+
receipts,
|
|
8260
|
+
...latest !== void 0 && { latest },
|
|
8261
|
+
totalDelivered: latest?.cumulativeDelivered ?? "0",
|
|
8262
|
+
holes
|
|
8263
|
+
};
|
|
8264
|
+
}
|
|
8265
|
+
};
|
|
8266
|
+
var RATE_REGEX22 = /^(0|[1-9]\d*)(\.\d+)?$/;
|
|
7878
8267
|
function applyRate(params) {
|
|
7879
8268
|
const { sourceAmount, fromScale, toScale, rate } = params;
|
|
7880
|
-
if (!
|
|
8269
|
+
if (!RATE_REGEX22.test(rate)) {
|
|
7881
8270
|
throw new SwapHandlerError(`Invalid rate format: ${rate}`);
|
|
7882
8271
|
}
|
|
7883
8272
|
if (/^0(\.0+)?$/.test(rate)) {
|
|
@@ -7897,8 +8286,8 @@ function applyRate(params) {
|
|
|
7897
8286
|
const scaleDown = 10n ** BigInt(fromScale);
|
|
7898
8287
|
return sourceAmount * rateNumerator * scaleUp / (rateDenominator * scaleDown);
|
|
7899
8288
|
}
|
|
7900
|
-
var
|
|
7901
|
-
var
|
|
8289
|
+
var RATE_REGEX3 = /^(0|[1-9]\d*)(\.\d+)?$/;
|
|
8290
|
+
var HEX64_REGEX2 = /^[0-9a-f]{64}$/;
|
|
7902
8291
|
var BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
7903
8292
|
function isBase64(s) {
|
|
7904
8293
|
if (s.length === 0 || s.length % 4 !== 0) return false;
|
|
@@ -7934,26 +8323,29 @@ function buildSwapRumor(input) {
|
|
|
7934
8323
|
totalPackets,
|
|
7935
8324
|
nonce,
|
|
7936
8325
|
createdAt,
|
|
7937
|
-
chainRecipient
|
|
8326
|
+
chainRecipient,
|
|
8327
|
+
streamNonce
|
|
7938
8328
|
} = input;
|
|
8329
|
+
const tags = [
|
|
8330
|
+
["swap-from", `${pair.from.assetCode}:${pair.from.chain}`],
|
|
8331
|
+
["swap-to", `${pair.to.assetCode}:${pair.to.chain}`],
|
|
8332
|
+
["amount", sourceAmount.toString()],
|
|
8333
|
+
["seq", String(packetIndex), String(totalPackets)],
|
|
8334
|
+
["nonce", Buffer.from(nonce).toString("hex")],
|
|
8335
|
+
["chain-recipient", chainRecipient]
|
|
8336
|
+
];
|
|
8337
|
+
if (streamNonce !== void 0) tags.push(["stream-nonce", streamNonce]);
|
|
7939
8338
|
return {
|
|
7940
8339
|
kind: 20032,
|
|
7941
8340
|
pubkey: senderPubkey,
|
|
7942
8341
|
content: "",
|
|
7943
8342
|
created_at: createdAt,
|
|
7944
|
-
tags
|
|
7945
|
-
["swap-from", `${pair.from.assetCode}:${pair.from.chain}`],
|
|
7946
|
-
["swap-to", `${pair.to.assetCode}:${pair.to.chain}`],
|
|
7947
|
-
["amount", sourceAmount.toString()],
|
|
7948
|
-
["seq", String(packetIndex), String(totalPackets)],
|
|
7949
|
-
["nonce", Buffer.from(nonce).toString("hex")],
|
|
7950
|
-
["chain-recipient", chainRecipient]
|
|
7951
|
-
]
|
|
8343
|
+
tags
|
|
7952
8344
|
};
|
|
7953
8345
|
}
|
|
7954
8346
|
var EVM_CHANNEL_ID_REGEX = /^0x[0-9a-f]{64}$/;
|
|
7955
8347
|
var EVM_ADDRESS_REGEX = /^0x[0-9a-f]{40}$/;
|
|
7956
|
-
var
|
|
8348
|
+
var DECIMAL_UINT_REGEX2 = /^(0|[1-9]\d*)$/;
|
|
7957
8349
|
var BASE58_REGEX = /^[1-9A-HJ-NP-Za-km-z]+$/;
|
|
7958
8350
|
function validateChainAddress(value, chain, kind) {
|
|
7959
8351
|
if (chain.startsWith("evm:")) {
|
|
@@ -8020,7 +8412,7 @@ function decodeFulfillMetadata(data, chain, opts) {
|
|
|
8020
8412
|
"FULFILL metadata.claim is missing or not base64 string"
|
|
8021
8413
|
);
|
|
8022
8414
|
}
|
|
8023
|
-
if (typeof ephemeralPubkey !== "string" || !
|
|
8415
|
+
if (typeof ephemeralPubkey !== "string" || !HEX64_REGEX2.test(ephemeralPubkey)) {
|
|
8024
8416
|
throw new StreamSwapError(
|
|
8025
8417
|
"FULFILL_DECODE_FAILED",
|
|
8026
8418
|
"FULFILL metadata.ephemeralPubkey is missing or not 64-char hex"
|
|
@@ -8054,7 +8446,7 @@ function decodeFulfillMetadata(data, chain, opts) {
|
|
|
8054
8446
|
);
|
|
8055
8447
|
}
|
|
8056
8448
|
if (hasRate) {
|
|
8057
|
-
if (typeof tapeRate !== "string" || !
|
|
8449
|
+
if (typeof tapeRate !== "string" || !RATE_REGEX3.test(tapeRate) || /^0(\.0+)?$/.test(tapeRate)) {
|
|
8058
8450
|
throw new StreamSwapError(
|
|
8059
8451
|
"FULFILL_DECODE_FAILED",
|
|
8060
8452
|
"FULFILL metadata.rate must be a positive decimal string"
|
|
@@ -8074,16 +8466,27 @@ function decodeFulfillMetadata(data, chain, opts) {
|
|
|
8074
8466
|
"FULFILL metadata is missing the quote tape (rate + rateTimestamp) required when minExchangeRate is set"
|
|
8075
8467
|
);
|
|
8076
8468
|
}
|
|
8469
|
+
if (obj["receipt"] !== void 0) {
|
|
8470
|
+
try {
|
|
8471
|
+
result.receipt = parseStreamReceipt(obj["receipt"]);
|
|
8472
|
+
} catch (err) {
|
|
8473
|
+
throw new StreamSwapError(
|
|
8474
|
+
"FULFILL_DECODE_FAILED",
|
|
8475
|
+
`FULFILL metadata.receipt is malformed: ${err instanceof Error ? err.message : String(err)}`,
|
|
8476
|
+
{ cause: err }
|
|
8477
|
+
);
|
|
8478
|
+
}
|
|
8479
|
+
}
|
|
8077
8480
|
const channelId = obj["channelId"];
|
|
8078
8481
|
if (typeof channelId === "string" && (!chain || validateChainAddress(channelId, chain, "channelId"))) {
|
|
8079
8482
|
result.channelId = channelId;
|
|
8080
8483
|
}
|
|
8081
8484
|
const nonce = obj["nonce"];
|
|
8082
|
-
if (typeof nonce === "string" &&
|
|
8485
|
+
if (typeof nonce === "string" && DECIMAL_UINT_REGEX2.test(nonce)) {
|
|
8083
8486
|
result.nonce = nonce;
|
|
8084
8487
|
}
|
|
8085
8488
|
const cumulativeAmount = obj["cumulativeAmount"];
|
|
8086
|
-
if (typeof cumulativeAmount === "string" &&
|
|
8489
|
+
if (typeof cumulativeAmount === "string" && DECIMAL_UINT_REGEX2.test(cumulativeAmount)) {
|
|
8087
8490
|
result.cumulativeAmount = cumulativeAmount;
|
|
8088
8491
|
}
|
|
8089
8492
|
const recipient = obj["recipient"];
|
|
@@ -8097,12 +8500,12 @@ function decodeFulfillMetadata(data, chain, opts) {
|
|
|
8097
8500
|
return result;
|
|
8098
8501
|
}
|
|
8099
8502
|
function compareDecimalRates(a, b) {
|
|
8100
|
-
const
|
|
8503
|
+
const split3 = (s) => {
|
|
8101
8504
|
const dot = s.indexOf(".");
|
|
8102
8505
|
return dot === -1 ? { int: s, frac: "" } : { int: s.slice(0, dot), frac: s.slice(dot + 1) };
|
|
8103
8506
|
};
|
|
8104
|
-
const pa =
|
|
8105
|
-
const pb =
|
|
8507
|
+
const pa = split3(a);
|
|
8508
|
+
const pb = split3(b);
|
|
8106
8509
|
const scale = Math.max(pa.frac.length, pb.frac.length);
|
|
8107
8510
|
const av = BigInt(pa.int + pa.frac.padEnd(scale, "0"));
|
|
8108
8511
|
const bv = BigInt(pb.int + pb.frac.padEnd(scale, "0"));
|
|
@@ -8199,7 +8602,7 @@ function validateParams(params) {
|
|
|
8199
8602
|
"senderSecretKey must be a 32-byte Uint8Array"
|
|
8200
8603
|
);
|
|
8201
8604
|
}
|
|
8202
|
-
if (typeof params.swapPubkey !== "string" || !
|
|
8605
|
+
if (typeof params.swapPubkey !== "string" || !HEX64_REGEX2.test(params.swapPubkey)) {
|
|
8203
8606
|
throw new StreamSwapError(
|
|
8204
8607
|
"INVALID_STATE",
|
|
8205
8608
|
"swapPubkey must be a 64-char lowercase hex string"
|
|
@@ -8220,10 +8623,10 @@ function validateParams(params) {
|
|
|
8220
8623
|
"pair.to must have { assetCode: string, assetScale: number, chain: string }"
|
|
8221
8624
|
);
|
|
8222
8625
|
}
|
|
8223
|
-
if (typeof params.pair.rate !== "string" || !
|
|
8626
|
+
if (typeof params.pair.rate !== "string" || !RATE_REGEX3.test(params.pair.rate)) {
|
|
8224
8627
|
throw new StreamSwapError(
|
|
8225
8628
|
"INVALID_PAIR",
|
|
8226
|
-
`pair.rate must match ${
|
|
8629
|
+
`pair.rate must match ${RATE_REGEX3}, got ${params.pair.rate}`
|
|
8227
8630
|
);
|
|
8228
8631
|
}
|
|
8229
8632
|
try {
|
|
@@ -8247,15 +8650,27 @@ function validateParams(params) {
|
|
|
8247
8650
|
);
|
|
8248
8651
|
}
|
|
8249
8652
|
if (params.minExchangeRate !== void 0) {
|
|
8250
|
-
if (typeof params.minExchangeRate !== "string" || !
|
|
8653
|
+
if (typeof params.minExchangeRate !== "string" || !RATE_REGEX3.test(params.minExchangeRate) || /^0(\.0+)?$/.test(params.minExchangeRate)) {
|
|
8251
8654
|
throw new StreamSwapError(
|
|
8252
8655
|
"INVALID_STATE",
|
|
8253
|
-
`minExchangeRate must be a positive decimal string matching ${
|
|
8656
|
+
`minExchangeRate must be a positive decimal string matching ${RATE_REGEX3}, got ${String(
|
|
8254
8657
|
params.minExchangeRate
|
|
8255
8658
|
)}`
|
|
8256
8659
|
);
|
|
8257
8660
|
}
|
|
8258
8661
|
}
|
|
8662
|
+
if (params.receiptPubkey !== void 0 && (typeof params.receiptPubkey !== "string" || !HEX64_REGEX2.test(params.receiptPubkey))) {
|
|
8663
|
+
throw new StreamSwapError(
|
|
8664
|
+
"INVALID_STATE",
|
|
8665
|
+
"receiptPubkey must be a 64-char lowercase hex string"
|
|
8666
|
+
);
|
|
8667
|
+
}
|
|
8668
|
+
if (params.requireReceipts !== void 0 && typeof params.requireReceipts !== "boolean") {
|
|
8669
|
+
throw new StreamSwapError(
|
|
8670
|
+
"INVALID_STATE",
|
|
8671
|
+
`requireReceipts must be a boolean, got ${String(params.requireReceipts)}`
|
|
8672
|
+
);
|
|
8673
|
+
}
|
|
8259
8674
|
if (params.packetExpiryMs !== void 0 && (typeof params.packetExpiryMs !== "number" || !Number.isInteger(params.packetExpiryMs) || params.packetExpiryMs <= 0)) {
|
|
8260
8675
|
throw new StreamSwapError(
|
|
8261
8676
|
"INVALID_STATE",
|
|
@@ -8292,6 +8707,9 @@ function streamSwapControlled(params) {
|
|
|
8292
8707
|
rate: params.pair.rate
|
|
8293
8708
|
});
|
|
8294
8709
|
const senderPubkey = getPublicKey32(params.senderSecretKey);
|
|
8710
|
+
const streamNonceBytes = new Uint8Array(16);
|
|
8711
|
+
getRandomValues(streamNonceBytes);
|
|
8712
|
+
const streamNonce = Buffer.from(streamNonceBytes).toString("hex");
|
|
8295
8713
|
let streamState = "running";
|
|
8296
8714
|
let resumeDeferred = null;
|
|
8297
8715
|
const controller = {
|
|
@@ -8342,6 +8760,7 @@ function streamSwapControlled(params) {
|
|
|
8342
8760
|
params,
|
|
8343
8761
|
frozenPair,
|
|
8344
8762
|
senderPubkey,
|
|
8763
|
+
streamNonce,
|
|
8345
8764
|
logger,
|
|
8346
8765
|
getState,
|
|
8347
8766
|
setState,
|
|
@@ -8351,6 +8770,7 @@ function streamSwapControlled(params) {
|
|
|
8351
8770
|
frozenPair,
|
|
8352
8771
|
schedule,
|
|
8353
8772
|
senderPubkey,
|
|
8773
|
+
streamNonce,
|
|
8354
8774
|
logger,
|
|
8355
8775
|
getState,
|
|
8356
8776
|
setState,
|
|
@@ -8359,7 +8779,15 @@ function streamSwapControlled(params) {
|
|
|
8359
8779
|
return { result, controller };
|
|
8360
8780
|
}
|
|
8361
8781
|
function buildAndWrapPacket(input) {
|
|
8362
|
-
const {
|
|
8782
|
+
const {
|
|
8783
|
+
params,
|
|
8784
|
+
pair,
|
|
8785
|
+
senderPubkey,
|
|
8786
|
+
sourceAmount,
|
|
8787
|
+
seq,
|
|
8788
|
+
totalPackets,
|
|
8789
|
+
streamNonce
|
|
8790
|
+
} = input;
|
|
8363
8791
|
const nonce = new Uint8Array(16);
|
|
8364
8792
|
getRandomValues(nonce);
|
|
8365
8793
|
const rumor = buildSwapRumor({
|
|
@@ -8370,7 +8798,8 @@ function buildAndWrapPacket(input) {
|
|
|
8370
8798
|
totalPackets,
|
|
8371
8799
|
nonce,
|
|
8372
8800
|
createdAt: Math.floor(Date.now() / 1e3),
|
|
8373
|
-
chainRecipient: params.chainRecipient
|
|
8801
|
+
chainRecipient: params.chainRecipient,
|
|
8802
|
+
streamNonce
|
|
8374
8803
|
});
|
|
8375
8804
|
const packetExpiresAt = params.packetExpiryMs !== void 0 ? new Date(Date.now() + params.packetExpiryMs) : void 0;
|
|
8376
8805
|
const wrapped = wrapSwapPacketToToon({
|
|
@@ -8460,6 +8889,47 @@ async function processAcceptedPacket(ctx, args) {
|
|
|
8460
8889
|
return { status: "below-floor" };
|
|
8461
8890
|
}
|
|
8462
8891
|
}
|
|
8892
|
+
let verifiedReceipt;
|
|
8893
|
+
if (metadata.receipt !== void 0) {
|
|
8894
|
+
const receipt = metadata.receipt;
|
|
8895
|
+
let failure;
|
|
8896
|
+
if (metadata.rate !== void 0 && receipt.rate !== metadata.rate) {
|
|
8897
|
+
failure = `receipt.rate ${receipt.rate} does not match tape rate ${metadata.rate}`;
|
|
8898
|
+
} else if (metadata.rateTimestamp !== void 0 && receipt.rateTimestamp !== metadata.rateTimestamp) {
|
|
8899
|
+
failure = `receipt.rateTimestamp ${receipt.rateTimestamp} does not match tape rateTimestamp ${metadata.rateTimestamp}`;
|
|
8900
|
+
} else {
|
|
8901
|
+
const added = ctx.receiptTracker.add(receipt);
|
|
8902
|
+
if (!added.ok) failure = `${added.code}: ${added.message}`;
|
|
8903
|
+
}
|
|
8904
|
+
if (failure !== void 0) {
|
|
8905
|
+
logger.warn({
|
|
8906
|
+
event: "stream_swap.receipt_invalid",
|
|
8907
|
+
packetIndex,
|
|
8908
|
+
seq: receipt.seq,
|
|
8909
|
+
error: failure
|
|
8910
|
+
});
|
|
8911
|
+
ctx.rejections.push({
|
|
8912
|
+
packetIndex,
|
|
8913
|
+
sourceAmount,
|
|
8914
|
+
code: "RECEIPT_INVALID",
|
|
8915
|
+
message: `Stream receipt failed verification: ${failure}`
|
|
8916
|
+
});
|
|
8917
|
+
return { status: "receipt-invalid" };
|
|
8918
|
+
}
|
|
8919
|
+
verifiedReceipt = receipt;
|
|
8920
|
+
} else if (params.requireReceipts === true) {
|
|
8921
|
+
logger.warn({
|
|
8922
|
+
event: "stream_swap.receipt_missing",
|
|
8923
|
+
packetIndex
|
|
8924
|
+
});
|
|
8925
|
+
ctx.rejections.push({
|
|
8926
|
+
packetIndex,
|
|
8927
|
+
sourceAmount,
|
|
8928
|
+
code: "RECEIPT_MISSING",
|
|
8929
|
+
message: "FULFILL carried no stream receipt but requireReceipts is set (legacy maker without rfc-0039 receipt support?)"
|
|
8930
|
+
});
|
|
8931
|
+
return { status: "receipt-invalid" };
|
|
8932
|
+
}
|
|
8463
8933
|
let claimBytes;
|
|
8464
8934
|
try {
|
|
8465
8935
|
const ciphertext = new Uint8Array(Buffer.from(metadata.claim, "base64"));
|
|
@@ -8535,6 +9005,7 @@ async function processAcceptedPacket(ctx, args) {
|
|
|
8535
9005
|
accumulated.rate = metadata.rate;
|
|
8536
9006
|
accumulated.rateTimestamp = metadata.rateTimestamp;
|
|
8537
9007
|
}
|
|
9008
|
+
if (verifiedReceipt !== void 0) accumulated.receipt = verifiedReceipt;
|
|
8538
9009
|
ctx.claims.push(accumulated);
|
|
8539
9010
|
logger.debug({
|
|
8540
9011
|
event: "stream_swap.packet_accepted",
|
|
@@ -8559,6 +9030,8 @@ async function processAcceptedPacket(ctx, args) {
|
|
|
8559
9030
|
rate: metadata.rate,
|
|
8560
9031
|
rateTimestamp: metadata.rateTimestamp
|
|
8561
9032
|
},
|
|
9033
|
+
// Issue #84: surface the verified per-fulfill receipt to the callback.
|
|
9034
|
+
...verifiedReceipt !== void 0 && { receipt: verifiedReceipt },
|
|
8562
9035
|
state: ctx.getState() === "paused" ? "paused" : ctx.getState() === "stopped" ? "stopped" : "running"
|
|
8563
9036
|
});
|
|
8564
9037
|
try {
|
|
@@ -8613,10 +9086,13 @@ function finalizeResult(input) {
|
|
|
8613
9086
|
cumulativeSource: cumulative.source,
|
|
8614
9087
|
cumulativeTarget: cumulative.target,
|
|
8615
9088
|
packetsSent: input.packetsSent,
|
|
8616
|
-
packetsScheduled: input.packetsScheduled
|
|
9089
|
+
packetsScheduled: input.packetsScheduled,
|
|
9090
|
+
// Issue #84: the verified receipt chain — present on abort too,
|
|
9091
|
+
// covering exactly the packets that filled before the halt.
|
|
9092
|
+
receipts: input.ctx.receiptTracker.chain()
|
|
8617
9093
|
};
|
|
8618
9094
|
}
|
|
8619
|
-
async function runLoop(params, pair, schedule, senderPubkey, logger, getState, setState, waitForResumeOrStop) {
|
|
9095
|
+
async function runLoop(params, pair, schedule, senderPubkey, streamNonce, logger, getState, setState, waitForResumeOrStop) {
|
|
8620
9096
|
const ctx = {
|
|
8621
9097
|
params,
|
|
8622
9098
|
pair,
|
|
@@ -8625,7 +9101,11 @@ async function runLoop(params, pair, schedule, senderPubkey, logger, getState, s
|
|
|
8625
9101
|
claims: [],
|
|
8626
9102
|
rejections: [],
|
|
8627
9103
|
errors: [],
|
|
8628
|
-
cumulative: { source: 0n, target: 0n }
|
|
9104
|
+
cumulative: { source: 0n, target: 0n },
|
|
9105
|
+
receiptTracker: new ReceiptChainTracker({
|
|
9106
|
+
streamNonce,
|
|
9107
|
+
makerPubkey: params.receiptPubkey ?? params.swapPubkey
|
|
9108
|
+
})
|
|
8629
9109
|
};
|
|
8630
9110
|
let packetsSent = 0;
|
|
8631
9111
|
let abortReason = "complete";
|
|
@@ -8666,7 +9146,8 @@ async function runLoop(params, pair, schedule, senderPubkey, logger, getState, s
|
|
|
8666
9146
|
senderPubkey,
|
|
8667
9147
|
sourceAmount,
|
|
8668
9148
|
seq: packetIndex + 1,
|
|
8669
|
-
totalPackets
|
|
9149
|
+
totalPackets,
|
|
9150
|
+
streamNonce
|
|
8670
9151
|
});
|
|
8671
9152
|
} catch (err) {
|
|
8672
9153
|
logger.error({
|
|
@@ -8729,6 +9210,10 @@ async function runLoop(params, pair, schedule, senderPubkey, logger, getState, s
|
|
|
8729
9210
|
abortReason = "below-floor";
|
|
8730
9211
|
break packetLoop;
|
|
8731
9212
|
}
|
|
9213
|
+
if (outcome.status === "receipt-invalid") {
|
|
9214
|
+
abortReason = "receipt-invalid";
|
|
9215
|
+
break packetLoop;
|
|
9216
|
+
}
|
|
8732
9217
|
if (outcome.status === "callback-throw") {
|
|
8733
9218
|
abortReason = "callback-throw";
|
|
8734
9219
|
break packetLoop;
|
|
@@ -8764,7 +9249,7 @@ function classifyReject(code, message) {
|
|
|
8764
9249
|
}
|
|
8765
9250
|
return "reject";
|
|
8766
9251
|
}
|
|
8767
|
-
async function runAdaptiveLoop(params, pair, senderPubkey, logger, getState, setState, waitForResumeOrStop) {
|
|
9252
|
+
async function runAdaptiveLoop(params, pair, senderPubkey, streamNonce, logger, getState, setState, waitForResumeOrStop) {
|
|
8768
9253
|
const controller = params.controller;
|
|
8769
9254
|
const ctx = {
|
|
8770
9255
|
params,
|
|
@@ -8774,7 +9259,11 @@ async function runAdaptiveLoop(params, pair, senderPubkey, logger, getState, set
|
|
|
8774
9259
|
claims: [],
|
|
8775
9260
|
rejections: [],
|
|
8776
9261
|
errors: [],
|
|
8777
|
-
cumulative: { source: 0n, target: 0n }
|
|
9262
|
+
cumulative: { source: 0n, target: 0n },
|
|
9263
|
+
receiptTracker: new ReceiptChainTracker({
|
|
9264
|
+
streamNonce,
|
|
9265
|
+
makerPubkey: params.receiptPubkey ?? params.swapPubkey
|
|
9266
|
+
})
|
|
8778
9267
|
};
|
|
8779
9268
|
let packetsSent = 0;
|
|
8780
9269
|
let abortReason = "complete";
|
|
@@ -8841,7 +9330,8 @@ async function runAdaptiveLoop(params, pair, senderPubkey, logger, getState, set
|
|
|
8841
9330
|
seq: packetIndex + 1,
|
|
8842
9331
|
// Adaptive mode: the final packet count is unknown upfront —
|
|
8843
9332
|
// `0` in the rumor's `seq` tag total position means "open".
|
|
8844
|
-
totalPackets: 0
|
|
9333
|
+
totalPackets: 0,
|
|
9334
|
+
streamNonce
|
|
8845
9335
|
});
|
|
8846
9336
|
} catch (err) {
|
|
8847
9337
|
logger.error({
|
|
@@ -8961,6 +9451,14 @@ async function runAdaptiveLoop(params, pair, senderPubkey, logger, getState, set
|
|
|
8961
9451
|
});
|
|
8962
9452
|
halt("below-floor");
|
|
8963
9453
|
break;
|
|
9454
|
+
case "receipt-invalid":
|
|
9455
|
+
await observeSafe({
|
|
9456
|
+
resolution: "reject",
|
|
9457
|
+
rttMs: settled.rttMs,
|
|
9458
|
+
remaining
|
|
9459
|
+
});
|
|
9460
|
+
halt("receipt-invalid");
|
|
9461
|
+
break;
|
|
8964
9462
|
case "callback-throw":
|
|
8965
9463
|
await observeSafe({
|
|
8966
9464
|
resolution: "fulfill",
|
|
@@ -9019,18 +9517,18 @@ function getRandomValues(buf) {
|
|
|
9019
9517
|
);
|
|
9020
9518
|
}
|
|
9021
9519
|
|
|
9022
|
-
// ../../node_modules/.pnpm/@toon-protocol+sdk@
|
|
9520
|
+
// ../../node_modules/.pnpm/@toon-protocol+sdk@3.0.0_mina-signer@3.1.0_typescript@5.9.3/node_modules/@toon-protocol/sdk/dist/index.js
|
|
9023
9521
|
var SwapControllerError = class extends ToonError {
|
|
9024
9522
|
constructor(message, cause) {
|
|
9025
9523
|
super(message, "SWAP_CONTROLLER_ERROR", cause);
|
|
9026
9524
|
this.name = "SwapControllerError";
|
|
9027
9525
|
}
|
|
9028
9526
|
};
|
|
9029
|
-
var
|
|
9527
|
+
var DECIMAL_UINT_REGEX3 = /^(0|[1-9]\d*)$/;
|
|
9030
9528
|
function isSwapControllerState(value) {
|
|
9031
9529
|
if (!value || typeof value !== "object") return false;
|
|
9032
9530
|
const s = value;
|
|
9033
|
-
return s["v"] === 1 && typeof s["delta"] === "string" &&
|
|
9531
|
+
return s["v"] === 1 && typeof s["delta"] === "string" && DECIMAL_UINT_REGEX3.test(s["delta"]) && typeof s["W"] === "number" && Number.isInteger(s["W"]) && s["W"] >= 1 && typeof s["vEwma"] === "number" && Number.isFinite(s["vEwma"]) && s["vEwma"] >= 0 && typeof s["tauEwma"] === "number" && Number.isFinite(s["tauEwma"]) && s["tauEwma"] >= 0 && typeof s["cleanStreak"] === "number" && Number.isInteger(s["cleanStreak"]) && s["cleanStreak"] >= 0 && typeof s["everShrunk"] === "boolean" && (s["lastWidened"] === "delta" || s["lastWidened"] === "window") && typeof s["updatedAt"] === "number";
|
|
9034
9532
|
}
|
|
9035
9533
|
function swapControllerStateKey(params) {
|
|
9036
9534
|
const { makerPubkey, pair } = params;
|
|
@@ -9379,7 +9877,19 @@ var EVM_SETTLEMENT_FUNCTION_SELECTOR = keccak_256(
|
|
|
9379
9877
|
var EVM_SETTLEMENT_EVENT_TOPIC = "0x" + bytesToHex(
|
|
9380
9878
|
keccak_256(new TextEncoder().encode(EVM_SETTLEMENT_EVENT_SIGNATURE))
|
|
9381
9879
|
);
|
|
9382
|
-
function recoverEvmSignerAddress(claim) {
|
|
9880
|
+
function recoverEvmSignerAddress(claim, chainId, verifyingContract) {
|
|
9881
|
+
if (typeof chainId !== "number" || !Number.isInteger(chainId) || chainId <= 0) {
|
|
9882
|
+
throw new SettlementTxError(
|
|
9883
|
+
"INVALID_INPUT",
|
|
9884
|
+
`EVM v2 digest requires a positive integer chainId, got ${chainId}`
|
|
9885
|
+
);
|
|
9886
|
+
}
|
|
9887
|
+
if (!verifyingContract) {
|
|
9888
|
+
throw new SettlementTxError(
|
|
9889
|
+
"INVALID_INPUT",
|
|
9890
|
+
"EVM v2 digest requires verifyingContract (RollingSwapChannel address)"
|
|
9891
|
+
);
|
|
9892
|
+
}
|
|
9383
9893
|
if (claim.channelId === void 0 || claim.cumulativeAmount === void 0 || claim.nonce === void 0 || claim.recipient === void 0) {
|
|
9384
9894
|
throw new SettlementTxError(
|
|
9385
9895
|
"MISSING_SETTLEMENT_METADATA",
|
|
@@ -9406,6 +9916,7 @@ function recoverEvmSignerAddress(claim) {
|
|
|
9406
9916
|
try {
|
|
9407
9917
|
const channelIdBytes = hexToBytes4(claim.channelId);
|
|
9408
9918
|
const recipientBytes = hexToBytes4(claim.recipient);
|
|
9919
|
+
const verifyingContractBytes = hexToBytes4(verifyingContract);
|
|
9409
9920
|
if (channelIdBytes.length !== 32) {
|
|
9410
9921
|
throw new Error(
|
|
9411
9922
|
`channelId must be 32 bytes (got ${channelIdBytes.length})`
|
|
@@ -9416,11 +9927,18 @@ function recoverEvmSignerAddress(claim) {
|
|
|
9416
9927
|
`recipient must be 20 bytes (got ${recipientBytes.length})`
|
|
9417
9928
|
);
|
|
9418
9929
|
}
|
|
9930
|
+
if (verifyingContractBytes.length !== 20) {
|
|
9931
|
+
throw new Error(
|
|
9932
|
+
`verifyingContract must be 20 bytes (got ${verifyingContractBytes.length})`
|
|
9933
|
+
);
|
|
9934
|
+
}
|
|
9419
9935
|
msgHash = balanceProofHashEvm(
|
|
9420
9936
|
channelIdBytes,
|
|
9421
9937
|
BigInt(claim.cumulativeAmount),
|
|
9422
9938
|
BigInt(claim.nonce),
|
|
9423
|
-
recipientBytes
|
|
9939
|
+
recipientBytes,
|
|
9940
|
+
BigInt(chainId),
|
|
9941
|
+
verifyingContractBytes
|
|
9424
9942
|
);
|
|
9425
9943
|
const sig = secp256k1.Signature.fromBytes(
|
|
9426
9944
|
compactRS,
|
|
@@ -9594,8 +10112,8 @@ function buildEvmSettlementTx(winner, signer, recipient, selectedClaimIndex, cla
|
|
|
9594
10112
|
sourceAssetCode: winner.pair.from.assetCode
|
|
9595
10113
|
};
|
|
9596
10114
|
}
|
|
9597
|
-
function verifyEvmClaimSignature(claim, expectedAddress) {
|
|
9598
|
-
const recovered = recoverEvmSignerAddress(claim);
|
|
10115
|
+
function verifyEvmClaimSignature(claim, expectedAddress, chainId, verifyingContract) {
|
|
10116
|
+
const recovered = recoverEvmSignerAddress(claim, chainId, verifyingContract);
|
|
9599
10117
|
const expected = expectedAddress.toLowerCase();
|
|
9600
10118
|
return {
|
|
9601
10119
|
valid: recovered.toLowerCase() === expected,
|
|
@@ -9953,7 +10471,9 @@ function buildSettlementTx(params) {
|
|
|
9953
10471
|
try {
|
|
9954
10472
|
const { valid, recovered } = verifyEvmClaimSignature(
|
|
9955
10473
|
claim,
|
|
9956
|
-
signer.address
|
|
10474
|
+
signer.address,
|
|
10475
|
+
signer.chainId,
|
|
10476
|
+
signer.contractAddress
|
|
9957
10477
|
);
|
|
9958
10478
|
if (!valid) {
|
|
9959
10479
|
rejected.push({
|
|
@@ -10203,10 +10723,18 @@ function buildSettlementTx(params) {
|
|
|
10203
10723
|
function verifyAccumulatedClaim(claim, signer, minaSignerClient) {
|
|
10204
10724
|
const kind = chainKindOf(claim.pair.to.chain);
|
|
10205
10725
|
if (kind === "evm") {
|
|
10726
|
+
if (typeof signer.chainId !== "number" || !Number.isInteger(signer.chainId) || signer.chainId <= 0 || !signer.contractAddress) {
|
|
10727
|
+
return {
|
|
10728
|
+
valid: false,
|
|
10729
|
+
reason: "INVALID_INPUT: EVM signer requires chainId (positive integer) + contractAddress for the v2 EIP-712 digest (connector#324 finding #1)"
|
|
10730
|
+
};
|
|
10731
|
+
}
|
|
10206
10732
|
try {
|
|
10207
10733
|
const { valid, recovered } = verifyEvmClaimSignature(
|
|
10208
10734
|
claim,
|
|
10209
|
-
signer.address
|
|
10735
|
+
signer.address,
|
|
10736
|
+
signer.chainId,
|
|
10737
|
+
signer.contractAddress
|
|
10210
10738
|
);
|
|
10211
10739
|
if (valid) return { valid: true };
|
|
10212
10740
|
return {
|
|
@@ -10269,6 +10797,192 @@ import {
|
|
|
10269
10797
|
} from "viem";
|
|
10270
10798
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, mkdirSync } from "fs";
|
|
10271
10799
|
import { dirname } from "path";
|
|
10800
|
+
import {
|
|
10801
|
+
hashTypedData
|
|
10802
|
+
} from "viem";
|
|
10803
|
+
|
|
10804
|
+
// ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha3.js
|
|
10805
|
+
var _0n8 = BigInt(0);
|
|
10806
|
+
var _1n7 = BigInt(1);
|
|
10807
|
+
var _2n7 = BigInt(2);
|
|
10808
|
+
var _7n3 = BigInt(7);
|
|
10809
|
+
var _256n2 = BigInt(256);
|
|
10810
|
+
var _0x71n2 = BigInt(113);
|
|
10811
|
+
var SHA3_PI2 = [];
|
|
10812
|
+
var SHA3_ROTL2 = [];
|
|
10813
|
+
var _SHA3_IOTA2 = [];
|
|
10814
|
+
for (let round = 0, R = _1n7, x = 1, y = 0; round < 24; round++) {
|
|
10815
|
+
[x, y] = [y, (2 * x + 3 * y) % 5];
|
|
10816
|
+
SHA3_PI2.push(2 * (5 * y + x));
|
|
10817
|
+
SHA3_ROTL2.push((round + 1) * (round + 2) / 2 % 64);
|
|
10818
|
+
let t = _0n8;
|
|
10819
|
+
for (let j = 0; j < 7; j++) {
|
|
10820
|
+
R = (R << _1n7 ^ (R >> _7n3) * _0x71n2) % _256n2;
|
|
10821
|
+
if (R & _2n7)
|
|
10822
|
+
t ^= _1n7 << (_1n7 << /* @__PURE__ */ BigInt(j)) - _1n7;
|
|
10823
|
+
}
|
|
10824
|
+
_SHA3_IOTA2.push(t);
|
|
10825
|
+
}
|
|
10826
|
+
var IOTAS2 = split2(_SHA3_IOTA2, true);
|
|
10827
|
+
var SHA3_IOTA_H2 = IOTAS2[0];
|
|
10828
|
+
var SHA3_IOTA_L2 = IOTAS2[1];
|
|
10829
|
+
var rotlH2 = (h, l, s) => s > 32 ? rotlBH2(h, l, s) : rotlSH2(h, l, s);
|
|
10830
|
+
var rotlL2 = (h, l, s) => s > 32 ? rotlBL2(h, l, s) : rotlSL2(h, l, s);
|
|
10831
|
+
function keccakP2(s, rounds = 24) {
|
|
10832
|
+
const B = new Uint32Array(5 * 2);
|
|
10833
|
+
for (let round = 24 - rounds; round < 24; round++) {
|
|
10834
|
+
for (let x = 0; x < 10; x++)
|
|
10835
|
+
B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
|
|
10836
|
+
for (let x = 0; x < 10; x += 2) {
|
|
10837
|
+
const idx1 = (x + 8) % 10;
|
|
10838
|
+
const idx0 = (x + 2) % 10;
|
|
10839
|
+
const B0 = B[idx0];
|
|
10840
|
+
const B1 = B[idx0 + 1];
|
|
10841
|
+
const Th = rotlH2(B0, B1, 1) ^ B[idx1];
|
|
10842
|
+
const Tl = rotlL2(B0, B1, 1) ^ B[idx1 + 1];
|
|
10843
|
+
for (let y = 0; y < 50; y += 10) {
|
|
10844
|
+
s[x + y] ^= Th;
|
|
10845
|
+
s[x + y + 1] ^= Tl;
|
|
10846
|
+
}
|
|
10847
|
+
}
|
|
10848
|
+
let curH = s[2];
|
|
10849
|
+
let curL = s[3];
|
|
10850
|
+
for (let t = 0; t < 24; t++) {
|
|
10851
|
+
const shift = SHA3_ROTL2[t];
|
|
10852
|
+
const Th = rotlH2(curH, curL, shift);
|
|
10853
|
+
const Tl = rotlL2(curH, curL, shift);
|
|
10854
|
+
const PI = SHA3_PI2[t];
|
|
10855
|
+
curH = s[PI];
|
|
10856
|
+
curL = s[PI + 1];
|
|
10857
|
+
s[PI] = Th;
|
|
10858
|
+
s[PI + 1] = Tl;
|
|
10859
|
+
}
|
|
10860
|
+
for (let y = 0; y < 50; y += 10) {
|
|
10861
|
+
for (let x = 0; x < 10; x++)
|
|
10862
|
+
B[x] = s[y + x];
|
|
10863
|
+
for (let x = 0; x < 10; x++)
|
|
10864
|
+
s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
|
|
10865
|
+
}
|
|
10866
|
+
s[0] ^= SHA3_IOTA_H2[round];
|
|
10867
|
+
s[1] ^= SHA3_IOTA_L2[round];
|
|
10868
|
+
}
|
|
10869
|
+
clean2(B);
|
|
10870
|
+
}
|
|
10871
|
+
var Keccak2 = class _Keccak extends Hash {
|
|
10872
|
+
// NOTE: we accept arguments in bytes instead of bits here.
|
|
10873
|
+
constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {
|
|
10874
|
+
super();
|
|
10875
|
+
this.pos = 0;
|
|
10876
|
+
this.posOut = 0;
|
|
10877
|
+
this.finished = false;
|
|
10878
|
+
this.destroyed = false;
|
|
10879
|
+
this.enableXOF = false;
|
|
10880
|
+
this.blockLen = blockLen;
|
|
10881
|
+
this.suffix = suffix;
|
|
10882
|
+
this.outputLen = outputLen;
|
|
10883
|
+
this.enableXOF = enableXOF;
|
|
10884
|
+
this.rounds = rounds;
|
|
10885
|
+
anumber2(outputLen);
|
|
10886
|
+
if (!(0 < blockLen && blockLen < 200))
|
|
10887
|
+
throw new Error("only keccak-f1600 function is supported");
|
|
10888
|
+
this.state = new Uint8Array(200);
|
|
10889
|
+
this.state32 = u322(this.state);
|
|
10890
|
+
}
|
|
10891
|
+
clone() {
|
|
10892
|
+
return this._cloneInto();
|
|
10893
|
+
}
|
|
10894
|
+
keccak() {
|
|
10895
|
+
swap32IfBE2(this.state32);
|
|
10896
|
+
keccakP2(this.state32, this.rounds);
|
|
10897
|
+
swap32IfBE2(this.state32);
|
|
10898
|
+
this.posOut = 0;
|
|
10899
|
+
this.pos = 0;
|
|
10900
|
+
}
|
|
10901
|
+
update(data) {
|
|
10902
|
+
aexists2(this);
|
|
10903
|
+
data = toBytes(data);
|
|
10904
|
+
abytes3(data);
|
|
10905
|
+
const { blockLen, state } = this;
|
|
10906
|
+
const len = data.length;
|
|
10907
|
+
for (let pos = 0; pos < len; ) {
|
|
10908
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
10909
|
+
for (let i = 0; i < take; i++)
|
|
10910
|
+
state[this.pos++] ^= data[pos++];
|
|
10911
|
+
if (this.pos === blockLen)
|
|
10912
|
+
this.keccak();
|
|
10913
|
+
}
|
|
10914
|
+
return this;
|
|
10915
|
+
}
|
|
10916
|
+
finish() {
|
|
10917
|
+
if (this.finished)
|
|
10918
|
+
return;
|
|
10919
|
+
this.finished = true;
|
|
10920
|
+
const { state, suffix, pos, blockLen } = this;
|
|
10921
|
+
state[pos] ^= suffix;
|
|
10922
|
+
if ((suffix & 128) !== 0 && pos === blockLen - 1)
|
|
10923
|
+
this.keccak();
|
|
10924
|
+
state[blockLen - 1] ^= 128;
|
|
10925
|
+
this.keccak();
|
|
10926
|
+
}
|
|
10927
|
+
writeInto(out) {
|
|
10928
|
+
aexists2(this, false);
|
|
10929
|
+
abytes3(out);
|
|
10930
|
+
this.finish();
|
|
10931
|
+
const bufferOut = this.state;
|
|
10932
|
+
const { blockLen } = this;
|
|
10933
|
+
for (let pos = 0, len = out.length; pos < len; ) {
|
|
10934
|
+
if (this.posOut >= blockLen)
|
|
10935
|
+
this.keccak();
|
|
10936
|
+
const take = Math.min(blockLen - this.posOut, len - pos);
|
|
10937
|
+
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
|
|
10938
|
+
this.posOut += take;
|
|
10939
|
+
pos += take;
|
|
10940
|
+
}
|
|
10941
|
+
return out;
|
|
10942
|
+
}
|
|
10943
|
+
xofInto(out) {
|
|
10944
|
+
if (!this.enableXOF)
|
|
10945
|
+
throw new Error("XOF is not possible for this instance");
|
|
10946
|
+
return this.writeInto(out);
|
|
10947
|
+
}
|
|
10948
|
+
xof(bytes) {
|
|
10949
|
+
anumber2(bytes);
|
|
10950
|
+
return this.xofInto(new Uint8Array(bytes));
|
|
10951
|
+
}
|
|
10952
|
+
digestInto(out) {
|
|
10953
|
+
aoutput2(out, this);
|
|
10954
|
+
if (this.finished)
|
|
10955
|
+
throw new Error("digest() was already called");
|
|
10956
|
+
this.writeInto(out);
|
|
10957
|
+
this.destroy();
|
|
10958
|
+
return out;
|
|
10959
|
+
}
|
|
10960
|
+
digest() {
|
|
10961
|
+
return this.digestInto(new Uint8Array(this.outputLen));
|
|
10962
|
+
}
|
|
10963
|
+
destroy() {
|
|
10964
|
+
this.destroyed = true;
|
|
10965
|
+
clean2(this.state);
|
|
10966
|
+
}
|
|
10967
|
+
_cloneInto(to) {
|
|
10968
|
+
const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
|
|
10969
|
+
to || (to = new _Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
|
|
10970
|
+
to.state32.set(this.state32);
|
|
10971
|
+
to.pos = this.pos;
|
|
10972
|
+
to.posOut = this.posOut;
|
|
10973
|
+
to.finished = this.finished;
|
|
10974
|
+
to.rounds = rounds;
|
|
10975
|
+
to.suffix = suffix;
|
|
10976
|
+
to.outputLen = outputLen;
|
|
10977
|
+
to.enableXOF = enableXOF;
|
|
10978
|
+
to.destroyed = this.destroyed;
|
|
10979
|
+
return to;
|
|
10980
|
+
}
|
|
10981
|
+
};
|
|
10982
|
+
var gen = (suffix, blockLen, outputLen) => createHasher2(() => new Keccak2(blockLen, suffix, outputLen));
|
|
10983
|
+
var keccak_2562 = /* @__PURE__ */ (() => gen(1, 136, 256 / 8))();
|
|
10984
|
+
|
|
10985
|
+
// ../client/dist/index.js
|
|
10272
10986
|
import { finalizeEvent as finalizeEvent22 } from "nostr-tools/pure";
|
|
10273
10987
|
import { nip19 } from "nostr-tools";
|
|
10274
10988
|
import { getPublicKey as getPublicKey33 } from "nostr-tools/pure";
|
|
@@ -10360,9 +11074,9 @@ function deriveEvmIdentity(secretKey) {
|
|
|
10360
11074
|
};
|
|
10361
11075
|
}
|
|
10362
11076
|
async function deriveSolanaKey(seed, accountIndex = 0) {
|
|
10363
|
-
const { hmac: hmac3 } = await import("./hmac-
|
|
10364
|
-
const { sha512: sha5122 } = await import("./sha512-
|
|
10365
|
-
const { ed25519: ed255194 } = await import("./ed25519-
|
|
11077
|
+
const { hmac: hmac3 } = await import("./hmac-GNBDA4UC.js");
|
|
11078
|
+
const { sha512: sha5122 } = await import("./sha512-D7TTPT7I.js");
|
|
11079
|
+
const { ed25519: ed255194 } = await import("./ed25519-VBPL32VX.js");
|
|
10366
11080
|
const encoder = new TextEncoder();
|
|
10367
11081
|
let I = hmac3(sha5122, encoder.encode("ed25519 seed"), seed);
|
|
10368
11082
|
let key2 = I.slice(0, 32);
|
|
@@ -10452,12 +11166,12 @@ async function deriveFullIdentity(mnemonic, accountIndex = 0) {
|
|
|
10452
11166
|
}
|
|
10453
11167
|
var BASE58_ALPHABET3 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
10454
11168
|
function toBase58(bytes) {
|
|
10455
|
-
let
|
|
10456
|
-
for (const b of bytes)
|
|
11169
|
+
let num2 = BigInt(0);
|
|
11170
|
+
for (const b of bytes) num2 = num2 * 256n + BigInt(b);
|
|
10457
11171
|
let result = "";
|
|
10458
|
-
while (
|
|
10459
|
-
result = BASE58_ALPHABET3[Number(
|
|
10460
|
-
|
|
11172
|
+
while (num2 > 0n) {
|
|
11173
|
+
result = BASE58_ALPHABET3[Number(num2 % 58n)] + result;
|
|
11174
|
+
num2 = num2 / 58n;
|
|
10461
11175
|
}
|
|
10462
11176
|
for (const b of bytes) {
|
|
10463
11177
|
if (b === 0) result = "1" + result;
|
|
@@ -11454,7 +12168,7 @@ var IsomorphicBtpClient = class {
|
|
|
11454
12168
|
};
|
|
11455
12169
|
var CONDITION_LENGTH = 32;
|
|
11456
12170
|
function mintExecutionCondition() {
|
|
11457
|
-
const preimage =
|
|
12171
|
+
const preimage = randomBytes3(CONDITION_LENGTH);
|
|
11458
12172
|
return { preimage, condition: sha2562(preimage) };
|
|
11459
12173
|
}
|
|
11460
12174
|
function isZeroCondition(condition) {
|
|
@@ -14493,8 +15207,8 @@ var Http402Client = class {
|
|
|
14493
15207
|
...opts.timeout !== void 0 ? { signal: AbortSignal.timeout(opts.timeout) } : {}
|
|
14494
15208
|
});
|
|
14495
15209
|
if (probe.status !== 402) return probe;
|
|
14496
|
-
const
|
|
14497
|
-
const accept =
|
|
15210
|
+
const challenge2 = await parseX402Challenge(probe.clone());
|
|
15211
|
+
const accept = challenge2.toonChannel;
|
|
14498
15212
|
if (!accept || !this.resolveClaim) return probe;
|
|
14499
15213
|
return this.payOverToon(url, method, opts, accept, this.resolveClaim);
|
|
14500
15214
|
}
|
|
@@ -14774,6 +15488,7 @@ function buildSwapSettlements(params) {
|
|
|
14774
15488
|
claims: [entryToAccumulatedClaim(entry)],
|
|
14775
15489
|
signers: { [entry.chain]: signer },
|
|
14776
15490
|
recipients: { [entry.chain]: entry.recipient },
|
|
15491
|
+
...params.verifySignatures !== void 0 ? { verifySignatures: params.verifySignatures } : {},
|
|
14777
15492
|
...params.minaSignerClient ? { minaSignerClient: params.minaSignerClient } : {}
|
|
14778
15493
|
});
|
|
14779
15494
|
const firstRejected = result.rejected[0];
|
|
@@ -14821,7 +15536,9 @@ function decodeEvmSettlementTx(bundle) {
|
|
|
14821
15536
|
const chainIdHex = fields[6];
|
|
14822
15537
|
const chainId = Number.parseInt(chainIdHex === "0x" ? "0x0" : chainIdHex, 16);
|
|
14823
15538
|
if (typeof to !== "string" || to.length !== 42) {
|
|
14824
|
-
throw new Error(
|
|
15539
|
+
throw new Error(
|
|
15540
|
+
`settlement tx "to" is not a 20-byte address: ${String(to)}`
|
|
15541
|
+
);
|
|
14825
15542
|
}
|
|
14826
15543
|
return { to, data: data === "0x" ? "0x" : data, chainId };
|
|
14827
15544
|
}
|
|
@@ -14838,7 +15555,10 @@ async function submitEvmSettlement(bundle, params) {
|
|
|
14838
15555
|
nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
|
|
14839
15556
|
rpcUrls: { default: { http: [params.rpcUrl] } }
|
|
14840
15557
|
});
|
|
14841
|
-
const publicClient = createPublicClient3({
|
|
15558
|
+
const publicClient = createPublicClient3({
|
|
15559
|
+
chain,
|
|
15560
|
+
transport: http3(params.rpcUrl)
|
|
15561
|
+
});
|
|
14842
15562
|
const [nonce, gasPrice, gas] = await Promise.all([
|
|
14843
15563
|
publicClient.getTransactionCount({
|
|
14844
15564
|
address: params.account.address,
|
|
@@ -16237,6 +16957,85 @@ function fromJson(entry) {
|
|
|
16237
16957
|
...entry.settleTxHash !== void 0 ? { settleTxHash: entry.settleTxHash } : {}
|
|
16238
16958
|
};
|
|
16239
16959
|
}
|
|
16960
|
+
var ROLLING_SWAP_DOMAIN_NAME = "RollingSwapChannel";
|
|
16961
|
+
var ROLLING_SWAP_DOMAIN_VERSION = "2";
|
|
16962
|
+
var CLAIM_TYPES = {
|
|
16963
|
+
ClaimBalanceProof: [
|
|
16964
|
+
{ name: "channelId", type: "bytes32" },
|
|
16965
|
+
{ name: "cumulativeAmount", type: "uint256" },
|
|
16966
|
+
{ name: "nonce", type: "uint256" },
|
|
16967
|
+
{ name: "recipient", type: "address" }
|
|
16968
|
+
]
|
|
16969
|
+
};
|
|
16970
|
+
function normalizeAddress(addr) {
|
|
16971
|
+
return addr.toLowerCase();
|
|
16972
|
+
}
|
|
16973
|
+
function domainOf(ctx) {
|
|
16974
|
+
return {
|
|
16975
|
+
name: ROLLING_SWAP_DOMAIN_NAME,
|
|
16976
|
+
version: ROLLING_SWAP_DOMAIN_VERSION,
|
|
16977
|
+
chainId: ctx.chainId,
|
|
16978
|
+
verifyingContract: normalizeAddress(ctx.verifyingContract)
|
|
16979
|
+
};
|
|
16980
|
+
}
|
|
16981
|
+
function evmClaimDigest(ctx, message) {
|
|
16982
|
+
return hashTypedData({
|
|
16983
|
+
domain: domainOf(ctx),
|
|
16984
|
+
types: CLAIM_TYPES,
|
|
16985
|
+
primaryType: "ClaimBalanceProof",
|
|
16986
|
+
message: {
|
|
16987
|
+
channelId: message.channelId,
|
|
16988
|
+
cumulativeAmount: message.cumulativeAmount,
|
|
16989
|
+
nonce: message.nonce,
|
|
16990
|
+
recipient: normalizeAddress(message.recipient)
|
|
16991
|
+
}
|
|
16992
|
+
});
|
|
16993
|
+
}
|
|
16994
|
+
var SIG_BYTES = 65;
|
|
16995
|
+
function signatureToBytes(sig) {
|
|
16996
|
+
if (typeof sig !== "string") return sig;
|
|
16997
|
+
const hex = sig.startsWith("0x") ? sig.slice(2) : sig;
|
|
16998
|
+
return hexToBytes3(hex);
|
|
16999
|
+
}
|
|
17000
|
+
function recoverEvmClaimSigner(ctx, message, signature) {
|
|
17001
|
+
const bytes = signatureToBytes(signature);
|
|
17002
|
+
if (bytes.length !== SIG_BYTES) {
|
|
17003
|
+
throw new Error(
|
|
17004
|
+
`EVM signature must be 65 bytes (r||s||v), got ${bytes.length}`
|
|
17005
|
+
);
|
|
17006
|
+
}
|
|
17007
|
+
const v = bytes[64];
|
|
17008
|
+
if (v !== 27 && v !== 28) {
|
|
17009
|
+
throw new Error(`EVM signature v must be 27 or 28, got ${v}`);
|
|
17010
|
+
}
|
|
17011
|
+
const digest = evmClaimDigest(ctx, message).slice(2);
|
|
17012
|
+
const recovered = secp256k1.Signature.fromBytes(bytes.slice(0, 64), "compact").addRecoveryBit(v - 27).recoverPublicKey(hexToBytes3(digest));
|
|
17013
|
+
const uncompressed = recovered.toBytes(false);
|
|
17014
|
+
const addrHash = keccak_2562(uncompressed.slice(1));
|
|
17015
|
+
return `0x${bytesToHex3(addrHash.slice(-20))}`;
|
|
17016
|
+
}
|
|
17017
|
+
function verifyEvmClaimSignature2(params) {
|
|
17018
|
+
let recovered;
|
|
17019
|
+
try {
|
|
17020
|
+
recovered = recoverEvmClaimSigner(
|
|
17021
|
+
params.ctx,
|
|
17022
|
+
params.message,
|
|
17023
|
+
params.signature
|
|
17024
|
+
);
|
|
17025
|
+
} catch (err) {
|
|
17026
|
+
return {
|
|
17027
|
+
valid: false,
|
|
17028
|
+
reason: `SIGNATURE_INVALID: ${err instanceof Error ? err.message : String(err)}`
|
|
17029
|
+
};
|
|
17030
|
+
}
|
|
17031
|
+
if (recovered.toLowerCase() !== params.expectedSigner.toLowerCase()) {
|
|
17032
|
+
return {
|
|
17033
|
+
valid: false,
|
|
17034
|
+
reason: `SIGNER_MISMATCH: recovered ${recovered}, expected ${params.expectedSigner}`
|
|
17035
|
+
};
|
|
17036
|
+
}
|
|
17037
|
+
return { valid: true, recovered };
|
|
17038
|
+
}
|
|
16240
17039
|
function hasSettlementMetadata(claim) {
|
|
16241
17040
|
return claim.channelId !== void 0 && claim.nonce !== void 0 && claim.cumulativeAmount !== void 0 && claim.recipient !== void 0 && claim.swapSignerAddress !== void 0;
|
|
16242
17041
|
}
|
|
@@ -16291,11 +17090,49 @@ function ingestReceivedClaims(params) {
|
|
|
16291
17090
|
continue;
|
|
16292
17091
|
}
|
|
16293
17092
|
const expectedSigner = params.expectedSignerAddress ?? claim.swapSignerAddress;
|
|
16294
|
-
|
|
16295
|
-
|
|
16296
|
-
|
|
16297
|
-
params.
|
|
16298
|
-
|
|
17093
|
+
let sig;
|
|
17094
|
+
if (chain.startsWith("evm")) {
|
|
17095
|
+
const chainId = parseEvmChainId2(chain);
|
|
17096
|
+
const verifyingContract = params.tokenNetworks?.[chain];
|
|
17097
|
+
if (chainId === void 0 || !verifyingContract) {
|
|
17098
|
+
reject(
|
|
17099
|
+
claim,
|
|
17100
|
+
"MISSING_CHAIN_CONFIG",
|
|
17101
|
+
`EVM v2 balance-proof verification for ${chain} needs a numeric chain id in the chain key AND tokenNetworks["${chain}"] (the RollingSwapChannel / verifyingContract) to reconstruct the EIP-712 domain; supply it from the connector/swap session context.`
|
|
17102
|
+
);
|
|
17103
|
+
continue;
|
|
17104
|
+
}
|
|
17105
|
+
let msgNonce;
|
|
17106
|
+
let msgCumulative;
|
|
17107
|
+
try {
|
|
17108
|
+
msgNonce = BigInt(claim.nonce);
|
|
17109
|
+
msgCumulative = BigInt(claim.cumulativeAmount);
|
|
17110
|
+
} catch {
|
|
17111
|
+
reject(
|
|
17112
|
+
claim,
|
|
17113
|
+
"MALFORMED_METADATA",
|
|
17114
|
+
`nonce "${claim.nonce}" / cumulativeAmount "${claim.cumulativeAmount}" are not decimal integers`
|
|
17115
|
+
);
|
|
17116
|
+
continue;
|
|
17117
|
+
}
|
|
17118
|
+
sig = verifyEvmClaimSignature2({
|
|
17119
|
+
ctx: { chainId, verifyingContract },
|
|
17120
|
+
message: {
|
|
17121
|
+
channelId: claim.channelId,
|
|
17122
|
+
cumulativeAmount: msgCumulative,
|
|
17123
|
+
nonce: msgNonce,
|
|
17124
|
+
recipient: claim.recipient
|
|
17125
|
+
},
|
|
17126
|
+
signature: claim.claimBytes,
|
|
17127
|
+
expectedSigner
|
|
17128
|
+
});
|
|
17129
|
+
} else {
|
|
17130
|
+
sig = verifyAccumulatedClaim(
|
|
17131
|
+
claim,
|
|
17132
|
+
{ address: expectedSigner },
|
|
17133
|
+
params.minaSignerClient
|
|
17134
|
+
);
|
|
17135
|
+
}
|
|
16299
17136
|
if (!sig.valid) {
|
|
16300
17137
|
reject(claim, signatureRejectionCode(sig.reason), sig.reason);
|
|
16301
17138
|
continue;
|
|
@@ -17220,4 +18057,4 @@ export {
|
|
|
17220
18057
|
@scure/bip32/lib/esm/index.js:
|
|
17221
18058
|
(*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
|
|
17222
18059
|
*/
|
|
17223
|
-
//# sourceMappingURL=chunk-
|
|
18060
|
+
//# sourceMappingURL=chunk-HSSJFB3I.js.map
|