@toon-protocol/client 0.16.0 → 0.18.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/index.d.ts +439 -28
- package/dist/index.js +630 -99
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as _toon_protocol_core from '@toon-protocol/core';
|
|
2
|
-
import { IlpPeerInfo, IlpClient,
|
|
2
|
+
import { IlpPeerInfo, IlpSendResult, IlpClient, SwapPair, NetworkFamilyStatus, ConnectorAdminClient, ConnectorChannelClient, OpenChannelParams, OpenChannelResult, ChannelState } from '@toon-protocol/core';
|
|
3
3
|
export { UI_RENDERER_KIND, UI_TAG, UiCoordinate, buildUiCoordinate, getUiCoordinate, parseUiCoordinate, selectLatestAddressable } from '@toon-protocol/core';
|
|
4
4
|
import { NostrEvent, EventTemplate } from 'nostr-tools/pure';
|
|
5
|
-
import {
|
|
5
|
+
import { MinaSignerClientLike, SettlementBundle } from '@toon-protocol/sdk';
|
|
6
|
+
import { AccumulatedClaim } from '@toon-protocol/sdk/swap';
|
|
7
|
+
import { PrivateKeyAccount, Hex } from 'viem';
|
|
8
|
+
import { PrivateKeyAccount as PrivateKeyAccount$1 } from 'viem/accounts';
|
|
6
9
|
export { A2uiDecision, ConsentDecision, ConsentRequest, DispatchGuardInfo, DispatchInput, GenerateContext, GeneratedRenderer, GenerativeDecision, GenerativeFallbackOptions, GenerativeFallbackRenderer, GenerativeFallbackResult, GuardedDispatchInput, IntentClassification, KindRegistry, MIME_A2UI, MIME_MCP_APP, McpUiDecision, NativeDecision, PublishBackOptions, RenderBranch, RenderDecision, RenderTrust, RendererGenerator, RendererPin, RendererPinStore, RendererPublisher, RendererSigner, ResolvedCoordinate, SwapApproval, SwapDecision, SwapRejection, SwapRejectionReason, UiResource, VerifyRendererInput, WidgetIntent, buildConsentRequest, buildRendererEventTemplate, classifyIntent, deterministicGenerator, extractUiResource, guardedRenderDispatch, isTrustDowngrade, publishBackCoordinate, renderDeterministicHtml, renderDispatch, resolveRendererMime, resolveUiCoordinate, resolveUiRenderer, verifyRendererTrust } from './render/index.js';
|
|
7
10
|
|
|
8
11
|
/** One on-chain wallet token balance. `amount` is base-unit integer, decimal. */
|
|
@@ -640,6 +643,63 @@ declare function requestBlobStorage(client: ToonClient, secretKey: Uint8Array, p
|
|
|
640
643
|
*/
|
|
641
644
|
declare function extractArweaveTxId(base64Data: string): string;
|
|
642
645
|
|
|
646
|
+
/**
|
|
647
|
+
* Shared sender-side plumbing for sender-chosen execution conditions
|
|
648
|
+
* (toon-client#350; contract: connector `docs/local-delivery-fulfillment-contract.md`,
|
|
649
|
+
* connector#309; spec: toon-meta `docs/rolling-swap.md` §3).
|
|
650
|
+
*
|
|
651
|
+
* Both ILP transports (HTTP `POST /ilp` and BTP) take the SAME extended send
|
|
652
|
+
* params and map FULFILL/REJECT responses through the SAME verifier so the
|
|
653
|
+
* two paths cannot drift:
|
|
654
|
+
*
|
|
655
|
+
* - absent/all-zero `executionCondition` → legacy class: today's behavior,
|
|
656
|
+
* byte-for-byte (zero condition on the wire, no FULFILL verification);
|
|
657
|
+
* - non-zero `executionCondition` → sender-chosen: the condition goes on
|
|
658
|
+
* the PREPARE verbatim and the FULFILL's 32-byte fulfillment MUST hash
|
|
659
|
+
* back to it — a missing/malformed/mismatching preimage is surfaced as a
|
|
660
|
+
* FAILED result (never a silent accept, never retried).
|
|
661
|
+
*/
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Send parameters accepted by both ILP transports. Extends the
|
|
665
|
+
* `@toon-protocol/core` `IlpClient` param shape with the sender-chosen
|
|
666
|
+
* condition and an explicit expiry — plain `IlpClient` callers keep working
|
|
667
|
+
* unchanged (both extras are optional; omitting them is the legacy path).
|
|
668
|
+
*/
|
|
669
|
+
interface IlpSendParams {
|
|
670
|
+
destination: string;
|
|
671
|
+
amount: string;
|
|
672
|
+
/** Base64 ILP `data` payload. */
|
|
673
|
+
data: string;
|
|
674
|
+
/** Transport timeout in ms; also the default expiry window. */
|
|
675
|
+
timeout?: number;
|
|
676
|
+
/**
|
|
677
|
+
* Sender-chosen 32-byte execution condition `C = sha256(P)` (spec R2).
|
|
678
|
+
* Absent or all-zero = legacy unverified packet (default — ordinary
|
|
679
|
+
* publish/upload writes MUST keep this default).
|
|
680
|
+
*/
|
|
681
|
+
executionCondition?: Uint8Array;
|
|
682
|
+
/**
|
|
683
|
+
* Explicit PREPARE `expiresAt` (spec R7). Defaults to `now + timeout`,
|
|
684
|
+
* preserving pre-#350 behavior. Accepts a `Date` or an ISO 8601 string —
|
|
685
|
+
* `@toon-protocol/core` ≥2.1.0's `IlpClient` passes the string form.
|
|
686
|
+
*/
|
|
687
|
+
expiresAt?: Date | string;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* `IlpSendResult` plus the FULFILL preimage when a sender-chosen condition
|
|
691
|
+
* was verified. Only populated on the sender-chosen path so legacy result
|
|
692
|
+
* objects stay byte-identical.
|
|
693
|
+
*/
|
|
694
|
+
interface IlpSendResultWithFulfillment extends IlpSendResult {
|
|
695
|
+
/** Base64 32-byte fulfillment preimage (verified: sha256 == condition). */
|
|
696
|
+
fulfillment?: string;
|
|
697
|
+
}
|
|
698
|
+
/** ILP code used for a client-side fulfillment-verification failure. */
|
|
699
|
+
declare const FULFILLMENT_MISMATCH_CODE = "F99";
|
|
700
|
+
/** Message for a client-side fulfillment-verification failure. */
|
|
701
|
+
declare const FULFILLMENT_MISMATCH_MESSAGE: string;
|
|
702
|
+
|
|
643
703
|
interface BtpRuntimeClientConfig {
|
|
644
704
|
btpUrl: string;
|
|
645
705
|
peerId: string;
|
|
@@ -676,23 +736,22 @@ declare class BtpRuntimeClient implements IlpClient {
|
|
|
676
736
|
/**
|
|
677
737
|
* Sends an ILP packet via BTP with auto-reconnect on connection errors.
|
|
678
738
|
* Satisfies IlpClient interface.
|
|
739
|
+
*
|
|
740
|
+
* `params` may carry a sender-chosen `executionCondition` and an explicit
|
|
741
|
+
* `expiresAt` (toon-client#350); omitting both is the legacy zero-condition
|
|
742
|
+
* path, unchanged. With a non-zero condition the FULFILL preimage is
|
|
743
|
+
* verified (`sha256(fulfillment) == condition`) and a mismatch is surfaced
|
|
744
|
+
* as a failed result — see `mapIlpResponse`.
|
|
679
745
|
*/
|
|
680
|
-
sendIlpPacket(params:
|
|
681
|
-
destination: string;
|
|
682
|
-
amount: string;
|
|
683
|
-
data: string;
|
|
684
|
-
timeout?: number;
|
|
685
|
-
}): Promise<IlpSendResult>;
|
|
746
|
+
sendIlpPacket(params: IlpSendParams): Promise<IlpSendResult>;
|
|
686
747
|
/**
|
|
687
748
|
* Sends a balance proof claim via BTP protocol data, then sends an ILP packet.
|
|
688
749
|
* Auto-reconnects on connection errors.
|
|
750
|
+
*
|
|
751
|
+
* Sender-chosen `executionCondition` / explicit `expiresAt` semantics are
|
|
752
|
+
* identical to {@link sendIlpPacket}.
|
|
689
753
|
*/
|
|
690
|
-
sendIlpPacketWithClaim(params:
|
|
691
|
-
destination: string;
|
|
692
|
-
amount: string;
|
|
693
|
-
data: string;
|
|
694
|
-
timeout?: number;
|
|
695
|
-
}, claim: Record<string, unknown>): Promise<IlpSendResult>;
|
|
754
|
+
sendIlpPacketWithClaim(params: IlpSendParams, claim: Record<string, unknown>): Promise<IlpSendResult>;
|
|
696
755
|
/**
|
|
697
756
|
* Send a standalone `payment-channel-claim` BTP MESSAGE (no ILP packet
|
|
698
757
|
* attached). The connector's ClaimReceiver consumes this fire-and-forget
|
|
@@ -701,6 +760,14 @@ declare class BtpRuntimeClient implements IlpClient {
|
|
|
701
760
|
*/
|
|
702
761
|
sendClaimMessage(claim: Record<string, unknown>): Promise<void>;
|
|
703
762
|
private _sendClaimMessageOnce;
|
|
763
|
+
/**
|
|
764
|
+
* Build the ILP PREPARE for a send, applying the sender-chosen condition /
|
|
765
|
+
* explicit expiry when provided (toon-client#350) and validating that a
|
|
766
|
+
* non-zero condition is exactly 32 bytes (the OER serializer would
|
|
767
|
+
* otherwise silently zero-fill it, downgrading the packet to the legacy
|
|
768
|
+
* unverified class).
|
|
769
|
+
*/
|
|
770
|
+
private buildPrepare;
|
|
704
771
|
/**
|
|
705
772
|
* Single-attempt ILP packet send. Reconnects if not connected.
|
|
706
773
|
*/
|
|
@@ -792,25 +859,24 @@ declare class HttpIlpClient implements IlpClient {
|
|
|
792
859
|
* Send an ILP PREPARE via `POST /ilp` WITHOUT a claim. The connector accepts
|
|
793
860
|
* this only on free/zero-amount routes; paid writes must use
|
|
794
861
|
* {@link sendIlpPacketWithClaim}. Satisfies the IlpClient interface.
|
|
862
|
+
*
|
|
863
|
+
* `params` may carry a sender-chosen `executionCondition` and an explicit
|
|
864
|
+
* `expiresAt` (toon-client#350); omitting both is the legacy zero-condition
|
|
865
|
+
* path, unchanged. With a non-zero condition the FULFILL preimage is
|
|
866
|
+
* verified (`sha256(fulfillment) == condition`) and a mismatch is surfaced
|
|
867
|
+
* as a failed result — see {@link mapIlpResponse}.
|
|
795
868
|
*/
|
|
796
|
-
sendIlpPacket(params:
|
|
797
|
-
destination: string;
|
|
798
|
-
amount: string;
|
|
799
|
-
data: string;
|
|
800
|
-
timeout?: number;
|
|
801
|
-
}): Promise<IlpSendResult>;
|
|
869
|
+
sendIlpPacket(params: IlpSendParams): Promise<IlpSendResult>;
|
|
802
870
|
/**
|
|
803
871
|
* Send an ILP PREPARE via `POST /ilp` with the payment-channel claim attached
|
|
804
872
|
* as the `ILP-Payment-Channel-Claim` header. `claim` is the SAME JSON object
|
|
805
873
|
* the BTP path attaches as the `payment-channel-claim` protocolData entry —
|
|
806
874
|
* we base64(JSON.stringify(claim)) it, byte-for-byte identical to BTP.
|
|
875
|
+
*
|
|
876
|
+
* Sender-chosen `executionCondition` / explicit `expiresAt` semantics are
|
|
877
|
+
* identical to {@link sendIlpPacket}.
|
|
807
878
|
*/
|
|
808
|
-
sendIlpPacketWithClaim(params:
|
|
809
|
-
destination: string;
|
|
810
|
-
amount: string;
|
|
811
|
-
data: string;
|
|
812
|
-
timeout?: number;
|
|
813
|
-
}, claim: unknown): Promise<IlpSendResult>;
|
|
879
|
+
sendIlpPacketWithClaim(params: IlpSendParams, claim: unknown): Promise<IlpSendResult>;
|
|
814
880
|
/**
|
|
815
881
|
* Upgrade to a duplex BTP session over the SAME endpoint.
|
|
816
882
|
*
|
|
@@ -838,6 +904,10 @@ declare class HttpIlpClient implements IlpClient {
|
|
|
838
904
|
* Map a `200 OK` body (OER FULFILL/REJECT) to an IlpSendResult; map a non-2xx
|
|
839
905
|
* to a transport error. Per the wire contract, ILP-level rejects arrive as a
|
|
840
906
|
* 200 + REJECT body — only HTTP non-2xx means a transport-layer failure.
|
|
907
|
+
*
|
|
908
|
+
* When `sentCondition` is non-zero the FULFILL preimage is verified against
|
|
909
|
+
* it; a mismatch yields `accepted: false` (shared `mapIlpResponse` logic,
|
|
910
|
+
* identical to the BTP path).
|
|
841
911
|
*/
|
|
842
912
|
private mapResponse;
|
|
843
913
|
private mapTransportError;
|
|
@@ -1051,6 +1121,173 @@ declare function serializeHttpRequest(req: {
|
|
|
1051
1121
|
*/
|
|
1052
1122
|
declare function parseHttpResponse(bytes: Uint8Array): Response;
|
|
1053
1123
|
|
|
1124
|
+
/**
|
|
1125
|
+
* The persisted receive-side watermark for one swap target channel: the
|
|
1126
|
+
* HIGHEST-NONCE verified chain-B claim per `(chain, channelId)` (toon-client
|
|
1127
|
+
* issue #352, rolling-swap spec toon-meta docs/rolling-swap.md §3.2/§9).
|
|
1128
|
+
*
|
|
1129
|
+
* Claims are cumulative balance proofs — a higher-nonce claim supersedes every
|
|
1130
|
+
* earlier one — so persisting only the winner per channel is lossless for
|
|
1131
|
+
* settlement: `buildSettlementTx` redeems exactly this claim. Superseded claims
|
|
1132
|
+
* are informational and dropped.
|
|
1133
|
+
*/
|
|
1134
|
+
interface ReceivedClaimEntry {
|
|
1135
|
+
/** Target chain the claim settles on (`pair.to.chain`, e.g. `evm:base:8453`). */
|
|
1136
|
+
chain: string;
|
|
1137
|
+
/** Payment-channel id on the target chain (0x-hex for EVM, base58 otherwise). */
|
|
1138
|
+
channelId: string;
|
|
1139
|
+
/** Balance-proof nonce (strictly increasing per channel). */
|
|
1140
|
+
nonce: bigint;
|
|
1141
|
+
/** Cumulative transferred amount, target micro-units. */
|
|
1142
|
+
cumulativeAmount: bigint;
|
|
1143
|
+
/** Recipient address the claim pays (the sender's `chainRecipient`). */
|
|
1144
|
+
recipient: string;
|
|
1145
|
+
/** Swap peer's on-chain signer address the signature verified against. */
|
|
1146
|
+
swapSignerAddress: string;
|
|
1147
|
+
/** The verified signed claim bytes (chain-specific encoding). */
|
|
1148
|
+
claimBytes: Uint8Array;
|
|
1149
|
+
/** Optional swap-side claim id. */
|
|
1150
|
+
claimId?: string;
|
|
1151
|
+
/** The SwapPair the claim was priced against (settlement-time routing). */
|
|
1152
|
+
pair: SwapPair;
|
|
1153
|
+
/** Unix ms the winning claim was accepted off the wire. */
|
|
1154
|
+
receivedAt: number;
|
|
1155
|
+
/** Unix ms this entry was last advanced. */
|
|
1156
|
+
updatedAt: number;
|
|
1157
|
+
/** Unix ms of the last successful on-chain settlement submission. */
|
|
1158
|
+
settledAt?: number;
|
|
1159
|
+
/** Watermark nonce redeemed by that settlement (claims ≤ this are settled). */
|
|
1160
|
+
settledNonce?: bigint;
|
|
1161
|
+
/** Tx hash of the last settlement submission. */
|
|
1162
|
+
settleTxHash?: string;
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Persistence interface for received (chain-B) swap claims. Mirrors
|
|
1166
|
+
* {@link ChannelStore}'s sync surface; keyed by `(chain, channelId)`.
|
|
1167
|
+
*/
|
|
1168
|
+
interface ReceivedClaimStore {
|
|
1169
|
+
save(entry: ReceivedClaimEntry): void;
|
|
1170
|
+
load(chain: string, channelId: string): ReceivedClaimEntry | undefined;
|
|
1171
|
+
list(): ReceivedClaimEntry[];
|
|
1172
|
+
delete(chain: string, channelId: string): void;
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
1175
|
+
* JSON file-backed {@link ReceivedClaimStore}. Synchronous I/O to match the
|
|
1176
|
+
* `JsonFileChannelStore` pattern (`ChannelStore.ts`); the parent directory is
|
|
1177
|
+
* created on first save so a fresh daemon home works out of the box.
|
|
1178
|
+
*/
|
|
1179
|
+
declare class JsonFileReceivedClaimStore implements ReceivedClaimStore {
|
|
1180
|
+
private readonly filePath;
|
|
1181
|
+
constructor(filePath: string);
|
|
1182
|
+
save(entry: ReceivedClaimEntry): void;
|
|
1183
|
+
load(chain: string, channelId: string): ReceivedClaimEntry | undefined;
|
|
1184
|
+
list(): ReceivedClaimEntry[];
|
|
1185
|
+
delete(chain: string, channelId: string): void;
|
|
1186
|
+
private readFile;
|
|
1187
|
+
private writeFile;
|
|
1188
|
+
}
|
|
1189
|
+
/**
|
|
1190
|
+
* In-memory {@link ReceivedClaimStore} for tests and path-less configs. NOT
|
|
1191
|
+
* restart-safe — a daemon should always be given a `JsonFileReceivedClaimStore`.
|
|
1192
|
+
*/
|
|
1193
|
+
declare class InMemoryReceivedClaimStore implements ReceivedClaimStore {
|
|
1194
|
+
private readonly entries;
|
|
1195
|
+
save(entry: ReceivedClaimEntry): void;
|
|
1196
|
+
load(chain: string, channelId: string): ReceivedClaimEntry | undefined;
|
|
1197
|
+
list(): ReceivedClaimEntry[];
|
|
1198
|
+
delete(chain: string, channelId: string): void;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
/**
|
|
1202
|
+
* Receive-side swap settlement (toon-client#352): turn persisted
|
|
1203
|
+
* {@link ReceivedClaimEntry} watermarks into on-chain settlement submissions.
|
|
1204
|
+
*
|
|
1205
|
+
* Building is pure and chain-agnostic — `buildSettlementTx` (sdk) re-verifies
|
|
1206
|
+
* the stored claim's signature and produces one {@link SettlementBundle} per
|
|
1207
|
+
* `(chain, channelId)` with the FINAL watermark, so N received advances net to
|
|
1208
|
+
* one on-chain close per channel (spec §9). Submission is chain-gated:
|
|
1209
|
+
*
|
|
1210
|
+
* - **EVM** — implemented here ({@link submitEvmSettlement}): the bundle's
|
|
1211
|
+
* unsigned RLP is decoded for `to`/calldata, gas is estimated against the
|
|
1212
|
+
* configured RPC, and the tx is signed by the client's EVM account (the
|
|
1213
|
+
* claim recipient) and broadcast. Real submission is therefore env-gated on
|
|
1214
|
+
* `chainRpcUrls[chain]` — absent RPC config yields a built-not-submitted
|
|
1215
|
+
* result, never a throw.
|
|
1216
|
+
* - **Solana** — the bundle carries a serialized Message; a submission path is
|
|
1217
|
+
* not wired yet (follow-up under toon-meta#145).
|
|
1218
|
+
* - **Mina** — receive-side redemption needs a co-sign (`claimFromChannel`
|
|
1219
|
+
* takes `signatureA` AND `signatureB`) plus o1js proof generation; the
|
|
1220
|
+
* client has no receive-side co-sign path. Explicitly out of scope for #352
|
|
1221
|
+
* (documented gap; follow-up: toon-client#357).
|
|
1222
|
+
*/
|
|
1223
|
+
|
|
1224
|
+
/** One per-channel settlement build outcome (result-shaped, never thrown). */
|
|
1225
|
+
interface SwapSettlementBuild {
|
|
1226
|
+
chain: string;
|
|
1227
|
+
channelId: string;
|
|
1228
|
+
/** The bundle, when the claim verified and the chain config sufficed. */
|
|
1229
|
+
bundle?: SettlementBundle;
|
|
1230
|
+
/** Why no bundle was produced (missing config, failed re-verification, …). */
|
|
1231
|
+
error?: {
|
|
1232
|
+
code: string;
|
|
1233
|
+
message: string;
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
interface BuildSwapSettlementsParams {
|
|
1237
|
+
/** Persisted watermarks to settle (typically `store.list()`, filtered). */
|
|
1238
|
+
entries: readonly ReceivedClaimEntry[];
|
|
1239
|
+
/**
|
|
1240
|
+
* Per-chain settlement contract: EVM TokenNetwork address / Solana
|
|
1241
|
+
* programId, keyed by the FULL chain key (e.g. `evm:base:8453`). Matches the
|
|
1242
|
+
* daemon config's `tokenNetworks` map.
|
|
1243
|
+
*/
|
|
1244
|
+
tokenNetworks?: Record<string, string>;
|
|
1245
|
+
/** Pre-loaded `mina-signer` client for `mina:*` re-verification. */
|
|
1246
|
+
minaSignerClient?: MinaSignerClientLike;
|
|
1247
|
+
}
|
|
1248
|
+
/** Rebuild the sdk `AccumulatedClaim` shape from a persisted entry. */
|
|
1249
|
+
declare function entryToAccumulatedClaim(entry: ReceivedClaimEntry): AccumulatedClaim;
|
|
1250
|
+
/**
|
|
1251
|
+
* Parse the numeric chain id off an `evm:{network}:{chainId}` / `evm:{chainId}`
|
|
1252
|
+
* chain key. Returns undefined for malformed keys (reported result-shaped).
|
|
1253
|
+
*/
|
|
1254
|
+
declare function parseEvmChainId(chain: string): number | undefined;
|
|
1255
|
+
/**
|
|
1256
|
+
* Build one settlement bundle per persisted entry via the sdk's
|
|
1257
|
+
* `buildSettlementTx` (signature re-verified at settle time — a tampered
|
|
1258
|
+
* store never reaches a submission). Per-entry isolation: one bad channel
|
|
1259
|
+
* cannot block the others.
|
|
1260
|
+
*/
|
|
1261
|
+
declare function buildSwapSettlements(params: BuildSwapSettlementsParams): SwapSettlementBuild[];
|
|
1262
|
+
interface SubmitEvmSettlementParams {
|
|
1263
|
+
/** JSON-RPC endpoint of the bundle's chain (`chainRpcUrls[bundle.chain]`). */
|
|
1264
|
+
rpcUrl: string;
|
|
1265
|
+
/** The claim recipient's EVM account (signs + pays gas for the redeem). */
|
|
1266
|
+
account: PrivateKeyAccount;
|
|
1267
|
+
/** Receipt wait bound, ms (default 60_000). */
|
|
1268
|
+
timeoutMs?: number;
|
|
1269
|
+
}
|
|
1270
|
+
interface SubmitEvmSettlementResult {
|
|
1271
|
+
txHash: string;
|
|
1272
|
+
/** Receipt status when the wait succeeded within the bound. */
|
|
1273
|
+
status?: 'success' | 'reverted';
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* Decode the unsigned legacy-RLP tx a settlement bundle carries.
|
|
1277
|
+
* Layout (EIP-155 unsigned): [nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0].
|
|
1278
|
+
*/
|
|
1279
|
+
declare function decodeEvmSettlementTx(bundle: SettlementBundle): {
|
|
1280
|
+
to: Hex;
|
|
1281
|
+
data: Hex;
|
|
1282
|
+
chainId: number;
|
|
1283
|
+
};
|
|
1284
|
+
/**
|
|
1285
|
+
* Sign + broadcast an EVM settlement bundle from the recipient's account.
|
|
1286
|
+
* Gas/nonce are read from the RPC; the tx is signed locally (non-custodial)
|
|
1287
|
+
* and sent as a raw transaction, then awaited to a receipt (bounded).
|
|
1288
|
+
*/
|
|
1289
|
+
declare function submitEvmSettlement(bundle: SettlementBundle, params: SubmitEvmSettlementParams): Promise<SubmitEvmSettlementResult>;
|
|
1290
|
+
|
|
1054
1291
|
/**
|
|
1055
1292
|
* ToonClient - High-level client for interacting with TOON network.
|
|
1056
1293
|
*
|
|
@@ -1254,6 +1491,14 @@ declare class ToonClient {
|
|
|
1254
1491
|
* matching `destination`,
|
|
1255
1492
|
* (c) neither -> throw MISSING_CLAIM.
|
|
1256
1493
|
*
|
|
1494
|
+
* A caller may supply a sender-chosen 32-byte `executionCondition`
|
|
1495
|
+
* (`C = sha256(P)`, one fresh preimage per packet — toon-client#350,
|
|
1496
|
+
* rolling-swap spec §3 R1/R2) and an explicit `expiresAt` (R7). Both are
|
|
1497
|
+
* set on the wire by either transport (HTTP `POST /ilp` and BTP), and on
|
|
1498
|
+
* FULFILL the transport verifies `sha256(fulfillment) == condition` —
|
|
1499
|
+
* a mismatch comes back as `accepted: false` (code F99), never a silent
|
|
1500
|
+
* accept. Omitting them keeps today's zero-condition legacy packet.
|
|
1501
|
+
*
|
|
1257
1502
|
* @throws {ToonClientError} INVALID_STATE / NO_ILP_TRANSPORT / MISSING_CLAIM
|
|
1258
1503
|
*/
|
|
1259
1504
|
sendSwapPacket(params: {
|
|
@@ -1262,6 +1507,10 @@ declare class ToonClient {
|
|
|
1262
1507
|
toonData: Uint8Array;
|
|
1263
1508
|
timeout?: number;
|
|
1264
1509
|
claim?: SignedBalanceProof;
|
|
1510
|
+
/** Sender-chosen 32-byte execution condition; absent/zero = legacy. */
|
|
1511
|
+
executionCondition?: Uint8Array;
|
|
1512
|
+
/** Explicit ILP expiry; defaults to `now + timeout` in the transport. */
|
|
1513
|
+
expiresAt?: Date;
|
|
1265
1514
|
}): Promise<IlpSendResult>;
|
|
1266
1515
|
/**
|
|
1267
1516
|
* Build a BTP claim message from a pre-signed balance proof using the
|
|
@@ -1393,6 +1642,19 @@ declare class ToonClient {
|
|
|
1393
1642
|
channelId: string;
|
|
1394
1643
|
txHash?: string;
|
|
1395
1644
|
}>;
|
|
1645
|
+
/**
|
|
1646
|
+
* Submit a receive-side swap settlement bundle on-chain (toon-client#352).
|
|
1647
|
+
* The bundle comes from the sdk's `buildSettlementTx` over persisted,
|
|
1648
|
+
* verified chain-B claims (`buildSwapSettlements`); this signs it with the
|
|
1649
|
+
* client's EVM account (the claim recipient) and broadcasts it.
|
|
1650
|
+
*
|
|
1651
|
+
* Env-gated seam: EVM only, and only when `chainRpcUrls[bundle.chain]` is
|
|
1652
|
+
* configured — otherwise this throws a clear config error and callers
|
|
1653
|
+
* surface a built-not-submitted result. Solana submission and the Mina
|
|
1654
|
+
* receive-side co-sign path are explicit follow-ups (see
|
|
1655
|
+
* swap/settle-received-claims.ts module doc).
|
|
1656
|
+
*/
|
|
1657
|
+
settleSwapBundle(bundle: SettlementBundle): Promise<SubmitEvmSettlementResult>;
|
|
1396
1658
|
/** Where a tracked channel sits in the withdraw journey. */
|
|
1397
1659
|
getChannelCloseState(channelId: string): 'open' | 'closing' | 'settleable' | 'settled';
|
|
1398
1660
|
getSettleableAt(channelId: string): bigint | undefined;
|
|
@@ -2075,7 +2337,7 @@ declare class EvmSigner {
|
|
|
2075
2337
|
/** ChainSigner identifier — EVM address */
|
|
2076
2338
|
get signerIdentifier(): string;
|
|
2077
2339
|
/** Viem PrivateKeyAccount — usable with walletClient for on-chain transactions */
|
|
2078
|
-
get account(): PrivateKeyAccount;
|
|
2340
|
+
get account(): PrivateKeyAccount$1;
|
|
2079
2341
|
/**
|
|
2080
2342
|
* Signs a balance proof using EIP-712 typed data.
|
|
2081
2343
|
*
|
|
@@ -2674,6 +2936,105 @@ declare class ChannelManager {
|
|
|
2674
2936
|
*/
|
|
2675
2937
|
declare function readMinaDepositTotal(graphqlUrl: string, zkAppAddress: string, fetchImpl?: typeof fetch): Promise<bigint>;
|
|
2676
2938
|
|
|
2939
|
+
/**
|
|
2940
|
+
* Receive-side swap-claim ingestion + verification (toon-client#352, part of
|
|
2941
|
+
* the rolling-swap epic toon-meta#145; spec: toon-meta docs/rolling-swap.md
|
|
2942
|
+
* §3.2/§9 dependency 1).
|
|
2943
|
+
*
|
|
2944
|
+
* The deployed client used to accept swapped-in chain-B claims blind: no
|
|
2945
|
+
* signature check, no watermark, no persistence — `buildSettlementTx` /
|
|
2946
|
+
* `verifyAccumulatedClaim` had zero call sites in this repo. This module is
|
|
2947
|
+
* the missing pipeline: every accumulated claim harvested from a swap stream
|
|
2948
|
+
* is VERIFIED at receipt time and, only if it passes, persisted as the
|
|
2949
|
+
* highest-nonce watermark for its `(chain, channelId)` in a
|
|
2950
|
+
* {@link ReceivedClaimStore}. A claim that fails verification is NEVER counted
|
|
2951
|
+
* as value received — failures are loud and result-shaped, not thrown.
|
|
2952
|
+
*
|
|
2953
|
+
* Verification order per claim (cheapest first, every check fail-closed):
|
|
2954
|
+
* 1. settlement metadata completeness — a claim missing any of channelId /
|
|
2955
|
+
* nonce / cumulativeAmount / recipient / swapSignerAddress cannot be
|
|
2956
|
+
* settled (`MISSING_SETTLEMENT_METADATA` later) and is bucketed `legacy`
|
|
2957
|
+
* (the pre-rename-peer path, #349) rather than rejected: the existing
|
|
2958
|
+
* loud swap-time warning stays the surface for those.
|
|
2959
|
+
* 2. chain consistency — the claim must settle on the session's target chain.
|
|
2960
|
+
* 3. recipient — must equal the session `chainRecipient` (EVM
|
|
2961
|
+
* case-insensitive), the anti-substitution check.
|
|
2962
|
+
* 4. advertised signer — when the caller supplies the maker's advertised
|
|
2963
|
+
* `swapSignerAddress` (kind:10032 discovery / operator config), the
|
|
2964
|
+
* claim's self-reported signer must match (`SWAP_SIGNER_MISMATCH`,
|
|
2965
|
+
* sdk 2.x vocabulary).
|
|
2966
|
+
* 5. signature — `verifyAccumulatedClaim` (sdk) against the expected signer:
|
|
2967
|
+
* the advertised address when given, else the claim's self-reported one
|
|
2968
|
+
* (which then still proves the claim is internally consistent and pins
|
|
2969
|
+
* the address the settlement tx will verify against on-chain).
|
|
2970
|
+
* 6. signer pinning — a claim may not silently rotate the signer of an
|
|
2971
|
+
* already-persisted watermark for the same channel.
|
|
2972
|
+
* 7. nonce/cumulative monotonicity vs the locally persisted watermark —
|
|
2973
|
+
* strictly increasing nonce AND cumulative; the cumulative advance must
|
|
2974
|
+
* cover this packet's `targetAmount` (an under-delivering advance means
|
|
2975
|
+
* the maker short-paid the packet).
|
|
2976
|
+
*/
|
|
2977
|
+
|
|
2978
|
+
/** Why a claim was rejected at receipt time. Codes are stable API. */
|
|
2979
|
+
type ReceivedClaimRejectionCode = 'CHAIN_MISMATCH' | 'RECIPIENT_MISMATCH' | 'SWAP_SIGNER_MISMATCH' | 'SIGNER_MISMATCH' | 'SIGNATURE_INVALID' | 'MINA_VERIFICATION_UNSUPPORTED' | 'UNSUPPORTED_CHAIN' | 'NON_MONOTONIC_NONCE' | 'NON_MONOTONIC_CUMULATIVE' | 'CUMULATIVE_SHORTFALL' | 'MALFORMED_METADATA';
|
|
2980
|
+
interface ReceivedClaimRejection {
|
|
2981
|
+
claim: AccumulatedClaim;
|
|
2982
|
+
code: ReceivedClaimRejectionCode;
|
|
2983
|
+
message: string;
|
|
2984
|
+
}
|
|
2985
|
+
interface VerifiedReceivedClaim {
|
|
2986
|
+
claim: AccumulatedClaim;
|
|
2987
|
+
/** How far this claim advanced the persisted cumulative watermark. */
|
|
2988
|
+
watermarkAdvance: bigint;
|
|
2989
|
+
}
|
|
2990
|
+
interface IngestReceivedClaimsParams {
|
|
2991
|
+
/** Accumulated claims off a swap stream (`streamSwap().claims`), in order. */
|
|
2992
|
+
claims: readonly AccumulatedClaim[];
|
|
2993
|
+
/** The session's target chain (`pair.to.chain` of the requested swap). */
|
|
2994
|
+
expectedChain: string;
|
|
2995
|
+
/** The session's payout address on `expectedChain`. */
|
|
2996
|
+
chainRecipient: string;
|
|
2997
|
+
/**
|
|
2998
|
+
* The maker's ADVERTISED on-chain signer address for `expectedChain`
|
|
2999
|
+
* (kind:10032 discovery or operator-supplied). When set, a claim whose
|
|
3000
|
+
* self-reported `swapSignerAddress` differs is rejected with
|
|
3001
|
+
* `SWAP_SIGNER_MISMATCH` and the signature is verified against THIS address,
|
|
3002
|
+
* never the claim's own.
|
|
3003
|
+
*/
|
|
3004
|
+
expectedSignerAddress?: string;
|
|
3005
|
+
/** Durable watermark store; verified claims are persisted here. */
|
|
3006
|
+
store: ReceivedClaimStore;
|
|
3007
|
+
/** Pre-loaded `mina-signer` client — required to verify `mina:*` claims. */
|
|
3008
|
+
minaSignerClient?: MinaSignerClientLike;
|
|
3009
|
+
/** Clock seam for tests. */
|
|
3010
|
+
now?: () => number;
|
|
3011
|
+
}
|
|
3012
|
+
interface IngestReceivedClaimsResult {
|
|
3013
|
+
/** Claims that passed every check and advanced a persisted watermark. */
|
|
3014
|
+
verified: VerifiedReceivedClaim[];
|
|
3015
|
+
/** Claims that failed verification. NEVER counted as value received. */
|
|
3016
|
+
rejected: ReceivedClaimRejection[];
|
|
3017
|
+
/**
|
|
3018
|
+
* Claims missing settlement metadata (pre-rename / legacy swap peer, #349).
|
|
3019
|
+
* Not verified, not persisted, surfaced through the existing swap-time
|
|
3020
|
+
* warning — behavior for legacy no-metadata swaps is unchanged.
|
|
3021
|
+
*/
|
|
3022
|
+
legacy: AccumulatedClaim[];
|
|
3023
|
+
/** Total watermark advance across verified claims (target micro-units). */
|
|
3024
|
+
valueReceived: bigint;
|
|
3025
|
+
}
|
|
3026
|
+
/** True when the claim carries every settlement-context field. */
|
|
3027
|
+
declare function hasSettlementMetadata(claim: AccumulatedClaim): claim is AccumulatedClaim & Required<Pick<AccumulatedClaim, 'channelId' | 'nonce' | 'cumulativeAmount' | 'recipient' | 'swapSignerAddress'>>;
|
|
3028
|
+
/**
|
|
3029
|
+
* Verify a batch of received chain-B claims and persist the winning watermark
|
|
3030
|
+
* per `(chain, channelId)`. See the module doc for the check ladder.
|
|
3031
|
+
*
|
|
3032
|
+
* Result-shaped: never throws on a bad claim — it lands in `rejected` with a
|
|
3033
|
+
* stable code, and later claims are still processed (a channel's watermark
|
|
3034
|
+
* only advances through claims that verified).
|
|
3035
|
+
*/
|
|
3036
|
+
declare function ingestReceivedClaims(params: IngestReceivedClaimsParams): IngestReceivedClaimsResult;
|
|
3037
|
+
|
|
2677
3038
|
/**
|
|
2678
3039
|
* Configuration options for retry behavior with exponential backoff.
|
|
2679
3040
|
*/
|
|
@@ -2809,6 +3170,56 @@ declare function parseFulfillHttpBytes(bytes: Uint8Array): ParsedFulfillHttp;
|
|
|
2809
3170
|
*/
|
|
2810
3171
|
declare function parseFulfillHttp(base64Data: string): ParsedFulfillHttp;
|
|
2811
3172
|
|
|
3173
|
+
/**
|
|
3174
|
+
* Sender-chosen ILP execution conditions (toon-client#350, rolling-swap
|
|
3175
|
+
* prerequisite — toon-meta#145 §3 R1/R2).
|
|
3176
|
+
*
|
|
3177
|
+
* Contract (normative: connector `docs/local-delivery-fulfillment-contract.md`,
|
|
3178
|
+
* connector#309):
|
|
3179
|
+
* - An ABSENT or ALL-ZERO (32×0x00) `executionCondition` is the LEGACY
|
|
3180
|
+
* class: no hashlock, no verification — today's publish/upload writes.
|
|
3181
|
+
* - Any NON-ZERO condition is SENDER-CHOSEN: the sender mints a fresh
|
|
3182
|
+
* random 32-byte preimage `P` per packet, sets `C = sha256(P)` on the
|
|
3183
|
+
* PREPARE, and on FULFILL MUST verify that the returned fulfillment
|
|
3184
|
+
* hashes back to `C` — a missing/malformed/mismatching fulfillment is a
|
|
3185
|
+
* hard failure (the packet is counted failed, never silently accepted).
|
|
3186
|
+
*
|
|
3187
|
+
* Isomorphic: @noble/hashes only (no Buffer, no node:crypto).
|
|
3188
|
+
*/
|
|
3189
|
+
/** Exact byte length of an ILP execution condition / fulfillment preimage. */
|
|
3190
|
+
declare const CONDITION_LENGTH = 32;
|
|
3191
|
+
/** A freshly minted per-packet hashlock: `condition = sha256(preimage)`. */
|
|
3192
|
+
interface ExecutionConditionPair {
|
|
3193
|
+
/** Random 32-byte preimage `P` — reveal is the commit act; never reuse. */
|
|
3194
|
+
preimage: Uint8Array;
|
|
3195
|
+
/** `C = sha256(P)` — goes on the PREPARE's `executionCondition`. */
|
|
3196
|
+
condition: Uint8Array;
|
|
3197
|
+
}
|
|
3198
|
+
/**
|
|
3199
|
+
* Mint a fresh random 32-byte preimage and its sha256 condition (spec R1).
|
|
3200
|
+
* Mint one PER PACKET: a reused preimage lets any observer of packet *i*
|
|
3201
|
+
* fulfill packet *i+1* without the sender's consent.
|
|
3202
|
+
*/
|
|
3203
|
+
declare function mintExecutionCondition(): ExecutionConditionPair;
|
|
3204
|
+
/**
|
|
3205
|
+
* True when `condition` selects the LEGACY (unverified) class: absent or
|
|
3206
|
+
* all-zero. The OER wire treats absent and 32×0x00 identically.
|
|
3207
|
+
*/
|
|
3208
|
+
declare function isZeroCondition(condition: Uint8Array | undefined): boolean;
|
|
3209
|
+
/**
|
|
3210
|
+
* Validate a caller-supplied execution condition before it goes on the wire.
|
|
3211
|
+
* @throws {Error} When the condition is not exactly 32 bytes — the OER
|
|
3212
|
+
* serializer would otherwise silently zero-fill it, downgrading a
|
|
3213
|
+
* sender-chosen packet to the legacy unverified class.
|
|
3214
|
+
*/
|
|
3215
|
+
declare function assertValidCondition(condition: Uint8Array): void;
|
|
3216
|
+
/**
|
|
3217
|
+
* True iff `fulfillment` is exactly 32 bytes and `sha256(fulfillment)`
|
|
3218
|
+
* equals `condition` — the sender-side FULFILL check (spec R6's mirror).
|
|
3219
|
+
* Fail-closed: an undefined/short/long fulfillment never matches.
|
|
3220
|
+
*/
|
|
3221
|
+
declare function fulfillmentMatchesCondition(fulfillment: Uint8Array | undefined, condition: Uint8Array): boolean;
|
|
3222
|
+
|
|
2812
3223
|
/**
|
|
2813
3224
|
* Settlement info produced by buildSettlementInfo().
|
|
2814
3225
|
* Extends the core SettlementConfig shape with ilpAddress for client use.
|
|
@@ -3326,4 +3737,4 @@ declare function loadKeystore(path: string, password: string): string;
|
|
|
3326
3737
|
*/
|
|
3327
3738
|
declare function writeKeystoreFile(path: string, keystore: EncryptedKeystore): void;
|
|
3328
3739
|
|
|
3329
|
-
export { type BackupPayload, type BalanceProofParams, BtpRuntimeClient, type BtpRuntimeClientConfig, type ChainMetadata, type ChainSigner, ChannelFundingError, ChannelManager, type ClaimMessage, type ClaimResolver, ConnectorError, type DiscoveredIlpPeer, type EVMClaimMessage, type EncryptedKeystore, EvmSigner, type FaucetChain, type FundWalletOptions, type FundWalletResult, type H402FetchOptions, Http402Client, type Http402ClientConfig, HttpConnectorAdmin, type HttpConnectorAdminConfig, HttpIlpClient, type HttpIlpClientConfig, type HttpIlpClientFactory, HttpRuntimeClient, type HttpRuntimeClientConfig, ILP_CLAIM_HEADER, ILP_CLAIM_WRAPPED_HEADER, ILP_PEER_ID_HEADER, type IlpTransportChoice, KeyManager, type KeyManagerConfig, type MinaClaimMessage, type MinaDepositReader, MinaSigner, type MinaSignerOptions, NetworkError, OnChainChannelClient, type OnChainChannelClientConfig, type ParsedFulfillHttp, type ParsedX402Challenge, type PasskeyInfo, type PublishEventResult, type RequestBlobStorageParams, type RequestBlobStorageResult, type RetryOptions, type SelectIlpTransportOptions, type SignedBalanceProof, type SolanaChannelClientOptions, type SolanaClaimMessage, SolanaSigner, type ToonChannelAccept, ToonClient, type ToonClientConfig, ToonClientError, type ToonIdentity, type ToonSigners, type ToonStartResult, ValidationError, type VaultData, type WalletBalance, type WalletBalanceSources, type WalletChainBalances, type WalletTokenAmount, applyDefaults, applyNetworkPresets, buildBackupEvent, buildBackupFilter, buildSettlementInfo, buildStoreWriteEnvelope, decryptMnemonic, defaultFaucetTimeout, deriveFromNsec, deriveFullIdentity, deriveNostrKeyFromMnemonic, encryptMnemonic, extractArweaveTxId, fundWallet, generateKeystore, generateMnemonic, generateRandomIdentity, getNetworkStatus, httpEndpointToBtpUrl, importKeystore, isInsufficientGasError, isPrfSupported, loadKeystore, parseBackupPayload, parseFulfillHttp, parseFulfillHttpBytes, parseHttpResponse, parseX402Body, parseX402Challenge, proxyIlpEndpoint, readDiscoveredIlpPeer, readEvmNativeBalance, readEvmTokenBalance, readMinaBalance, readMinaDepositTotal, readSolanaNativeBalance, readSolanaTokenBalance, readWalletBalances, requestBlobStorage, selectIlpTransport, serializeHttpRequest, validateConfig, validateMnemonic, withRetry, writeKeystoreFile };
|
|
3740
|
+
export { type BackupPayload, type BalanceProofParams, BtpRuntimeClient, type BtpRuntimeClientConfig, type BuildSwapSettlementsParams, CONDITION_LENGTH, type ChainMetadata, type ChainSigner, ChannelFundingError, ChannelManager, type ClaimMessage, type ClaimResolver, ConnectorError, type DiscoveredIlpPeer, type EVMClaimMessage, type EncryptedKeystore, EvmSigner, type ExecutionConditionPair, FULFILLMENT_MISMATCH_CODE, FULFILLMENT_MISMATCH_MESSAGE, type FaucetChain, type FundWalletOptions, type FundWalletResult, type H402FetchOptions, Http402Client, type Http402ClientConfig, HttpConnectorAdmin, type HttpConnectorAdminConfig, HttpIlpClient, type HttpIlpClientConfig, type HttpIlpClientFactory, HttpRuntimeClient, type HttpRuntimeClientConfig, ILP_CLAIM_HEADER, ILP_CLAIM_WRAPPED_HEADER, ILP_PEER_ID_HEADER, type IlpSendParams, type IlpSendResultWithFulfillment, type IlpTransportChoice, InMemoryReceivedClaimStore, type IngestReceivedClaimsParams, type IngestReceivedClaimsResult, JsonFileReceivedClaimStore, KeyManager, type KeyManagerConfig, type MinaClaimMessage, type MinaDepositReader, MinaSigner, type MinaSignerOptions, NetworkError, OnChainChannelClient, type OnChainChannelClientConfig, type ParsedFulfillHttp, type ParsedX402Challenge, type PasskeyInfo, type PublishEventResult, type ReceivedClaimEntry, type ReceivedClaimRejection, type ReceivedClaimRejectionCode, type ReceivedClaimStore, type RequestBlobStorageParams, type RequestBlobStorageResult, type RetryOptions, type SelectIlpTransportOptions, type SignedBalanceProof, type SolanaChannelClientOptions, type SolanaClaimMessage, SolanaSigner, type SubmitEvmSettlementParams, type SubmitEvmSettlementResult, type SwapSettlementBuild, type ToonChannelAccept, ToonClient, type ToonClientConfig, ToonClientError, type ToonIdentity, type ToonSigners, type ToonStartResult, ValidationError, type VaultData, type VerifiedReceivedClaim, type WalletBalance, type WalletBalanceSources, type WalletChainBalances, type WalletTokenAmount, applyDefaults, applyNetworkPresets, assertValidCondition, buildBackupEvent, buildBackupFilter, buildSettlementInfo, buildStoreWriteEnvelope, buildSwapSettlements, decodeEvmSettlementTx, decryptMnemonic, defaultFaucetTimeout, deriveFromNsec, deriveFullIdentity, deriveNostrKeyFromMnemonic, encryptMnemonic, entryToAccumulatedClaim, extractArweaveTxId, fulfillmentMatchesCondition, fundWallet, generateKeystore, generateMnemonic, generateRandomIdentity, getNetworkStatus, hasSettlementMetadata, httpEndpointToBtpUrl, importKeystore, ingestReceivedClaims, isInsufficientGasError, isPrfSupported, isZeroCondition, loadKeystore, mintExecutionCondition, parseBackupPayload, parseEvmChainId, parseFulfillHttp, parseFulfillHttpBytes, parseHttpResponse, parseX402Body, parseX402Challenge, proxyIlpEndpoint, readDiscoveredIlpPeer, readEvmNativeBalance, readEvmTokenBalance, readMinaBalance, readMinaDepositTotal, readSolanaNativeBalance, readSolanaTokenBalance, readWalletBalances, requestBlobStorage, selectIlpTransport, serializeHttpRequest, submitEvmSettlement, validateConfig, validateMnemonic, withRetry, writeKeystoreFile };
|