midnight-wallet-cli 0.5.7 → 0.5.8

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.
@@ -0,0 +1,47 @@
1
+ # midnight-wallet-cli — Agent Skill (Core)
2
+
3
+ You have access to the `midnight-wallet-cli` MCP server. This is the **core** skill — intent routing and non-negotiable safety rules. Fetch `midnight-wallet://skill/full` on demand for canonical multi-step flows, error-recovery recipes, concept primers (NIGHT, DUST, shielded vs unshielded), network selection, and deeper context.
4
+
5
+ ## Intent routing (natural language → tool)
6
+
7
+ | User says | Call this tool |
8
+ |---|---|
9
+ | "Create a new wallet called alice" | `midnight_wallet_generate({ name: "alice" })` |
10
+ | "Show my wallets" / "list wallets" | `midnight_wallet_list()` |
11
+ | "Switch to bob" / "use wallet bob" | `midnight_wallet_use({ name: "bob" })` |
12
+ | "What's my balance?" | `midnight_balance()` |
13
+ | "Balance for this address 0x…" | `midnight_balance({ address: "mn_addr_..." })` |
14
+ | "Send 100 NIGHT to alice" | `midnight_transfer({ to: "alice", amount: "100" })` — ask consent first |
15
+ | "Send shielded" | use the shielded address directly, or pass `--shielded` via the CLI |
16
+ | "Fund my wallet" (localnet only) | `midnight_airdrop({ amount: "1000" })` |
17
+ | "Register dust" / "I need fees" | `midnight_dust_register()` |
18
+ | "Am I registered for dust?" | `midnight_dust_status()` |
19
+ | "Start localnet" / "start a local network" | `midnight_localnet_up()` |
20
+ | "Stop localnet" | `midnight_localnet_stop()` |
21
+ | "Show localnet logs" / "what's the indexer doing" | `midnight_localnet_logs({ tail: "200" })` |
22
+ | "Inspect this contract" / "what circuits does this dApp expose" | `midnight_contract_inspect({ path })` |
23
+ | "Deploy this contract" / "deploy on undeployed" | `midnight_contract_deploy({ path, wallet, network })` — two-step pending token |
24
+ | "Call circuit X" / "submit a score" | `midnight_contract_call({ address, circuit, args })` — two-step pending token |
25
+ | "What's the contract state?" / "read the ledger" | `midnight_contract_state({ address, path })` |
26
+ | "Generate tests for this contract" / "scaffold a test suite" | `midnight_test_create({ path })` (default cli; pass `strategy: "browser"` + `port` + `build-cmd` for UI tests) |
27
+
28
+ ## Safety rules (non-negotiable)
29
+
30
+ - **Read tools** (`readOnlyHint: true`) — safe to call without user consent. Examples: balance, info, list, status, address derivation.
31
+ - **Destructive tools** (`destructiveHint: true`) — require explicit user consent before calling. Examples: transfer, airdrop, dust register, wallet generate, wallet remove, cache clear, localnet down.
32
+ - **Open-world tools** (`openWorldHint: true`) — touch the network/chain/Docker. Can fail non-deterministically; retry is usually safe for reads, risky for writes.
33
+ - **Never** auto-execute a fund-moving operation. Always describe amount + recipient + network first.
34
+ - **Never** invent a mnemonic, seed, or private key. If the user needs one, call `midnight_wallet_generate`.
35
+ - **Transfers use a two-step confirmation token.** `midnight_transfer` returns a pending token + description; you must show the description verbatim and then call `midnight_confirm_operation({ token })` only after the user explicitly says yes. Full flow in `midnight-wallet://skill/full`.
36
+
37
+ ## Slow first call on preprod and preview
38
+
39
+ The first call that needs a wallet's Dust on a hosted network (dust register, transfer, contract deploy or call) reads the chain's Dust history first: about 5 minutes on `preprod`, about 30 seconds on `preview`, once per wallet and network. Later calls take seconds. Tell the user before that first call, allow it that long, and don't cancel and retry. If it takes far longer, the CLI's native Dust reader is not in use: fetch `midnight-wallet://skill/full` and read "First sync on a hosted network".
40
+
41
+ ## When to fetch the full skill
42
+
43
+ - On any error from a tool call → fetch `midnight-wallet://skill/full`, find the recipe in "Error recovery recipes".
44
+ - Before a multi-step flow (first session, deploying a contract, transfer with confirmation) → fetch `/full` for the canonical sequence.
45
+ - When the user asks conceptual questions (what is dust, shielded vs unshielded, which network) → fetch `/full`.
46
+ - For per-tool details: read the tool description in `tools/list`.
47
+ - For CLI reference: `mn help <command>`.
package/docs/SKILL.md CHANGED
@@ -15,14 +15,28 @@ Manage wallets, check balances, transfer NIGHT tokens, register dust (fee token)
15
15
  - **No self-shielding** — a wallet cannot move its own funds from unshielded to shielded. To get shielded NIGHT, receive a shielded transfer from a wallet that already has some (genesis wallet has 250M shielded NIGHT on localnet).
16
16
  - **Networks**
17
17
  - `undeployed` — local Docker network via `mn localnet up`. Use this for dev iteration.
18
- - `preprod` — public testnet. Its indexer and node are served by Blockfrost and need the user's own project id (see "Preprod needs a Blockfrost project id" below). First-time wallet sync processes the full event history and can take significantly longer than subsequent syncs (which restore from cached wallet state). Exact time depends on wallet age, event density, network, and hardware.
19
- - `preview` — public preview testnet. Same first-sync trade-off as preprod.
18
+ - `preprod` — public testnet. Its indexer and node are served by Blockfrost and need the user's own project id (see "Preprod needs a Blockfrost project id" below). The first call that needs the wallet's Dust reads the chain's whole Dust history: about 5 minutes, once per wallet (see "First sync on a hosted network" below).
19
+ - `preview` — public preview testnet. No project id needed. Same first sync, about 30 seconds.
20
20
  - **Proof server** — local HTTP service that generates ZK proofs for transactions. Default port 6300. Version must match the network's ledger version or writes fail with "Custom error 170".
21
21
 
22
22
  ### Preprod needs a Blockfrost project id
23
23
 
24
24
  Midnight shut its own preprod indexer down on 2026-10-09. Blockfrost serves preprod's indexer and node now, and every request needs the user's own project id (created at https://blockfrost.io, one project per network; preprod ids start with `nightpreprod`; requests count against the user's Blockfrost plan). The user sets it once with `midnight config set blockfrost-project-id <project id>` in their own terminal, or `BLOCKFROST_PROJECT_ID` (or `MN_BLOCKFROST_PROJECT_ID`) in the MCP server's environment. It is a secret: `midnight_config_get` shows it masked, no tool result contains it, and you should never ask for it in chat or echo it. Preview and the local network need none.
25
25
 
26
+ ### First sync on a hosted network
27
+
28
+ The first call that needs a wallet's Dust on `preprod` or `preview` (`midnight_dust_register`, `midnight_dust_status` of a registered wallet, `midnight_transfer`, any contract deploy or call, `mn serve`, `mn dust export`) reads the chain's whole Dust event history before it does anything else. It happens once per wallet and network; later calls resume from a cache and take seconds. A balance of an empty wallet does not trigger it.
29
+
30
+ | Network | Dust events (2026-10-11) | First sync, native reader | First sync, WASM reader | Later calls |
31
+ |---|---|---|---|---|
32
+ | `preprod` | 1.6M | about 5 min | about 27 min (estimated) | about 6 s |
33
+ | `preview` | 144k | about 30 s | about 2 min | about 10 s |
34
+
35
+ - **Tell the user before the first such call** how long it will take, and allow the tool call that long. Don't cancel and retry: an interrupted sync resumes from its last checkpoint, so nothing is lost, but nothing is gained either.
36
+ - **The native reader** is the `dust-sync` sidecar: an optional npm package for the platform (`@nel349/dust-sync-<os>-<arch>`; macOS arm64/x64, Linux x64/arm64 on glibc, Windows x64) that installs with the CLI and needs no setup. Without it the CLI reads with its built-in WASM reader: same result, several times slower.
37
+ - **How to tell which reader ran** (CLI): add `--verbose`. Each sync logs `dust: native sidecar: <path>`, or `dust: native sidecar <reason>, using WASM`. On a long sync the CLI also prints one line on stderr without `--verbose`: `Native Dust reader <reason>: reading with the built-in one, several times slower on a long sync.`
38
+ - **If the native reader is not in use**, the reason is one of: `not installed` (npm ran with `--omit=optional`, or the platform has no build), `can't start on this system` (Alpine or another musl Linux: the Linux builds need glibc), `disabled by MN_DISABLE_NATIVE_DUST=1`, or `failed` (a run error; the CLI carries on in WASM). Fixes for the user to run: reinstall without omitting optional dependencies (`npm install -g midnight-wallet-cli`), or use a glibc container image (`node:22-slim`, not `node:22-alpine`). Don't set `MN_DISABLE_NATIVE_DUST` yourself.
39
+
26
40
  ## Intent routing (natural language → tool)
27
41
 
28
42
  | User says | Call this tool |
@@ -90,7 +104,7 @@ Use `midnight_test_create({ path, strategy })`. Strategies:
90
104
  - `"cli"` (default) — emits `dapp.test.json` + `tests/suites/cli-default/{suite,actions,assertions}.json` with deploy → state → one call per impure circuit → state. Placeholder args; user reviews and edits before `mn test run`.
91
105
  - `"browser"` — additionally needs `port` and `build-cmd`; emits `prompt.md` instead of `actions.json`. Claude drives the UI per `prompt.md`.
92
106
 
93
- Run via `midnight_test_run` (CLI: `mn test run --suite <name>`). Browser strategy supports `browserMode: "vision"` (screenshots — default), `"dom"` (accessibility tree, faster, requires `chrome-devtools-mcp`), `"script"` (direct JS, fastest, requires `chrome-devtools-mcp`). Pre-flight detects missing `chrome-devtools-mcp` and orphan automation Chromes from prior crashes.
107
+ Running a suite is a CLI command, not an MCP tool: `mn test run --suite <name>` (exit code 0 on PASS, 1 on FAIL; `--json` prints the result, `mn test results` shows the last one). Its prep steps start the localnet if it is down, fund the active wallet, register Dust and wait until there is enough of it to pay for a transaction (about a minute and a half on a new chain), then start `mn serve`. Browser strategy supports `browserMode: "vision"` (screenshots — default), `"dom"` (accessibility tree, faster, requires `chrome-devtools-mcp`), `"script"` (direct JS, fastest, requires `chrome-devtools-mcp`). Pre-flight detects missing `chrome-devtools-mcp` and orphan automation Chromes from prior crashes.
94
108
 
95
109
  ## Safety rules (non-negotiable)
96
110
 
@@ -111,10 +125,10 @@ Every MCP tool error returns `{ error: true, code: <ERROR_CODE>, message: <human
111
125
  | `INVALID_DUST_PROOF` | Chain rejected the dust spend proof as malformed (substrate "Custom error 170"). Stale commitment tree. | `midnight_cache_clear({ wallet: "<name>" })` then retry. |
112
126
  | `STALE_CACHE` | Local wallet cache disagrees with chain (e.g. localnet reset, remote testnet re-indexed). | `midnight_cache_clear({ wallet: "<name>" })` then retry. |
113
127
  | `STALE_UTXO` | UTXO was already spent on-chain (substrate "error code 115"). | Re-sync (the next call will refresh state) and retry. |
114
- | `PROOF_FAILURE` | Proof server rejected or failed to generate the ZK proof. Often a stale commitment tree or unreachable proof server. | Check `midnight_status()`; if proof server healthy, `midnight_cache_clear({ wallet: "<name>" })` then retry. |
128
+ | `PROOF_FAILURE` | Proof server rejected or failed to generate the ZK proof. Often a stale commitment tree or unreachable proof server. | Check that the proof server is running (on localnet: `midnight_localnet_status()`); if it is, `midnight_cache_clear({ wallet: "<name>" })` then retry. |
115
129
  | `PROOF_TIMEOUT` | ZK proof generation didn't finish within the deadline. | Retry — proofs can be slow under load. |
116
- | `SYNC_TIMEOUT` | Long-running wallet sync hit its deadline. Common on a hosted-network first-cold-sync. | Retry; the cache resumes from the last applied event so progress is preserved. |
117
- | `NETWORK_ERROR` | Indexer/node/proof-server connection refused or DNS failure. | Check `midnight_status()`; if localnet, `midnight_localnet_up()`. |
130
+ | `SYNC_TIMEOUT` | Long-running wallet sync hit its deadline. Common on a hosted-network first-cold-sync. | Retry; the cache resumes from the last applied event so progress is preserved. If first syncs take far longer than the times in "First sync on a hosted network", the native Dust reader is not in use: see that section. |
131
+ | `NETWORK_ERROR` | Indexer/node/proof-server connection refused or DNS failure. | On localnet: `midnight_localnet_status()`, then `midnight_localnet_up()` if it is down. On a hosted network: retry once, then show the message to the user. |
118
132
  | `BLOCKFROST_PROJECT_ID_REQUIRED` | The network (preprod) is served by Blockfrost and no project id is set. | Ask the user to create a Midnight preprod project at https://blockfrost.io and run `midnight config set blockfrost-project-id <project id>` themselves. Never ask them to paste the id into the chat. Don't retry until they have. |
119
133
  | `BLOCKFROST_PROJECT_ID_REJECTED` | Blockfrost refused the project id (HTTP 403): mistyped, revoked, or for another network. | Ask the user to check it at blockfrost.io and set it again. Don't retry blindly. |
120
134
  | `BLOCKFROST_LIMIT_REACHED` | Blockfrost's plan limit or rate limit. | Wait and retry once; if it persists, tell the user it is their Blockfrost plan. |
@@ -128,14 +142,14 @@ Every MCP tool error returns `{ error: true, code: <ERROR_CODE>, message: <human
128
142
  ## When to use which network
129
143
 
130
144
  - **Developing a contract?** → `undeployed` (localnet). No first-sync cost; everything is local.
131
- - **Integration testing against a hosted chain?** → `preprod`. First sync for a new wallet on this network processes full event history; subsequent syncs restore from cache and are much faster.
145
+ - **Integration testing against a hosted chain?** → `preprod` (needs a Blockfrost project id; first Dust sync about 5 minutes) or `preview` (no project id; about 30 seconds). Later syncs restore from cache and take seconds.
132
146
  - **Demoing to users?** → `preview` (if the dApp is deployed there) or `undeployed` (if self-contained).
133
147
  - **Mainnet?** → not on this CLI yet. Don't claim it is.
134
148
 
135
149
  ## What this CLI is NOT
136
150
 
137
151
  - Not a custody service. Keys are on the user's disk (`~/.midnight/wallets/<name>.json`).
138
- - Not an instant-sync tool for a first-time wallet on a hosted network. First run replays the chain's event history; the CLI caches state after that so repeat runs are fast. Dust priming specifically uses a bundled native accelerator (~5× faster than the WASM fallback — set `MN_DISABLE_NATIVE_DUST=1` to force WASM), but a cold prime is still minutes, not seconds.
152
+ - Not an instant-sync tool for a first-time wallet on a hosted network. The first call that needs the wallet's Dust reads the chain's Dust history (about 5 minutes on preprod, 30 seconds on preview, with the native reader that installs with the CLI); the CLI caches state after that so later calls take seconds. See "First sync on a hosted network".
139
153
  - Not a contract compiler. The project's `package.json` should expose a `compact` script (Midnight convention, e.g. `"compact": "compact compile src/foo.compact src/managed/foo"`) or a `compile` script as a generic fallback. `mn dev` detects whichever is present; create-mn-app and midnight-starship templates ship with the `compact` script already wired.
140
154
 
141
155
  ## Authoritative references
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midnight-wallet-cli",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "type": "module",
5
5
  "description": "Git-style CLI wallet for the Midnight blockchain",
6
6
  "license": "Apache-2.0",
@@ -36,6 +36,7 @@
36
36
  "files": [
37
37
  "dist",
38
38
  "docs/SKILL.md",
39
+ "docs/SKILL-CORE.md",
39
40
  "NOTICE"
40
41
  ],
41
42
  "engines": {
@@ -88,10 +89,10 @@
88
89
  "vitest": "^3.2.4"
89
90
  },
90
91
  "optionalDependencies": {
91
- "@nel349/dust-sync-darwin-arm64": "0.5.7",
92
- "@nel349/dust-sync-darwin-x64": "0.5.7",
93
- "@nel349/dust-sync-linux-x64": "0.5.7",
94
- "@nel349/dust-sync-linux-arm64": "0.5.7",
95
- "@nel349/dust-sync-win32-x64": "0.5.7"
92
+ "@nel349/dust-sync-darwin-arm64": "0.5.8",
93
+ "@nel349/dust-sync-darwin-x64": "0.5.8",
94
+ "@nel349/dust-sync-linux-x64": "0.5.8",
95
+ "@nel349/dust-sync-linux-arm64": "0.5.8",
96
+ "@nel349/dust-sync-win32-x64": "0.5.8"
96
97
  }
97
98
  }