midnight-wallet-cli 0.5.2 → 0.6.0-rc.0
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/README.md +36 -24
- package/dist/mcp-server.js +497 -493
- package/dist/wallet.js +566 -531
- package/docs/SKILL-CORE.md +45 -0
- package/docs/SKILL.md +21 -11
- package/package.json +16 -26
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
**Ledger 9 only.** This build refuses a chain still on ledger 8 (preview and preprod today; those stay on `midnight-wallet-cli` 0.5.x) and refuses `midnight_localnet_up` (no published ledger-9 indexer image yet). The user runs a ledger-9 stack and points mn at it; details in `/full`.
|
|
6
|
+
|
|
7
|
+
## Intent routing (natural language → tool)
|
|
8
|
+
|
|
9
|
+
| User says | Call this tool |
|
|
10
|
+
|---|---|
|
|
11
|
+
| "Create a new wallet called alice" | `midnight_wallet_generate({ name: "alice" })` |
|
|
12
|
+
| "Show my wallets" / "list wallets" | `midnight_wallet_list()` |
|
|
13
|
+
| "Switch to bob" / "use wallet bob" | `midnight_wallet_use({ name: "bob" })` |
|
|
14
|
+
| "What's my balance?" | `midnight_balance()` |
|
|
15
|
+
| "Balance for this address 0x…" | `midnight_balance({ address: "mn_addr_..." })` |
|
|
16
|
+
| "Send 100 NIGHT to alice" | `midnight_transfer({ to: "alice", amount: "100" })` — ask consent first |
|
|
17
|
+
| "Send shielded" | use the shielded address directly, or pass `--shielded` via the CLI |
|
|
18
|
+
| "Fund my wallet" (localnet only) | `midnight_airdrop({ amount: "1000" })` |
|
|
19
|
+
| "Register dust" / "I need fees" | `midnight_dust_register()` |
|
|
20
|
+
| "Am I registered for dust?" | `midnight_dust_status()` |
|
|
21
|
+
| "Start localnet" / "start a local network" | Refused on this build: explain, and point the user at running a ledger-9 stack (see `/full`) |
|
|
22
|
+
| "Stop localnet" | `midnight_localnet_stop()` |
|
|
23
|
+
| "Show localnet logs" / "what's the indexer doing" | `midnight_localnet_logs({ tail: "200" })` |
|
|
24
|
+
| "Inspect this contract" / "what circuits does this dApp expose" | `midnight_contract_inspect({ path })` |
|
|
25
|
+
| "Deploy this contract" / "deploy on undeployed" | `midnight_contract_deploy({ path, wallet, network })` — two-step pending token |
|
|
26
|
+
| "Call circuit X" / "submit a score" | `midnight_contract_call({ address, circuit, args })` — two-step pending token |
|
|
27
|
+
| "What's the contract state?" / "read the ledger" | `midnight_contract_state({ address, path })` |
|
|
28
|
+
| "Generate tests for this contract" / "scaffold a test suite" | `midnight_test_create({ path })` (default cli; pass `strategy: "browser"` + `port` + `build-cmd` for UI tests) |
|
|
29
|
+
|
|
30
|
+
## Safety rules (non-negotiable)
|
|
31
|
+
|
|
32
|
+
- **Read tools** (`readOnlyHint: true`) — safe to call without user consent. Examples: balance, info, list, status, address derivation.
|
|
33
|
+
- **Destructive tools** (`destructiveHint: true`) — require explicit user consent before calling. Examples: transfer, airdrop, dust register, wallet generate, wallet remove, cache clear, localnet down.
|
|
34
|
+
- **Open-world tools** (`openWorldHint: true`) — touch the network/chain/Docker. Can fail non-deterministically; retry is usually safe for reads, risky for writes.
|
|
35
|
+
- **Never** auto-execute a fund-moving operation. Always describe amount + recipient + network first.
|
|
36
|
+
- **Never** invent a mnemonic, seed, or private key. If the user needs one, call `midnight_wallet_generate`.
|
|
37
|
+
- **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`.
|
|
38
|
+
|
|
39
|
+
## When to fetch the full skill
|
|
40
|
+
|
|
41
|
+
- On any error from a tool call → fetch `midnight-wallet://skill/full`, find the recipe in "Error recovery recipes".
|
|
42
|
+
- Before a multi-step flow (first session, deploying a contract, transfer with confirmation) → fetch `/full` for the canonical sequence.
|
|
43
|
+
- When the user asks conceptual questions (what is dust, shielded vs unshielded, which network) → fetch `/full`.
|
|
44
|
+
- For per-tool details: read the tool description in `tools/list`.
|
|
45
|
+
- For CLI reference: `mn help <command>`.
|
package/docs/SKILL.md
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
You have access to the `midnight-wallet-cli` MCP server. This document teaches you how to use it well. Read it once at the start of a session; use it as reference throughout.
|
|
4
4
|
|
|
5
|
+
> **Ledger 9 only.** This build speaks ledger 9 only. A chain still on ledger 8 (preview and preprod today) is refused up front with an error saying so: tell the user to use `midnight-wallet-cli` 0.5.x for it, don't retry. `midnight_localnet_up` is refused too, because no published indexer image runs ledger 9 yet. The user runs a ledger-9 stack themselves; on the default ports (node 9944, indexer 8088, proof server 6300) `undeployed` reaches it with no configuration, otherwise set its URLs with `midnight_config_set` (keys `node`, `indexer-ws`, `proof-server`) or pass `--node` / `--indexer-ws` / `--proof-server` on the CLI.
|
|
6
|
+
|
|
5
7
|
## What you can do with this CLI
|
|
6
8
|
|
|
7
|
-
Manage wallets, check balances, transfer NIGHT tokens, register dust (fee token),
|
|
9
|
+
Manage wallets, check balances, transfer NIGHT tokens, register dust (fee token), manage a local Midnight network, act as a fee wallet for an agent's dApp transactions (`mn serve --approve-fees`), and deploy/call/inspect Compact smart contracts — all on behalf of the user. Every CLI command is also an MCP tool.
|
|
8
10
|
|
|
9
11
|
## Core concepts (teach these accurately)
|
|
10
12
|
|
|
@@ -14,9 +16,9 @@ Manage wallets, check balances, transfer NIGHT tokens, register dust (fee token)
|
|
|
14
16
|
- **Shielded vs unshielded** — shielded addresses start `mn_shield-addr_*`; unshielded start `mn_addr_*`. A wallet has one of each per network. Sender controls the privacy: `mn transfer --shielded` sends privately.
|
|
15
17
|
- **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
18
|
- **Networks**
|
|
17
|
-
- `undeployed` — local
|
|
18
|
-
- `preprod` — public testnet. 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.
|
|
19
|
+
- `undeployed` — local network. Use this for dev iteration. On this build it must be a ledger-9 stack the user runs (`mn localnet up` is refused, see the note at the top).
|
|
20
|
+
- `preprod` — public testnet (ledger 8 today, so refused by this build). 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.
|
|
21
|
+
- `preview` — public preview testnet (ledger 8 today, so refused by this build). Same first-sync trade-off as preprod.
|
|
20
22
|
- **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
23
|
|
|
22
24
|
## Intent routing (natural language → tool)
|
|
@@ -34,13 +36,13 @@ Manage wallets, check balances, transfer NIGHT tokens, register dust (fee token)
|
|
|
34
36
|
| "Fund this address …" (localnet only) | `midnight_airdrop({ amount: "1000", wallet: "mn_addr_undeployed1…" })` — `wallet` accepts a name, path, or raw bech32m address |
|
|
35
37
|
| "Register dust" / "I need fees" | `midnight_dust_register()` |
|
|
36
38
|
| "Am I registered for dust?" | `midnight_dust_status()` |
|
|
37
|
-
| "Start localnet" / "start a local network" | `midnight_localnet_up()` |
|
|
39
|
+
| "Start localnet" / "start a local network" | Explain that `midnight_localnet_up()` is refused on this ledger-9 build; the user runs a ledger-9 stack and points mn at it (see the note at the top) |
|
|
38
40
|
| "Stop localnet" | `midnight_localnet_stop()` |
|
|
39
41
|
|
|
40
42
|
## Canonical flows
|
|
41
43
|
|
|
42
44
|
### New user, first session (localnet)
|
|
43
|
-
1. `midnight_localnet_up()`
|
|
45
|
+
1. Make sure a ledger-9 stack is running and reachable (see the note at the top); `midnight_localnet_up()` won't start one on this build.
|
|
44
46
|
2. `midnight_wallet_generate({ name: "alice" })` — create wallet, set active.
|
|
45
47
|
3. `midnight_airdrop({ amount: "1000" })` — fund from genesis.
|
|
46
48
|
4. `midnight_dust_register()` — make wallet able to pay fees.
|
|
@@ -77,10 +79,14 @@ Use `midnight_contract_*` MCP tools (or `mn contract` CLI). Flow: `compact compi
|
|
|
77
79
|
|
|
78
80
|
Plain strings, booleans, fractional numbers, and `null` pass through unchanged. No hex-string detection — `"1234"` stays a string.
|
|
79
81
|
|
|
80
|
-
**Compatibility caveat — runtime version skew.** Contracts must be compiled with
|
|
82
|
+
**Compatibility caveat — runtime version skew.** Contracts must be compiled with Compact 0.35 (language 0.27). The CLI bundles `@midnight-ntwrk/compact-runtime` `0.20.0`, so contracts have to target runtime `0.20.0`. Artifacts built for another runtime (e.g. `0.16.0`, from a ledger-8 toolchain) are rejected at deploy/call with a message like `CompactError: Version mismatch: compiled code expects 0.16.0`. The fix is to recompile with Compact 0.35 (`compact compile`) rather than asking the user to change `mn`; a contract that must stay on the ledger-8 toolchain belongs with `midnight-wallet-cli` 0.5.x. `midnight_contract_inspect` shows the compiled `runtimeVersion` so you can flag the mismatch before attempting deploy.
|
|
81
83
|
|
|
82
84
|
**Stale MCP server.** Every MCP response carries `_serverVersion`. If the user upgraded `midnight-wallet-cli` but `_serverVersion` lags `mn --version`, the MCP client is talking to a long-lived stale process. Tell them to disconnect and re-add the MCP server (a /mcp reconnect alone will not respawn it).
|
|
83
85
|
|
|
86
|
+
### Agent needs a fee wallet for its own dApp transactions
|
|
87
|
+
|
|
88
|
+
When an agent builds and proves its own ledger-9 transaction (its own value already balanced) and only needs the Dust fee paid, the user runs `mn serve --approve-fees` (CLI only, not an MCP tool). In that mode `balanceUnsealedTransaction` / `balanceSealedTransaction` add only Dust, and are auto-approved only when the transaction spends none of the wallet's funds, has no unsigned unshielded input, needs no non-Dust value, and is not a rewards claim; otherwise they are refused with every reason listed. `submitTransaction` is auto-approved only for a transaction that server balanced that way on the same connection. Everything else still prompts the user (and is rejected without a terminal). `--approve-fees` cannot be combined with `--approve-all`. Two limits bound what an agent can cost the wallet: `--max-fee <DUST>` refuses a transaction whose total Dust fee (the agent's transaction plus the wallet's balancing) is higher (default 10 DUST; a simple contract call costs about 0.5), and `--max-pending <n>` refuses new balances while n balanced transactions wait to be submitted (default 2). Both are checked before any Dust is reserved. Each balanced transaction reserves a whole Dust coin until it is submitted and on chain (about 20 seconds on a 6-second-block localnet) or released, so a fee wallet serves as many agents at once as it has Dust coins: one per NIGHT UTXO registered for Dust generation. A request that finds none free waits for one, then fails with an error saying so. With `--json`, the line `mn serve` prints once it is listening includes the approval policy (`"approval": {"reads": "auto", "balancing": "fee-only", "writes": "fee-only", "feeLimits": {"maxFeeSpecks": "10000000000000000", "maxPending": 2}}`), so whoever started it can check what it will approve.
|
|
89
|
+
|
|
84
90
|
### User wants to scaffold tests for a contract
|
|
85
91
|
Use `midnight_test_create({ path, strategy })`. Strategies:
|
|
86
92
|
- `"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`.
|
|
@@ -110,7 +116,11 @@ Every MCP tool error returns `{ error: true, code: <ERROR_CODE>, message: <human
|
|
|
110
116
|
| `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. |
|
|
111
117
|
| `PROOF_TIMEOUT` | ZK proof generation didn't finish within the deadline. | Retry — proofs can be slow under load. |
|
|
112
118
|
| `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. |
|
|
113
|
-
| `NETWORK_ERROR` | Indexer/node/proof-server connection refused or DNS failure. | Check `
|
|
119
|
+
| `NETWORK_ERROR` | Indexer/node/proof-server connection refused or DNS failure. | Check `midnight_localnet_status()` or the endpoints the user configured; on this build `midnight_localnet_up()` is refused, so ask the user to start their ledger-9 stack. |
|
|
120
|
+
| `UNSUPPORTED_LEDGER` | The network is on ledger 8; this build supports ledger 9 only. | Tell the user: this network needs midnight-wallet-cli 0.5.x. Don't retry. |
|
|
121
|
+
| `LOCALNET_UNAVAILABLE` | `midnight_localnet_up()` can't start a ledger-9 stack on this build. | Ask the user to start their ledger-9 stack and point mn at it (endpoint config). |
|
|
122
|
+
| `LOCAL_STACK_UNREACHABLE` | No ledger-9 stack answers at the configured endpoints. | Ask the user to start their stack or fix the configured node / indexer-ws / proof-server endpoints. |
|
|
123
|
+
| `AMBIGUOUS_LOCAL_STACKS` | Several local Midnight stacks are running and no endpoints are configured, so mn won't guess. | Ask the user which stack to use; they set its endpoints with `midnight config set`. Don't retry blindly. |
|
|
114
124
|
| `WALLET_NOT_FOUND` | Named wallet doesn't exist on disk. | `midnight_wallet_list()` — user may have removed it. |
|
|
115
125
|
| `INVALID_ARGS` | Missing/invalid argument. | Show the message to the user verbatim — it names the missing field. |
|
|
116
126
|
| `TX_REJECTED` | Chain rejected the submitted transaction (catch-all when no more specific code applies). | Read the message; usually a state mismatch resolved by re-sync + retry. |
|
|
@@ -119,15 +129,15 @@ Every MCP tool error returns `{ error: true, code: <ERROR_CODE>, message: <human
|
|
|
119
129
|
|
|
120
130
|
## When to use which network
|
|
121
131
|
|
|
122
|
-
- **Developing a contract?** → `undeployed` (
|
|
123
|
-
- **Integration testing against a hosted chain?** → `preprod
|
|
132
|
+
- **Developing a contract?** → `undeployed` (a ledger-9 stack the user runs locally). No first-sync cost; everything is local.
|
|
133
|
+
- **Integration testing against a hosted chain?** → `preprod`, once it runs ledger 9 (refused while it is on ledger 8). First sync for a new wallet on this network processes full event history; subsequent syncs restore from cache and are much faster.
|
|
124
134
|
- **Demoing to users?** → `preview` (if the dApp is deployed there) or `undeployed` (if self-contained).
|
|
125
135
|
- **Mainnet?** → not on this CLI yet. Don't claim it is.
|
|
126
136
|
|
|
127
137
|
## What this CLI is NOT
|
|
128
138
|
|
|
129
139
|
- Not a custody service. Keys are on the user's disk (`~/.midnight/wallets/<name>.json`).
|
|
130
|
-
- 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.
|
|
140
|
+
- 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. On this ledger-9 build dust priming always runs in WASM (the native accelerator is built for ledger 8 and is not used), so a cold prime takes minutes, not seconds.
|
|
131
141
|
- 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.
|
|
132
142
|
|
|
133
143
|
## Authoritative references
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "midnight-wallet-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0-rc.0",
|
|
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": {
|
|
@@ -53,25 +54,21 @@
|
|
|
53
54
|
"typecheck": "tsc --noEmit"
|
|
54
55
|
},
|
|
55
56
|
"dependencies": {
|
|
56
|
-
"@midnight-ntwrk/compact-runtime": "
|
|
57
|
-
"@midnight-ntwrk/dapp-connector-api": "^4.0.1",
|
|
57
|
+
"@midnight-ntwrk/compact-runtime": "0.20.0",
|
|
58
58
|
"@midnight-ntwrk/ledger-v8": "^8.1.0",
|
|
59
|
-
"@midnight-ntwrk/midnight-js-contracts": "
|
|
60
|
-
"@midnight-ntwrk/midnight-js-http-client-proof-provider": "
|
|
61
|
-
"@midnight-ntwrk/midnight-js-indexer-public-data-provider": "
|
|
62
|
-
"@midnight-ntwrk/midnight-js-level-private-state-provider": "
|
|
63
|
-
"@midnight-ntwrk/midnight-js-network-id": "
|
|
64
|
-
"@midnight-ntwrk/midnight-js-node-zk-config-provider": "
|
|
65
|
-
"@midnight-ntwrk/midnight-js-
|
|
66
|
-
"@midnight-ntwrk/midnight-js-
|
|
67
|
-
"@midnight-ntwrk/
|
|
68
|
-
"@
|
|
69
|
-
"@
|
|
70
|
-
"@
|
|
71
|
-
"@
|
|
72
|
-
"@midnight-ntwrk/wallet-sdk-hd": "^3.0.1",
|
|
73
|
-
"@midnight-ntwrk/wallet-sdk-shielded": "^3.0.0",
|
|
74
|
-
"@midnight-ntwrk/wallet-sdk-unshielded-wallet": "^3.0.0",
|
|
59
|
+
"@midnight-ntwrk/midnight-js-contracts": "5.0.0-rc.1",
|
|
60
|
+
"@midnight-ntwrk/midnight-js-http-client-proof-provider": "5.0.0-rc.1",
|
|
61
|
+
"@midnight-ntwrk/midnight-js-indexer-public-data-provider": "5.0.0-rc.1",
|
|
62
|
+
"@midnight-ntwrk/midnight-js-level-private-state-provider": "5.0.0-rc.1",
|
|
63
|
+
"@midnight-ntwrk/midnight-js-network-id": "5.0.0-rc.1",
|
|
64
|
+
"@midnight-ntwrk/midnight-js-node-zk-config-provider": "5.0.0-rc.1",
|
|
65
|
+
"@midnight-ntwrk/midnight-js-protocol": "5.0.0-rc.1",
|
|
66
|
+
"@midnight-ntwrk/midnight-js-types": "5.0.0-rc.1",
|
|
67
|
+
"@midnight-ntwrk/midnight-js-utils": "5.0.0-rc.1",
|
|
68
|
+
"@midnightntwrk/dapp-connector-api": "4.1.0-beta.1",
|
|
69
|
+
"@midnightntwrk/ledger-v9": "1.0.0-rc.5",
|
|
70
|
+
"@midnightntwrk/onchain-runtime-v4": "4.0.0-rc.3",
|
|
71
|
+
"@midnightntwrk/wallet-sdk": "2.0.0-rc.0",
|
|
75
72
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
76
73
|
"@scure/bip39": "^2.0.1",
|
|
77
74
|
"rxjs": "^7.8.1",
|
|
@@ -83,12 +80,5 @@
|
|
|
83
80
|
"tsx": "^4.21.0",
|
|
84
81
|
"typescript": "^5.9.3",
|
|
85
82
|
"vitest": "^3.2.4"
|
|
86
|
-
},
|
|
87
|
-
"optionalDependencies": {
|
|
88
|
-
"@nel349/dust-sync-darwin-arm64": "0.5.2",
|
|
89
|
-
"@nel349/dust-sync-darwin-x64": "0.5.2",
|
|
90
|
-
"@nel349/dust-sync-linux-x64": "0.5.2",
|
|
91
|
-
"@nel349/dust-sync-linux-arm64": "0.5.2",
|
|
92
|
-
"@nel349/dust-sync-win32-x64": "0.5.2"
|
|
93
83
|
}
|
|
94
84
|
}
|