@toon-protocol/core 3.3.0 → 3.4.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/chunk-K72H36Y4.js +591 -0
- package/dist/chunk-K72H36Y4.js.map +1 -0
- package/dist/index.d.ts +108 -7
- package/dist/index.js +154 -21
- package/dist/index.js.map +1 -1
- package/dist/wire/index.d.ts +638 -0
- package/dist/wire/index.js +115 -0
- package/dist/wire/index.js.map +1 -0
- package/package.json +7 -1
package/dist/index.js
CHANGED
|
@@ -9,6 +9,10 @@ import {
|
|
|
9
9
|
encodeEventToToonString,
|
|
10
10
|
shallowParseToon
|
|
11
11
|
} from "./chunk-5WT7ISKC.js";
|
|
12
|
+
import {
|
|
13
|
+
readExchangeOutcome,
|
|
14
|
+
sealExchange
|
|
15
|
+
} from "./chunk-K72H36Y4.js";
|
|
12
16
|
|
|
13
17
|
// src/constants.ts
|
|
14
18
|
var ILP_PEER_INFO_KIND = 10032;
|
|
@@ -395,6 +399,21 @@ function assertSwapPairForParse(pair, index) {
|
|
|
395
399
|
function isObject2(value) {
|
|
396
400
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
397
401
|
}
|
|
402
|
+
function parseNotice(raw) {
|
|
403
|
+
if (!isObject2(raw)) {
|
|
404
|
+
return void 0;
|
|
405
|
+
}
|
|
406
|
+
const { id, severity, summary, url } = raw;
|
|
407
|
+
if (typeof id !== "string" || id.length === 0 || typeof summary !== "string" || summary.length === 0 || typeof url !== "string" || url.length === 0) {
|
|
408
|
+
return void 0;
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
id,
|
|
412
|
+
severity: severity === "action-required" ? "action-required" : "info",
|
|
413
|
+
summary,
|
|
414
|
+
url
|
|
415
|
+
};
|
|
416
|
+
}
|
|
398
417
|
function parseIlpPeerInfo(event) {
|
|
399
418
|
if (event.kind !== ILP_PEER_INFO_KIND) {
|
|
400
419
|
throw new InvalidEventError(
|
|
@@ -538,6 +557,8 @@ function parseIlpPeerInfo(event) {
|
|
|
538
557
|
}
|
|
539
558
|
prefixPricing = { basePrice };
|
|
540
559
|
}
|
|
560
|
+
const { notice: rawNotice } = parsed;
|
|
561
|
+
const notice = parseNotice(rawNotice);
|
|
541
562
|
const { swapPairs: rawSwapPairs } = parsed;
|
|
542
563
|
let swapPairs;
|
|
543
564
|
if (rawSwapPairs !== void 0) {
|
|
@@ -590,7 +611,8 @@ function parseIlpPeerInfo(event) {
|
|
|
590
611
|
ilpAddresses,
|
|
591
612
|
feePerByte,
|
|
592
613
|
...prefixPricing !== void 0 && { prefixPricing },
|
|
593
|
-
...swapPairs !== void 0 && { swapPairs }
|
|
614
|
+
...swapPairs !== void 0 && { swapPairs },
|
|
615
|
+
...notice !== void 0 && { notice }
|
|
594
616
|
};
|
|
595
617
|
}
|
|
596
618
|
|
|
@@ -3068,7 +3090,9 @@ var BootstrapService = class {
|
|
|
3068
3090
|
ownIlpAddress;
|
|
3069
3091
|
toonEncoder;
|
|
3070
3092
|
toonDecoder;
|
|
3093
|
+
/** @deprecated see {@link BootstrapServiceConfig.basePricePerByte}. */
|
|
3071
3094
|
basePricePerByte;
|
|
3095
|
+
connectorEdgeLookup;
|
|
3072
3096
|
// Event emitter
|
|
3073
3097
|
listeners = [];
|
|
3074
3098
|
phase = "discovering";
|
|
@@ -3095,7 +3119,8 @@ var BootstrapService = class {
|
|
|
3095
3119
|
this.ownIlpAddress = config.ownIlpAddress;
|
|
3096
3120
|
this.toonEncoder = config.toonEncoder;
|
|
3097
3121
|
this.toonDecoder = config.toonDecoder;
|
|
3098
|
-
this.basePricePerByte = config.basePricePerByte
|
|
3122
|
+
this.basePricePerByte = config.basePricePerByte;
|
|
3123
|
+
this.connectorEdgeLookup = config.connectorEdgeLookup;
|
|
3099
3124
|
}
|
|
3100
3125
|
/**
|
|
3101
3126
|
* Set the ILP client for sending packets via the connector.
|
|
@@ -3396,32 +3421,86 @@ var BootstrapService = class {
|
|
|
3396
3421
|
}
|
|
3397
3422
|
return result;
|
|
3398
3423
|
}
|
|
3424
|
+
/**
|
|
3425
|
+
* What the announce PREPARE should carry as its amount.
|
|
3426
|
+
*
|
|
3427
|
+
* ASKED for (ADR 0020, flat per handler), never computed as bytes × rate.
|
|
3428
|
+
* `basePricePerByte`, when a caller still sets it, is a deprecated explicit
|
|
3429
|
+
* override rather than a per-byte rate — see its doc comment on
|
|
3430
|
+
* {@link BootstrapServiceConfig}.
|
|
3431
|
+
*
|
|
3432
|
+
* @throws {BootstrapError} when nothing terminated here prices `destination`.
|
|
3433
|
+
*/
|
|
3434
|
+
async resolveAnnounceAmount(lookup, destination) {
|
|
3435
|
+
if (this.basePricePerByte !== void 0) {
|
|
3436
|
+
return String(this.basePricePerByte);
|
|
3437
|
+
}
|
|
3438
|
+
const routePrice = await lookup.getRoutePrice(destination);
|
|
3439
|
+
if (routePrice === null) {
|
|
3440
|
+
throw new BootstrapError(
|
|
3441
|
+
`No locally-terminated route price for ${destination}`
|
|
3442
|
+
);
|
|
3443
|
+
}
|
|
3444
|
+
return String(routePrice.price);
|
|
3445
|
+
}
|
|
3399
3446
|
/**
|
|
3400
3447
|
* Announce own kind:10032 as paid ILP PREPARE (Phase 2).
|
|
3401
3448
|
*/
|
|
3402
3449
|
async announceViaIlp(result) {
|
|
3403
|
-
if (!this.ilpClient || !this.toonEncoder) {
|
|
3450
|
+
if (!this.ilpClient || !this.toonEncoder || !this.connectorEdgeLookup) {
|
|
3404
3451
|
return;
|
|
3405
3452
|
}
|
|
3406
3453
|
const ilpInfoEvent = buildIlpPeerInfoEvent(this.ownIlpInfo, this.secretKey);
|
|
3407
3454
|
const toonBytes = this.toonEncoder(ilpInfoEvent);
|
|
3408
|
-
const
|
|
3409
|
-
|
|
3455
|
+
const identity = await this.connectorEdgeLookup.getIdentity(
|
|
3456
|
+
result.peerInfo.ilpAddress
|
|
3457
|
+
);
|
|
3458
|
+
const amount = await this.resolveAnnounceAmount(
|
|
3459
|
+
this.connectorEdgeLookup,
|
|
3460
|
+
result.peerInfo.ilpAddress
|
|
3461
|
+
);
|
|
3462
|
+
const request = {
|
|
3463
|
+
method: "POST",
|
|
3464
|
+
target: "",
|
|
3465
|
+
headers: [["content-type", "application/json"]],
|
|
3466
|
+
body: toonBytes
|
|
3467
|
+
};
|
|
3468
|
+
const exchange = sealExchange(request, identity.publicKey);
|
|
3469
|
+
const data = Buffer.from(exchange.data).toString("base64");
|
|
3470
|
+
const executionCondition = Buffer.from(exchange.condition).toString(
|
|
3471
|
+
"base64"
|
|
3472
|
+
);
|
|
3410
3473
|
let ilpResult;
|
|
3411
3474
|
if (this.claimSigner && result.channelId && this.ilpClient.sendIlpPacketWithClaim) {
|
|
3412
3475
|
const claim = await this.claimSigner(result.channelId, BigInt(amount));
|
|
3413
3476
|
ilpResult = await this.ilpClient.sendIlpPacketWithClaim(
|
|
3414
|
-
{
|
|
3477
|
+
{
|
|
3478
|
+
destination: result.peerInfo.ilpAddress,
|
|
3479
|
+
amount,
|
|
3480
|
+
data,
|
|
3481
|
+
executionCondition
|
|
3482
|
+
},
|
|
3415
3483
|
claim
|
|
3416
3484
|
);
|
|
3417
3485
|
} else {
|
|
3418
3486
|
ilpResult = await this.ilpClient.sendIlpPacket({
|
|
3419
3487
|
destination: result.peerInfo.ilpAddress,
|
|
3420
3488
|
amount,
|
|
3421
|
-
data
|
|
3489
|
+
data,
|
|
3490
|
+
executionCondition
|
|
3422
3491
|
});
|
|
3423
3492
|
}
|
|
3424
|
-
|
|
3493
|
+
const responseData = ilpResult.data !== void 0 ? Uint8Array.from(Buffer.from(ilpResult.data, "base64")) : void 0;
|
|
3494
|
+
const outcome = readExchangeOutcome(
|
|
3495
|
+
{
|
|
3496
|
+
accepted: ilpResult.accepted,
|
|
3497
|
+
code: ilpResult.code,
|
|
3498
|
+
message: ilpResult.message
|
|
3499
|
+
},
|
|
3500
|
+
responseData,
|
|
3501
|
+
exchange.sharedSecret
|
|
3502
|
+
);
|
|
3503
|
+
if (outcome.kind === "answered") {
|
|
3425
3504
|
console.log(
|
|
3426
3505
|
`[Bootstrap] Announced to ${result.registeredPeerId} via ILP (eventId: ${ilpInfoEvent.id})`
|
|
3427
3506
|
);
|
|
@@ -3431,17 +3510,18 @@ var BootstrapService = class {
|
|
|
3431
3510
|
eventId: ilpInfoEvent.id,
|
|
3432
3511
|
amount
|
|
3433
3512
|
});
|
|
3434
|
-
|
|
3435
|
-
const reason = `${ilpResult.code} ${ilpResult.message}`;
|
|
3436
|
-
this.emit({
|
|
3437
|
-
type: "bootstrap:announce-failed",
|
|
3438
|
-
peerId: result.registeredPeerId,
|
|
3439
|
-
reason
|
|
3440
|
-
});
|
|
3441
|
-
console.warn(
|
|
3442
|
-
`[Bootstrap] Announce rejected by ${result.registeredPeerId}: ${reason}`
|
|
3443
|
-
);
|
|
3513
|
+
return;
|
|
3444
3514
|
}
|
|
3515
|
+
const refusedBy = outcome.kind === "destination-refused" ? "destination" : "path";
|
|
3516
|
+
const reason = `${outcome.code} ${outcome.message} (${refusedBy} refused)`;
|
|
3517
|
+
this.emit({
|
|
3518
|
+
type: "bootstrap:announce-failed",
|
|
3519
|
+
peerId: result.registeredPeerId,
|
|
3520
|
+
reason
|
|
3521
|
+
});
|
|
3522
|
+
console.warn(
|
|
3523
|
+
`[Bootstrap] Announce rejected by ${result.registeredPeerId}: ${reason}`
|
|
3524
|
+
);
|
|
3445
3525
|
}
|
|
3446
3526
|
/**
|
|
3447
3527
|
* Query a peer's relay for their kind:10032 ILP Peer Info event.
|
|
@@ -3996,6 +4076,9 @@ function createHttpIlpClient(baseUrl) {
|
|
|
3996
4076
|
...params.timeout !== void 0 && { timeout: params.timeout },
|
|
3997
4077
|
...params.expiresAt !== void 0 && {
|
|
3998
4078
|
expiresAt: params.expiresAt
|
|
4079
|
+
},
|
|
4080
|
+
...params.executionCondition !== void 0 && {
|
|
4081
|
+
executionCondition: params.executionCondition
|
|
3999
4082
|
}
|
|
4000
4083
|
})
|
|
4001
4084
|
});
|
|
@@ -4041,7 +4124,12 @@ function createDirectIlpClient(connector, _config) {
|
|
|
4041
4124
|
destination: params.destination,
|
|
4042
4125
|
amount,
|
|
4043
4126
|
data,
|
|
4044
|
-
expiresAt
|
|
4127
|
+
expiresAt,
|
|
4128
|
+
...params.executionCondition !== void 0 && {
|
|
4129
|
+
executionCondition: Uint8Array.from(
|
|
4130
|
+
Buffer.from(params.executionCondition, "base64")
|
|
4131
|
+
)
|
|
4132
|
+
}
|
|
4045
4133
|
});
|
|
4046
4134
|
if (result.type === "fulfill" || result.type === 13) {
|
|
4047
4135
|
return {
|
|
@@ -4211,6 +4299,9 @@ function createHttpIlpClient2(connectorUrl) {
|
|
|
4211
4299
|
data: params.data,
|
|
4212
4300
|
...params.expiresAt !== void 0 && {
|
|
4213
4301
|
expiresAt: params.expiresAt
|
|
4302
|
+
},
|
|
4303
|
+
...params.executionCondition !== void 0 && {
|
|
4304
|
+
executionCondition: params.executionCondition
|
|
4214
4305
|
}
|
|
4215
4306
|
}),
|
|
4216
4307
|
signal: params.timeout ? AbortSignal.timeout(params.timeout) : void 0
|
|
@@ -4464,7 +4555,8 @@ function createToonNode(config) {
|
|
|
4464
4555
|
ownIlpAddress: config.ilpInfo.ilpAddress,
|
|
4465
4556
|
toonEncoder: config.toonEncoder,
|
|
4466
4557
|
toonDecoder: config.toonDecoder,
|
|
4467
|
-
basePricePerByte: config.basePricePerByte
|
|
4558
|
+
basePricePerByte: config.basePricePerByte,
|
|
4559
|
+
connectorEdgeLookup: config.connectorEdgeLookup
|
|
4468
4560
|
},
|
|
4469
4561
|
config.secretKey,
|
|
4470
4562
|
config.ilpInfo
|
|
@@ -4648,8 +4740,49 @@ var SOLANA_CHAIN_PRESETS = {
|
|
|
4648
4740
|
name: "solana-devnet",
|
|
4649
4741
|
chainType: "solana",
|
|
4650
4742
|
rpcUrl: "http://localhost:19899",
|
|
4651
|
-
|
|
4743
|
+
// Deliberately empty: this preset targets a local `solana-test-validator`
|
|
4744
|
+
// (see rpcUrl), not public devnet -- the public-devnet program id
|
|
4745
|
+
// (2aEVJ8ko…, per connector's packages/solana-program/deployments/
|
|
4746
|
+
// devnet-public.md) does not exist there. A local validator's program id
|
|
4747
|
+
// is a fresh keypair generated per `cargo build-sbf` deploy, so no fixed
|
|
4748
|
+
// default is meaningful; callers must supply the id of whatever they
|
|
4749
|
+
// deployed locally via the `SOLANA_PROGRAM_ID` env override below.
|
|
4750
|
+
programId: "",
|
|
4652
4751
|
cluster: "devnet"
|
|
4752
|
+
},
|
|
4753
|
+
// Solana mainnet-beta (public). NOT wired into network-profile.ts's
|
|
4754
|
+
// public tiers, which already resolve their own mainnet Solana endpoint
|
|
4755
|
+
// (SOLANA_TIER.mainnet) independently of this low-level,
|
|
4756
|
+
// e2e-stack-facing preset table.
|
|
4757
|
+
"solana-mainnet": {
|
|
4758
|
+
name: "solana-mainnet",
|
|
4759
|
+
chainType: "solana",
|
|
4760
|
+
rpcUrl: "https://api.mainnet-beta.solana.com",
|
|
4761
|
+
// VERIFIED 2026-08-14, per toon#198: owner
|
|
4762
|
+
// BPFLoaderUpgradeab1e11111111111111111111111 (executable, upgradeable),
|
|
4763
|
+
// ProgramData 29MT16eh1GCdL4JWrJHjyTWu5ZMn217h25ojCvFpx2wc, 136,770
|
|
4764
|
+
// bytes, deployed slot 439316400. Bytecode pulled back with
|
|
4765
|
+
// `solana program dump` hashes identical to a local build from
|
|
4766
|
+
// connector@main with the pinned `cargo build-sbf --tools-version
|
|
4767
|
+
// v1.52`, so the on-chain program is provably the audited source. Full
|
|
4768
|
+
// deployment record: toon-protocol/connector#971.
|
|
4769
|
+
programId: "8e7BhzydH1EqL486tw6Lp99BXviH3i5JN8qNpMSNmHj3",
|
|
4770
|
+
cluster: "mainnet-beta",
|
|
4771
|
+
// Circle's native USDC mint on Solana mainnet-beta, 6 decimals.
|
|
4772
|
+
// VERIFIED 2026-08-13 by Drew Pierson, per toon#166's "Needs a human
|
|
4773
|
+
// before merge" criterion, on two independent sources:
|
|
4774
|
+
// - Circle's published list gives this address for Solana mainnet:
|
|
4775
|
+
// https://developers.circle.com/stablecoins/usdc-contract-addresses
|
|
4776
|
+
// That page names bridged representations separately where they
|
|
4777
|
+
// exist (X Layer's USDC.e); none is listed for Solana.
|
|
4778
|
+
// - mainnet-beta at slot 439080550: initialized mint, decimals 6,
|
|
4779
|
+
// supply ~7.73e9, live mint and freeze authorities, owned by the
|
|
4780
|
+
// SPL Token program (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA),
|
|
4781
|
+
// not Token-2022.
|
|
4782
|
+
// Native, not bridged. Two things not to confuse it with: this is the
|
|
4783
|
+
// token's MINT ACCOUNT, never a transfer destination; and Circle runs
|
|
4784
|
+
// separate CCTP/Gateway pre-mint addresses that are not this one.
|
|
4785
|
+
tokenMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
|
|
4653
4786
|
}
|
|
4654
4787
|
};
|
|
4655
4788
|
var MINA_CHAIN_PRESETS = {
|