@toon-protocol/core 1.4.0 → 1.4.2
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/index.d.ts +493 -8
- package/dist/index.js +641 -22
- package/dist/index.js.map +1 -1
- package/package.json +11 -10
package/dist/index.js
CHANGED
|
@@ -27,12 +27,12 @@ var JOB_REVIEW_KIND = 31117;
|
|
|
27
27
|
var WEB_OF_TRUST_KIND = 30382;
|
|
28
28
|
var PREFIX_CLAIM_KIND = 10034;
|
|
29
29
|
var PREFIX_GRANT_KIND = 10037;
|
|
30
|
+
var ILP_ROOT_PREFIX = "g.toon";
|
|
30
31
|
var BLOB_STORAGE_REQUEST_KIND = 5094;
|
|
31
32
|
var BLOB_STORAGE_RESULT_KIND = 6094;
|
|
32
33
|
var PET_INTERACTION_REQUEST_KIND = 5900;
|
|
33
34
|
var PET_INTERACTION_RESULT_KIND = 6900;
|
|
34
35
|
var PET_INTERACTION_EVENT_KIND = 14919;
|
|
35
|
-
var ILP_ROOT_PREFIX = "g.toon";
|
|
36
36
|
|
|
37
37
|
// src/address/ilp-address-validation.ts
|
|
38
38
|
var ILP_SEGMENT_PATTERN = /^[a-z0-9-]+$/;
|
|
@@ -277,15 +277,121 @@ function validatePrefix(prefix) {
|
|
|
277
277
|
return { valid: true };
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
-
// src/
|
|
280
|
+
// src/chain/chain-id.ts
|
|
281
281
|
function validateChainId(chainId) {
|
|
282
282
|
if (!chainId) return false;
|
|
283
283
|
const segments = chainId.split(":");
|
|
284
284
|
if (segments.length < 2 || segments.length > 3) return false;
|
|
285
285
|
return segments.every((s) => s.length > 0);
|
|
286
286
|
}
|
|
287
|
+
|
|
288
|
+
// src/events/swap-pair-validation.ts
|
|
289
|
+
var RATE_REGEX = /^(0|[1-9]\d*)(\.\d+)?$/;
|
|
290
|
+
var AMOUNT_REGEX = /^\d+$/;
|
|
291
|
+
var MAX_NUMERIC_STRING_LENGTH = 80;
|
|
287
292
|
function isObject(value) {
|
|
288
|
-
return typeof value === "object" && value !== null;
|
|
293
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
294
|
+
}
|
|
295
|
+
function isNonEmptyString(value) {
|
|
296
|
+
return typeof value === "string" && value.length > 0;
|
|
297
|
+
}
|
|
298
|
+
function isNonNegativeInteger(value) {
|
|
299
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
300
|
+
}
|
|
301
|
+
function validateAsset(asset, side) {
|
|
302
|
+
if (!isObject(asset)) {
|
|
303
|
+
return {
|
|
304
|
+
valid: false,
|
|
305
|
+
reason: `${side} must be an object`,
|
|
306
|
+
field: side
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
if (!isNonEmptyString(asset.assetCode)) {
|
|
310
|
+
return {
|
|
311
|
+
valid: false,
|
|
312
|
+
reason: `${side}.assetCode must be a non-empty string`,
|
|
313
|
+
field: `${side}.assetCode`
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
if (!isNonNegativeInteger(asset.assetScale)) {
|
|
317
|
+
return {
|
|
318
|
+
valid: false,
|
|
319
|
+
reason: `${side}.assetScale must be a non-negative integer`,
|
|
320
|
+
field: `${side}.assetScale`
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
if (typeof asset.chain !== "string" || !validateChainId(asset.chain)) {
|
|
324
|
+
return {
|
|
325
|
+
valid: false,
|
|
326
|
+
reason: `${side}.chain must be a valid chain identifier (e.g., "evm:base:8453")`,
|
|
327
|
+
field: `${side}.chain`
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
return { valid: true };
|
|
331
|
+
}
|
|
332
|
+
function isValidSwapPair(pair) {
|
|
333
|
+
if (!isObject(pair)) {
|
|
334
|
+
return { valid: false, reason: "pair must be an object", field: "" };
|
|
335
|
+
}
|
|
336
|
+
const fromResult = validateAsset(pair.from, "from");
|
|
337
|
+
if (!fromResult.valid) return fromResult;
|
|
338
|
+
const toResult = validateAsset(pair.to, "to");
|
|
339
|
+
if (!toResult.valid) return toResult;
|
|
340
|
+
if (typeof pair.rate !== "string" || pair.rate.length > MAX_NUMERIC_STRING_LENGTH || !RATE_REGEX.test(pair.rate)) {
|
|
341
|
+
return {
|
|
342
|
+
valid: false,
|
|
343
|
+
reason: `rate must be a non-negative decimal string (no leading zeros, no exponent, max ${MAX_NUMERIC_STRING_LENGTH} chars)`,
|
|
344
|
+
field: "rate"
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
if (pair.minAmount !== void 0) {
|
|
348
|
+
if (typeof pair.minAmount !== "string" || pair.minAmount.length > MAX_NUMERIC_STRING_LENGTH || !AMOUNT_REGEX.test(pair.minAmount)) {
|
|
349
|
+
return {
|
|
350
|
+
valid: false,
|
|
351
|
+
reason: `minAmount must be a non-negative integer string (max ${MAX_NUMERIC_STRING_LENGTH} digits)`,
|
|
352
|
+
field: "minAmount"
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (pair.maxAmount !== void 0) {
|
|
357
|
+
if (typeof pair.maxAmount !== "string" || pair.maxAmount.length > MAX_NUMERIC_STRING_LENGTH || !AMOUNT_REGEX.test(pair.maxAmount)) {
|
|
358
|
+
return {
|
|
359
|
+
valid: false,
|
|
360
|
+
reason: `maxAmount must be a non-negative integer string (max ${MAX_NUMERIC_STRING_LENGTH} digits)`,
|
|
361
|
+
field: "maxAmount"
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (pair.minAmount !== void 0 && pair.maxAmount !== void 0) {
|
|
366
|
+
if (BigInt(pair.minAmount) > BigInt(pair.maxAmount)) {
|
|
367
|
+
return {
|
|
368
|
+
valid: false,
|
|
369
|
+
reason: "minAmount must not exceed maxAmount",
|
|
370
|
+
field: "minAmount/maxAmount"
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return { valid: true };
|
|
375
|
+
}
|
|
376
|
+
function formatMessage(index, result) {
|
|
377
|
+
return `swapPairs[${index}]: ${result.reason} (field: ${result.field})`;
|
|
378
|
+
}
|
|
379
|
+
function assertSwapPairForBuild(pair, index) {
|
|
380
|
+
const result = isValidSwapPair(pair);
|
|
381
|
+
if (!result.valid) {
|
|
382
|
+
throw new ToonError(formatMessage(index, result), "INVALID_SWAP_PAIR");
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
function assertSwapPairForParse(pair, index) {
|
|
386
|
+
const result = isValidSwapPair(pair);
|
|
387
|
+
if (!result.valid) {
|
|
388
|
+
throw new InvalidEventError(formatMessage(index, result));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// src/events/parsers.ts
|
|
393
|
+
function isObject2(value) {
|
|
394
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
289
395
|
}
|
|
290
396
|
function parseIlpPeerInfo(event) {
|
|
291
397
|
if (event.kind !== ILP_PEER_INFO_KIND) {
|
|
@@ -302,7 +408,7 @@ function parseIlpPeerInfo(event) {
|
|
|
302
408
|
err instanceof Error ? err : void 0
|
|
303
409
|
);
|
|
304
410
|
}
|
|
305
|
-
if (!
|
|
411
|
+
if (!isObject2(parsed)) {
|
|
306
412
|
throw new InvalidEventError("Event content must be a JSON object");
|
|
307
413
|
}
|
|
308
414
|
const {
|
|
@@ -319,10 +425,8 @@ function parseIlpPeerInfo(event) {
|
|
|
319
425
|
"Missing or invalid required field: ilpAddress"
|
|
320
426
|
);
|
|
321
427
|
}
|
|
322
|
-
if (typeof btpEndpoint !== "string"
|
|
323
|
-
throw new InvalidEventError(
|
|
324
|
-
"Missing or invalid required field: btpEndpoint"
|
|
325
|
-
);
|
|
428
|
+
if (btpEndpoint !== void 0 && typeof btpEndpoint !== "string") {
|
|
429
|
+
throw new InvalidEventError("Invalid field: btpEndpoint must be a string");
|
|
326
430
|
}
|
|
327
431
|
if (typeof assetCode !== "string" || assetCode.length === 0) {
|
|
328
432
|
throw new InvalidEventError("Missing or invalid required field: assetCode");
|
|
@@ -361,7 +465,7 @@ function parseIlpPeerInfo(event) {
|
|
|
361
465
|
}
|
|
362
466
|
}
|
|
363
467
|
if (settlementAddresses !== void 0) {
|
|
364
|
-
if (!
|
|
468
|
+
if (!isObject2(settlementAddresses)) {
|
|
365
469
|
throw new InvalidEventError("settlementAddresses must be an object");
|
|
366
470
|
}
|
|
367
471
|
for (const [key, value] of Object.entries(settlementAddresses)) {
|
|
@@ -388,12 +492,12 @@ function parseIlpPeerInfo(event) {
|
|
|
388
492
|
}
|
|
389
493
|
}
|
|
390
494
|
if (preferredTokens !== void 0) {
|
|
391
|
-
if (!
|
|
495
|
+
if (!isObject2(preferredTokens)) {
|
|
392
496
|
throw new InvalidEventError("preferredTokens must be an object");
|
|
393
497
|
}
|
|
394
498
|
}
|
|
395
499
|
if (tokenNetworks !== void 0) {
|
|
396
|
-
if (!
|
|
500
|
+
if (!isObject2(tokenNetworks)) {
|
|
397
501
|
throw new InvalidEventError("tokenNetworks must be an object");
|
|
398
502
|
}
|
|
399
503
|
}
|
|
@@ -411,7 +515,7 @@ function parseIlpPeerInfo(event) {
|
|
|
411
515
|
const { prefixPricing: rawPrefixPricing } = parsed;
|
|
412
516
|
let prefixPricing;
|
|
413
517
|
if (rawPrefixPricing !== void 0) {
|
|
414
|
-
if (!
|
|
518
|
+
if (!isObject2(rawPrefixPricing)) {
|
|
415
519
|
throw new InvalidEventError("prefixPricing must be an object");
|
|
416
520
|
}
|
|
417
521
|
const { basePrice } = rawPrefixPricing;
|
|
@@ -422,6 +526,17 @@ function parseIlpPeerInfo(event) {
|
|
|
422
526
|
}
|
|
423
527
|
prefixPricing = { basePrice };
|
|
424
528
|
}
|
|
529
|
+
const { swapPairs: rawSwapPairs } = parsed;
|
|
530
|
+
let swapPairs;
|
|
531
|
+
if (rawSwapPairs !== void 0) {
|
|
532
|
+
if (!Array.isArray(rawSwapPairs)) {
|
|
533
|
+
throw new InvalidEventError("swapPairs must be an array");
|
|
534
|
+
}
|
|
535
|
+
rawSwapPairs.forEach((pair, index) => {
|
|
536
|
+
assertSwapPairForParse(pair, index);
|
|
537
|
+
});
|
|
538
|
+
swapPairs = rawSwapPairs;
|
|
539
|
+
}
|
|
425
540
|
let ilpAddresses;
|
|
426
541
|
if (rawIlpAddresses !== void 0) {
|
|
427
542
|
if (!Array.isArray(rawIlpAddresses)) {
|
|
@@ -445,7 +560,7 @@ function parseIlpPeerInfo(event) {
|
|
|
445
560
|
}
|
|
446
561
|
return {
|
|
447
562
|
ilpAddress,
|
|
448
|
-
btpEndpoint,
|
|
563
|
+
btpEndpoint: typeof btpEndpoint === "string" ? btpEndpoint : "",
|
|
449
564
|
...blsHttpEndpoint !== void 0 && typeof blsHttpEndpoint === "string" && { blsHttpEndpoint },
|
|
450
565
|
assetCode,
|
|
451
566
|
assetScale,
|
|
@@ -460,13 +575,30 @@ function parseIlpPeerInfo(event) {
|
|
|
460
575
|
},
|
|
461
576
|
ilpAddresses,
|
|
462
577
|
feePerByte,
|
|
463
|
-
...prefixPricing !== void 0 && { prefixPricing }
|
|
578
|
+
...prefixPricing !== void 0 && { prefixPricing },
|
|
579
|
+
...swapPairs !== void 0 && { swapPairs }
|
|
464
580
|
};
|
|
465
581
|
}
|
|
466
582
|
|
|
467
583
|
// src/events/builders.ts
|
|
468
584
|
import { finalizeEvent } from "nostr-tools/pure";
|
|
469
|
-
|
|
585
|
+
|
|
586
|
+
// src/events/nip40.ts
|
|
587
|
+
var EXPIRATION_TAG = "expiration";
|
|
588
|
+
function getEventExpiration(event) {
|
|
589
|
+
const tag = event.tags.find((t) => t[0] === EXPIRATION_TAG);
|
|
590
|
+
if (!tag || tag[1] === void 0) return void 0;
|
|
591
|
+
const ts = Number(tag[1]);
|
|
592
|
+
if (!Number.isFinite(ts) || ts < 0) return void 0;
|
|
593
|
+
return ts;
|
|
594
|
+
}
|
|
595
|
+
function isEventExpired(event, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
596
|
+
const exp = getEventExpiration(event);
|
|
597
|
+
return exp !== void 0 && exp <= nowSeconds;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// src/events/builders.ts
|
|
601
|
+
function buildIlpPeerInfoEvent(info, secretKey, options = {}) {
|
|
470
602
|
if (info.feePerByte !== void 0) {
|
|
471
603
|
if (typeof info.feePerByte !== "string" || !/^\d+$/.test(info.feePerByte)) {
|
|
472
604
|
throw new ToonError(
|
|
@@ -498,12 +630,31 @@ function buildIlpPeerInfoEvent(info, secretKey) {
|
|
|
498
630
|
ilpAddress: primaryAddress
|
|
499
631
|
};
|
|
500
632
|
}
|
|
633
|
+
if (info.swapPairs !== void 0) {
|
|
634
|
+
if (!Array.isArray(info.swapPairs)) {
|
|
635
|
+
throw new ToonError(
|
|
636
|
+
"swapPairs must be an array when provided",
|
|
637
|
+
"INVALID_SWAP_PAIR"
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
info.swapPairs.forEach((pair, index) => {
|
|
641
|
+
assertSwapPairForBuild(pair, index);
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
const createdAt = Math.floor(Date.now() / 1e3);
|
|
645
|
+
const tags = [];
|
|
646
|
+
if (options.ttlSeconds !== void 0 && options.ttlSeconds > 0) {
|
|
647
|
+
tags.push([
|
|
648
|
+
EXPIRATION_TAG,
|
|
649
|
+
String(createdAt + Math.floor(options.ttlSeconds))
|
|
650
|
+
]);
|
|
651
|
+
}
|
|
501
652
|
return finalizeEvent(
|
|
502
653
|
{
|
|
503
654
|
kind: ILP_PEER_INFO_KIND,
|
|
504
655
|
content: JSON.stringify(effectiveInfo),
|
|
505
|
-
tags
|
|
506
|
-
created_at:
|
|
656
|
+
tags,
|
|
657
|
+
created_at: createdAt
|
|
507
658
|
},
|
|
508
659
|
secretKey
|
|
509
660
|
);
|
|
@@ -1220,7 +1371,8 @@ function buildWorkflowDefinitionEvent(params, secretKey) {
|
|
|
1220
1371
|
};
|
|
1221
1372
|
const contentJson = JSON.stringify(contentBody);
|
|
1222
1373
|
const tags = [];
|
|
1223
|
-
const
|
|
1374
|
+
const randomSuffix = Math.random().toString(36).slice(2, 8);
|
|
1375
|
+
const dTag = params.workflowId ?? `wf-${Date.now()}-${params.steps.length}-${randomSuffix}`;
|
|
1224
1376
|
tags.push(["d", dTag]);
|
|
1225
1377
|
tags.push(["bid", params.totalBid, "usdc"]);
|
|
1226
1378
|
return finalizeEvent6(
|
|
@@ -2486,6 +2638,12 @@ var SeedRelayDiscovery = class {
|
|
|
2486
2638
|
);
|
|
2487
2639
|
continue;
|
|
2488
2640
|
}
|
|
2641
|
+
if (isEventExpired(event)) {
|
|
2642
|
+
console.warn(
|
|
2643
|
+
`[SeedRelayDiscovery] Skipping expired kind:10032 announcement: ${event.id}`
|
|
2644
|
+
);
|
|
2645
|
+
continue;
|
|
2646
|
+
}
|
|
2489
2647
|
const info = parseIlpPeerInfo(event);
|
|
2490
2648
|
info.pubkey = event.pubkey;
|
|
2491
2649
|
discoveredPeers.push(info);
|
|
@@ -2749,6 +2907,152 @@ function resolveTokenForChain(chain, requesterPreferredTokens, responderPreferre
|
|
|
2749
2907
|
return void 0;
|
|
2750
2908
|
}
|
|
2751
2909
|
|
|
2910
|
+
// src/settlement/hashes.ts
|
|
2911
|
+
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
2912
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
2913
|
+
import {
|
|
2914
|
+
bytesToHex,
|
|
2915
|
+
hexToBytes as nobleHexToBytes
|
|
2916
|
+
} from "@noble/hashes/utils.js";
|
|
2917
|
+
function hexToBytes(hex) {
|
|
2918
|
+
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
2919
|
+
if (clean.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(clean)) {
|
|
2920
|
+
throw new Error(`Invalid hex string: ${hex}`);
|
|
2921
|
+
}
|
|
2922
|
+
return nobleHexToBytes(clean);
|
|
2923
|
+
}
|
|
2924
|
+
function bigintToBytes32BE(x) {
|
|
2925
|
+
if (x < 0n) {
|
|
2926
|
+
throw new Error("bigint must be non-negative for balance-proof encoding");
|
|
2927
|
+
}
|
|
2928
|
+
const out = new Uint8Array(32);
|
|
2929
|
+
let v = x;
|
|
2930
|
+
for (let i = 31; i >= 0; i--) {
|
|
2931
|
+
out[i] = Number(v & 0xffn);
|
|
2932
|
+
v >>= 8n;
|
|
2933
|
+
}
|
|
2934
|
+
if (v !== 0n) {
|
|
2935
|
+
throw new Error("bigint exceeds 256 bits");
|
|
2936
|
+
}
|
|
2937
|
+
return out;
|
|
2938
|
+
}
|
|
2939
|
+
function concatBytes(...parts) {
|
|
2940
|
+
let len = 0;
|
|
2941
|
+
for (const p of parts) len += p.length;
|
|
2942
|
+
const out = new Uint8Array(len);
|
|
2943
|
+
let o = 0;
|
|
2944
|
+
for (const p of parts) {
|
|
2945
|
+
out.set(p, o);
|
|
2946
|
+
o += p.length;
|
|
2947
|
+
}
|
|
2948
|
+
return out;
|
|
2949
|
+
}
|
|
2950
|
+
function balanceProofHashEvm(channelIdBytes, cumulativeAmount, nonce, recipientBytes) {
|
|
2951
|
+
return keccak_256(
|
|
2952
|
+
concatBytes(
|
|
2953
|
+
channelIdBytes,
|
|
2954
|
+
bigintToBytes32BE(cumulativeAmount),
|
|
2955
|
+
bigintToBytes32BE(nonce),
|
|
2956
|
+
recipientBytes
|
|
2957
|
+
)
|
|
2958
|
+
);
|
|
2959
|
+
}
|
|
2960
|
+
function balanceProofHashSolana(channelId, cumulativeAmount, nonce, recipient) {
|
|
2961
|
+
return sha256(
|
|
2962
|
+
concatBytes(
|
|
2963
|
+
new TextEncoder().encode(channelId),
|
|
2964
|
+
bigintToBytes32BE(cumulativeAmount),
|
|
2965
|
+
bigintToBytes32BE(nonce),
|
|
2966
|
+
new TextEncoder().encode(recipient)
|
|
2967
|
+
)
|
|
2968
|
+
);
|
|
2969
|
+
}
|
|
2970
|
+
function minaHashToField(s) {
|
|
2971
|
+
const digestHex = bytesToHex(sha256(new TextEncoder().encode(s)));
|
|
2972
|
+
return BigInt("0x" + digestHex.slice(0, 60));
|
|
2973
|
+
}
|
|
2974
|
+
function balanceProofFieldsMina(channelId, cumulativeAmount, nonce, recipient) {
|
|
2975
|
+
return [
|
|
2976
|
+
minaHashToField(channelId),
|
|
2977
|
+
cumulativeAmount,
|
|
2978
|
+
nonce,
|
|
2979
|
+
minaHashToField(recipient)
|
|
2980
|
+
];
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2983
|
+
// src/settlement/base58.ts
|
|
2984
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
2985
|
+
function base58Encode(bytes) {
|
|
2986
|
+
let zeros = 0;
|
|
2987
|
+
for (let i = 0; i < bytes.length && bytes[i] === 0; i++) zeros++;
|
|
2988
|
+
let value = 0n;
|
|
2989
|
+
for (const byte of bytes) {
|
|
2990
|
+
value = value * 256n + BigInt(byte);
|
|
2991
|
+
}
|
|
2992
|
+
let result = "";
|
|
2993
|
+
while (value > 0n) {
|
|
2994
|
+
result = BASE58_ALPHABET[Number(value % 58n)] + result;
|
|
2995
|
+
value = value / 58n;
|
|
2996
|
+
}
|
|
2997
|
+
for (let i = 0; i < zeros; i++) {
|
|
2998
|
+
result = "1" + result;
|
|
2999
|
+
}
|
|
3000
|
+
return result || "1";
|
|
3001
|
+
}
|
|
3002
|
+
function base58Decode(str) {
|
|
3003
|
+
let zeros = 0;
|
|
3004
|
+
for (let i = 0; i < str.length && str[i] === "1"; i++) zeros++;
|
|
3005
|
+
let value = 0n;
|
|
3006
|
+
for (const ch of str) {
|
|
3007
|
+
const idx = BASE58_ALPHABET.indexOf(ch);
|
|
3008
|
+
if (idx === -1) throw new Error(`Invalid base58 character: ${ch}`);
|
|
3009
|
+
value = value * 58n + BigInt(idx);
|
|
3010
|
+
}
|
|
3011
|
+
const hex = value === 0n ? "" : value.toString(16);
|
|
3012
|
+
const hexPadded = hex.length % 2 ? "0" + hex : hex;
|
|
3013
|
+
const rawBytes = [];
|
|
3014
|
+
for (let i = 0; i < hexPadded.length; i += 2) {
|
|
3015
|
+
rawBytes.push(parseInt(hexPadded.slice(i, i + 2), 16));
|
|
3016
|
+
}
|
|
3017
|
+
const result = new Uint8Array(zeros + rawBytes.length);
|
|
3018
|
+
result.set(rawBytes, zeros);
|
|
3019
|
+
return result;
|
|
3020
|
+
}
|
|
3021
|
+
|
|
3022
|
+
// src/settlement/mina-key.ts
|
|
3023
|
+
import { sha256 as sha2562 } from "@noble/hashes/sha2.js";
|
|
3024
|
+
var MINA_PRIVATE_KEY_VERSION = 90;
|
|
3025
|
+
function hexToMinaBase58PrivateKey(privateKey) {
|
|
3026
|
+
if (!/^(0x)?[0-9a-fA-F]{64}$/.test(privateKey)) {
|
|
3027
|
+
return privateKey;
|
|
3028
|
+
}
|
|
3029
|
+
const beScalar = hexToBytes(privateKey);
|
|
3030
|
+
const leScalar = Uint8Array.from(beScalar).reverse();
|
|
3031
|
+
const payload = concatBytes(
|
|
3032
|
+
Uint8Array.from([MINA_PRIVATE_KEY_VERSION, 1]),
|
|
3033
|
+
leScalar
|
|
3034
|
+
);
|
|
3035
|
+
const checksum = sha2562(sha2562(payload)).slice(0, 4);
|
|
3036
|
+
return base58Encode(concatBytes(payload, checksum));
|
|
3037
|
+
}
|
|
3038
|
+
async function deriveMinaPublicKeyBase58(privateKey) {
|
|
3039
|
+
let signerModule = null;
|
|
3040
|
+
try {
|
|
3041
|
+
const specifier = "mina-signer";
|
|
3042
|
+
signerModule = await import(
|
|
3043
|
+
/* @vite-ignore */
|
|
3044
|
+
specifier
|
|
3045
|
+
);
|
|
3046
|
+
} catch {
|
|
3047
|
+
return null;
|
|
3048
|
+
}
|
|
3049
|
+
if (!signerModule) return null;
|
|
3050
|
+
const mod = signerModule;
|
|
3051
|
+
const ClientCtor = mod.default ?? mod;
|
|
3052
|
+
const client = new ClientCtor({ network: "mainnet" });
|
|
3053
|
+
return client.derivePublicKey(hexToMinaBase58PrivateKey(privateKey));
|
|
3054
|
+
}
|
|
3055
|
+
|
|
2752
3056
|
// src/bootstrap/BootstrapService.ts
|
|
2753
3057
|
import { SimplePool as SimplePool3 } from "nostr-tools/pool";
|
|
2754
3058
|
import { getPublicKey as getPublicKey3 } from "nostr-tools/pure";
|
|
@@ -4097,6 +4401,32 @@ var AttestationBootstrap = class {
|
|
|
4097
4401
|
}
|
|
4098
4402
|
};
|
|
4099
4403
|
|
|
4404
|
+
// src/utils/reject-code.ts
|
|
4405
|
+
var ILP_TO_SEMANTIC = Object.freeze({
|
|
4406
|
+
T00: "internal_error",
|
|
4407
|
+
T04: "insufficient_funds",
|
|
4408
|
+
F00: "invalid_request",
|
|
4409
|
+
// F01 ("Invalid Packet" in ILP terms — emitted by the swap handler for
|
|
4410
|
+
// "Invalid gift wrap" / "Invalid amount") has NO dedicated entry in the
|
|
4411
|
+
// connector's REJECT_CODE_MAP (accepted semantics are: insufficient_funds,
|
|
4412
|
+
// expired, unreachable, invalid_request, invalid_amount,
|
|
4413
|
+
// insufficient_destination_amount, unexpected_payment, application_error,
|
|
4414
|
+
// internal_error, timeout). The closest faithful reason is `invalid_request`,
|
|
4415
|
+
// which the connector re-encodes to wire code F00. We map F01 EXPLICITLY
|
|
4416
|
+
// (rather than relying on the fallback below) so the F01 -> F00 normalization
|
|
4417
|
+
// is intentional and test-pinned, not a silent collapse that misleads callers
|
|
4418
|
+
// into thinking they hit a different failure class. See issue #86.
|
|
4419
|
+
F01: "invalid_request",
|
|
4420
|
+
F02: "unreachable",
|
|
4421
|
+
F03: "invalid_amount",
|
|
4422
|
+
F04: "insufficient_destination_amount",
|
|
4423
|
+
F06: "unexpected_payment",
|
|
4424
|
+
R00: "expired"
|
|
4425
|
+
});
|
|
4426
|
+
function ilpCodeToSemantic(ilpCode) {
|
|
4427
|
+
return ILP_TO_SEMANTIC[ilpCode] ?? "invalid_request";
|
|
4428
|
+
}
|
|
4429
|
+
|
|
4100
4430
|
// src/compose.ts
|
|
4101
4431
|
function createToonNode(config) {
|
|
4102
4432
|
const directIlpClient = createDirectIlpClient(config.connector, {
|
|
@@ -4156,7 +4486,7 @@ function createToonNode(config) {
|
|
|
4156
4486
|
}
|
|
4157
4487
|
const adapted = result;
|
|
4158
4488
|
adapted.rejectReason = {
|
|
4159
|
-
code: result.code,
|
|
4489
|
+
code: ilpCodeToSemantic(result.code),
|
|
4160
4490
|
message: result.message
|
|
4161
4491
|
};
|
|
4162
4492
|
return adapted;
|
|
@@ -4227,6 +4557,29 @@ var CHAIN_PRESETS = {
|
|
|
4227
4557
|
usdcAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
4228
4558
|
tokenNetworkAddress: "",
|
|
4229
4559
|
registryAddress: ""
|
|
4560
|
+
},
|
|
4561
|
+
// Base Sepolia (public testnet) — TOON's deployed public-testnet settlement
|
|
4562
|
+
// environment (source of truth: e2e/testnets.json). USDC is the deployed test
|
|
4563
|
+
// token the TokenNetwork was opened against (NOT Circle's native testnet USDC,
|
|
4564
|
+
// which the channel would not recognise). Registry + TokenNetwork are live, so
|
|
4565
|
+
// this preset is settlement-complete: `--network testnet|devnet` settles here.
|
|
4566
|
+
"base-sepolia": {
|
|
4567
|
+
name: "base-sepolia",
|
|
4568
|
+
chainId: 84532,
|
|
4569
|
+
rpcUrl: "https://sepolia.base.org",
|
|
4570
|
+
usdcAddress: "0xac80670b86db1eeb5c18c82e18a6bda98fcb4504",
|
|
4571
|
+
tokenNetworkAddress: "0x47616F4b9cF4dA25F74FD727Cd85E9CA0C70Ec5C",
|
|
4572
|
+
registryAddress: "0xb9516c6c53c016c43f3671b1e5eb6096c83ec2c7"
|
|
4573
|
+
},
|
|
4574
|
+
// Base mainnet (public). USDC is Circle's native USDC on Base.
|
|
4575
|
+
// TOON TokenNetwork/registry not deployed yet → settlement relay-only.
|
|
4576
|
+
"base-mainnet": {
|
|
4577
|
+
name: "base-mainnet",
|
|
4578
|
+
chainId: 8453,
|
|
4579
|
+
rpcUrl: "https://mainnet.base.org",
|
|
4580
|
+
usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
4581
|
+
tokenNetworkAddress: "",
|
|
4582
|
+
registryAddress: ""
|
|
4230
4583
|
}
|
|
4231
4584
|
};
|
|
4232
4585
|
function resolveChainConfig(chain) {
|
|
@@ -4234,8 +4587,9 @@ function resolveChainConfig(chain) {
|
|
|
4234
4587
|
const name = envChain || chain || "anvil";
|
|
4235
4588
|
const preset = CHAIN_PRESETS[name];
|
|
4236
4589
|
if (!preset) {
|
|
4590
|
+
const validNames = Object.keys(CHAIN_PRESETS).join(", ");
|
|
4237
4591
|
throw new ToonError(
|
|
4238
|
-
`Unknown chain "${name}". Valid chains:
|
|
4592
|
+
`Unknown chain "${name}". Valid chains: ${validNames}`,
|
|
4239
4593
|
"INVALID_CHAIN"
|
|
4240
4594
|
);
|
|
4241
4595
|
}
|
|
@@ -4328,6 +4682,7 @@ function buildEvmProviderEntry(config, keyId) {
|
|
|
4328
4682
|
chainId: `evm:${config.chainId}`,
|
|
4329
4683
|
rpcUrl: config.rpcUrl,
|
|
4330
4684
|
registryAddress: config.registryAddress,
|
|
4685
|
+
tokenAddress: config.usdcAddress,
|
|
4331
4686
|
keyId
|
|
4332
4687
|
};
|
|
4333
4688
|
}
|
|
@@ -4354,6 +4709,251 @@ function buildMinaProviderEntry(config, keyId) {
|
|
|
4354
4709
|
};
|
|
4355
4710
|
}
|
|
4356
4711
|
|
|
4712
|
+
// src/chain/network-profile.ts
|
|
4713
|
+
var DEV_EVM_PRESET = "anvil";
|
|
4714
|
+
var DEV_SOLANA = {
|
|
4715
|
+
usdcMint: "6GbdrVghwNKTz9raga7y3Y4qqX5Zgg3AC4d48Kt7C59Q",
|
|
4716
|
+
programId: ""
|
|
4717
|
+
// TOON payment-channel program not deployed on the dev Solana node
|
|
4718
|
+
};
|
|
4719
|
+
var RELAY_ONLY_CHAIN = "none";
|
|
4720
|
+
var EVM_TIER = {
|
|
4721
|
+
mainnet: { primary: "base-mainnet", also: ["arbitrum-one"] },
|
|
4722
|
+
testnet: { primary: "base-sepolia", also: ["arbitrum-sepolia"] },
|
|
4723
|
+
// EVM has no public devnet → the public Sepolia testnets serve the devnet tier.
|
|
4724
|
+
devnet: { primary: "base-sepolia", also: ["arbitrum-sepolia"] }
|
|
4725
|
+
};
|
|
4726
|
+
var SOLANA_DEPLOYED_DEVNET = {
|
|
4727
|
+
rpcUrl: "https://api.devnet.solana.com",
|
|
4728
|
+
cluster: "devnet",
|
|
4729
|
+
usdcMint: "9FtYCXjNiGDn17jSGvZuB5P4dZAKgVxUsDiQpLc8rbWy",
|
|
4730
|
+
programId: "EdJxYPDxGvaJuu57DSUptf4soLv8enpdyQJJhHDLiydG"
|
|
4731
|
+
};
|
|
4732
|
+
var SOLANA_TIER = {
|
|
4733
|
+
mainnet: {
|
|
4734
|
+
rpcUrl: "https://api.mainnet-beta.solana.com",
|
|
4735
|
+
cluster: "mainnet-beta",
|
|
4736
|
+
usdcMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
4737
|
+
programId: ""
|
|
4738
|
+
// TOON payment-channel program not deployed on mainnet
|
|
4739
|
+
},
|
|
4740
|
+
testnet: SOLANA_DEPLOYED_DEVNET,
|
|
4741
|
+
devnet: SOLANA_DEPLOYED_DEVNET
|
|
4742
|
+
};
|
|
4743
|
+
var MINA_DEPLOYED_DEVNET = {
|
|
4744
|
+
graphqlUrl: "https://api.minascan.io/node/devnet/v1/graphql",
|
|
4745
|
+
network: "devnet",
|
|
4746
|
+
// Reconciled with e2e/testnets.json (#205): the previous address
|
|
4747
|
+
// (B62qjFgX…) is a bare, unfunded zkApp on-chain (balance 0, channel
|
|
4748
|
+
// nonceField 0) — usable for claim issuance only. This is the funded,
|
|
4749
|
+
// on-chain-settling PaymentChannel zkApp (balance ~4 MINA, nonceField 21
|
|
4750
|
+
// — the on-chain settle proven in #217), same VK hash 21482326…
|
|
4751
|
+
zkAppAddress: "B62qrH1As4odHiNyKpTZMHaM6tRs6gi5DJ53efZKQBtbaR5CUctbDs6"
|
|
4752
|
+
};
|
|
4753
|
+
var MINA_TIER = {
|
|
4754
|
+
mainnet: {
|
|
4755
|
+
graphqlUrl: "https://api.minascan.io/node/mainnet/v1/graphql",
|
|
4756
|
+
network: "mainnet",
|
|
4757
|
+
zkAppAddress: ""
|
|
4758
|
+
// TOON payment-channel zkApp not deployed on mainnet
|
|
4759
|
+
},
|
|
4760
|
+
testnet: MINA_DEPLOYED_DEVNET,
|
|
4761
|
+
devnet: MINA_DEPLOYED_DEVNET
|
|
4762
|
+
};
|
|
4763
|
+
function evmSettlementComplete(p) {
|
|
4764
|
+
return p.registryAddress !== "" && p.tokenNetworkAddress !== "";
|
|
4765
|
+
}
|
|
4766
|
+
function resolveNetworkProfile(network, opts = {}) {
|
|
4767
|
+
if (network === "custom") {
|
|
4768
|
+
return resolveCustom(
|
|
4769
|
+
opts.customProviders ?? [],
|
|
4770
|
+
opts.endpoints ?? {},
|
|
4771
|
+
opts.keyId
|
|
4772
|
+
);
|
|
4773
|
+
}
|
|
4774
|
+
const tier = network;
|
|
4775
|
+
const chainProviders = [];
|
|
4776
|
+
const status = {
|
|
4777
|
+
evm: "unconfigured",
|
|
4778
|
+
solana: "unconfigured",
|
|
4779
|
+
mina: "unconfigured"
|
|
4780
|
+
};
|
|
4781
|
+
const primary = CHAIN_PRESETS[EVM_TIER[tier].primary];
|
|
4782
|
+
const nodeEnv = {
|
|
4783
|
+
EVM_CHAIN: primary.name,
|
|
4784
|
+
EVM_RPC_URL: primary.rpcUrl,
|
|
4785
|
+
EVM_CHAIN_ID: String(primary.chainId),
|
|
4786
|
+
EVM_USDC_ADDRESS: primary.usdcAddress
|
|
4787
|
+
};
|
|
4788
|
+
if (opts.keyId) {
|
|
4789
|
+
for (const name of [EVM_TIER[tier].primary, ...EVM_TIER[tier].also]) {
|
|
4790
|
+
const preset = CHAIN_PRESETS[name];
|
|
4791
|
+
if (evmSettlementComplete(preset)) {
|
|
4792
|
+
chainProviders.push(buildEvmProviderEntry(preset, opts.keyId));
|
|
4793
|
+
status.evm = "configured";
|
|
4794
|
+
}
|
|
4795
|
+
}
|
|
4796
|
+
}
|
|
4797
|
+
const sol = SOLANA_TIER[tier];
|
|
4798
|
+
nodeEnv.SOLANA_RPC_URL = sol.rpcUrl;
|
|
4799
|
+
if (sol.usdcMint) nodeEnv.SOLANA_USDC_MINT = sol.usdcMint;
|
|
4800
|
+
if (opts.keyId && sol.programId) {
|
|
4801
|
+
chainProviders.push(
|
|
4802
|
+
buildSolanaProviderEntry(
|
|
4803
|
+
{
|
|
4804
|
+
name: `solana-${sol.cluster}`,
|
|
4805
|
+
chainType: "solana",
|
|
4806
|
+
rpcUrl: sol.rpcUrl,
|
|
4807
|
+
programId: sol.programId,
|
|
4808
|
+
cluster: sol.cluster,
|
|
4809
|
+
...sol.usdcMint && { tokenMint: sol.usdcMint }
|
|
4810
|
+
},
|
|
4811
|
+
opts.keyId
|
|
4812
|
+
)
|
|
4813
|
+
);
|
|
4814
|
+
status.solana = "configured";
|
|
4815
|
+
}
|
|
4816
|
+
const mina = MINA_TIER[tier];
|
|
4817
|
+
if (opts.keyId && mina.zkAppAddress) {
|
|
4818
|
+
chainProviders.push(
|
|
4819
|
+
buildMinaProviderEntry(
|
|
4820
|
+
{
|
|
4821
|
+
name: `mina-${mina.network}`,
|
|
4822
|
+
chainType: "mina",
|
|
4823
|
+
graphqlUrl: mina.graphqlUrl,
|
|
4824
|
+
zkAppAddress: mina.zkAppAddress,
|
|
4825
|
+
network: mina.network
|
|
4826
|
+
},
|
|
4827
|
+
opts.keyId
|
|
4828
|
+
)
|
|
4829
|
+
);
|
|
4830
|
+
status.mina = "configured";
|
|
4831
|
+
}
|
|
4832
|
+
return { network, chainProviders, nodeEnv, status };
|
|
4833
|
+
}
|
|
4834
|
+
function evmClientId(preset) {
|
|
4835
|
+
const family = preset.name.split("-")[0] ?? preset.name;
|
|
4836
|
+
return `evm:${family}:${preset.chainId}`;
|
|
4837
|
+
}
|
|
4838
|
+
function resolveClientNetwork(network) {
|
|
4839
|
+
const supportedChains = [];
|
|
4840
|
+
const chainRpcUrls = {};
|
|
4841
|
+
const preferredTokens = {};
|
|
4842
|
+
const tokenNetworks = {};
|
|
4843
|
+
const status = {
|
|
4844
|
+
evm: "unconfigured",
|
|
4845
|
+
solana: "unconfigured",
|
|
4846
|
+
mina: "unconfigured"
|
|
4847
|
+
};
|
|
4848
|
+
const evm = CHAIN_PRESETS[EVM_TIER[network].primary];
|
|
4849
|
+
const evmId = evmClientId(evm);
|
|
4850
|
+
supportedChains.push(evmId);
|
|
4851
|
+
chainRpcUrls[evmId] = evm.rpcUrl;
|
|
4852
|
+
if (evm.usdcAddress) preferredTokens[evmId] = evm.usdcAddress;
|
|
4853
|
+
if (evmSettlementComplete(evm)) {
|
|
4854
|
+
tokenNetworks[evmId] = evm.tokenNetworkAddress;
|
|
4855
|
+
status.evm = "configured";
|
|
4856
|
+
}
|
|
4857
|
+
const sol = SOLANA_TIER[network];
|
|
4858
|
+
const solId = `solana:${sol.cluster}`;
|
|
4859
|
+
supportedChains.push(solId);
|
|
4860
|
+
chainRpcUrls[solId] = sol.rpcUrl;
|
|
4861
|
+
if (sol.usdcMint) preferredTokens[solId] = sol.usdcMint;
|
|
4862
|
+
let solanaChannel;
|
|
4863
|
+
if (sol.programId) {
|
|
4864
|
+
solanaChannel = {
|
|
4865
|
+
rpcUrl: sol.rpcUrl,
|
|
4866
|
+
programId: sol.programId,
|
|
4867
|
+
...sol.usdcMint && { tokenMint: sol.usdcMint }
|
|
4868
|
+
};
|
|
4869
|
+
status.solana = "configured";
|
|
4870
|
+
}
|
|
4871
|
+
const mina = MINA_TIER[network];
|
|
4872
|
+
const minaId = `mina:${mina.network}`;
|
|
4873
|
+
supportedChains.push(minaId);
|
|
4874
|
+
chainRpcUrls[minaId] = mina.graphqlUrl;
|
|
4875
|
+
let minaChannel;
|
|
4876
|
+
if (mina.zkAppAddress) {
|
|
4877
|
+
minaChannel = {
|
|
4878
|
+
graphqlUrl: mina.graphqlUrl,
|
|
4879
|
+
zkAppAddress: mina.zkAppAddress,
|
|
4880
|
+
networkId: mina.network === "mainnet" ? "mainnet" : "devnet"
|
|
4881
|
+
};
|
|
4882
|
+
status.mina = "configured";
|
|
4883
|
+
}
|
|
4884
|
+
return {
|
|
4885
|
+
supportedChains,
|
|
4886
|
+
chainRpcUrls,
|
|
4887
|
+
preferredTokens,
|
|
4888
|
+
tokenNetworks,
|
|
4889
|
+
...solanaChannel && { solanaChannel },
|
|
4890
|
+
...minaChannel && { minaChannel },
|
|
4891
|
+
status
|
|
4892
|
+
};
|
|
4893
|
+
}
|
|
4894
|
+
function resolveCustom(providers, endpoints, keyId) {
|
|
4895
|
+
if (providers.length === 0 && (endpoints.evmUrl || endpoints.solUrl)) {
|
|
4896
|
+
return resolveCustomEndpoints(endpoints, keyId);
|
|
4897
|
+
}
|
|
4898
|
+
const status = {
|
|
4899
|
+
evm: "unconfigured",
|
|
4900
|
+
solana: "unconfigured",
|
|
4901
|
+
mina: "unconfigured"
|
|
4902
|
+
};
|
|
4903
|
+
const nodeEnv = {};
|
|
4904
|
+
const evm = providers.find((p) => p.chainType === "evm");
|
|
4905
|
+
if (evm && evm.chainType === "evm") {
|
|
4906
|
+
nodeEnv.EVM_RPC_URL = evm.rpcUrl;
|
|
4907
|
+
nodeEnv.EVM_CHAIN_ID = evm.chainId.replace(/^evm:/, "");
|
|
4908
|
+
nodeEnv.EVM_USDC_ADDRESS = evm.tokenAddress;
|
|
4909
|
+
nodeEnv.EVM_CHAIN = RELAY_ONLY_CHAIN;
|
|
4910
|
+
if (evm.registryAddress) status.evm = "configured";
|
|
4911
|
+
} else {
|
|
4912
|
+
nodeEnv.EVM_CHAIN = RELAY_ONLY_CHAIN;
|
|
4913
|
+
}
|
|
4914
|
+
const sol = providers.find((p) => p.chainType === "solana");
|
|
4915
|
+
if (sol && sol.chainType === "solana") {
|
|
4916
|
+
nodeEnv.SOLANA_RPC_URL = sol.rpcUrl;
|
|
4917
|
+
if (sol.tokenMint) nodeEnv.SOLANA_USDC_MINT = sol.tokenMint;
|
|
4918
|
+
if (sol.programId) status.solana = "configured";
|
|
4919
|
+
}
|
|
4920
|
+
const mina = providers.find((p) => p.chainType === "mina");
|
|
4921
|
+
if (mina && mina.chainType === "mina" && mina.zkAppAddress) {
|
|
4922
|
+
status.mina = "configured";
|
|
4923
|
+
}
|
|
4924
|
+
return { network: "custom", chainProviders: providers, nodeEnv, status };
|
|
4925
|
+
}
|
|
4926
|
+
function resolveCustomEndpoints(endpoints, keyId) {
|
|
4927
|
+
const evm = CHAIN_PRESETS[DEV_EVM_PRESET];
|
|
4928
|
+
const status = {
|
|
4929
|
+
evm: "unconfigured",
|
|
4930
|
+
solana: "unconfigured",
|
|
4931
|
+
mina: "unconfigured"
|
|
4932
|
+
};
|
|
4933
|
+
const chainProviders = [];
|
|
4934
|
+
const nodeEnv = {
|
|
4935
|
+
EVM_CHAIN: DEV_EVM_PRESET,
|
|
4936
|
+
EVM_CHAIN_ID: String(evm.chainId),
|
|
4937
|
+
EVM_USDC_ADDRESS: evm.usdcAddress
|
|
4938
|
+
};
|
|
4939
|
+
if (endpoints.evmUrl) {
|
|
4940
|
+
nodeEnv.EVM_RPC_URL = endpoints.evmUrl;
|
|
4941
|
+
status.evm = "configured";
|
|
4942
|
+
if (keyId) {
|
|
4943
|
+
chainProviders.push(
|
|
4944
|
+
buildEvmProviderEntry({ ...evm, rpcUrl: endpoints.evmUrl }, keyId)
|
|
4945
|
+
);
|
|
4946
|
+
}
|
|
4947
|
+
} else {
|
|
4948
|
+
nodeEnv.EVM_CHAIN = RELAY_ONLY_CHAIN;
|
|
4949
|
+
}
|
|
4950
|
+
if (endpoints.solUrl) {
|
|
4951
|
+
nodeEnv.SOLANA_RPC_URL = endpoints.solUrl;
|
|
4952
|
+
nodeEnv.SOLANA_USDC_MINT = DEV_SOLANA.usdcMint;
|
|
4953
|
+
}
|
|
4954
|
+
return { network: "custom", chainProviders, nodeEnv, status };
|
|
4955
|
+
}
|
|
4956
|
+
|
|
4357
4957
|
// src/x402/build-ilp-prepare.ts
|
|
4358
4958
|
function buildIlpPrepare(params) {
|
|
4359
4959
|
return {
|
|
@@ -4500,8 +5100,8 @@ var NixBuilder = class {
|
|
|
4500
5100
|
);
|
|
4501
5101
|
}
|
|
4502
5102
|
const imageData = await readFile(imagePath);
|
|
4503
|
-
const
|
|
4504
|
-
const imageHash = `sha256:${
|
|
5103
|
+
const sha2563 = createHash("sha256").update(imageData).digest("hex");
|
|
5104
|
+
const imageHash = `sha256:${sha2563}`;
|
|
4505
5105
|
const pcr0 = createHash("sha384").update(imageData).digest("hex");
|
|
4506
5106
|
const KERNEL_REGION_SIZE = 1024 * 1024;
|
|
4507
5107
|
const kernelRegion = imageData.subarray(
|
|
@@ -4714,9 +5314,11 @@ export {
|
|
|
4714
5314
|
BootstrapError,
|
|
4715
5315
|
BootstrapService,
|
|
4716
5316
|
CHAIN_PRESETS,
|
|
5317
|
+
EXPIRATION_TAG,
|
|
4717
5318
|
GenesisPeerLoader,
|
|
4718
5319
|
ILP_PEER_INFO_KIND,
|
|
4719
5320
|
ILP_ROOT_PREFIX,
|
|
5321
|
+
ILP_TO_SEMANTIC,
|
|
4720
5322
|
IMAGE_GENERATION_KIND,
|
|
4721
5323
|
InvalidEventError,
|
|
4722
5324
|
JOB_FEEDBACK_KIND,
|
|
@@ -4736,6 +5338,7 @@ export {
|
|
|
4736
5338
|
PREFIX_GRANT_KIND,
|
|
4737
5339
|
PcrReproducibilityError,
|
|
4738
5340
|
PeerDiscoveryError,
|
|
5341
|
+
RELAY_ONLY_CHAIN,
|
|
4739
5342
|
ReputationScoreCalculator,
|
|
4740
5343
|
SEED_RELAY_LIST_KIND,
|
|
4741
5344
|
SERVICE_DISCOVERY_KIND,
|
|
@@ -4757,6 +5360,12 @@ export {
|
|
|
4757
5360
|
WORKFLOW_CHAIN_KIND,
|
|
4758
5361
|
analyzeDockerfileForNonDeterminism,
|
|
4759
5362
|
assignAddressFromHandshake,
|
|
5363
|
+
balanceProofFieldsMina,
|
|
5364
|
+
balanceProofHashEvm,
|
|
5365
|
+
balanceProofHashSolana,
|
|
5366
|
+
base58Decode,
|
|
5367
|
+
base58Encode,
|
|
5368
|
+
bigintToBytes32BE,
|
|
4760
5369
|
buildAttestationEvent,
|
|
4761
5370
|
buildBlobStorageRequest,
|
|
4762
5371
|
buildEip712Domain,
|
|
@@ -4780,6 +5389,7 @@ export {
|
|
|
4780
5389
|
buildWotDeclarationEvent,
|
|
4781
5390
|
calculateRouteAmount,
|
|
4782
5391
|
checkAddressCollision,
|
|
5392
|
+
concatBytes,
|
|
4783
5393
|
createAgentRuntimeClient,
|
|
4784
5394
|
createDirectChannelClient,
|
|
4785
5395
|
createDirectConnectorAdmin,
|
|
@@ -4796,13 +5406,20 @@ export {
|
|
|
4796
5406
|
decodeEventFromToon,
|
|
4797
5407
|
deriveChildAddress,
|
|
4798
5408
|
deriveFromKmsSeed,
|
|
5409
|
+
deriveMinaPublicKeyBase58,
|
|
4799
5410
|
encodeEventToToon,
|
|
4800
5411
|
encodeEventToToonString,
|
|
4801
5412
|
extractPrefixFromHandshake,
|
|
5413
|
+
getEventExpiration,
|
|
4802
5414
|
hasMinReputation,
|
|
4803
5415
|
hasRequireAttestation,
|
|
5416
|
+
hexToBytes,
|
|
5417
|
+
hexToMinaBase58PrivateKey,
|
|
5418
|
+
ilpCodeToSemantic,
|
|
5419
|
+
isEventExpired,
|
|
4804
5420
|
isGenesisNode,
|
|
4805
5421
|
isValidIlpAddressStructure,
|
|
5422
|
+
minaHashToField,
|
|
4806
5423
|
negotiateSettlementChain,
|
|
4807
5424
|
parseAttestation,
|
|
4808
5425
|
parseBlobStorageRequest,
|
|
@@ -4822,7 +5439,9 @@ export {
|
|
|
4822
5439
|
publishSeedRelayEntry,
|
|
4823
5440
|
readDockerfileNix,
|
|
4824
5441
|
resolveChainConfig,
|
|
5442
|
+
resolveClientNetwork,
|
|
4825
5443
|
resolveMinaChainConfig,
|
|
5444
|
+
resolveNetworkProfile,
|
|
4826
5445
|
resolveRouteFees,
|
|
4827
5446
|
resolveSolanaChainConfig,
|
|
4828
5447
|
resolveTokenForChain,
|