@toon-protocol/client 0.20.3 → 0.21.1

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 CHANGED
@@ -177,8 +177,49 @@ interface SolanaChannelClientOptions {
177
177
  interface MinaChannelClientOptions {
178
178
  /** Mina GraphQL URL used to open the channel + read zkApp state. */
179
179
  graphqlUrl: string;
180
- /** Deployed payment-channel zkApp address (B62 base58). */
181
- zkAppAddress: string;
180
+ /**
181
+ * Deployed payment-channel zkApp address (B62 base58). Optional when
182
+ * `autoDeploy` is set — the open path then resolves (or deploys) a
183
+ * pair-owned zkApp itself.
184
+ */
185
+ zkAppAddress?: string;
186
+ /**
187
+ * Per-pair zkApp auto-deploy: the Mina `PaymentChannel` zkApp is
188
+ * single-pair (its on-chain channelHash bakes the participant pair at
189
+ * initialization), so a fresh identity can never reuse a shared/announced
190
+ * zkApp. With `autoDeploy`, opening a Mina channel first checks whether
191
+ * the recorded/configured zkApp is provably OURS for this pair and deploys
192
+ * a dedicated one otherwise (compile ≈1-3 min, inclusion ≈3-6 min,
193
+ * ~1.1 MINA + fees — surfaced through `onProgress`).
194
+ */
195
+ autoDeploy?: {
196
+ /** A previously recorded own deployment for this identity, if any. */
197
+ deployed?: {
198
+ zkAppAddress: string;
199
+ zkAppPrivateKey: string;
200
+ };
201
+ /**
202
+ * Persist hook — called with the zkApp address + key BEFORE the deploy tx
203
+ * is sent (and before the circuit compiles), so a crash between send and
204
+ * on-chain confirmation reuses the SAME zkApp next run instead of
205
+ * deploying (and paying ~1.1 MINA for) a second one.
206
+ */
207
+ onDeploying?: (record: {
208
+ zkAppAddress: string;
209
+ zkAppPrivateKey: string;
210
+ feePayer: string;
211
+ }) => void | Promise<void>;
212
+ /** Persist hook — called BEFORE the open proceeds on a fresh deploy. */
213
+ onDeployed?: (record: {
214
+ zkAppAddress: string;
215
+ zkAppPrivateKey: string;
216
+ feePayer: string;
217
+ deployTxHash?: string;
218
+ vkHash?: string;
219
+ }) => void | Promise<void>;
220
+ /** Progress lines for the slow compile/deploy/inclusion phases. */
221
+ onProgress?: (line: string) => void;
222
+ };
182
223
  /** Channel settlement timeout in slots for `initializeChannel` (default 86400). */
183
224
  challengeDuration?: number;
184
225
  /** Mina token id field (decimal string) for `initializeChannel` (default '1'). */
@@ -2571,7 +2612,50 @@ interface SolanaChannelConfig {
2571
2612
  interface MinaChannelConfig {
2572
2613
  graphqlUrl: string;
2573
2614
  privateKey: string;
2574
- zkAppAddress: string;
2615
+ /**
2616
+ * Deployed payment-channel zkApp address (B62). Optional when `autoDeploy`
2617
+ * is set — the open path then resolves (or deploys) a pair-owned zkApp
2618
+ * itself; see `mina-channel-deploy.ts`.
2619
+ */
2620
+ zkAppAddress?: string;
2621
+ /**
2622
+ * Per-pair zkApp auto-deploy (the Mina `PaymentChannel` zkApp is
2623
+ * single-pair: one deployment serves exactly one client↔connector pair).
2624
+ * When set, `openMinaChannel` first resolves a zkApp that is provably OURS
2625
+ * — the recorded `deployed` one, or `zkAppAddress` when its on-chain
2626
+ * channelHash matches this pair — and deploys a fresh one otherwise
2627
+ * (compile ≈1-3 min; inclusion ≈3-6 min; costs ~1.1 MINA + fees).
2628
+ * Without it, behavior is exactly the pre-autoDeploy contract: the
2629
+ * configured `zkAppAddress` is required and used verbatim.
2630
+ */
2631
+ autoDeploy?: {
2632
+ /** A previously recorded own deployment for this identity, if any. */
2633
+ deployed?: {
2634
+ zkAppAddress: string;
2635
+ zkAppPrivateKey: string;
2636
+ };
2637
+ /**
2638
+ * Persist hook — called with the zkApp address + key BEFORE the deploy tx
2639
+ * is sent (and before the circuit compiles), so a crash between send and
2640
+ * on-chain confirmation reuses the SAME zkApp next run instead of
2641
+ * deploying (and paying ~1.1 MINA for) a second one.
2642
+ */
2643
+ onDeploying?: (record: {
2644
+ zkAppAddress: string;
2645
+ zkAppPrivateKey: string;
2646
+ feePayer: string;
2647
+ }) => void | Promise<void>;
2648
+ /** Persist hook — called BEFORE the open proceeds on a fresh deploy. */
2649
+ onDeployed?: (record: {
2650
+ zkAppAddress: string;
2651
+ zkAppPrivateKey: string;
2652
+ feePayer: string;
2653
+ deployTxHash?: string;
2654
+ vkHash?: string;
2655
+ }) => void | Promise<void>;
2656
+ /** Progress lines (compile/deploy/inclusion phases take minutes). */
2657
+ onProgress?: (line: string) => void;
2658
+ };
2575
2659
  /**
2576
2660
  * Channel settlement timeout in slots for `initializeChannel`. Defaults to
2577
2661
  * `OpenChannelParams.settlementTimeout` or 86400.
@@ -4344,4 +4428,132 @@ declare function loadKeystore(path: string, password: string): string;
4344
4428
  */
4345
4429
  declare function writeKeystoreFile(path: string, keystore: EncryptedKeystore): void;
4346
4430
 
4347
- 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 };
4431
+ /**
4432
+ * Per-pair Mina `PaymentChannel` zkApp deployment — the missing zero-config
4433
+ * piece of the Mina channel-open path.
4434
+ *
4435
+ * The `PaymentChannel` zkApp is SINGLE-PAIR: `initializeChannel` bakes
4436
+ * `channelHash = Poseidon([participantA.x, participantB.x, nonce])` into the
4437
+ * zkApp's on-chain state, and the zkApp address IS the channel id. One
4438
+ * deployment therefore serves exactly one client↔connector pair — a fresh
4439
+ * client cannot reuse the pair-bound zkApp another identity opened (its claim
4440
+ * would fail `mina_claim_verification_failed`: wrong on-chain channelHash).
4441
+ *
4442
+ * {@link ensureOwnedMinaZkApp} makes the open path self-sufficient:
4443
+ *
4444
+ * 1. Check the candidates (a previously recorded own deployment first, then
4445
+ * the announce/preset-resolved address) for a zkApp that is ALREADY OURS
4446
+ * — on-chain OPEN with channelHash == Poseidon([client.x, peer.x, 0]),
4447
+ * or our own recorded deployment still awaiting initialization.
4448
+ * 2. Otherwise deploy a FRESH zkApp (new random zkApp key) from the same
4449
+ * npm `@toon-protocol/mina-zkapp` + o1js build the claim verifier uses —
4450
+ * the deployed verification key is the locally compiled one BY
4451
+ * CONSTRUCTION, so the "vk drift" class of failure cannot occur.
4452
+ *
4453
+ * The connector accepts claims against ANY zkApp it can read on-chain (its
4454
+ * inbound verify resolves the claim's `zkAppAddress` on-chain and registers
4455
+ * unknown channels dynamically), so no connector-side registration step is
4456
+ * needed.
4457
+ *
4458
+ * Deploy and initialize are SEPARATE transactions (connector Issue #128:
4459
+ * `initializeChannel`'s `getAndRequireEquals` precondition fails while the
4460
+ * account does not exist yet) — this module only DEPLOYS; the normal
4461
+ * {@link openMinaChannelOnChain} initialize+deposit flow runs afterwards.
4462
+ *
4463
+ * Reuses the `createRequire`-anchored o1js loader from `mina-channel-open.ts`
4464
+ * (one shared CJS o1js instance — the ESM/CJS split instance bug) and stays
4465
+ * lazy so npm consumers who never touch Mina never load the WASM runtime.
4466
+ *
4467
+ * @module
4468
+ */
4469
+ /** Everything worth persisting about an auto-deployed zkApp. */
4470
+ interface MinaZkAppDeployRecord {
4471
+ /** The deployed zkApp B62 address (== the channel id). */
4472
+ zkAppAddress: string;
4473
+ /** The zkApp's `EK…` base58 private key (needed to co-sign future txs). */
4474
+ zkAppPrivateKey: string;
4475
+ /** The fee payer (client Mina B62) that funded the deployment. */
4476
+ feePayer: string;
4477
+ /** Deploy tx hash, when the send surfaced one. */
4478
+ deployTxHash?: string;
4479
+ /** Verification-key hash of the compiled contract that was deployed. */
4480
+ vkHash?: string;
4481
+ }
4482
+ interface DeployMinaZkAppParams {
4483
+ /** Mina GraphQL endpoint to deploy through. */
4484
+ graphqlUrl: string;
4485
+ /** Fee payer private key (hex scalar or `EK…` base58 — same as the opener). */
4486
+ payerPrivateKey: string;
4487
+ /**
4488
+ * Deploy fee in nanomina. Default 100_000_000 (0.1 MINA); the new zkApp
4489
+ * account additionally costs the protocol's 1 MINA account-creation fee,
4490
+ * charged to the payer via `AccountUpdate.fundNewAccount`.
4491
+ */
4492
+ feeNanomina?: bigint;
4493
+ /**
4494
+ * Reuse THIS zkApp key (`EK…` base58) instead of generating a fresh one.
4495
+ * Used to re-attempt a deployment whose key was already recorded (so a
4496
+ * crashed/pending first attempt does not orphan a NEW ~1.1-MINA zkApp on
4497
+ * every retry — the SAME address is redeployed).
4498
+ */
4499
+ zkAppPrivateKey?: string;
4500
+ /**
4501
+ * Called with the zkApp address + key IMMEDIATELY after the key is known and
4502
+ * the fee-payer preflight passes — BEFORE the circuit compiles or the deploy
4503
+ * tx is sent. The rig store persists this so a crash between send and
4504
+ * confirmation reuses the SAME zkApp next run rather than deploying (and
4505
+ * paying for) a second one. Fired only for a freshly-generated key (a
4506
+ * redeploy of a recorded key is already persisted).
4507
+ */
4508
+ onDeploying?: (record: {
4509
+ zkAppAddress: string;
4510
+ zkAppPrivateKey: string;
4511
+ feePayer: string;
4512
+ }) => void | Promise<void>;
4513
+ /** Progress lines (compile/deploy/inclusion phases take minutes). */
4514
+ onProgress?: (line: string) => void;
4515
+ /** Inclusion poll interval ms (default 15_000; tests shrink it). */
4516
+ pollIntervalMs?: number;
4517
+ /** Inclusion poll budget ms (default 540_000 ≈ 9 min). */
4518
+ pollTimeoutMs?: number;
4519
+ }
4520
+ interface EnsureOwnedMinaZkAppParams extends DeployMinaZkAppParams {
4521
+ /** The connector peer's Mina settlement B62 (participantB of the pair). */
4522
+ peerPublicKey: string;
4523
+ /** A previously recorded own deployment for this identity/pair, if any. */
4524
+ deployed?: {
4525
+ zkAppAddress: string;
4526
+ zkAppPrivateKey: string;
4527
+ };
4528
+ /** The announce/preset-resolved zkApp address (checked after `deployed`). */
4529
+ candidateZkAppAddress?: string;
4530
+ /**
4531
+ * Called with the record IMMEDIATELY after a fresh deployment is confirmed
4532
+ * on-chain — BEFORE this function returns — so the zkApp key is persisted
4533
+ * even if the caller's subsequent initialize fails.
4534
+ */
4535
+ onDeployed?: (record: MinaZkAppDeployRecord) => void | Promise<void>;
4536
+ }
4537
+ interface EnsureOwnedMinaZkAppResult {
4538
+ /** The zkApp to open the channel on (ours — reused or freshly deployed). */
4539
+ zkAppAddress: string;
4540
+ /** True when this call deployed a fresh zkApp. */
4541
+ deployed: boolean;
4542
+ /** The deploy record (fresh deploys only). */
4543
+ record?: MinaZkAppDeployRecord;
4544
+ }
4545
+ /**
4546
+ * Deploy a fresh `PaymentChannel` zkApp (BARE — no initialization) and wait
4547
+ * for the account to exist on-chain. Returns the full deploy record; the
4548
+ * caller persists it (losing the zkApp key would strand the ~1.1 MINA the
4549
+ * deployment cost).
4550
+ */
4551
+ declare function deployMinaChannelZkApp(params: DeployMinaZkAppParams): Promise<MinaZkAppDeployRecord>;
4552
+ /**
4553
+ * Resolve the zkApp this (client, peer) pair should open its channel on:
4554
+ * reuse one that is provably ours, else deploy fresh. See the module doc for
4555
+ * the decision table.
4556
+ */
4557
+ declare function ensureOwnedMinaZkApp(params: EnsureOwnedMinaZkAppParams): Promise<EnsureOwnedMinaZkAppResult>;
4558
+
4559
+ 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 DeployMinaZkAppParams, type DiscoveredIlpPeer, type EVMClaimMessage, type EncryptedKeystore, type EnsureOwnedMinaZkAppParams, type EnsureOwnedMinaZkAppResult, 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, type MinaZkAppDeployRecord, 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, deployMinaChannelZkApp, deriveFromNsec, deriveFullIdentity, deriveNostrKeyFromMnemonic, encryptMnemonic, ensureOwnedMinaZkApp, 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 };
package/dist/index.js CHANGED
@@ -25,6 +25,11 @@ import {
25
25
  selectLatestAddressable,
26
26
  verifyRendererTrust
27
27
  } from "./chunk-QEMD5EAI.js";
28
+ import {
29
+ deployMinaChannelZkApp,
30
+ ensureOwnedMinaZkApp,
31
+ openMinaChannelOnChain
32
+ } from "./chunk-7TDAU43L.js";
28
33
 
29
34
  // src/ToonClient.ts
30
35
  import { generateSecretKey as generateSecretKey3, getPublicKey as getPublicKey2, finalizeEvent } from "nostr-tools/pure";
@@ -2186,181 +2191,6 @@ async function depositSolanaChannel(params) {
2186
2191
  return { depositTxSignature };
2187
2192
  }
2188
2193
 
2189
- // src/channel/mina-channel-open.ts
2190
- import { hexToMinaBase58PrivateKey as hexToMinaBase58PrivateKey2 } from "@toon-protocol/core";
2191
- var cachedO1js = null;
2192
- var cachedPaymentChannel = null;
2193
- var compiledContract = null;
2194
- var runtimeOverride = null;
2195
- async function loadMinaRuntime() {
2196
- if (cachedO1js && cachedPaymentChannel) {
2197
- return { o1js: cachedO1js, PaymentChannel: cachedPaymentChannel };
2198
- }
2199
- if (runtimeOverride) {
2200
- const injected = await runtimeOverride();
2201
- cachedO1js = injected.o1js;
2202
- cachedPaymentChannel = injected.PaymentChannel;
2203
- return injected;
2204
- }
2205
- const { createRequire } = await import("module");
2206
- const nodePath = await import("path");
2207
- const requireHere = createRequire(import.meta.url);
2208
- const mzkPkgPath = requireHere.resolve(
2209
- "@toon-protocol/mina-zkapp/package.json"
2210
- );
2211
- const requireFromMzk = createRequire(mzkPkgPath);
2212
- const o1js = requireFromMzk("o1js");
2213
- const mzkPkgJson = requireFromMzk(mzkPkgPath);
2214
- const mzkDir = nodePath.dirname(mzkPkgPath);
2215
- const mzkEntry = nodePath.join(mzkDir, mzkPkgJson.main ?? "dist/index.js");
2216
- const mzk = requireFromMzk(mzkEntry);
2217
- const PaymentChannel = mzk.PaymentChannel ?? mzk.default?.PaymentChannel;
2218
- if (!PaymentChannel) {
2219
- throw new Error(
2220
- "@toon-protocol/mina-zkapp does not export PaymentChannel \u2014 cannot open a Mina channel"
2221
- );
2222
- }
2223
- cachedO1js = o1js;
2224
- cachedPaymentChannel = PaymentChannel;
2225
- return { o1js, PaymentChannel };
2226
- }
2227
- async function getO1js() {
2228
- return (await loadMinaRuntime()).o1js;
2229
- }
2230
- async function getCompiledPaymentChannel() {
2231
- const { PaymentChannel } = await loadMinaRuntime();
2232
- if (!compiledContract) {
2233
- await PaymentChannel.compile();
2234
- compiledContract = PaymentChannel;
2235
- }
2236
- return compiledContract;
2237
- }
2238
- var MINA_CHANNEL_STATE_OPEN = 1n;
2239
- var MINA_CHANNEL_STATE_UNINITIALIZED = 0n;
2240
- async function openMinaChannelOnChain(params) {
2241
- const { Mina, PrivateKey, PublicKey, Field, AccountUpdate, fetchAccount } = await getO1js();
2242
- const network = Mina.Network(params.graphqlUrl);
2243
- Mina.setActiveInstance(network);
2244
- const txFee = params.feeNanomina ?? 100000000n;
2245
- const payerKeyBase58 = hexToMinaBase58PrivateKey2(params.payerPrivateKey);
2246
- const payerPrivateKey = PrivateKey.fromBase58(payerKeyBase58);
2247
- const payerPublicKey = payerPrivateKey.toPublicKey();
2248
- const zkAppPublicKey = PublicKey.fromBase58(params.zkAppAddress);
2249
- const readChannelState = async () => {
2250
- const res = await fetchAccount({ publicKey: zkAppPublicKey });
2251
- if (res.error || !res.account) {
2252
- throw new Error(
2253
- `Mina zkApp account ${params.zkAppAddress} not found on-chain (${String(
2254
- res.error
2255
- )}) \u2014 deploy the PaymentChannel zkApp before opening a channel`
2256
- );
2257
- }
2258
- const appState = res.account.zkapp?.appState;
2259
- const raw = appState?.[3]?.toString() ?? "0";
2260
- return BigInt(raw);
2261
- };
2262
- const readDepositTotal = async () => {
2263
- const res = await fetchAccount({ publicKey: zkAppPublicKey });
2264
- if (res.error || !res.account) {
2265
- throw new Error(
2266
- `Mina zkApp account ${params.zkAppAddress} not found on-chain (${String(
2267
- res.error
2268
- )}) \u2014 deploy the PaymentChannel zkApp before opening a channel`
2269
- );
2270
- }
2271
- const appState = res.account.zkapp?.appState;
2272
- const raw = appState?.[4]?.toString() ?? "0";
2273
- return BigInt(raw);
2274
- };
2275
- const currentState = await readChannelState();
2276
- await fetchAccount({ publicKey: payerPublicKey });
2277
- let opened = false;
2278
- let initTxHash;
2279
- let zkApp;
2280
- const getZkApp = async () => {
2281
- if (!zkApp) {
2282
- const PaymentChannel = await getCompiledPaymentChannel();
2283
- zkApp = new PaymentChannel(zkAppPublicKey);
2284
- }
2285
- return zkApp;
2286
- };
2287
- if (currentState === MINA_CHANNEL_STATE_UNINITIALIZED) {
2288
- const channel = await getZkApp();
2289
- const participantA = payerPublicKey;
2290
- const participantB = params.peerPublicKey ? PublicKey.fromBase58(params.peerPublicKey) : payerPublicKey;
2291
- const nonce = Field(0);
2292
- const timeoutField = Field((params.timeout ?? 86400n).toString());
2293
- const tokenIdField = Field(params.tokenId ?? "1");
2294
- await fetchAccount({ publicKey: zkAppPublicKey });
2295
- await fetchAccount({ publicKey: payerPublicKey });
2296
- const initTx = await Mina.transaction(
2297
- { sender: payerPublicKey, fee: Number(txFee) },
2298
- async () => {
2299
- await channel.initializeChannel(
2300
- participantA,
2301
- participantB,
2302
- nonce,
2303
- timeoutField,
2304
- tokenIdField
2305
- );
2306
- }
2307
- );
2308
- await initTx.prove();
2309
- const sentInit = await initTx.sign([payerPrivateKey]).send();
2310
- initTxHash = sentInit.hash ?? void 0;
2311
- opened = true;
2312
- await sentInit.wait();
2313
- await fetchAccount({ publicKey: zkAppPublicKey });
2314
- await fetchAccount({ publicKey: payerPublicKey });
2315
- } else if (currentState !== MINA_CHANNEL_STATE_OPEN) {
2316
- throw new Error(
2317
- `Mina channel ${params.zkAppAddress} is in state ${currentState} (not UNINITIALIZED/OPEN) \u2014 cannot open`
2318
- );
2319
- }
2320
- let depositTxHash;
2321
- if (params.deposit && params.deposit.amount > 0n) {
2322
- const channel = await getZkApp();
2323
- await fetchAccount({ publicKey: zkAppPublicKey });
2324
- const amountField = Field(params.deposit.amount.toString());
2325
- const depositTx = await Mina.transaction(
2326
- { sender: payerPublicKey, fee: Number(txFee) },
2327
- async () => {
2328
- await channel.deposit(amountField, payerPublicKey);
2329
- }
2330
- );
2331
- await depositTx.prove();
2332
- const sentDeposit = await depositTx.sign([payerPrivateKey]).send();
2333
- depositTxHash = sentDeposit.hash ?? void 0;
2334
- await sentDeposit.wait();
2335
- await fetchAccount({ publicKey: zkAppPublicKey });
2336
- await fetchAccount({ publicKey: payerPublicKey });
2337
- }
2338
- let finalState;
2339
- try {
2340
- finalState = Number(await readChannelState());
2341
- } catch {
2342
- finalState = opened ? Number(MINA_CHANNEL_STATE_OPEN) : Number(currentState);
2343
- }
2344
- if (opened && finalState === Number(MINA_CHANNEL_STATE_UNINITIALIZED)) {
2345
- finalState = Number(MINA_CHANNEL_STATE_OPEN);
2346
- }
2347
- void AccountUpdate;
2348
- let depositTotal;
2349
- try {
2350
- depositTotal = await readDepositTotal();
2351
- } catch {
2352
- depositTotal = 0n;
2353
- }
2354
- return {
2355
- zkAppAddress: params.zkAppAddress,
2356
- opened,
2357
- initTxHash,
2358
- depositTxHash,
2359
- channelState: finalState,
2360
- depositTotal
2361
- };
2362
- }
2363
-
2364
2194
  // src/channel/OnChainChannelClient.ts
2365
2195
  var TOKEN_NETWORK_ABI = [
2366
2196
  {
@@ -2585,7 +2415,9 @@ var OnChainChannelClient = class {
2585
2415
  return this.depositSolana(channelId, amount, opts.currentDeposit);
2586
2416
  }
2587
2417
  if (chainPrefix === "mina") {
2588
- throw new Error("Deposit on mina is not yet supported (EVM + Solana today; Mina follow-up).");
2418
+ throw new Error(
2419
+ "Deposit on mina is not yet supported (EVM + Solana today; Mina follow-up)."
2420
+ );
2589
2421
  }
2590
2422
  return this.depositEvm(channelId, amount, opts.currentDeposit, ctx);
2591
2423
  }
@@ -2601,7 +2433,9 @@ var OnChainChannelClient = class {
2601
2433
  }
2602
2434
  const cfg = this.solanaConfig;
2603
2435
  const payerSeed = cfg.keypair.slice(0, 32);
2604
- const payerPubkey = base58Encode2(new Uint8Array(ed255192.getPublicKey(payerSeed)));
2436
+ const payerPubkey = base58Encode2(
2437
+ new Uint8Array(ed255192.getPublicKey(payerSeed))
2438
+ );
2605
2439
  let payerTokenAccount = cfg.deposit?.payerTokenAccount;
2606
2440
  if (!payerTokenAccount) {
2607
2441
  if (!cfg.tokenMint) {
@@ -2609,7 +2443,10 @@ var OnChainChannelClient = class {
2609
2443
  "Solana deposit requires solanaConfig.deposit.payerTokenAccount or solanaConfig.tokenMint to derive the payer ATA."
2610
2444
  );
2611
2445
  }
2612
- payerTokenAccount = deriveAssociatedTokenAccount(payerPubkey, cfg.tokenMint);
2446
+ payerTokenAccount = deriveAssociatedTokenAccount(
2447
+ payerPubkey,
2448
+ cfg.tokenMint
2449
+ );
2613
2450
  }
2614
2451
  const { depositTxSignature } = await depositSolanaChannel({
2615
2452
  rpcUrl: cfg.rpcUrl,
@@ -2620,7 +2457,10 @@ var OnChainChannelClient = class {
2620
2457
  payerTokenAccount,
2621
2458
  amount
2622
2459
  });
2623
- return { txHash: depositTxSignature, depositTotal: currentDeposit + amount };
2460
+ return {
2461
+ txHash: depositTxSignature,
2462
+ depositTotal: currentDeposit + amount
2463
+ };
2624
2464
  }
2625
2465
  /**
2626
2466
  * EVM deposit: approve the token-network for the delta if the allowance is
@@ -2689,7 +2529,11 @@ var OnChainChannelClient = class {
2689
2529
  args: [channelId]
2690
2530
  });
2691
2531
  await publicClient.waitForTransactionReceipt({ hash: closeHash });
2692
- const info = await this.readEvmChannel(publicClient, tokenNetworkAddr, channelId);
2532
+ const info = await this.readEvmChannel(
2533
+ publicClient,
2534
+ tokenNetworkAddr,
2535
+ channelId
2536
+ );
2693
2537
  return {
2694
2538
  txHash: closeHash,
2695
2539
  closedAt: info.closedAt,
@@ -2733,13 +2577,20 @@ var OnChainChannelClient = class {
2733
2577
  */
2734
2578
  async getChannelCloseInfo(channelId) {
2735
2579
  const ctx = this.channelContext.get(channelId);
2736
- if (!ctx) throw new Error(`No on-chain context for channel "${channelId}".`);
2580
+ if (!ctx)
2581
+ throw new Error(`No on-chain context for channel "${channelId}".`);
2737
2582
  const chainPrefix = ctx.chain.split(":")[0];
2738
2583
  if (chainPrefix === "solana" || chainPrefix === "mina") {
2739
- throw new Error(`getChannelCloseInfo on ${chainPrefix} is not supported.`);
2584
+ throw new Error(
2585
+ `getChannelCloseInfo on ${chainPrefix} is not supported.`
2586
+ );
2740
2587
  }
2741
2588
  const { publicClient } = this.createClients(ctx.chain);
2742
- const info = await this.readEvmChannel(publicClient, ctx.tokenNetworkAddress, channelId);
2589
+ const info = await this.readEvmChannel(
2590
+ publicClient,
2591
+ ctx.tokenNetworkAddress,
2592
+ channelId
2593
+ );
2743
2594
  return {
2744
2595
  status: STATE_MAP2[info.state] ?? "open",
2745
2596
  closedAt: info.closedAt,
@@ -2755,7 +2606,11 @@ var OnChainChannelClient = class {
2755
2606
  functionName: "channels",
2756
2607
  args: [channelId]
2757
2608
  });
2758
- return { settlementTimeout: res[0], state: Number(res[1]), closedAt: res[2] };
2609
+ return {
2610
+ settlementTimeout: res[0],
2611
+ state: Number(res[1]),
2612
+ closedAt: res[2]
2613
+ };
2759
2614
  }
2760
2615
  /**
2761
2616
  * Read a participant's on-chain channel state — `deposit` (locked collateral),
@@ -2870,15 +2725,29 @@ var OnChainChannelClient = class {
2870
2725
  "Mina channel config not provided \u2014 cannot open Mina channel"
2871
2726
  );
2872
2727
  }
2873
- const zkAppAddress = this.minaConfig.zkAppAddress;
2874
- if (!zkAppAddress) {
2728
+ if (!params.peerAddress) {
2875
2729
  throw new Error(
2876
- "Mina channel requires a deployed zkAppAddress (minaConfig.zkAppAddress)"
2730
+ "Mina channel requires peerAddress (apex Mina settlement B62) so the on-chain channel is opened two-party \u2014 the participant-form claim cannot settle against a single-party channel"
2877
2731
  );
2878
2732
  }
2879
- if (!params.peerAddress) {
2733
+ let zkAppAddress = this.minaConfig.zkAppAddress;
2734
+ if (this.minaConfig.autoDeploy) {
2735
+ const { ensureOwnedMinaZkApp: ensureOwnedMinaZkApp2 } = await import("./mina-channel-deploy-5GPMFBGR.js");
2736
+ const ensured = await ensureOwnedMinaZkApp2({
2737
+ graphqlUrl: this.minaConfig.graphqlUrl,
2738
+ payerPrivateKey: this.minaConfig.privateKey,
2739
+ peerPublicKey: params.peerAddress,
2740
+ ...this.minaConfig.autoDeploy.deployed ? { deployed: this.minaConfig.autoDeploy.deployed } : {},
2741
+ ...zkAppAddress ? { candidateZkAppAddress: zkAppAddress } : {},
2742
+ ...this.minaConfig.autoDeploy.onDeploying ? { onDeploying: this.minaConfig.autoDeploy.onDeploying } : {},
2743
+ ...this.minaConfig.autoDeploy.onDeployed ? { onDeployed: this.minaConfig.autoDeploy.onDeployed } : {},
2744
+ ...this.minaConfig.autoDeploy.onProgress ? { onProgress: this.minaConfig.autoDeploy.onProgress } : {}
2745
+ });
2746
+ zkAppAddress = ensured.zkAppAddress;
2747
+ }
2748
+ if (!zkAppAddress) {
2880
2749
  throw new Error(
2881
- "Mina channel requires peerAddress (apex Mina settlement B62) so the on-chain channel is opened two-party \u2014 the participant-form claim cannot settle against a single-party channel"
2750
+ "Mina channel requires a deployed zkAppAddress (minaConfig.zkAppAddress)"
2882
2751
  );
2883
2752
  }
2884
2753
  const timeout = BigInt(
@@ -3327,7 +3196,7 @@ var SolanaSigner = class {
3327
3196
  };
3328
3197
 
3329
3198
  // src/signing/mina-signer.ts
3330
- import { hexToMinaBase58PrivateKey as hexToMinaBase58PrivateKey3 } from "@toon-protocol/core";
3199
+ import { hexToMinaBase58PrivateKey as hexToMinaBase58PrivateKey2 } from "@toon-protocol/core";
3331
3200
  import { sha256 as sha2563 } from "@noble/hashes/sha2.js";
3332
3201
  import { bytesToHex } from "@noble/hashes/utils.js";
3333
3202
 
@@ -3574,7 +3443,7 @@ var MinaSigner = class {
3574
3443
  "MinaSigner requires a zkAppAddress (channel id) to sign a balance proof"
3575
3444
  );
3576
3445
  }
3577
- const minaPrivateKey = hexToMinaBase58PrivateKey3(this.privateKey);
3446
+ const minaPrivateKey = hexToMinaBase58PrivateKey2(this.privateKey);
3578
3447
  const tokenId = params.metadata.tokenId ?? DEFAULT_MINA_TOKEN_ID;
3579
3448
  const salt = deriveMinaSalt(zkAppAddress, params.nonce);
3580
3449
  const clientPubKey = this.publicKeyBase58 ?? await this.deriveOwnPublicKey(minaPrivateKey);
@@ -4861,7 +4730,7 @@ async function submitEvmSettlement(bundle, params) {
4861
4730
  }
4862
4731
 
4863
4732
  // src/swap/mina-settlement.ts
4864
- import { hexToMinaBase58PrivateKey as hexToMinaBase58PrivateKey4 } from "@toon-protocol/core";
4733
+ import { hexToMinaBase58PrivateKey as hexToMinaBase58PrivateKey3 } from "@toon-protocol/core";
4865
4734
  var MinaSettlementError = class extends Error {
4866
4735
  code;
4867
4736
  constructor(code, message) {
@@ -4930,7 +4799,7 @@ async function buildMinaCoSignedClaim(inputs) {
4930
4799
  balanceB,
4931
4800
  salt
4932
4801
  ).toString();
4933
- const recipientPrivateKeyBase58 = hexToMinaBase58PrivateKey4(
4802
+ const recipientPrivateKeyBase58 = hexToMinaBase58PrivateKey3(
4934
4803
  inputs.recipientPrivateKey
4935
4804
  );
4936
4805
  const built = await buildMinaPaymentChannelProof({
@@ -5057,7 +4926,7 @@ function createO1jsMinaClaimSubmitter() {
5057
4926
  const PaymentChannel = zkAppMod.PaymentChannel;
5058
4927
  Mina.setActiveInstance(Mina.Network(args.graphqlUrl));
5059
4928
  const feePayerKey = PrivateKey.fromBase58(
5060
- hexToMinaBase58PrivateKey4(args.feePayerPrivateKey)
4929
+ hexToMinaBase58PrivateKey3(args.feePayerPrivateKey)
5061
4930
  );
5062
4931
  const feePayerPub = feePayerKey.toPublicKey();
5063
4932
  await PaymentChannel.compile();
@@ -5350,7 +5219,8 @@ var ToonClient = class {
5350
5219
  if (this.config.minaChannel && this.minaPrivateKey) {
5351
5220
  initialization.onChainChannelClient.setMinaConfig({
5352
5221
  graphqlUrl: this.config.minaChannel.graphqlUrl,
5353
- zkAppAddress: this.config.minaChannel.zkAppAddress,
5222
+ ...this.config.minaChannel.zkAppAddress !== void 0 ? { zkAppAddress: this.config.minaChannel.zkAppAddress } : {},
5223
+ ...this.config.minaChannel.autoDeploy !== void 0 ? { autoDeploy: this.config.minaChannel.autoDeploy } : {},
5354
5224
  privateKey: this.minaPrivateKey,
5355
5225
  ...this.config.minaChannel.challengeDuration !== void 0 ? { challengeDuration: this.config.minaChannel.challengeDuration } : {},
5356
5226
  ...this.config.minaChannel.tokenId !== void 0 ? { tokenId: this.config.minaChannel.tokenId } : {},
@@ -8093,11 +7963,13 @@ export {
8093
7963
  decodeEvmSettlementTx,
8094
7964
  decryptMnemonic2 as decryptMnemonic,
8095
7965
  defaultFaucetTimeout,
7966
+ deployMinaChannelZkApp,
8096
7967
  deriveFromNsec,
8097
7968
  deriveFullIdentity,
8098
7969
  deriveNostrKeyFromMnemonic,
8099
7970
  deterministicGenerator,
8100
7971
  encryptMnemonic2 as encryptMnemonic,
7972
+ ensureOwnedMinaZkApp,
8101
7973
  entryToAccumulatedClaim,
8102
7974
  evmClaimDigest,
8103
7975
  evmCooperativeCloseDigest,