@toon-protocol/client 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -24
- package/dist/index.d.ts +611 -10
- package/dist/index.js +598 -46
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { UI_RENDERER_KIND, UI_TAG, UiCoordinate, buildUiCoordinate, getUiCoordin
|
|
|
4
4
|
import { NostrEvent, EventTemplate } from 'nostr-tools/pure';
|
|
5
5
|
import { MinaSignerClientLike, SettlementBundle } from '@toon-protocol/sdk';
|
|
6
6
|
import { AccumulatedClaim } from '@toon-protocol/sdk/swap';
|
|
7
|
-
import { PrivateKeyAccount, Hex } from 'viem';
|
|
7
|
+
import { PrivateKeyAccount, Hex, Address } from 'viem';
|
|
8
8
|
import { PrivateKeyAccount as PrivateKeyAccount$1 } from 'viem/accounts';
|
|
9
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';
|
|
10
10
|
|
|
@@ -407,6 +407,24 @@ interface ToonClientConfig {
|
|
|
407
407
|
* gated (distinct from the connector #88 on-chain-settle gate).
|
|
408
408
|
*/
|
|
409
409
|
minaChannel?: MinaChannelClientOptions;
|
|
410
|
+
/**
|
|
411
|
+
* Receive-side Mina swap-claim redemption (#357): maker on-chain co-signatures
|
|
412
|
+
* keyed by dest-channel zkApp address (B62).
|
|
413
|
+
*
|
|
414
|
+
* On-chain `claimFromChannel` is dual-party — it verifies BOTH participants
|
|
415
|
+
* signed `[commitment, nonce, channelHash]`. The recipient (this client)
|
|
416
|
+
* produces its own co-signature from the derived Mina key, but the swap-wire
|
|
417
|
+
* claim only carries the maker's `balanceProofFieldsMina` signature (a
|
|
418
|
+
* DIFFERENT message), so the maker must additionally deliver a
|
|
419
|
+
* payment-channel-commitment-form co-signature. Until that flows over the swap
|
|
420
|
+
* wire, an operator can inject the maker's `{ r, s }` here to complete a
|
|
421
|
+
* receive-side redemption. Absent one, settlement fails closed with
|
|
422
|
+
* `MINA_MAKER_COSIGN_REQUIRED` (never a silent pass).
|
|
423
|
+
*/
|
|
424
|
+
swapMinaMakerSignatures?: Record<string, {
|
|
425
|
+
r: string;
|
|
426
|
+
s: string;
|
|
427
|
+
}>;
|
|
410
428
|
/** File path for persisting payment channel nonce/amount state across restarts */
|
|
411
429
|
channelStorePath?: string;
|
|
412
430
|
/** Nostr relay URL for peer discovery. Default: 'ws://localhost:7100' */
|
|
@@ -1244,6 +1262,21 @@ interface BuildSwapSettlementsParams {
|
|
|
1244
1262
|
tokenNetworks?: Record<string, string>;
|
|
1245
1263
|
/** Pre-loaded `mina-signer` client for `mina:*` re-verification. */
|
|
1246
1264
|
minaSignerClient?: MinaSignerClientLike;
|
|
1265
|
+
/**
|
|
1266
|
+
* Re-verify the stored claim's signature at settle time (defense in depth
|
|
1267
|
+
* over the store file). Default `true` — the published **v2** sdk
|
|
1268
|
+
* (`@toon-protocol/sdk@^3`, connector#324 finding #1) verifies EVM claims
|
|
1269
|
+
* against the **v2** EIP-712 domain-separated balance-proof digest, the SAME
|
|
1270
|
+
* digest the receive-side used (`ingestReceivedClaims`). Reconstructing that
|
|
1271
|
+
* EIP-712 domain needs `chainId` + `verifyingContract`, which this builder
|
|
1272
|
+
* threads into the sdk signer config from `tokenNetworks` (for EVM claims) —
|
|
1273
|
+
* so a claim verified at receipt re-verifies correctly here.
|
|
1274
|
+
*
|
|
1275
|
+
* Set `false` only to skip the settle-time re-verify entirely (e.g. when the
|
|
1276
|
+
* receive-side verify is treated as the sole authoritative gate); the sdk is
|
|
1277
|
+
* then used only to BUILD the settlement calldata.
|
|
1278
|
+
*/
|
|
1279
|
+
verifySignatures?: boolean;
|
|
1247
1280
|
}
|
|
1248
1281
|
/** Rebuild the sdk `AccumulatedClaim` shape from a persisted entry. */
|
|
1249
1282
|
declare function entryToAccumulatedClaim(entry: ReceivedClaimEntry): AccumulatedClaim;
|
|
@@ -1561,8 +1594,6 @@ declare class ToonClient {
|
|
|
1561
1594
|
private getClaimTransport;
|
|
1562
1595
|
/**
|
|
1563
1596
|
* Shared claim-resolution logic used by `publishEvent` and `sendSwapPacket`.
|
|
1564
|
-
* TODO(12.5 followup): also factor `publishEvent`'s inline claim resolution
|
|
1565
|
-
* to call this helper. Kept duplicated for now to minimize regression risk.
|
|
1566
1597
|
*/
|
|
1567
1598
|
private resolveClaimForDestination;
|
|
1568
1599
|
/**
|
|
@@ -2935,6 +2966,44 @@ declare class ChannelManager {
|
|
|
2935
2966
|
* @param fetchImpl - injectable for tests; defaults to global `fetch`.
|
|
2936
2967
|
*/
|
|
2937
2968
|
declare function readMinaDepositTotal(graphqlUrl: string, zkAppAddress: string, fetchImpl?: typeof fetch): Promise<bigint>;
|
|
2969
|
+
/** Channel-lifecycle enum written to `channelState` (matches the zkApp). */
|
|
2970
|
+
declare const MINA_CHANNEL_STATE: {
|
|
2971
|
+
readonly UNINITIALIZED: 0;
|
|
2972
|
+
readonly OPEN: 1;
|
|
2973
|
+
readonly CLOSING: 2;
|
|
2974
|
+
readonly SETTLED: 3;
|
|
2975
|
+
};
|
|
2976
|
+
/**
|
|
2977
|
+
* On-chain `PaymentChannel` state the receive-side settler needs to assemble a
|
|
2978
|
+
* co-signed `claimFromChannel` — all read via plain GraphQL (NO o1js / WASM), so
|
|
2979
|
+
* the read path stays lightweight and unit-testable. Field semantics match
|
|
2980
|
+
* {@link MinaChannelState} in the connector's Mina SDK.
|
|
2981
|
+
*/
|
|
2982
|
+
interface MinaOnChainChannelState {
|
|
2983
|
+
/** `Poseidon([participantA.x, participantB.x, channelNonce])`, decimal Field. */
|
|
2984
|
+
channelHash: string;
|
|
2985
|
+
/** Current `Poseidon([balanceA, balanceB, salt])`, decimal Field. */
|
|
2986
|
+
balanceCommitment: string;
|
|
2987
|
+
/** Highest claimed nonce recorded on-chain. */
|
|
2988
|
+
nonceField: bigint;
|
|
2989
|
+
/** {@link MINA_CHANNEL_STATE} enum value. */
|
|
2990
|
+
channelState: number;
|
|
2991
|
+
/** Total escrowed deposit (base units). */
|
|
2992
|
+
depositTotal: bigint;
|
|
2993
|
+
}
|
|
2994
|
+
/**
|
|
2995
|
+
* Read the channel's on-chain `PaymentChannel` state via GraphQL.
|
|
2996
|
+
*
|
|
2997
|
+
* Reuses the same `account(publicKey).zkappState` query as
|
|
2998
|
+
* {@link readMinaDepositTotal} and decodes the fields the co-signed
|
|
2999
|
+
* `claimFromChannel` assembly binds: `channelHash` (participant identity),
|
|
3000
|
+
* `depositTotal` (balance conservation), `nonceField` (monotonicity gate), and
|
|
3001
|
+
* `channelState` (must be OPEN). No o1js is loaded — the values are raw Field
|
|
3002
|
+
* decimal strings straight off the node.
|
|
3003
|
+
*
|
|
3004
|
+
* @param fetchImpl - injectable for tests; defaults to global `fetch`.
|
|
3005
|
+
*/
|
|
3006
|
+
declare function readMinaChannelState(graphqlUrl: string, zkAppAddress: string, fetchImpl?: typeof fetch): Promise<MinaOnChainChannelState>;
|
|
2938
3007
|
|
|
2939
3008
|
/**
|
|
2940
3009
|
* Receive-side swap-claim ingestion + verification (toon-client#352, part of
|
|
@@ -2963,10 +3032,15 @@ declare function readMinaDepositTotal(graphqlUrl: string, zkAppAddress: string,
|
|
|
2963
3032
|
* `swapSignerAddress` (kind:10032 discovery / operator config), the
|
|
2964
3033
|
* claim's self-reported signer must match (`SWAP_SIGNER_MISMATCH`,
|
|
2965
3034
|
* sdk 2.x vocabulary).
|
|
2966
|
-
* 5. signature —
|
|
2967
|
-
*
|
|
2968
|
-
*
|
|
2969
|
-
*
|
|
3035
|
+
* 5. signature — against the expected signer (advertised address when given,
|
|
3036
|
+
* else the claim's self-reported one). EVM claims verify against the
|
|
3037
|
+
* **v2 EIP-712 domain-separated** balance-proof digest
|
|
3038
|
+
* (`verifyEvmClaimSignature`, connector#324 finding #1) — the digest binds
|
|
3039
|
+
* `chainId` + `verifyingContract`, so `tokenNetworks[chain]` (the
|
|
3040
|
+
* RollingSwapChannel address) and a numeric chain id are REQUIRED (an EVM
|
|
3041
|
+
* claim without them is rejected `MISSING_CHAIN_CONFIG`, fail-closed).
|
|
3042
|
+
* Solana/Mina keep the sdk `verifyAccumulatedClaim` path (their domain is
|
|
3043
|
+
* folded into the message).
|
|
2970
3044
|
* 6. signer pinning — a claim may not silently rotate the signer of an
|
|
2971
3045
|
* already-persisted watermark for the same channel.
|
|
2972
3046
|
* 7. nonce/cumulative monotonicity vs the locally persisted watermark —
|
|
@@ -2976,7 +3050,7 @@ declare function readMinaDepositTotal(graphqlUrl: string, zkAppAddress: string,
|
|
|
2976
3050
|
*/
|
|
2977
3051
|
|
|
2978
3052
|
/** 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';
|
|
3053
|
+
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' | 'MISSING_CHAIN_CONFIG' | 'MALFORMED_METADATA';
|
|
2980
3054
|
interface ReceivedClaimRejection {
|
|
2981
3055
|
claim: AccumulatedClaim;
|
|
2982
3056
|
code: ReceivedClaimRejectionCode;
|
|
@@ -3002,6 +3076,21 @@ interface IngestReceivedClaimsParams {
|
|
|
3002
3076
|
* never the claim's own.
|
|
3003
3077
|
*/
|
|
3004
3078
|
expectedSignerAddress?: string;
|
|
3079
|
+
/**
|
|
3080
|
+
* Per-chain settlement contract addresses (the deployed `RollingSwapChannel`
|
|
3081
|
+
* / `verifyingContract`), keyed by the FULL chain key (e.g. `evm:base:8453`).
|
|
3082
|
+
* Matches the daemon config's `tokenNetworks` map and what
|
|
3083
|
+
* `buildSwapSettlements` already threads on the submit side.
|
|
3084
|
+
*
|
|
3085
|
+
* REQUIRED for EVM claims under the v2 EIP-712 digest (connector#324 finding
|
|
3086
|
+
* #1): the claim signature is domain-separated over `(chainId,
|
|
3087
|
+
* verifyingContract)`, so an EVM claim whose chain key lacks a `tokenNetworks`
|
|
3088
|
+
* entry (or a numeric chain id) is rejected `MISSING_CHAIN_CONFIG` — it cannot
|
|
3089
|
+
* be verified fail-closed without the domain. Supplied by the connector/swap
|
|
3090
|
+
* session context (the RollingSwapChannel the client settles against). Unused
|
|
3091
|
+
* for Solana/Mina claims, which fold their domain into the message itself.
|
|
3092
|
+
*/
|
|
3093
|
+
tokenNetworks?: Record<string, string>;
|
|
3005
3094
|
/** Durable watermark store; verified claims are persisted here. */
|
|
3006
3095
|
store: ReceivedClaimStore;
|
|
3007
3096
|
/** Pre-loaded `mina-signer` client — required to verify `mina:*` claims. */
|
|
@@ -3035,6 +3124,517 @@ declare function hasSettlementMetadata(claim: AccumulatedClaim): claim is Accumu
|
|
|
3035
3124
|
*/
|
|
3036
3125
|
declare function ingestReceivedClaims(params: IngestReceivedClaimsParams): IngestReceivedClaimsResult;
|
|
3037
3126
|
|
|
3127
|
+
/**
|
|
3128
|
+
* EVM rolling-swap **v2** balance-proof claim digest (EIP-712 domain-separated).
|
|
3129
|
+
*
|
|
3130
|
+
* Refs connector#324 **finding #1** / connector#325 (canonical spec:
|
|
3131
|
+
* `docs/rolling-swap-v2-digest-spec.md`). This is the client's byte-for-byte
|
|
3132
|
+
* conformance anchor for the v2 migration.
|
|
3133
|
+
*
|
|
3134
|
+
* ## Why this exists in the client
|
|
3135
|
+
*
|
|
3136
|
+
* The v1 digest that shipped in `@toon-protocol/core` `balanceProofHashEvm`
|
|
3137
|
+
* (imported transitively by the sdk's `verifyAccumulatedClaim` /
|
|
3138
|
+
* `buildSettlementTx`, which is what this repo used to lean on) was
|
|
3139
|
+
*
|
|
3140
|
+
* keccak256( channelId(32) || cumulativeAmount(32BE)
|
|
3141
|
+
* || nonce(32BE) || recipient(20) )
|
|
3142
|
+
*
|
|
3143
|
+
* — it bound **neither** `chainId` **nor** the settling contract address, so a
|
|
3144
|
+
* signer-signed claim redeemed on one (chain, deployment) could be replayed
|
|
3145
|
+
* verbatim on another for the same tuple (cross-chain / cross-deployment
|
|
3146
|
+
* replay). v2 folds `chainId` **and** `verifyingContract` into the signed
|
|
3147
|
+
* preimage via a standard **EIP-712** typed-data domain, so a signature is
|
|
3148
|
+
* valid on **exactly one `(chainId, contract)` pair**, and the `version="2"`
|
|
3149
|
+
* string makes the cutover fail-closed (a v1 raw-keccak sig can never validate
|
|
3150
|
+
* as v2 and vice-versa).
|
|
3151
|
+
*
|
|
3152
|
+
* ## Lockstep dependency
|
|
3153
|
+
*
|
|
3154
|
+
* The canonical v2 digest util lives in `@toon-protocol/core`
|
|
3155
|
+
* (`balanceProofHashEvm` → EIP-712) + `@toon-protocol/sdk`
|
|
3156
|
+
* (`verifyAccumulatedClaim` / `buildSettlementTx`). Those packages migrate in
|
|
3157
|
+
* lockstep (connector#324 release order: core/sdk → swap → client). Until a v2
|
|
3158
|
+
* core/sdk is published, this module is the client's own v2 digest so the
|
|
3159
|
+
* receive-side verify (see {@link file://./received-claims.ts}) is already
|
|
3160
|
+
* domain-separated and the golden-vector conformance test
|
|
3161
|
+
* (`evm-claim-digest.test.ts`) pins the exact literals from the spec. When the
|
|
3162
|
+
* v2 core/sdk ships, the recompute here should delegate to it (or be asserted
|
|
3163
|
+
* byte-identical to it) — the golden-vector test stays as the shared fixture.
|
|
3164
|
+
*
|
|
3165
|
+
* The signer leg (`swap` `EvmPaymentChannelSigner.signBalanceProof`) MUST also
|
|
3166
|
+
* move to this same EIP-712 preimage and now REQUIRES `chainId` +
|
|
3167
|
+
* `verifyingContract` inputs it did not take before.
|
|
3168
|
+
*/
|
|
3169
|
+
|
|
3170
|
+
/** EIP-712 domain `name` for the RollingSwapChannel (spec §2.1). */
|
|
3171
|
+
declare const ROLLING_SWAP_DOMAIN_NAME: "RollingSwapChannel";
|
|
3172
|
+
/** EIP-712 domain `version` — `"2"` is the domain-separated migration. */
|
|
3173
|
+
declare const ROLLING_SWAP_DOMAIN_VERSION: "2";
|
|
3174
|
+
/**
|
|
3175
|
+
* `keccak256("ClaimBalanceProof(bytes32 channelId,uint256 cumulativeAmount,uint256 nonce,address recipient)")`.
|
|
3176
|
+
* Pinned from the spec; asserted in `evm-claim-digest.test.ts`.
|
|
3177
|
+
*/
|
|
3178
|
+
declare const CLAIM_TYPEHASH: "0xa0c8262c1a8615f7674d3af796b14d19672d3634f89c6093502ab35c0afe2d91";
|
|
3179
|
+
/**
|
|
3180
|
+
* `keccak256("CooperativeClose(bytes32 channelId,uint256 cumulativeAmount,uint256 nonce)")`.
|
|
3181
|
+
* Pinned from the spec; asserted in `evm-claim-digest.test.ts`.
|
|
3182
|
+
*/
|
|
3183
|
+
declare const COOP_CLOSE_TYPEHASH: "0xa5753389755fea51cd5016d7b02b508ac03f2e822d9a7ee345ec45b36574ff9f";
|
|
3184
|
+
/** The two chain-context inputs v2 adds over v1 (the domain binding). */
|
|
3185
|
+
interface EvmClaimDomainContext {
|
|
3186
|
+
/** Settlement chain id (`block.chainid` on-chain). e.g. `8453` for Base. */
|
|
3187
|
+
chainId: number;
|
|
3188
|
+
/** Deployed `RollingSwapChannel` address (`address(this)` / EIP-712 `verifyingContract`). */
|
|
3189
|
+
verifyingContract: string;
|
|
3190
|
+
}
|
|
3191
|
+
/** Fields of the `ClaimBalanceProof` message (the balance-proof claim leg). */
|
|
3192
|
+
interface EvmClaimMessage {
|
|
3193
|
+
/** Channel id, 0x-prefixed 32-byte hex. */
|
|
3194
|
+
channelId: string;
|
|
3195
|
+
/** Cumulative transferred amount (target micro-units). */
|
|
3196
|
+
cumulativeAmount: bigint;
|
|
3197
|
+
/** Monotonic balance-proof nonce. */
|
|
3198
|
+
nonce: bigint;
|
|
3199
|
+
/** Recipient (the claim payout address), 0x-prefixed 20-byte hex. */
|
|
3200
|
+
recipient: string;
|
|
3201
|
+
}
|
|
3202
|
+
/** Fields of the `CooperativeClose` message (recipient close-ack leg). */
|
|
3203
|
+
interface EvmCooperativeCloseMessage {
|
|
3204
|
+
channelId: string;
|
|
3205
|
+
cumulativeAmount: bigint;
|
|
3206
|
+
nonce: bigint;
|
|
3207
|
+
}
|
|
3208
|
+
/**
|
|
3209
|
+
* The v2 EIP-712 claim digest — `keccak256(0x1901 || domainSeparator ||
|
|
3210
|
+
* hashStruct(ClaimBalanceProof))` — that the on-chain `updateBalance` verifier
|
|
3211
|
+
* (and the swap signer) produce. This is what a received claim's signature must
|
|
3212
|
+
* recover against.
|
|
3213
|
+
*/
|
|
3214
|
+
declare function evmClaimDigest(ctx: EvmClaimDomainContext, message: EvmClaimMessage): Hex;
|
|
3215
|
+
/**
|
|
3216
|
+
* The v2 EIP-712 cooperative-close digest — same domain as the claim, distinct
|
|
3217
|
+
* type hash — that a recipient's close-ack signature must recover against.
|
|
3218
|
+
*/
|
|
3219
|
+
declare function evmCooperativeCloseDigest(ctx: EvmClaimDomainContext, message: EvmCooperativeCloseMessage): Hex;
|
|
3220
|
+
/** A 65-byte `r || s || v` signature, as 0x-hex or raw bytes. */
|
|
3221
|
+
type ClaimSignature = Hex | Uint8Array;
|
|
3222
|
+
/**
|
|
3223
|
+
* Recover the EVM address that signed a v2 claim digest. Uses the same
|
|
3224
|
+
* `@noble/curves` secp256k1 recovery + keccak address derivation as the sdk's
|
|
3225
|
+
* on-chain-matching `recoverEvmSignerAddress`, over the **v2** EIP-712 digest.
|
|
3226
|
+
* Enforces the same 65-byte `r||s||v`, `v ∈ {27,28}` envelope the on-chain OZ
|
|
3227
|
+
* `ECDSA.recover` accepts (fail-closed on a malformed signature).
|
|
3228
|
+
*
|
|
3229
|
+
* @returns the recovered address (lowercase 0x-hex).
|
|
3230
|
+
* @throws if the signature is not 65 bytes or `v` is not 27/28.
|
|
3231
|
+
*/
|
|
3232
|
+
declare function recoverEvmClaimSigner(ctx: EvmClaimDomainContext, message: EvmClaimMessage, signature: ClaimSignature): Address;
|
|
3233
|
+
/** Result of {@link verifyEvmClaimSignature}. Mirrors the sdk verify shape. */
|
|
3234
|
+
type EvmClaimVerifyResult = {
|
|
3235
|
+
valid: true;
|
|
3236
|
+
recovered: Address;
|
|
3237
|
+
} | {
|
|
3238
|
+
valid: false;
|
|
3239
|
+
reason: string;
|
|
3240
|
+
};
|
|
3241
|
+
/**
|
|
3242
|
+
* Verify a received EVM balance-proof claim: recover the v2-digest signer and
|
|
3243
|
+
* check it equals `expectedSigner` (case-insensitive, per EVM address rules).
|
|
3244
|
+
*
|
|
3245
|
+
* Result-shaped — never throws; a malformed signature or a mismatch is a
|
|
3246
|
+
* `{ valid: false, reason }` so the receive ladder can bucket it fail-closed.
|
|
3247
|
+
*/
|
|
3248
|
+
declare function verifyEvmClaimSignature(params: {
|
|
3249
|
+
ctx: EvmClaimDomainContext;
|
|
3250
|
+
message: EvmClaimMessage;
|
|
3251
|
+
signature: ClaimSignature;
|
|
3252
|
+
expectedSigner: string;
|
|
3253
|
+
}): EvmClaimVerifyResult;
|
|
3254
|
+
|
|
3255
|
+
/**
|
|
3256
|
+
* Per-packet preimage retention (toon-client#360, rolling-swap epic
|
|
3257
|
+
* toon-meta#145 — spec `docs/rolling-swap.md` §3 R1 / §3.2 leg-B reveal).
|
|
3258
|
+
*
|
|
3259
|
+
* `withSenderConditions` (toon-client#354) mints a fresh 32-byte preimage
|
|
3260
|
+
* `P_i` per fill packet, sets `C_i = sha256(P_i)` on the leg-A PREPARE, and —
|
|
3261
|
+
* before this module — DISCARDED `P_i`. Leg-B reveal (spec §3.2) is the commit
|
|
3262
|
+
* act: the sender reveals `P_i` only AFTER verifying the leg-B claim, so the
|
|
3263
|
+
* daemon must retain each `P_i` from mint time until the reveal step consumes
|
|
3264
|
+
* it. This is that retention seam.
|
|
3265
|
+
*
|
|
3266
|
+
* Keyed by `packetIndex` — the 0-indexed position in the swap's packet stream.
|
|
3267
|
+
* `packetIndex` is the one identifier shared between the send side (the wrapper
|
|
3268
|
+
* mints one condition per `sendSwapPacket` call, which `streamSwap` issues in
|
|
3269
|
+
* strictly increasing `packetIndex` order) and the receive side
|
|
3270
|
+
* (`AccumulatedClaim.packetIndex`), so it correlates a retained preimage to the
|
|
3271
|
+
* claim whose reveal will consume it.
|
|
3272
|
+
*
|
|
3273
|
+
* Reveal is single-use: {@link PreimageRetentionStore.take} removes the entry
|
|
3274
|
+
* so a preimage is never revealed twice (spec R1 — a reused preimage lets an
|
|
3275
|
+
* observer of packet *i* fulfill packet *i+1* without the sender's consent).
|
|
3276
|
+
*
|
|
3277
|
+
* Session-scoped and in-memory by design: a preimage is only meaningful within
|
|
3278
|
+
* the swap stream that minted it (a fresh stream mints fresh preimages), and a
|
|
3279
|
+
* preimage revealed after a crash would commit leg A for a leg-B claim the
|
|
3280
|
+
* restarted daemon can no longer verify. Durability lives on the *watermark*
|
|
3281
|
+
* (`ReceivedClaimStore`), not here.
|
|
3282
|
+
*/
|
|
3283
|
+
/** A retained per-packet hashlock secret awaiting (or past) its leg-B reveal. */
|
|
3284
|
+
interface RetainedPreimage {
|
|
3285
|
+
/** 0-indexed position in the swap's packet stream; the correlation key. */
|
|
3286
|
+
packetIndex: number;
|
|
3287
|
+
/** The 32-byte preimage `P_i` — revealed to commit leg A (spec R6). */
|
|
3288
|
+
preimage: Uint8Array;
|
|
3289
|
+
/** `C_i = sha256(P_i)` — what went on the leg-A PREPARE (kept for auditing). */
|
|
3290
|
+
condition: Uint8Array;
|
|
3291
|
+
/** Unix ms the preimage was minted/retained. */
|
|
3292
|
+
retainedAt: number;
|
|
3293
|
+
}
|
|
3294
|
+
/**
|
|
3295
|
+
* Retention interface for per-packet preimages, keyed by `packetIndex`. Mirrors
|
|
3296
|
+
* the sync surface of the daemon's other stores ({@link ReceivedClaimStore}).
|
|
3297
|
+
*/
|
|
3298
|
+
interface PreimageRetentionStore {
|
|
3299
|
+
/** Retain `entry`, replacing any prior entry for the same `packetIndex`. */
|
|
3300
|
+
retain(entry: RetainedPreimage): void;
|
|
3301
|
+
/** Peek the retained preimage for `packetIndex` without consuming it. */
|
|
3302
|
+
get(packetIndex: number): RetainedPreimage | undefined;
|
|
3303
|
+
/** Consume (return AND remove) the preimage — single-use reveal (spec R1). */
|
|
3304
|
+
take(packetIndex: number): RetainedPreimage | undefined;
|
|
3305
|
+
/** Number of preimages still retained (awaiting reveal). */
|
|
3306
|
+
size(): number;
|
|
3307
|
+
/** Drop every retained preimage — call when the session ends. */
|
|
3308
|
+
clear(): void;
|
|
3309
|
+
}
|
|
3310
|
+
/**
|
|
3311
|
+
* In-memory {@link PreimageRetentionStore}. The only implementation: preimages
|
|
3312
|
+
* are session-scoped secrets that MUST NOT outlive their stream (see the module
|
|
3313
|
+
* doc), so there is deliberately no file-backed variant.
|
|
3314
|
+
*/
|
|
3315
|
+
declare class InMemoryPreimageRetentionStore implements PreimageRetentionStore {
|
|
3316
|
+
private readonly entries;
|
|
3317
|
+
retain(entry: RetainedPreimage): void;
|
|
3318
|
+
get(packetIndex: number): RetainedPreimage | undefined;
|
|
3319
|
+
take(packetIndex: number): RetainedPreimage | undefined;
|
|
3320
|
+
size(): number;
|
|
3321
|
+
clear(): void;
|
|
3322
|
+
}
|
|
3323
|
+
|
|
3324
|
+
/**
|
|
3325
|
+
* Atomic verify -> persist -> reveal composition (toon-client#360, rolling-swap
|
|
3326
|
+
* epic toon-meta#145 — spec `docs/rolling-swap.md` §3 R5/R8, §3.2 leg-B reveal).
|
|
3327
|
+
*
|
|
3328
|
+
* {@link ingestReceivedClaims} (toon-client#358) verifies a received chain-B
|
|
3329
|
+
* claim and persists its watermark AT VERIFY TIME. But verification is not the
|
|
3330
|
+
* commit: leg-B reveal is (spec R5 — the sender reveals `P_i` only after the
|
|
3331
|
+
* claim verifies). A daemon that verifies a claim, advances the watermark, and
|
|
3332
|
+
* then WITHHOLDS or FAILS the reveal has advanced a watermark for value it never
|
|
3333
|
+
* committed to. Left there, engine rule R8 bites: after the maker rolls its own
|
|
3334
|
+
* side back it REUSES the rolled-back nonce for the next fill, and the client's
|
|
3335
|
+
* monotonicity check (`nonce <= watermark.nonce -> NON_MONOTONIC_NONCE`) would
|
|
3336
|
+
* falsely reject that legitimate re-fill.
|
|
3337
|
+
*
|
|
3338
|
+
* So verify/persist/reveal must compose as ONE unit whose durable effect is
|
|
3339
|
+
* "watermark advanced iff the reveal committed":
|
|
3340
|
+
*
|
|
3341
|
+
* 1. snapshot the prior watermark for the claim's `(chain, channelId)`;
|
|
3342
|
+
* 2. verify + persist via {@link ingestReceivedClaims} (single claim);
|
|
3343
|
+
* 3. reveal the retained preimage `P_i` for `claim.packetIndex`;
|
|
3344
|
+
* 4. on `withheld` / thrown / preimage-missing -> COMPENSATING ROLLBACK:
|
|
3345
|
+
* restore the snapshot (or delete when there was none), so the watermark
|
|
3346
|
+
* tracks only ACCEPTED/REVEALED packets and R8's reused nonce is accepted.
|
|
3347
|
+
*
|
|
3348
|
+
* Claims are processed strictly in order and each claim's fate is decided
|
|
3349
|
+
* before the next is verified, so cross-claim monotonicity flows through the
|
|
3350
|
+
* durable store: a rolled-back claim leaves no trace for the next to trip over.
|
|
3351
|
+
* Legacy no-metadata claims (spec §349 path) and hard verification rejects
|
|
3352
|
+
* never reach a reveal and never touch a watermark — behavior unchanged.
|
|
3353
|
+
*/
|
|
3354
|
+
|
|
3355
|
+
/** The sender's leg-B decision for a verified claim (spec R5). */
|
|
3356
|
+
type RevealDecision = 'revealed' | 'withheld';
|
|
3357
|
+
interface RevealResult {
|
|
3358
|
+
decision: RevealDecision;
|
|
3359
|
+
/** Human-readable detail, surfaced on a rolled-back record when withheld. */
|
|
3360
|
+
reason?: string;
|
|
3361
|
+
}
|
|
3362
|
+
/**
|
|
3363
|
+
* Reveal a verified claim's preimage to commit leg A, OR withhold it. Receives
|
|
3364
|
+
* the claim and the retained preimage for its `packetIndex` (`undefined` when
|
|
3365
|
+
* none was retained — e.g. a legacy zero-condition packet reaching this path).
|
|
3366
|
+
* Returning `withheld`, resolving to no decision, or THROWING all trigger the
|
|
3367
|
+
* compensating rollback; only `revealed` keeps the watermark advance.
|
|
3368
|
+
*/
|
|
3369
|
+
type RevealFn = (claim: AccumulatedClaim, preimage: RetainedPreimage | undefined) => RevealResult | Promise<RevealResult>;
|
|
3370
|
+
interface IngestAndRevealParams extends IngestReceivedClaimsParams {
|
|
3371
|
+
/** Leg-B reveal decision, invoked once per VERIFIED claim (spec R5/R6). */
|
|
3372
|
+
reveal: RevealFn;
|
|
3373
|
+
/**
|
|
3374
|
+
* Retained per-packet preimages ({@link PreimageRetentionStore}). The reveal
|
|
3375
|
+
* for a verified claim CONSUMES (`take`) the preimage for its `packetIndex`,
|
|
3376
|
+
* so a preimage is never revealed twice (spec R1). Optional: without it the
|
|
3377
|
+
* reveal fn receives `undefined` and decides on its own.
|
|
3378
|
+
*/
|
|
3379
|
+
preimages?: PreimageRetentionStore;
|
|
3380
|
+
}
|
|
3381
|
+
interface RevealedClaim {
|
|
3382
|
+
claim: AccumulatedClaim;
|
|
3383
|
+
/** How far the (now committed) watermark advanced. */
|
|
3384
|
+
watermarkAdvance: bigint;
|
|
3385
|
+
}
|
|
3386
|
+
interface RolledBackClaim {
|
|
3387
|
+
claim: AccumulatedClaim;
|
|
3388
|
+
/** The advance that was persisted then rolled back (never counted). */
|
|
3389
|
+
watermarkAdvance: bigint;
|
|
3390
|
+
/** Why the reveal did not commit (withheld reason, or the thrown error). */
|
|
3391
|
+
reason: string;
|
|
3392
|
+
}
|
|
3393
|
+
interface IngestAndRevealResult {
|
|
3394
|
+
/** Claims that verified AND revealed — the only ones whose value counts. */
|
|
3395
|
+
revealed: RevealedClaim[];
|
|
3396
|
+
/**
|
|
3397
|
+
* Claims that verified but whose reveal was withheld/failed: the watermark
|
|
3398
|
+
* advance was persisted then ROLLED BACK, so a subsequent re-fill reusing
|
|
3399
|
+
* the same nonce (engine R8) is accepted, not falsely rejected.
|
|
3400
|
+
*/
|
|
3401
|
+
rolledBack: RolledBackClaim[];
|
|
3402
|
+
/** Claims that failed verification. NEVER revealed, NEVER persisted. */
|
|
3403
|
+
rejected: ReceivedClaimRejection[];
|
|
3404
|
+
/** Legacy no-metadata claims (spec §349). Unchanged: not verified/revealed. */
|
|
3405
|
+
legacy: AccumulatedClaim[];
|
|
3406
|
+
/** Total watermark advance across REVEALED claims only. */
|
|
3407
|
+
valueRevealed: bigint;
|
|
3408
|
+
}
|
|
3409
|
+
/**
|
|
3410
|
+
* Verify, persist, and reveal a batch of received chain-B claims atomically:
|
|
3411
|
+
* a verified claim's watermark advance survives iff its reveal commits, and is
|
|
3412
|
+
* rolled back otherwise (see the module doc for why R8 needs this).
|
|
3413
|
+
*
|
|
3414
|
+
* Never throws on a bad claim or a throwing reveal — both land in the result
|
|
3415
|
+
* (`rejected` / `rolledBack`) with the durable watermark left consistent.
|
|
3416
|
+
*/
|
|
3417
|
+
declare function ingestAndReveal(params: IngestAndRevealParams): Promise<IngestAndRevealResult>;
|
|
3418
|
+
|
|
3419
|
+
/**
|
|
3420
|
+
* Mina receive-side swap settlement (toon-client#357, part of the rolling-swap
|
|
3421
|
+
* epic toon-meta#145; follow-up to the #352 receive-side ingestion PR).
|
|
3422
|
+
*
|
|
3423
|
+
* #352 shipped VERIFICATION of swapped-in Mina claims but explicitly left
|
|
3424
|
+
* REDEMPTION out: `POST /swap/settle` returned `SUBMISSION_UNSUPPORTED` for
|
|
3425
|
+
* `mina:*` bundles. This module is the missing redemption seam — it turns a
|
|
3426
|
+
* verified accumulated Mina claim into an on-chain co-signed `claimFromChannel`
|
|
3427
|
+
* transaction against the payment-channel zkApp.
|
|
3428
|
+
*
|
|
3429
|
+
* ## Why Mina needs a co-sign (and EVM/Solana do not)
|
|
3430
|
+
*
|
|
3431
|
+
* The zkApp's `claimFromChannel(newBalanceA, newBalanceB, newSalt, signatureA,
|
|
3432
|
+
* signatureB, participantA, participantB, channelNonce, newBalanceCommitment,
|
|
3433
|
+
* newNonce)` is DUAL-PARTY (connector#84): it verifies BOTH participants signed
|
|
3434
|
+
* the SAME message `[newBalanceCommitment, newNonce, storedChannelHash]`
|
|
3435
|
+
* (`packages/mina-zkapp/src/PaymentChannel.ts`). The client's existing
|
|
3436
|
+
* {@link MinaSigner} is payer-side only. On the swap RECEIVE side the client is
|
|
3437
|
+
* the RECIPIENT of the channel, so it must contribute the recipient's
|
|
3438
|
+
* co-signature (`signatureB` for its participant slot).
|
|
3439
|
+
*
|
|
3440
|
+
* ## Signature-message mismatch — the maker-side dependency
|
|
3441
|
+
*
|
|
3442
|
+
* The swap-wire claim (`AccumulatedClaim.claimBytes`) carries the maker's
|
|
3443
|
+
* Schnorr signature over `balanceProofFieldsMina(channelId, cumulativeAmount,
|
|
3444
|
+
* nonce, recipient)` (verified by the sdk's `verifyMinaSignature`). That is a
|
|
3445
|
+
* DIFFERENT message than the on-chain `[commitment, nonce, channelHash]`, so it
|
|
3446
|
+
* CANNOT be reused as an on-chain participant signature. On-chain redemption
|
|
3447
|
+
* therefore needs the maker to ALSO contribute a payment-channel-commitment-form
|
|
3448
|
+
* signature over `[commitment, nonce, channelHash]` (the same form the connector
|
|
3449
|
+
* payment-channel provider produces from a client claim). Until a maker delivers
|
|
3450
|
+
* that, {@link submitMinaSettlement} fails closed with
|
|
3451
|
+
* `MINA_MAKER_COSIGN_REQUIRED` (never a silent pass). See the PR body for the
|
|
3452
|
+
* cross-repo maker/wire follow-up.
|
|
3453
|
+
*
|
|
3454
|
+
* ## globalSlot preconditions
|
|
3455
|
+
*
|
|
3456
|
+
* Unlike `initiateClose`/`settle` (which pin `network.globalSlotSinceGenesis`
|
|
3457
|
+
* and were the subject of the #202 exact-slot-precondition bug), the zkApp's
|
|
3458
|
+
* `claimFromChannel` binds NO slot precondition — only `channelState == OPEN`,
|
|
3459
|
+
* `channelHash`, `depositTotal`, and a strictly-increasing `nonceField`. The
|
|
3460
|
+
* redeem path is therefore immune to the #202 slot-drift failure. The eventual
|
|
3461
|
+
* close+settle that pays escrow out to the recipient DOES touch the slot window
|
|
3462
|
+
* and remains the connector's `settleChannel` responsibility (a separate step).
|
|
3463
|
+
*
|
|
3464
|
+
* ## What runs where
|
|
3465
|
+
*
|
|
3466
|
+
* - On-chain STATE READ + co-sign assembly ({@link buildMinaCoSignedClaim}):
|
|
3467
|
+
* plain GraphQL + `mina-signer` (Pallas Schnorr / Poseidon) — NO o1js, fully
|
|
3468
|
+
* unit-testable in-process.
|
|
3469
|
+
* - Proof generation + broadcast ({@link submitMinaSettlement}): drives an
|
|
3470
|
+
* injectable {@link MinaClaimSubmitter}; the default is an o1js-backed settler
|
|
3471
|
+
* ({@link createO1jsMinaClaimSubmitter}) that dynamically imports `o1js` +
|
|
3472
|
+
* `@toon-protocol/mina-zkapp` only when invoked (never loaded by the non-Mina
|
|
3473
|
+
* suite). o1js circuit compilation + proving is slow (30-120s) and is exercised
|
|
3474
|
+
* only against live devnet Mina behind an env gate.
|
|
3475
|
+
*/
|
|
3476
|
+
|
|
3477
|
+
/** Bare Pallas Schnorr signature in the o1js JSON (decimal `r`/`s`) form. */
|
|
3478
|
+
interface MinaSignaturePair {
|
|
3479
|
+
r: string;
|
|
3480
|
+
s: string;
|
|
3481
|
+
}
|
|
3482
|
+
/** Stable failure codes for Mina receive-side settlement. */
|
|
3483
|
+
type MinaSettlementErrorCode = 'NOT_MINA_BUNDLE' | 'NO_GRAPHQL_CONFIGURED' | 'CHANNEL_NOT_OPEN' | 'NONCE_NOT_ADVANCING' | 'CHANNEL_HASH_MISMATCH' | 'CUMULATIVE_EXCEEDS_DEPOSIT' | 'MINA_MAKER_COSIGN_REQUIRED' | 'PROVING_FAILED';
|
|
3484
|
+
/** Result-shaped-by-throw settlement error carrying a stable {@link code}. */
|
|
3485
|
+
declare class MinaSettlementError extends Error {
|
|
3486
|
+
readonly code: MinaSettlementErrorCode;
|
|
3487
|
+
constructor(code: MinaSettlementErrorCode, message: string);
|
|
3488
|
+
}
|
|
3489
|
+
/** Inputs to {@link buildMinaCoSignedClaim} (pure assembly, no o1js). */
|
|
3490
|
+
interface MinaCoSignInputs {
|
|
3491
|
+
/** Deployed payment-channel zkApp address (B62) — the on-chain channel id. */
|
|
3492
|
+
channelId: string;
|
|
3493
|
+
/** Claim nonce being redeemed (must exceed the on-chain `nonceField`). */
|
|
3494
|
+
nonce: bigint;
|
|
3495
|
+
/** Cumulative amount credited to the recipient (base units). */
|
|
3496
|
+
cumulativeAmount: bigint;
|
|
3497
|
+
/** Recipient's Mina B62 pubkey — one channel participant (the co-signer). */
|
|
3498
|
+
recipient: string;
|
|
3499
|
+
/** Swap maker's Mina B62 pubkey — the other channel participant. */
|
|
3500
|
+
swapSignerAddress: string;
|
|
3501
|
+
/** On-chain `depositTotal` (base units) for balance conservation. */
|
|
3502
|
+
depositTotal: bigint;
|
|
3503
|
+
/** On-chain `channelHash` (decimal Field) used to resolve A/B ordering. */
|
|
3504
|
+
onChainChannelHash: string;
|
|
3505
|
+
/** Recipient's Mina private key (big-endian hex scalar OR `EK…` base58). */
|
|
3506
|
+
recipientPrivateKey: string;
|
|
3507
|
+
/** Channel nonce baked into the on-chain `channelHash` (default 0). */
|
|
3508
|
+
channelNonce?: bigint;
|
|
3509
|
+
/** Override the deterministic salt (else {@link deriveMinaSalt}). */
|
|
3510
|
+
saltOverride?: bigint;
|
|
3511
|
+
/**
|
|
3512
|
+
* Maker's payment-channel-commitment-form signature over
|
|
3513
|
+
* `[commitment, nonce, channelHash]`. REQUIRED for a fully-redeemable claim;
|
|
3514
|
+
* when absent the returned claim reports {@link makerSignatureMissing}.
|
|
3515
|
+
*/
|
|
3516
|
+
makerSignature?: MinaSignaturePair;
|
|
3517
|
+
}
|
|
3518
|
+
/** A dual-party claim assembled for the zkApp's `claimFromChannel`. */
|
|
3519
|
+
interface MinaCoSignedClaim {
|
|
3520
|
+
channelId: string;
|
|
3521
|
+
/** Balance credited to `participantA` (base units). */
|
|
3522
|
+
balanceA: bigint;
|
|
3523
|
+
/** Balance credited to `participantB` (`depositTotal - balanceA`). */
|
|
3524
|
+
balanceB: bigint;
|
|
3525
|
+
salt: bigint;
|
|
3526
|
+
nonce: bigint;
|
|
3527
|
+
channelNonce: bigint;
|
|
3528
|
+
/** `Poseidon([balanceA, balanceB, salt])`, decimal Field. */
|
|
3529
|
+
balanceCommitment: string;
|
|
3530
|
+
/** Participant A B62 (ordered to reproduce the on-chain `channelHash`). */
|
|
3531
|
+
participantA: string;
|
|
3532
|
+
/** Participant B B62. */
|
|
3533
|
+
participantB: string;
|
|
3534
|
+
/** Which participant slot the recipient/co-signer occupies. */
|
|
3535
|
+
recipientRole: 'A' | 'B';
|
|
3536
|
+
/** The recipient's co-signature over `[commitment, nonce, channelHash]`. */
|
|
3537
|
+
recipientSignature: MinaSignaturePair;
|
|
3538
|
+
/** Signature for participant A (recipient's or maker's per {@link recipientRole}). */
|
|
3539
|
+
signatureA?: MinaSignaturePair;
|
|
3540
|
+
/** Signature for participant B. */
|
|
3541
|
+
signatureB?: MinaSignaturePair;
|
|
3542
|
+
/** True when no maker co-signature was supplied (claim not yet redeemable). */
|
|
3543
|
+
makerSignatureMissing: boolean;
|
|
3544
|
+
}
|
|
3545
|
+
/**
|
|
3546
|
+
* Assemble a dual-party `claimFromChannel` claim from a verified swap claim.
|
|
3547
|
+
*
|
|
3548
|
+
* Pure crypto (GraphQL-read state is passed in): resolves the on-chain A/B
|
|
3549
|
+
* participant ordering by reproducing `channelHash`, conserves balances against
|
|
3550
|
+
* `depositTotal`, computes the Poseidon commitment, and produces the recipient's
|
|
3551
|
+
* co-signature over `[commitment, nonce, channelHash]` with `mina-signer`. No
|
|
3552
|
+
* o1js is loaded.
|
|
3553
|
+
*
|
|
3554
|
+
* @throws {MinaSettlementError} `CHANNEL_HASH_MISMATCH` when neither ordering of
|
|
3555
|
+
* `{recipient, swapSignerAddress}` reproduces `onChainChannelHash`;
|
|
3556
|
+
* `CUMULATIVE_EXCEEDS_DEPOSIT` when the credit exceeds the escrow.
|
|
3557
|
+
*/
|
|
3558
|
+
declare function buildMinaCoSignedClaim(inputs: MinaCoSignInputs): Promise<MinaCoSignedClaim>;
|
|
3559
|
+
/** Arguments handed to a {@link MinaClaimSubmitter} (o1js proving boundary). */
|
|
3560
|
+
interface MinaClaimSubmitArgs {
|
|
3561
|
+
/** Mina GraphQL endpoint bound as the active o1js network. */
|
|
3562
|
+
graphqlUrl: string;
|
|
3563
|
+
/** Channel zkApp address (B62). */
|
|
3564
|
+
channelId: string;
|
|
3565
|
+
balanceA: bigint;
|
|
3566
|
+
balanceB: bigint;
|
|
3567
|
+
salt: bigint;
|
|
3568
|
+
nonce: bigint;
|
|
3569
|
+
/** Participant pubkeys (B62), ordered to match the on-chain `channelHash`. */
|
|
3570
|
+
participantA: string;
|
|
3571
|
+
participantB: string;
|
|
3572
|
+
channelNonce: bigint;
|
|
3573
|
+
signatureA: MinaSignaturePair;
|
|
3574
|
+
signatureB: MinaSignaturePair;
|
|
3575
|
+
/** Fee-payer / submitter Mina private key (hex scalar or `EK…` base58). */
|
|
3576
|
+
feePayerPrivateKey: string;
|
|
3577
|
+
/** zkApp tx fee (nanomina); the default settler applies 0.1 MINA when unset. */
|
|
3578
|
+
txFeeNanomina?: bigint;
|
|
3579
|
+
}
|
|
3580
|
+
/**
|
|
3581
|
+
* Generates the o1js proof and broadcasts the `claimFromChannel` tx. Injected so
|
|
3582
|
+
* the assembly logic can be unit-tested without loading the WASM circuit runtime.
|
|
3583
|
+
*/
|
|
3584
|
+
interface MinaClaimSubmitter {
|
|
3585
|
+
claimFromChannel(args: MinaClaimSubmitArgs): Promise<{
|
|
3586
|
+
txHash: string;
|
|
3587
|
+
}>;
|
|
3588
|
+
}
|
|
3589
|
+
/** Read seam for the on-chain channel state (default: plain GraphQL). */
|
|
3590
|
+
type MinaChannelStateReader = (graphqlUrl: string, zkAppAddress: string) => Promise<MinaOnChainChannelState>;
|
|
3591
|
+
/** Context for {@link submitMinaSettlement}. */
|
|
3592
|
+
interface MinaSettlementContext {
|
|
3593
|
+
/** Mina GraphQL URL (reads state + binds the o1js network). */
|
|
3594
|
+
graphqlUrl?: string;
|
|
3595
|
+
/** Recipient's Mina private key (co-signs; also the default fee payer). */
|
|
3596
|
+
recipientPrivateKey: string;
|
|
3597
|
+
/** Maker's on-chain-form co-signature over `[commitment, nonce, channelHash]`. */
|
|
3598
|
+
makerSignature?: MinaSignaturePair;
|
|
3599
|
+
/** Fee-payer key override (defaults to `recipientPrivateKey`). */
|
|
3600
|
+
feePayerPrivateKey?: string;
|
|
3601
|
+
/** zkApp tx fee (nanomina). */
|
|
3602
|
+
txFeeNanomina?: bigint;
|
|
3603
|
+
/** Channel nonce for the on-chain `channelHash` (default 0). */
|
|
3604
|
+
channelNonce?: bigint;
|
|
3605
|
+
/** Inject a state reader (tests). Defaults to {@link readMinaChannelState}. */
|
|
3606
|
+
reader?: MinaChannelStateReader;
|
|
3607
|
+
/** Inject a proof submitter (tests). Defaults to an o1js-backed settler. */
|
|
3608
|
+
submitter?: MinaClaimSubmitter;
|
|
3609
|
+
}
|
|
3610
|
+
interface MinaSettlementResult {
|
|
3611
|
+
txHash: string;
|
|
3612
|
+
}
|
|
3613
|
+
/**
|
|
3614
|
+
* Redeem a verified Mina swap claim via a co-signed on-chain `claimFromChannel`.
|
|
3615
|
+
*
|
|
3616
|
+
* Env/config-gated like the EVM path: with no `graphqlUrl` the caller gets
|
|
3617
|
+
* `NO_GRAPHQL_CONFIGURED` (built-not-submitted). Reads the live channel state,
|
|
3618
|
+
* asserts it is OPEN and the claim nonce advances the on-chain watermark,
|
|
3619
|
+
* assembles the dual-party claim ({@link buildMinaCoSignedClaim}), and — only
|
|
3620
|
+
* with a maker co-signature present — drives the o1js proof + broadcast.
|
|
3621
|
+
*
|
|
3622
|
+
* @throws {MinaSettlementError} with a stable {@link MinaSettlementErrorCode}.
|
|
3623
|
+
*/
|
|
3624
|
+
declare function submitMinaSettlement(bundle: SettlementBundle, context: MinaSettlementContext): Promise<MinaSettlementResult>;
|
|
3625
|
+
/**
|
|
3626
|
+
* Build the default o1js-backed {@link MinaClaimSubmitter}.
|
|
3627
|
+
*
|
|
3628
|
+
* Mirrors the connector's `MinaPaymentChannelSDK.claimFromChannel`: binds the
|
|
3629
|
+
* active Mina network, fetches the channel + fee-payer accounts, deserializes the
|
|
3630
|
+
* `{r,s}` signatures, and builds + proves + broadcasts the zkApp
|
|
3631
|
+
* `claimFromChannel` method. o1js and `@toon-protocol/mina-zkapp` are imported
|
|
3632
|
+
* dynamically INSIDE `claimFromChannel` so the non-Mina test suite never loads
|
|
3633
|
+
* the multi-hundred-MB WASM circuit runtime. Compilation + proving are slow
|
|
3634
|
+
* (30-120s) and only run against live devnet Mina.
|
|
3635
|
+
*/
|
|
3636
|
+
declare function createO1jsMinaClaimSubmitter(): MinaClaimSubmitter;
|
|
3637
|
+
|
|
3038
3638
|
/**
|
|
3039
3639
|
* Configuration options for retry behavior with exponential backoff.
|
|
3040
3640
|
*/
|
|
@@ -3274,7 +3874,7 @@ declare function validateConfig(config: ToonClientConfig): void;
|
|
|
3274
3874
|
* The resolved config type after defaults are applied.
|
|
3275
3875
|
* secretKey is guaranteed to be present (auto-generated if omitted).
|
|
3276
3876
|
*/
|
|
3277
|
-
type ResolvedConfig = Required<Omit<ToonClientConfig, 'connector' | 'mnemonic' | 'mnemonicAccountIndex' | 'evmPrivateKey' | 'network' | 'supportedChains' | 'settlementAddresses' | 'preferredTokens' | 'tokenNetworks' | 'btpUrl' | 'btpAuthToken' | 'btpPeerId' | 'connectorHttpEndpoint' | 'proxyUrl' | 'faucetUrl' | 'connectorSupportsUpgrade' | 'chainRpcUrls' | 'initialDeposit' | 'settlementTimeout' | 'solanaChannel' | 'minaChannel' | 'channelStorePath' | 'knownPeers' | 'destinationAddress'>> & {
|
|
3877
|
+
type ResolvedConfig = Required<Omit<ToonClientConfig, 'connector' | 'mnemonic' | 'mnemonicAccountIndex' | 'evmPrivateKey' | 'network' | 'supportedChains' | 'settlementAddresses' | 'preferredTokens' | 'tokenNetworks' | 'btpUrl' | 'btpAuthToken' | 'btpPeerId' | 'connectorHttpEndpoint' | 'proxyUrl' | 'faucetUrl' | 'connectorSupportsUpgrade' | 'chainRpcUrls' | 'initialDeposit' | 'settlementTimeout' | 'solanaChannel' | 'minaChannel' | 'swapMinaMakerSignatures' | 'channelStorePath' | 'knownPeers' | 'destinationAddress'>> & {
|
|
3278
3878
|
connector?: unknown;
|
|
3279
3879
|
/** Always present after applyDefaults() — derived from secretKey if not explicitly provided */
|
|
3280
3880
|
evmPrivateKey: string | Uint8Array;
|
|
@@ -3308,6 +3908,7 @@ type ResolvedConfig = Required<Omit<ToonClientConfig, 'connector' | 'mnemonic' |
|
|
|
3308
3908
|
settlementTimeout?: number;
|
|
3309
3909
|
solanaChannel?: ToonClientConfig['solanaChannel'];
|
|
3310
3910
|
minaChannel?: ToonClientConfig['minaChannel'];
|
|
3911
|
+
swapMinaMakerSignatures?: ToonClientConfig['swapMinaMakerSignatures'];
|
|
3311
3912
|
channelStorePath?: string;
|
|
3312
3913
|
knownPeers?: {
|
|
3313
3914
|
pubkey: string;
|
|
@@ -3737,4 +4338,4 @@ declare function loadKeystore(path: string, password: string): string;
|
|
|
3737
4338
|
*/
|
|
3738
4339
|
declare function writeKeystoreFile(path: string, keystore: EncryptedKeystore): void;
|
|
3739
4340
|
|
|
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 };
|
|
4341
|
+
export { type BackupPayload, type BalanceProofParams, BtpRuntimeClient, type BtpRuntimeClientConfig, type BuildSwapSettlementsParams, CLAIM_TYPEHASH, CONDITION_LENGTH, COOP_CLOSE_TYPEHASH, type ChainMetadata, type ChainSigner, ChannelFundingError, ChannelManager, type ClaimMessage, type ClaimResolver, type ClaimSignature, ConnectorError, type DiscoveredIlpPeer, type EVMClaimMessage, type EncryptedKeystore, type EvmClaimDomainContext, type EvmClaimMessage, type EvmClaimVerifyResult, type EvmCooperativeCloseMessage, 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, InMemoryPreimageRetentionStore, InMemoryReceivedClaimStore, type IngestAndRevealParams, type IngestAndRevealResult, type IngestReceivedClaimsParams, type IngestReceivedClaimsResult, JsonFileReceivedClaimStore, KeyManager, type KeyManagerConfig, MINA_CHANNEL_STATE, type MinaChannelStateReader, type MinaClaimMessage, type MinaClaimSubmitArgs, type MinaClaimSubmitter, type MinaCoSignInputs, type MinaCoSignedClaim, type MinaDepositReader, type MinaOnChainChannelState, type MinaSettlementContext, MinaSettlementError, type MinaSettlementErrorCode, type MinaSettlementResult, type MinaSignaturePair, MinaSigner, type MinaSignerOptions, NetworkError, OnChainChannelClient, type OnChainChannelClientConfig, type ParsedFulfillHttp, type ParsedX402Challenge, type PasskeyInfo, type PreimageRetentionStore, type PublishEventResult, ROLLING_SWAP_DOMAIN_NAME, ROLLING_SWAP_DOMAIN_VERSION, type ReceivedClaimEntry, type ReceivedClaimRejection, type ReceivedClaimRejectionCode, type ReceivedClaimStore, type RequestBlobStorageParams, type RequestBlobStorageResult, type RetainedPreimage, type RetryOptions, type RevealDecision, type RevealFn, type RevealResult, type RevealedClaim, type RolledBackClaim, 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, buildMinaCoSignedClaim, buildSettlementInfo, buildStoreWriteEnvelope, buildSwapSettlements, createO1jsMinaClaimSubmitter, decodeEvmSettlementTx, decryptMnemonic, defaultFaucetTimeout, deriveFromNsec, deriveFullIdentity, deriveNostrKeyFromMnemonic, encryptMnemonic, entryToAccumulatedClaim, evmClaimDigest, evmCooperativeCloseDigest, extractArweaveTxId, fulfillmentMatchesCondition, fundWallet, generateKeystore, generateMnemonic, generateRandomIdentity, getNetworkStatus, hasSettlementMetadata, httpEndpointToBtpUrl, importKeystore, ingestAndReveal, ingestReceivedClaims, isInsufficientGasError, isPrfSupported, isZeroCondition, loadKeystore, mintExecutionCondition, parseBackupPayload, parseEvmChainId, parseFulfillHttp, parseFulfillHttpBytes, parseHttpResponse, parseX402Body, parseX402Challenge, proxyIlpEndpoint, readDiscoveredIlpPeer, readEvmNativeBalance, readEvmTokenBalance, readMinaBalance, readMinaChannelState, readMinaDepositTotal, readSolanaNativeBalance, readSolanaTokenBalance, readWalletBalances, recoverEvmClaimSigner, requestBlobStorage, selectIlpTransport, serializeHttpRequest, submitEvmSettlement, submitMinaSettlement, validateConfig, validateMnemonic, verifyEvmClaimSignature, withRetry, writeKeystoreFile };
|