@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/chunk-7TDAU43L.js +412 -0
- package/dist/chunk-7TDAU43L.js.map +1 -0
- package/dist/index.d.ts +216 -4
- package/dist/index.js +67 -195
- package/dist/index.js.map +1 -1
- package/dist/mina-channel-deploy-5GPMFBGR.js +9 -0
- package/dist/mina-channel-deploy-5GPMFBGR.js.map +1 -0
- package/package.json +1 -1
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
|
-
/**
|
|
181
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
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(
|
|
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)
|
|
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(
|
|
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(
|
|
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 {
|
|
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
|
-
|
|
2874
|
-
if (!zkAppAddress) {
|
|
2728
|
+
if (!params.peerAddress) {
|
|
2875
2729
|
throw new Error(
|
|
2876
|
-
"Mina channel requires
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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,
|