@toon-protocol/core 2.0.1 → 3.0.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Peer discovery, bootstrap, settlement negotiation, and TOON event encoding for the TOON Protocol network.
4
4
 
5
- > This is an internal package. Most users should start with [`@toon-protocol/client`](../client) or [`@toon-protocol/sdk`](../sdk).
5
+ > This is an internal package. Most users should start with [`@toon-protocol/client`](https://github.com/toon-protocol/toon-client) or [`@toon-protocol/sdk`](../sdk).
6
6
 
7
7
  ## Install
8
8
 
package/dist/index.d.ts CHANGED
@@ -1946,7 +1946,13 @@ interface GenesisPeer {
1946
1946
  ilpAddress: string;
1947
1947
  btpEndpoint: string;
1948
1948
  }
1949
- /** Load and validate genesis peers from the bundled JSON file. */
1949
+ /**
1950
+ * Load and validate genesis peers from the bundled JSON file.
1951
+ *
1952
+ * The `TOON_GENESIS_PEERS` environment variable, when set, REPLACES the
1953
+ * bundled seed entirely (same JSON array format). Set it to `[]` to disable
1954
+ * bundled genesis peers — e.g. for private networks or hermetic tests.
1955
+ */
1950
1956
  declare function loadGenesisPeers(): GenesisPeer[];
1951
1957
  /** Parse and validate additional peers from a JSON string. */
1952
1958
  declare function loadAdditionalPeers(json: string): GenesisPeer[];
@@ -2332,6 +2338,12 @@ interface IlpClient {
2332
2338
  amount: string;
2333
2339
  data: string;
2334
2340
  timeout?: number;
2341
+ /**
2342
+ * Per-packet expiry as an ISO 8601 string. When set, the transport
2343
+ * MUST use exactly this expiry for the outgoing PREPARE. When absent,
2344
+ * the transport applies its default (timeout-derived).
2345
+ */
2346
+ expiresAt?: string;
2335
2347
  }): Promise<IlpSendResult>;
2336
2348
  /**
2337
2349
  * Optional: Send ILP packet with signed balance proof claim (BTP only).
@@ -2342,6 +2354,8 @@ interface IlpClient {
2342
2354
  amount: string;
2343
2355
  data: string;
2344
2356
  timeout?: number;
2357
+ /** Per-packet expiry as an ISO 8601 string (see sendIlpPacket). */
2358
+ expiresAt?: string;
2345
2359
  }, claim: unknown): Promise<IlpSendResult>;
2346
2360
  }
2347
2361
  /**
@@ -2503,16 +2517,57 @@ declare function bigintToBytes32BE(x: bigint): Uint8Array;
2503
2517
  */
2504
2518
  declare function concatBytes(...parts: Uint8Array[]): Uint8Array;
2505
2519
  /**
2506
- * Compute the EVM balance-proof message hash:
2507
- * keccak256(channelId || cumulativeAmount(32BE) || nonce(32BE) || recipient)
2520
+ * Compute the EIP-712 domain separator for the RollingSwapChannel v2 domain:
2521
+ * keccak256(abi.encode(
2522
+ * EIP712DOMAIN_TYPEHASH,
2523
+ * keccak256("RollingSwapChannel"),
2524
+ * keccak256("2"),
2525
+ * chainId, // uint256, big-endian
2526
+ * verifyingContract // address, right-aligned in 32 bytes
2527
+ * ))
2528
+ *
2529
+ * `verifyingContractBytes` MUST be the 20-byte deployed RollingSwapChannel
2530
+ * address. Equivalent to OpenZeppelin `EIP712._domainSeparatorV4()`.
2531
+ *
2532
+ * @stable — every signer and verifier depends on the exact layout.
2533
+ */
2534
+ declare function eip712DomainSeparatorEvm(chainId: bigint, verifyingContractBytes: Uint8Array): Uint8Array;
2535
+ /**
2536
+ * Compute the v2 EVM balance-proof (claim) digest — the 32-byte EIP-712 typed
2537
+ * digest the swap node signs and the on-chain `RollingSwapChannel` verifies:
2538
+ *
2539
+ * structHash = keccak256(abi.encode(
2540
+ * CLAIM_TYPEHASH, channelId, cumulativeAmount, nonce, recipient))
2541
+ * digest = keccak256(0x1901 || domainSeparator || structHash)
2508
2542
  *
2509
- * `channelIdBytes` MUST be 32 bytes. `recipientBytes` MUST be 20 bytes.
2510
- * This hash is what `EvmPaymentChannelSigner.signBalanceProof` signs and
2511
- * what `recoverEvmSignerAddress` recovers against.
2543
+ * with domain `EIP712Domain(name="RollingSwapChannel", version="2", chainId,
2544
+ * verifyingContract)`. `channelIdBytes` MUST be 32 bytes, `recipientBytes` MUST
2545
+ * be 20 bytes, `verifyingContractBytes` MUST be the 20-byte deployed contract
2546
+ * address. Equivalent to OZ `EIP712._hashTypedDataV4(claimStructHash)`.
2547
+ *
2548
+ * v2 REQUIRES `chainId` + `verifyingContract` — the two inputs v1 lacked. This
2549
+ * hash is what `EvmPaymentChannelSigner.signBalanceProof` signs and what
2550
+ * `recoverEvmSignerAddress` recovers against.
2512
2551
  *
2513
2552
  * @stable — signer and verifier depend on the exact byte layout.
2514
2553
  */
2515
- declare function balanceProofHashEvm(channelIdBytes: Uint8Array, cumulativeAmount: bigint, nonce: bigint, recipientBytes: Uint8Array): Uint8Array;
2554
+ declare function balanceProofHashEvm(channelIdBytes: Uint8Array, cumulativeAmount: bigint, nonce: bigint, recipientBytes: Uint8Array, chainId: bigint, verifyingContractBytes: Uint8Array): Uint8Array;
2555
+ /**
2556
+ * Compute the v2 EVM cooperative-close digest — the 32-byte EIP-712 typed
2557
+ * digest the recipient signs to acknowledge a cooperative close:
2558
+ *
2559
+ * structHash = keccak256(abi.encode(
2560
+ * COOP_CLOSE_TYPEHASH, channelId, cumulativeAmount, nonce))
2561
+ * digest = keccak256(0x1901 || domainSeparator || structHash)
2562
+ *
2563
+ * Shares the SAME domain as the claim digest (so it is bound to
2564
+ * `chainId + verifyingContract` too), but the distinct `CooperativeClose`
2565
+ * type hash guarantees a close-ack can never be recovered as a balance-proof
2566
+ * claim (or vice-versa). `channelIdBytes` MUST be 32 bytes.
2567
+ *
2568
+ * @stable — signer and verifier depend on the exact byte layout.
2569
+ */
2570
+ declare function coopCloseHashEvm(channelIdBytes: Uint8Array, cumulativeAmount: bigint, nonce: bigint, chainId: bigint, verifyingContractBytes: Uint8Array): Uint8Array;
2516
2571
  /**
2517
2572
  * Compute the Solana balance-proof message hash:
2518
2573
  * sha256(utf8(channelId) || cumulativeAmount(32BE) || nonce(32BE) || utf8(recipient))
@@ -4098,7 +4153,12 @@ interface BuildIlpPrepareParams {
4098
4153
  amount: bigint;
4099
4154
  /** TOON-encoded event as raw bytes. */
4100
4155
  data: Uint8Array;
4101
- /** Packet expiry. Default: 30 seconds from now. */
4156
+ /**
4157
+ * Per-packet expiry. When provided, it is propagated onto the produced
4158
+ * PREPARE (as an ISO 8601 string) so the transport sets exactly this
4159
+ * expiry on the wire. When omitted, the transport applies its own
4160
+ * default (typically derived from the request timeout, ~30s).
4161
+ */
4102
4162
  expiresAt?: Date;
4103
4163
  }
4104
4164
  /**
@@ -4115,12 +4175,20 @@ interface IlpPreparePacket {
4115
4175
  amount: string;
4116
4176
  /** TOON-encoded event as base64 string. */
4117
4177
  data: string;
4178
+ /**
4179
+ * Packet expiry as an ISO 8601 string. Present only when the caller
4180
+ * supplied `expiresAt`; absent means the transport picks its default
4181
+ * (timeout-derived). Matches the connector's `POST /admin/ilp/send`
4182
+ * request field.
4183
+ */
4184
+ expiresAt?: string;
4118
4185
  }
4119
4186
  /**
4120
4187
  * Build an ILP PREPARE packet from the given parameters.
4121
4188
  *
4122
4189
  * Converts the bigint amount to a string, encodes the TOON data to base64,
4123
- * and passes through the destination. This is deliberately simple -- the
4190
+ * passes through the destination, and when supplied serializes the
4191
+ * per-packet expiry to ISO 8601. This is deliberately simple -- the
4124
4192
  * value is in having ONE function both the x402 and ILP paths call, not
4125
4193
  * in complex logic.
4126
4194
  *
@@ -4618,4 +4686,4 @@ declare function selectLatestAddressable<T extends Event>(events: T[]): T | unde
4618
4686
  */
4619
4687
  declare const VERSION = "0.1.0";
4620
4688
 
4621
- export { AddressRegistry, type AgentRuntimeClient, ArDrivePeerRegistry, AttestationBootstrap, type AttestationBootstrapConfig, type AttestationBootstrapEvent, type AttestationBootstrapEventListener, type AttestationBootstrapResult, type AttestationEventOptions, AttestationState, AttestationVerifier, type AttestationVerifierConfig, type AttestedResultVerificationOptions, type AttestedResultVerificationResult, AttestedResultVerifier, BLOB_STORAGE_REQUEST_KIND, BLOB_STORAGE_RESULT_KIND, type BlobStorageRequestParams, type BootstrapConfig, BootstrapError, type BootstrapEvent, type BootstrapEventListener, type BootstrapPhase, type BootstrapResult, BootstrapService, type BootstrapServiceConfig, type BtpHandshakeExtension, type BuildIlpPeerInfoOptions, type BuildIlpPrepareParams, CHAIN_PRESETS, type CalculateRouteAmountParams, type ChainName, type ChainPreset, type ChainProviderConfigEntry, type ChainType, type ChannelState, type ClientNetworkPresets, type ConnectorAdminClient, type ConnectorAdminLike, type ConnectorChannelClient, type ConnectorChannelLike, type ConnectorNodeLike, type CustomEndpoints, type DeriveFromKmsSeedOptions, type DeterminismReport, type DirectRuntimeClientConfig, type DiscoveredPeer, type DiscoveryTracker, type DiscoveryTrackerConfig, type DvmJobStatus, type EVMProviderConfigEntry, EXPIRATION_TAG, type EmbeddableConnectorLike, type ForbiddenPattern, type GenesisPeer, GenesisPeerLoader, type HandlePacketAcceptResponse, type HandlePacketRejectResponse, type HandlePacketRequest, type HandlePacketResponse, ILP_PEER_INFO_KIND, ILP_ROOT_PREFIX, ILP_TO_SEMANTIC, IMAGE_GENERATION_KIND, type IlpClient, type IlpPeerInfo, type IlpPreparePacket, type IlpSendResult, JOB_FEEDBACK_KIND, JOB_REQUEST_KIND_BASE, JOB_RESULT_KIND_BASE, JOB_REVIEW_KIND, type JobFeedbackParams, type JobRequestParams, type JobResultParams, type JobReviewParams, KmsIdentityError, type KmsKeypair, type KnownPeer, type LogEntry, type LogLevel, type Logger, type LoggerConfig, MINA_CHAIN_PRESETS, MOCK_USDC_ADDRESS, MOCK_USDC_CONFIG, type MinaChainName, type MinaChainPreset, type MinaProviderConfigEntry, type MockUsdcConfig, type MultiChainName, type NetworkFamilyStatus, type NetworkMode, type NetworkNodeEnv, type NetworkProfile, type NixBuildResult, NixBuilder, type NixBuilderConfig, NostrPeerDiscovery, type OpenChannelParams, type OpenChannelResult, PET_INTERACTION_EVENT_KIND, PET_INTERACTION_REQUEST_KIND, PET_INTERACTION_RESULT_KIND, PREFIX_CLAIM_KIND, PREFIX_GRANT_KIND, type PacketHandler, type ParsedAttestation, type ParsedBlobStorageRequest, type ParsedJobFeedback, type ParsedJobRequest, type ParsedJobResult, type ParsedJobReview, type ParsedSwarmRequest, type ParsedSwarmSelection, type ParsedWorkflowDefinition, type ParsedWotDeclaration, PcrReproducibilityError, type PcrReproducibilityResult, type PeerDescriptor, type PrefixClaimContent, type PrefixGrantContent, type PrefixValidationResult, type PublishSeedRelayConfig, RELAY_ONLY_CHAIN, type RegisterPeerParams, type ReputationScore, ReputationScoreCalculator, type ReputationSignals, type ResolveRouteFeesParams, type ResolveRouteFeesResult, SEED_RELAY_LIST_KIND, SERVICE_DISCOVERY_KIND, SOLANA_CHAIN_PRESETS, SeedRelayDiscovery, type SeedRelayDiscoveryConfig, type SeedRelayDiscoveryResult, type SeedRelayEntry, type SendPacketParams, type SendPacketResult, type ServiceDiscoveryContent, type SettlementConfig, type SkillDescriptor, type SocialDiscoveryEvent, type SocialDiscoveryEventListener, SocialPeerDiscovery, type SocialPeerDiscoveryConfig, type SolanaChainName, type SolanaChainPreset, type SolanaProviderConfigEntry, type Subscription, type SwapPair, type SwarmRequestParams, type SwarmSelectionParams, TEE_ATTESTATION_KIND, TEXT_GENERATION_KIND, TEXT_TO_SPEECH_KIND, TRANSLATION_KIND, type TeeAttestation, ToonError, type ToonNode, type ToonNodeConfig, type ToonNodeStartResult, UI_RENDERER_KIND, UI_TAG, USDC_DECIMALS, USDC_NAME, USDC_SYMBOL, type UiCoordinate, VERSION, type VerificationResult, type VerifyOptions, type Violation, WEB_OF_TRUST_KIND, WORKFLOW_CHAIN_KIND, type WorkflowDefinitionParams, type WorkflowStep, type WotDeclarationParams, analyzeDockerfileForNonDeterminism, assignAddressFromHandshake, balanceProofFieldsMina, balanceProofHashEvm, balanceProofHashSolana, base58Decode, base58Encode, bigintToBytes32BE, buildAttestationEvent, buildBlobStorageRequest, buildEip712Domain, buildEvmProviderEntry, buildIlpPeerInfoEvent, buildIlpPrepare, buildJobFeedbackEvent, buildJobRequestEvent, buildJobResultEvent, buildJobReviewEvent, buildMinaProviderEntry, buildPrefixClaimEvent, buildPrefixGrantEvent, buildPrefixHandshakeData, buildSeedRelayListEvent, buildServiceDiscoveryEvent, buildSolanaProviderEntry, buildSwarmRequestEvent, buildSwarmSelectionEvent, buildUiCoordinate, buildWorkflowDefinitionEvent, buildWotDeclarationEvent, calculateRouteAmount, checkAddressCollision, concatBytes, createAgentRuntimeClient, createDirectChannelClient, createDirectConnectorAdmin, createDirectIlpClient, createDirectRuntimeClient, createDiscoveryTracker, createHttpChannelClient, createHttpConnectorAdmin, createHttpIlpClient$1 as createHttpIlpClient, createHttpRuntimeClient, createHttpIlpClient as createHttpRuntimeClientV2, createLogger, createToonNode, deriveChildAddress, deriveFromKmsSeed, deriveMinaPublicKeyBase58, extractPrefixFromHandshake, getEventExpiration, getUiCoordinate, hasMinReputation, hasRequireAttestation, hexToBytes, hexToMinaBase58PrivateKey, ilpCodeToSemantic, isEventExpired, isGenesisNode, isValidIlpAddressStructure, minaHashToField, negotiateSettlementChain, parseAttestation, parseBlobStorageRequest, parseIlpPeerInfo, parseJobFeedback, parseJobRequest, parseJobResult, parseJobReview, parsePrefixClaimEvent, parsePrefixGrantEvent, parseSeedRelayList, parseServiceDiscovery, parseSwarmRequest, parseSwarmSelection, parseUiCoordinate, parseWorkflowDefinition, parseWotDeclaration, publishSeedRelayEntry, readDockerfileNix, resolveChainConfig, resolveClientNetwork, resolveMinaChainConfig, resolveNetworkProfile, resolveRouteFees, resolveSolanaChainConfig, resolveTokenForChain, selectLatestAddressable, validateChainId, validateIlpAddress, validatePrefix, validatePrefixConsistency, verifyPcrReproducibility };
4689
+ export { AddressRegistry, type AgentRuntimeClient, ArDrivePeerRegistry, AttestationBootstrap, type AttestationBootstrapConfig, type AttestationBootstrapEvent, type AttestationBootstrapEventListener, type AttestationBootstrapResult, type AttestationEventOptions, AttestationState, AttestationVerifier, type AttestationVerifierConfig, type AttestedResultVerificationOptions, type AttestedResultVerificationResult, AttestedResultVerifier, BLOB_STORAGE_REQUEST_KIND, BLOB_STORAGE_RESULT_KIND, type BlobStorageRequestParams, type BootstrapConfig, BootstrapError, type BootstrapEvent, type BootstrapEventListener, type BootstrapPhase, type BootstrapResult, BootstrapService, type BootstrapServiceConfig, type BtpHandshakeExtension, type BuildIlpPeerInfoOptions, type BuildIlpPrepareParams, CHAIN_PRESETS, type CalculateRouteAmountParams, type ChainName, type ChainPreset, type ChainProviderConfigEntry, type ChainType, type ChannelState, type ClientNetworkPresets, type ConnectorAdminClient, type ConnectorAdminLike, type ConnectorChannelClient, type ConnectorChannelLike, type ConnectorNodeLike, type CustomEndpoints, type DeriveFromKmsSeedOptions, type DeterminismReport, type DirectRuntimeClientConfig, type DiscoveredPeer, type DiscoveryTracker, type DiscoveryTrackerConfig, type DvmJobStatus, type EVMProviderConfigEntry, EXPIRATION_TAG, type EmbeddableConnectorLike, type ForbiddenPattern, type GenesisPeer, GenesisPeerLoader, type HandlePacketAcceptResponse, type HandlePacketRejectResponse, type HandlePacketRequest, type HandlePacketResponse, ILP_PEER_INFO_KIND, ILP_ROOT_PREFIX, ILP_TO_SEMANTIC, IMAGE_GENERATION_KIND, type IlpClient, type IlpPeerInfo, type IlpPreparePacket, type IlpSendResult, JOB_FEEDBACK_KIND, JOB_REQUEST_KIND_BASE, JOB_RESULT_KIND_BASE, JOB_REVIEW_KIND, type JobFeedbackParams, type JobRequestParams, type JobResultParams, type JobReviewParams, KmsIdentityError, type KmsKeypair, type KnownPeer, type LogEntry, type LogLevel, type Logger, type LoggerConfig, MINA_CHAIN_PRESETS, MOCK_USDC_ADDRESS, MOCK_USDC_CONFIG, type MinaChainName, type MinaChainPreset, type MinaProviderConfigEntry, type MockUsdcConfig, type MultiChainName, type NetworkFamilyStatus, type NetworkMode, type NetworkNodeEnv, type NetworkProfile, type NixBuildResult, NixBuilder, type NixBuilderConfig, NostrPeerDiscovery, type OpenChannelParams, type OpenChannelResult, PET_INTERACTION_EVENT_KIND, PET_INTERACTION_REQUEST_KIND, PET_INTERACTION_RESULT_KIND, PREFIX_CLAIM_KIND, PREFIX_GRANT_KIND, type PacketHandler, type ParsedAttestation, type ParsedBlobStorageRequest, type ParsedJobFeedback, type ParsedJobRequest, type ParsedJobResult, type ParsedJobReview, type ParsedSwarmRequest, type ParsedSwarmSelection, type ParsedWorkflowDefinition, type ParsedWotDeclaration, PcrReproducibilityError, type PcrReproducibilityResult, type PeerDescriptor, type PrefixClaimContent, type PrefixGrantContent, type PrefixValidationResult, type PublishSeedRelayConfig, RELAY_ONLY_CHAIN, type RegisterPeerParams, type ReputationScore, ReputationScoreCalculator, type ReputationSignals, type ResolveRouteFeesParams, type ResolveRouteFeesResult, SEED_RELAY_LIST_KIND, SERVICE_DISCOVERY_KIND, SOLANA_CHAIN_PRESETS, SeedRelayDiscovery, type SeedRelayDiscoveryConfig, type SeedRelayDiscoveryResult, type SeedRelayEntry, type SendPacketParams, type SendPacketResult, type ServiceDiscoveryContent, type SettlementConfig, type SkillDescriptor, type SocialDiscoveryEvent, type SocialDiscoveryEventListener, SocialPeerDiscovery, type SocialPeerDiscoveryConfig, type SolanaChainName, type SolanaChainPreset, type SolanaProviderConfigEntry, type Subscription, type SwapPair, type SwarmRequestParams, type SwarmSelectionParams, TEE_ATTESTATION_KIND, TEXT_GENERATION_KIND, TEXT_TO_SPEECH_KIND, TRANSLATION_KIND, type TeeAttestation, ToonError, type ToonNode, type ToonNodeConfig, type ToonNodeStartResult, UI_RENDERER_KIND, UI_TAG, USDC_DECIMALS, USDC_NAME, USDC_SYMBOL, type UiCoordinate, VERSION, type VerificationResult, type VerifyOptions, type Violation, WEB_OF_TRUST_KIND, WORKFLOW_CHAIN_KIND, type WorkflowDefinitionParams, type WorkflowStep, type WotDeclarationParams, analyzeDockerfileForNonDeterminism, assignAddressFromHandshake, balanceProofFieldsMina, balanceProofHashEvm, balanceProofHashSolana, base58Decode, base58Encode, bigintToBytes32BE, buildAttestationEvent, buildBlobStorageRequest, buildEip712Domain, buildEvmProviderEntry, buildIlpPeerInfoEvent, buildIlpPrepare, buildJobFeedbackEvent, buildJobRequestEvent, buildJobResultEvent, buildJobReviewEvent, buildMinaProviderEntry, buildPrefixClaimEvent, buildPrefixGrantEvent, buildPrefixHandshakeData, buildSeedRelayListEvent, buildServiceDiscoveryEvent, buildSolanaProviderEntry, buildSwarmRequestEvent, buildSwarmSelectionEvent, buildUiCoordinate, buildWorkflowDefinitionEvent, buildWotDeclarationEvent, calculateRouteAmount, checkAddressCollision, concatBytes, coopCloseHashEvm, createAgentRuntimeClient, createDirectChannelClient, createDirectConnectorAdmin, createDirectIlpClient, createDirectRuntimeClient, createDiscoveryTracker, createHttpChannelClient, createHttpConnectorAdmin, createHttpIlpClient$1 as createHttpIlpClient, createHttpRuntimeClient, createHttpIlpClient as createHttpRuntimeClientV2, createLogger, createToonNode, deriveChildAddress, deriveFromKmsSeed, deriveMinaPublicKeyBase58, eip712DomainSeparatorEvm, extractPrefixFromHandshake, getEventExpiration, getUiCoordinate, hasMinReputation, hasRequireAttestation, hexToBytes, hexToMinaBase58PrivateKey, ilpCodeToSemantic, isEventExpired, isGenesisNode, isValidIlpAddressStructure, minaHashToField, negotiateSettlementChain, parseAttestation, parseBlobStorageRequest, parseIlpPeerInfo, parseJobFeedback, parseJobRequest, parseJobResult, parseJobReview, parsePrefixClaimEvent, parsePrefixGrantEvent, parseSeedRelayList, parseServiceDiscovery, parseSwarmRequest, parseSwarmSelection, parseUiCoordinate, parseWorkflowDefinition, parseWotDeclaration, publishSeedRelayEntry, readDockerfileNix, resolveChainConfig, resolveClientNetwork, resolveMinaChainConfig, resolveNetworkProfile, resolveRouteFees, resolveSolanaChainConfig, resolveTokenForChain, selectLatestAddressable, validateChainId, validateIlpAddress, validatePrefix, validatePrefixConsistency, verifyPcrReproducibility };
package/dist/index.js CHANGED
@@ -2269,6 +2269,29 @@ function deduplicateByPubkey(peers) {
2269
2269
  return [...map.values()];
2270
2270
  }
2271
2271
  function loadGenesisPeers() {
2272
+ const envOverride = process.env["TOON_GENESIS_PEERS"];
2273
+ if (envOverride !== void 0) {
2274
+ let parsed;
2275
+ try {
2276
+ parsed = JSON.parse(envOverride);
2277
+ } catch {
2278
+ console.warn("Failed to parse TOON_GENESIS_PEERS JSON:", envOverride);
2279
+ return [];
2280
+ }
2281
+ if (!Array.isArray(parsed)) {
2282
+ console.warn("TOON_GENESIS_PEERS JSON is not an array");
2283
+ return [];
2284
+ }
2285
+ const valid2 = [];
2286
+ for (const entry of parsed) {
2287
+ if (isValidGenesisPeer(entry)) {
2288
+ valid2.push(entry);
2289
+ } else {
2290
+ console.warn("Skipping invalid TOON_GENESIS_PEERS entry:", entry);
2291
+ }
2292
+ }
2293
+ return deduplicateByPubkey(valid2);
2294
+ }
2272
2295
  const raw = genesis_peers_default;
2273
2296
  const valid = [];
2274
2297
  for (const entry of raw) {
@@ -2964,15 +2987,88 @@ function concatBytes(...parts) {
2964
2987
  }
2965
2988
  return out;
2966
2989
  }
2967
- function balanceProofHashEvm(channelIdBytes, cumulativeAmount, nonce, recipientBytes) {
2990
+ var EIP712_PREFIX = new Uint8Array([25, 1]);
2991
+ var EIP712DOMAIN_TYPEHASH = keccak_256(
2992
+ new TextEncoder().encode(
2993
+ "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
2994
+ )
2995
+ );
2996
+ var DOMAIN_NAME_HASH = keccak_256(new TextEncoder().encode("RollingSwapChannel"));
2997
+ var DOMAIN_VERSION_HASH = keccak_256(new TextEncoder().encode("2"));
2998
+ var CLAIM_TYPEHASH = keccak_256(
2999
+ new TextEncoder().encode(
3000
+ "ClaimBalanceProof(bytes32 channelId,uint256 cumulativeAmount,uint256 nonce,address recipient)"
3001
+ )
3002
+ );
3003
+ var COOP_CLOSE_TYPEHASH = keccak_256(
3004
+ new TextEncoder().encode(
3005
+ "CooperativeClose(bytes32 channelId,uint256 cumulativeAmount,uint256 nonce)"
3006
+ )
3007
+ );
3008
+ function leftPad32(bytes) {
3009
+ if (bytes.length > 32) {
3010
+ throw new Error(`cannot left-pad ${bytes.length} bytes into 32`);
3011
+ }
3012
+ const out = new Uint8Array(32);
3013
+ out.set(bytes, 32 - bytes.length);
3014
+ return out;
3015
+ }
3016
+ function eip712DomainSeparatorEvm(chainId, verifyingContractBytes) {
3017
+ if (verifyingContractBytes.length !== 20) {
3018
+ throw new Error(
3019
+ `verifyingContract must be 20 bytes (got ${verifyingContractBytes.length})`
3020
+ );
3021
+ }
2968
3022
  return keccak_256(
2969
3023
  concatBytes(
3024
+ EIP712DOMAIN_TYPEHASH,
3025
+ DOMAIN_NAME_HASH,
3026
+ DOMAIN_VERSION_HASH,
3027
+ bigintToBytes32BE(chainId),
3028
+ leftPad32(verifyingContractBytes)
3029
+ )
3030
+ );
3031
+ }
3032
+ function eip712Digest(domainSeparator, structHash) {
3033
+ return keccak_256(concatBytes(EIP712_PREFIX, domainSeparator, structHash));
3034
+ }
3035
+ function balanceProofHashEvm(channelIdBytes, cumulativeAmount, nonce, recipientBytes, chainId, verifyingContractBytes) {
3036
+ if (channelIdBytes.length !== 32) {
3037
+ throw new Error(`channelId must be 32 bytes (got ${channelIdBytes.length})`);
3038
+ }
3039
+ if (recipientBytes.length !== 20) {
3040
+ throw new Error(`recipient must be 20 bytes (got ${recipientBytes.length})`);
3041
+ }
3042
+ const structHash = keccak_256(
3043
+ concatBytes(
3044
+ CLAIM_TYPEHASH,
2970
3045
  channelIdBytes,
2971
3046
  bigintToBytes32BE(cumulativeAmount),
2972
3047
  bigintToBytes32BE(nonce),
2973
- recipientBytes
3048
+ leftPad32(recipientBytes)
3049
+ )
3050
+ );
3051
+ return eip712Digest(
3052
+ eip712DomainSeparatorEvm(chainId, verifyingContractBytes),
3053
+ structHash
3054
+ );
3055
+ }
3056
+ function coopCloseHashEvm(channelIdBytes, cumulativeAmount, nonce, chainId, verifyingContractBytes) {
3057
+ if (channelIdBytes.length !== 32) {
3058
+ throw new Error(`channelId must be 32 bytes (got ${channelIdBytes.length})`);
3059
+ }
3060
+ const structHash = keccak_256(
3061
+ concatBytes(
3062
+ COOP_CLOSE_TYPEHASH,
3063
+ channelIdBytes,
3064
+ bigintToBytes32BE(cumulativeAmount),
3065
+ bigintToBytes32BE(nonce)
2974
3066
  )
2975
3067
  );
3068
+ return eip712Digest(
3069
+ eip712DomainSeparatorEvm(chainId, verifyingContractBytes),
3070
+ structHash
3071
+ );
2976
3072
  }
2977
3073
  function balanceProofHashSolana(channelId, cumulativeAmount, nonce, recipient) {
2978
3074
  return sha256(
@@ -4004,7 +4100,10 @@ function createHttpIlpClient(baseUrl) {
4004
4100
  destination: params.destination,
4005
4101
  amount: params.amount,
4006
4102
  data: params.data,
4007
- ...params.timeout !== void 0 && { timeout: params.timeout }
4103
+ ...params.timeout !== void 0 && { timeout: params.timeout },
4104
+ ...params.expiresAt !== void 0 && {
4105
+ expiresAt: params.expiresAt
4106
+ }
4008
4107
  })
4009
4108
  });
4010
4109
  } catch (error) {
@@ -4039,11 +4138,17 @@ function createDirectIlpClient(connector, _config) {
4039
4138
  try {
4040
4139
  const amount = BigInt(params.amount);
4041
4140
  const data = Uint8Array.from(Buffer.from(params.data, "base64"));
4141
+ const expiresAt = params.expiresAt ? new Date(params.expiresAt) : new Date(Date.now() + 3e4);
4142
+ if (Number.isNaN(expiresAt.getTime())) {
4143
+ throw new BootstrapError(
4144
+ `Invalid expiresAt: ${params.expiresAt} is not a parseable date`
4145
+ );
4146
+ }
4042
4147
  const result = await connector.sendPacket({
4043
4148
  destination: params.destination,
4044
4149
  amount,
4045
4150
  data,
4046
- expiresAt: new Date(Date.now() + 3e4)
4151
+ expiresAt
4047
4152
  });
4048
4153
  if (result.type === "fulfill" || result.type === 13) {
4049
4154
  return {
@@ -4210,7 +4315,10 @@ function createHttpIlpClient2(connectorUrl) {
4210
4315
  body: JSON.stringify({
4211
4316
  destination: params.destination,
4212
4317
  amount: params.amount,
4213
- data: params.data
4318
+ data: params.data,
4319
+ ...params.expiresAt !== void 0 && {
4320
+ expiresAt: params.expiresAt
4321
+ }
4214
4322
  }),
4215
4323
  signal: params.timeout ? AbortSignal.timeout(params.timeout) : void 0
4216
4324
  });
@@ -4974,7 +5082,10 @@ function buildIlpPrepare(params) {
4974
5082
  return {
4975
5083
  destination: params.destination,
4976
5084
  amount: String(params.amount),
4977
- data: Buffer.from(params.data).toString("base64")
5085
+ data: Buffer.from(params.data).toString("base64"),
5086
+ ...params.expiresAt !== void 0 && {
5087
+ expiresAt: params.expiresAt.toISOString()
5088
+ }
4978
5089
  };
4979
5090
  }
4980
5091
 
@@ -5476,6 +5587,7 @@ export {
5476
5587
  calculateRouteAmount,
5477
5588
  checkAddressCollision,
5478
5589
  concatBytes,
5590
+ coopCloseHashEvm,
5479
5591
  createAgentRuntimeClient,
5480
5592
  createDirectChannelClient,
5481
5593
  createDirectConnectorAdmin,
@@ -5493,6 +5605,7 @@ export {
5493
5605
  deriveChildAddress,
5494
5606
  deriveFromKmsSeed,
5495
5607
  deriveMinaPublicKeyBase58,
5608
+ eip712DomainSeparatorEvm,
5496
5609
  encodeEventToToon,
5497
5610
  encodeEventToToonString,
5498
5611
  extractPrefixFromHandshake,