@toon-protocol/client 0.20.0 → 0.20.2

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
@@ -427,7 +427,7 @@ interface ToonClientConfig {
427
427
  }>;
428
428
  /** File path for persisting payment channel nonce/amount state across restarts */
429
429
  channelStorePath?: string;
430
- /** Nostr relay URL for peer discovery. Default: 'ws://localhost:7100' */
430
+ /** Nostr relay URL for peer discovery. Default: 'wss://relay-ws.devnet.toonprotocol.dev' */
431
431
  relayUrl?: string;
432
432
  /**
433
433
  * Known peers to bootstrap with.
@@ -3932,17 +3932,21 @@ declare function buildSettlementInfo(rawConfig: ToonClientConfig): ClientSettlem
3932
3932
  /**
3933
3933
  * Devnet faucet helper.
3934
3934
  *
3935
- * The deployed TOON devnet exposes a faucet that drips test funds to a given
3936
- * chain address so a client can open payment channels and pay for writes:
3935
+ * The deployed TOON devnet exposes a faucet that drips the settlement token
3936
+ * (USDC) to a given chain address so a client can open payment channels and pay
3937
+ * for writes. This helper hits the USDC-ONLY faucet legs — it funds USDC and
3938
+ * assumes the wallet already holds enough native gas to transact:
3937
3939
  *
3938
- * EVM `POST {faucetUrl}/api/request` body `{ address }` → 100 ETH + 10k USDC
3939
- * Solana `POST {faucetUrl}/api/solana/request` body `{ address }` → SOL + USDC
3940
- * Mina `POST {faucetUrl}/api/mina/request` body `{ address }` → native MINA + USDC
3940
+ * EVM `POST {faucetUrl}/api/base-sepolia/request` body `{ address }` → USDC (Base Sepolia mint)
3941
+ * Solana `POST {faucetUrl}/api/solana/usdc-request` body `{ address }` → USDC (no SOL leg)
3942
+ * Mina `POST {faucetUrl}/api/mina/usdc-request` body `{ address }` → USDC (no MINA leg)
3941
3943
  *
3942
3944
  * Devnet edge (today): `https://faucet.devnet.toonprotocol.dev`.
3943
3945
  *
3944
3946
  * All three chains are live on the deployed faucet — the request shape is
3945
- * identical (`{ address }`); only the path differs.
3947
+ * identical (`{ address }`); only the path differs. (The EVM leg mints the
3948
+ * ungated mock USDC on Base Sepolia and best-effort tops up gas; the Solana and
3949
+ * Mina legs are strictly USDC-only and expect the address to already hold gas.)
3946
3950
  */
3947
3951
  /** Supported faucet chains. */
3948
3952
  type FaucetChain = 'evm' | 'solana' | 'mina';
@@ -3969,12 +3973,12 @@ interface FundWalletOptions {
3969
3973
  /**
3970
3974
  * Default faucet request timeout (ms) for a chain.
3971
3975
  *
3972
- * EVM and Solana faucets respond in a few seconds, so 30s is plenty. The Mina
3973
- * faucet sends native MINA *and* mints USDC on a chain that settles much more
3974
- * slowly: the drip routinely succeeds server-side (the faucet logs
3975
- * `✅ Mina faucet request completed`) but takes well over 30s to answer the
3976
- * HTTP request, so a flat 30s budget makes the client give up on a request that
3977
- * actually worked. Give mina a much longer budget.
3976
+ * The EVM (Base Sepolia mint) and Solana USDC legs respond in a few seconds, so
3977
+ * 30s is plenty. The Mina USDC leg TRANSFERS the token via an o1js-proven
3978
+ * transaction on a chain that settles much more slowly: the drip routinely
3979
+ * succeeds server-side but takes well over 30s to answer the HTTP request, so a
3980
+ * flat 30s budget makes the client give up on a request that actually worked.
3981
+ * Give mina a much longer budget.
3978
3982
  */
3979
3983
  declare function defaultFaucetTimeout(chain: FaucetChain): number;
3980
3984
  /**
package/dist/index.js CHANGED
@@ -470,7 +470,10 @@ function applyDefaults(rawConfig) {
470
470
  connectorUrl,
471
471
  // Surface the derived `POST /ilp` endpoint so HTTP mode selects HttpIlpClient.
472
472
  ...connectorHttpEndpoint ? { connectorHttpEndpoint } : {},
473
- relayUrl: config.relayUrl ?? "ws://localhost:7100",
473
+ // Last-resort relay default. An explicit `config.relayUrl` always wins;
474
+ // `applyNetworkPresets` does not set a per-network relay, so this fallback
475
+ // points at the public devnet relay rather than a dead localhost socket.
476
+ relayUrl: config.relayUrl ?? "wss://relay-ws.devnet.toonprotocol.dev",
474
477
  queryTimeout: config.queryTimeout ?? 3e4,
475
478
  maxRetries: config.maxRetries ?? 3,
476
479
  retryDelay: config.retryDelay ?? 1e3,
@@ -1871,6 +1874,17 @@ function deriveChannelPDA(participantA, participantB, tokenMint, programId) {
1871
1874
  const { pda, bump } = findProgramAddress(seeds, program);
1872
1875
  return { pda: base58Encode(pda), bump };
1873
1876
  }
1877
+ function deriveAssociatedTokenAccount(owner, tokenMint) {
1878
+ const TOKEN_PROGRAM_ID2 = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
1879
+ const ASSOCIATED_TOKEN_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
1880
+ const seeds = [
1881
+ padTo32(base58Decode(owner)),
1882
+ padTo32(base58Decode(TOKEN_PROGRAM_ID2)),
1883
+ padTo32(base58Decode(tokenMint))
1884
+ ];
1885
+ const { pda } = findProgramAddress(seeds, padTo32(base58Decode(ASSOCIATED_TOKEN_PROGRAM_ID)));
1886
+ return base58Encode(pda);
1887
+ }
1874
1888
  function deriveVaultPDA(channelPDA, programId) {
1875
1889
  const channel = padTo32(base58Decode(channelPDA));
1876
1890
  const program = padTo32(base58Decode(programId));
@@ -2586,14 +2600,17 @@ var OnChainChannelClient = class {
2586
2600
  throw new Error("Solana channel config not set \u2014 cannot deposit.");
2587
2601
  }
2588
2602
  const cfg = this.solanaConfig;
2589
- const payerTokenAccount = cfg.deposit?.payerTokenAccount;
2590
- if (!payerTokenAccount) {
2591
- throw new Error(
2592
- "Solana deposit requires solanaConfig.deposit.payerTokenAccount (the funded SPL token account)."
2593
- );
2594
- }
2595
2603
  const payerSeed = cfg.keypair.slice(0, 32);
2596
2604
  const payerPubkey = base58Encode2(new Uint8Array(ed255192.getPublicKey(payerSeed)));
2605
+ let payerTokenAccount = cfg.deposit?.payerTokenAccount;
2606
+ if (!payerTokenAccount) {
2607
+ if (!cfg.tokenMint) {
2608
+ throw new Error(
2609
+ "Solana deposit requires solanaConfig.deposit.payerTokenAccount or solanaConfig.tokenMint to derive the payer ATA."
2610
+ );
2611
+ }
2612
+ payerTokenAccount = deriveAssociatedTokenAccount(payerPubkey, cfg.tokenMint);
2613
+ }
2597
2614
  const { depositTxSignature } = await depositSolanaChannel({
2598
2615
  rpcUrl: cfg.rpcUrl,
2599
2616
  programId: cfg.programId,
@@ -2799,7 +2816,9 @@ var OnChainChannelClient = class {
2799
2816
  );
2800
2817
  const deposit = cfg.deposit ? {
2801
2818
  amount: BigInt(cfg.deposit.amount),
2802
- payerTokenAccount: cfg.deposit.payerTokenAccount
2819
+ // Derive the payer ATA (owner + channel mint) when not supplied — it is
2820
+ // deterministic, so the caller need not thread payerTokenAccount through.
2821
+ payerTokenAccount: cfg.deposit.payerTokenAccount || deriveAssociatedTokenAccount(payerPubkey, tokenMint)
2803
2822
  } : void 0;
2804
2823
  const { channelPDA } = await openSolanaChannel({
2805
2824
  rpcUrl: cfg.rpcUrl,
@@ -6852,11 +6871,11 @@ function defaultFaucetTimeout(chain) {
6852
6871
  function faucetPath(chain) {
6853
6872
  switch (chain) {
6854
6873
  case "evm":
6855
- return "/api/request";
6874
+ return "/api/base-sepolia/request";
6856
6875
  case "solana":
6857
- return "/api/solana/request";
6876
+ return "/api/solana/usdc-request";
6858
6877
  case "mina":
6859
- return "/api/mina/request";
6878
+ return "/api/mina/usdc-request";
6860
6879
  }
6861
6880
  }
6862
6881
  async function fundWallet(faucetUrl, address, chain, options = {}) {