@tokamak-private-dapps/private-state-cli 2.3.2 → 2.3.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 2.3.4 - 2026-05-29
6
+
7
+ - Removed the implicit wallet proof context recovery path so proof-backed wallet commands require
8
+ their channel context to be prepared before proof generation.
9
+ - Added a post-proof, pre-submit channel root check for proof-backed channel state updates so stale
10
+ proofs are rejected before submitting transactions whenever the root changed during proof generation.
11
+
12
+ ## 2.3.3 - 2026-05-27
13
+
14
+ - Changed `help observer` and monitoring references to use the public observer URL
15
+ `https://observer.tonnel.io`.
16
+ - Clarified CLI help, guide output, and README guidance so channel join tolls are paid directly
17
+ from the L1 wallet, while `account deposit-bridge` is only for channel liquidity.
18
+ - Clarified README and `help commands` guidance so AI agents answer user gas, fee, and USD cost
19
+ questions by running `help transaction-fees --json` instead of escalating to developers.
20
+
5
21
  ## 2.3.2 - 2026-05-21
6
22
 
7
23
  - Clarified `wallet transfer-notes` JSON-array argument formats in CLI help and README guidance.
package/README.md CHANGED
@@ -131,11 +131,11 @@ and the global CLI npm package when npm reports that it is globally installed.
131
131
 
132
132
  ## Commands
133
133
 
134
- A common private-state flow is:
134
+ A common note-use flow after channel policy review is:
135
135
 
136
136
  1. `channel create`
137
- 2. `account deposit-bridge`
138
- 3. `channel join`
137
+ 2. `channel join`
138
+ 3. `account deposit-bridge`
139
139
  4. `wallet deposit-channel`
140
140
  5. `wallet mint-notes`
141
141
  6. `wallet transfer-notes`
@@ -145,6 +145,8 @@ A common private-state flow is:
145
145
  10. `channel exit`
146
146
  11. `account withdraw-bridge`
147
147
 
148
+ `channel join` pays any join toll directly from the L1 wallet; `account deposit-bridge` funds later channel liquidity and does not pay the join toll.
149
+
148
150
  Use `private-state-cli help commands` for the full command list and required options. `private-state-cli --help`
149
151
  continues to print the same command list for shell compatibility.
150
152
 
@@ -312,7 +314,8 @@ private-state-cli help transaction-fees --network mainnet
312
314
  `help transaction-fees` uses the measured gas data packaged in `assets/tx-fees.json`, the selected network's live fee data,
313
315
  and live ETH/USD pricing to print an ETH/USD fee table for transaction-sending commands. The table separates typical
314
316
  cost, based on the RPC `gasPrice`, from worst-case cost, based on `maxFeePerGas` when the network reports EIP-1559 fee
315
- data.
317
+ data. AI agents answering user questions about gas, transaction fees, transaction cost, or USD cost should run
318
+ `private-state-cli help transaction-fees --network <NETWORK> --json` and answer from the returned table.
316
319
 
317
320
  Proof-backed note commands can use a separate L1 transaction submitter:
318
321
 
@@ -529,6 +532,10 @@ Operating rules:
529
532
  recovery can be very slow because it scans channel logs from the creation block. If a channel workspace mirror is
530
533
  available, try mirror-based recovery first, and use RPC genesis replay only when mirror recovery is unavailable or
531
534
  unsuitable.
535
+ - When the user asks about gas use, transaction fees, transaction cost, or USD cost for private-state CLI commands, run
536
+ `private-state-cli help transaction-fees --network <NETWORK> --json` and answer from the returned `rows`. If the
537
+ network is unclear, ask which network to use. Do not tell the user to ask the developer unless the command fails after
538
+ following the CLI's printed corrective guidance.
532
539
  - When `channel recover-workspace` or `wallet recover-workspace` is unexpectedly slow, first inspect the RPC provider
533
540
  configured by `set rpc`. Explain that recovery speed is dominated by `eth_getLogs` block range cap and log request
534
541
  rate. Suggest re-running `set rpc` with a provider that supports a larger block range cap, such as Ankr or Chainnodes
@@ -553,7 +560,7 @@ Operating rules:
553
560
  8. prepare a wallet secret source file locally, for example with `openssl rand -hex 32 > ./wallet-secret.txt`
554
561
  9. inspect the channel with `channel get-meta` if it already exists, or create it with `channel create` if the user is
555
562
  the channel creator
556
- 10. explain the immutable policy warning printed by the CLI
563
+ 10. explain the immutable policy warning and that the join toll is paid directly from the L1 wallet, not bridge-deposited balance
557
564
  11. run `channel join --channel-name <CHANNEL> --network <NETWORK> --account <ACCOUNT> --wallet-secret-path <PATH> --acknowledge-action-impact`
558
565
  - Before executing any command for a user that requires an `--acknowledge-*` option, strongly warn the user in plain
559
566
  language about what that acknowledgement means and ask for explicit confirmation. Do not add
@@ -585,7 +592,7 @@ Operating rules:
585
592
  - Do not present one fixed command sequence as universally correct. Some flows start from an existing channel or wallet,
586
593
  while others require creating or joining a channel first.
587
594
  - When the user asks for a transfer, first determine whether the sender has minted notes available. If not, guide them
588
- through funding the bridge, joining or recovering the channel wallet, depositing into the channel, and minting notes.
595
+ through joining or recovering the channel wallet, funding the bridge for channel liquidity, depositing into the channel, and minting notes.
589
596
  - When generating commands, use placeholders for secrets and explicit values for public fields. Show one command at a
590
597
  time unless the user asks for a batch.
591
598
 
@@ -596,7 +603,7 @@ Suggested interaction flow:
596
603
  3. Identify the sender and recipient wallets or local account names.
597
604
  4. Run `help doctor`.
598
605
  5. Run `wallet list` and relevant metadata or balance checks.
599
- 6. If needed, guide the user through `channel create`, `account deposit-bridge`, `channel join`, `wallet deposit-channel`, and
606
+ 6. If needed, guide the user through `channel create`, `channel join`, `account deposit-bridge`, `wallet deposit-channel`, and
600
607
  `wallet mint-notes`.
601
608
  7. For a confidential note transfer, select available note IDs from `wallet get-notes`, find the recipient L2 address from
602
609
  `wallet get-meta`, then build `wallet transfer-notes` with JSON arrays for `--note-ids`, `--recipients`, and `--amounts`.
@@ -422,11 +422,12 @@
422
422
  <li>
423
423
  <span class="guide-label">Join a channel:</span> <code>channel join</code>
424
424
  <div class="guide-example">
425
- <code>channel join --channel-name 'my-private-channel' --network 'sepolia' --account 'my-account' --wallet-secret-path '/path/to/wallet-secret'</code>
425
+ <code>channel join --channel-name 'my-private-channel' --network 'sepolia' --account 'my-account' --wallet-secret-path '/path/to/wallet-secret'</code><br />
426
+ Pays the join toll directly from the L1 wallet, not from bridge-deposited balance.
426
427
  </div>
427
428
  </li>
428
429
  <li>
429
- <span class="guide-label">Create notes:</span> <code>account deposit-bridge</code> -&gt; <code>wallet deposit-channel</code> -&gt; <code>wallet mint-notes</code>
430
+ <span class="guide-label">Fund note balance:</span> <code>account deposit-bridge</code> -&gt; <code>wallet deposit-channel</code> -&gt; <code>wallet mint-notes</code>
430
431
  <div class="guide-example">
431
432
  <code>account deposit-bridge --amount '100' --network 'sepolia' --account 'my-account'</code><br />
432
433
  <code>wallet deposit-channel --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --amount '100'</code><br />
@@ -330,7 +330,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
330
330
  fields: ["network", "channelName", "account", "wallet"],
331
331
  optionalFields: ["network", "channelName", "account", "wallet"],
332
332
  usage: "optional --network, --channel-name, --account, and --wallet",
333
- help: ["Does not accept --rpc-url and never writes RPC configuration"],
333
+ help: ["Does not accept --rpc-url and never writes RPC configuration", "Recommends bridge deposits only after a wallet is joined and needs channel liquidity"],
334
334
  },
335
335
  {
336
336
  id: "help-observer",
@@ -352,6 +352,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
352
352
  help: [
353
353
  "Uses packages/apps/private-state/cli/assets/tx-fees.json as the measured gas source packaged with the CLI",
354
354
  "Reads live fee data from the selected network RPC and live ETH/USD from CoinGecko",
355
+ "AI agents should run this command with --json when users ask about gas, transaction fees, transaction cost, or USD cost",
355
356
  ],
356
357
  },
357
358
  {
@@ -461,7 +462,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
461
462
  usage: "--amount, --network, --account, --acknowledge-action-impact",
462
463
  help: [
463
464
  "Action impact: emits public L1 approval and bridge funding events that expose the local L1 account, bridge vault, amount, and transaction hashes.",
464
- "Private note state is not changed by this command.",
465
+ "Private note state is not changed by this command; it does not pay a channel join toll.",
465
466
  ACTION_IMPACT_HELP.exchangeControlledAddress,
466
467
  ACTION_IMPACT_HELP.illegalUse,
467
468
  ACTION_IMPACT_HELP.acknowledgement,
@@ -514,6 +515,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
514
515
  "Refreshes the local channel workspace through the saved recovery index before joining when the scan fits the 7,200-block pre-command budget",
515
516
  "Fails instead of replaying from genesis; run channel recover-workspace --source rpc --from-genesis when a genesis rebuild is required",
516
517
  "--wallet-secret-path is read once for channel-bound L2 spending-key derivation and is not stored in the wallet workspace",
518
+ "Pays any join toll directly from the L1 wallet, not from bridge-deposited balance",
517
519
  "Prints the immutable policy snapshot before first registration",
518
520
  "Action impact: emits public channel join and token-vault registration events exposing the L1 account, L2 address pair, note-receive public key, join toll, and channel id.",
519
521
  "Private note state is not changed by this command.",
package/lib/runtime.mjs CHANGED
@@ -137,7 +137,7 @@ const PRIVATE_STATE_UNINSTALL_CONFIRMATION =
137
137
  const ACTION_IMPACT_CONFIRMATION =
138
138
  "I understand the public and private impact of this action";
139
139
  const PRIVATE_STATE_CLI_PACKAGE_NAME = privateStateCliPackageJson.name;
140
- const PRIVATE_STATE_OBSERVER_URL = "https://project-scw1r.vercel.app";
140
+ const PRIVATE_STATE_OBSERVER_URL = "https://observer.tonnel.io";
141
141
  const GROTH16_PACKAGE_NAME = "@tokamak-private-dapps/groth16";
142
142
  const TOKAMAK_ZKEVM_CLI_PACKAGE_NAME = "@tokamak-zk-evm/cli";
143
143
  const WALLET_BACKUP_EXPORT_FORMAT = "tokamak-private-state-wallet-backup-export";
@@ -327,7 +327,7 @@ const ACTION_IMPACT_SUMMARIES = Object.freeze({
327
327
  },
328
328
  "channel-join": {
329
329
  display: "channel join",
330
- l1PublicEvent: "Yes. Channel join and token-vault registration transactions are public L1 data.",
330
+ l1PublicEvent: "Yes. Channel join and token-vault registration transactions are public L1 data; any join toll is paid directly from the L1 wallet.",
331
331
  privateNoteState: "No. This action registers identity and note-receive metadata; it does not create or spend notes.",
332
332
  publicFields: ({ l1Address, l2Address, noteReceivePubKey, joinToll, channelName, channelId }) => [
333
333
  `Channel: ${channelName} (${channelId})`,
@@ -4120,7 +4120,7 @@ function applyGuideNextAction(guide) {
4120
4120
  const account = guide.selectors.account ?? "<ACCOUNT>";
4121
4121
  setGuideNextAction(guide, {
4122
4122
  command: `channel join --channel-name ${channelName} --network ${guide.selectors.network} --account ${account} --wallet-secret-path <PATH> --acknowledge-action-impact`,
4123
- why: "The selected local wallet does not exist. Join the channel to create the wallet and register the channel L2 identity.",
4123
+ why: "The selected local wallet does not exist. Join the channel to create the wallet, register the channel L2 identity, and pay any join toll directly from the L1 wallet.",
4124
4124
  });
4125
4125
  return;
4126
4126
  }
@@ -4129,7 +4129,7 @@ function applyGuideNextAction(guide) {
4129
4129
  const account = guide.selectors.account ?? "<ACCOUNT>";
4130
4130
  setGuideNextAction(guide, {
4131
4131
  command: `channel join --channel-name ${channelName} --network ${guide.selectors.network} --account ${account} --wallet-secret-path <PATH> --acknowledge-action-impact`,
4132
- why: "The local wallet exists, but the corresponding L1 address is not registered in the channel.",
4132
+ why: "The local wallet exists, but the corresponding L1 address is not registered in the channel; joining pays any join toll directly from the L1 wallet.",
4133
4133
  });
4134
4134
  return;
4135
4135
  }
@@ -4146,7 +4146,7 @@ function applyGuideNextAction(guide) {
4146
4146
  const account = guide.selectors.account ?? "<ACCOUNT>";
4147
4147
  setGuideNextAction(guide, {
4148
4148
  command: `account deposit-bridge --amount <TOKENS> --network ${guide.selectors.network} --account ${account} --acknowledge-action-impact`,
4149
- why: "The wallet is joined, but there is no bridge balance, channel balance, or local unused note to spend.",
4149
+ why: "The wallet is joined, but there is no bridge balance, channel balance, or local unused note to spend; bridge deposits fund channel liquidity and do not pay join tolls.",
4150
4150
  });
4151
4151
  return;
4152
4152
  }
@@ -4909,6 +4909,7 @@ async function handleGrothVaultMove({ args, provider, direction }) {
4909
4909
  });
4910
4910
 
4911
4911
  const methodName = direction === "deposit" ? "depositToChannelVault" : "withdrawFromChannelVault";
4912
+ await assertWorkspaceAlignedWithChain(context);
4912
4913
  emitProgress(operationName, "submitting");
4913
4914
  const receipt = await waitForReceipt(
4914
4915
  await bridgeTokenVault[methodName](ethers.toBigInt(context.workspace.channelId), transition.proof, transition.update),
@@ -7639,7 +7640,7 @@ async function executeWalletDirectTemplateCommand({
7639
7640
  provider,
7640
7641
  operationName,
7641
7642
  templatePayload,
7642
- preparedContextResult = null,
7643
+ preparedContextResult,
7643
7644
  }) {
7644
7645
  emitProgress(operationName, "loading");
7645
7646
  const { signer, l2Identity } = restoreWalletParticipant(wallet, provider);
@@ -7653,11 +7654,8 @@ async function executeWalletDirectTemplateCommand({
7653
7654
  ownerSigner: signer,
7654
7655
  provider,
7655
7656
  });
7656
- const contextResult = preparedContextResult ?? await loadFreshWalletChannelContext({
7657
- walletContext: wallet,
7658
- provider,
7659
- progressAction: operationName,
7660
- });
7657
+ expect(preparedContextResult?.context, "Internal error: prepared channel context is required before proof generation.");
7658
+ const contextResult = preparedContextResult;
7661
7659
  const execution = await executeWalletTemplateSend({
7662
7660
  wallet,
7663
7661
  signer,
@@ -7755,6 +7753,7 @@ async function executeWalletTemplateSend({
7755
7753
  "Generated Tokamak proof does not match the channel aPubBlockHash. Check the workspace block_info.json context.",
7756
7754
  );
7757
7755
 
7756
+ await assertWorkspaceAlignedWithChain(context);
7758
7757
  emitProgress(operationName, "submitting");
7759
7758
  const receipt =
7760
7759
  await waitForReceipt(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokamak-private-dapps/private-state-cli",
3
- "version": "2.3.2",
3
+ "version": "2.3.4",
4
4
  "description": "Command-line client for the Tokamak private-state DApp.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "author": "Tokamak Network",