midnight-wallet-cli 0.6.0-rc.1 → 0.6.0-rc.11
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/NOTICE +1 -1
- package/README.md +67 -39
- package/dist/account-backup-kvg9gyq1.js +2 -0
- package/dist/account-protector-gx1yrfgp.js +2 -0
- package/dist/actions-runner-9xfw1w9e.js +5 -0
- package/dist/address-evr423re.js +10 -0
- package/dist/ai-scaffold-6tb9d9z6.js +2 -0
- package/dist/airdrop-q2ay0qh5.js +45 -0
- package/dist/balance-898sn3v8.js +45 -0
- package/dist/cache-gbw42c6c.js +5 -0
- package/dist/chain-caches-2cysk5pv.js +2 -0
- package/dist/circuit-witness-deps-04k7ajgt.js +2 -0
- package/dist/contract-742etqts.js +71 -0
- package/dist/create-a2bmx3q9.js +2 -0
- package/dist/create-writer-6wx6swxc.js +9 -0
- package/dist/deploy-wj9dmx17.js +2 -0
- package/dist/dev-6pf7bcnj.js +55 -0
- package/dist/discover-screens-q2tft8zf.js +2 -0
- package/dist/dust-z4av6tq0.js +57 -0
- package/dist/generate-eb8wbmfd.js +21 -0
- package/dist/genesis-address-cskqa9mm.js +9 -0
- package/dist/grant-0rcbfpsn.js +61 -0
- package/dist/help-6q5bv3ma.js +2 -0
- package/dist/info-636h7nea.js +17 -0
- package/dist/inspect-cge38gtw.js +2 -0
- package/dist/inspect-cost-rjcacee7.js +14 -0
- package/dist/localnet-4c1h8g5c.js +119 -0
- package/dist/manual-xf8mep9e.js +11 -0
- package/dist/mcp-server.js +39 -1305
- package/dist/passphrase-x33jkceg.js +2 -0
- package/dist/prepare-qhmmx1cp.js +2 -0
- package/dist/private-state-42r7118m.js +2 -0
- package/dist/protect-account-cjt1kprd.js +2 -0
- package/dist/request-1ywpssaq.js +2 -0
- package/dist/request-7cv5q4zr.js +2 -0
- package/dist/request-w4m7mnd6.js +2 -0
- package/dist/runner-jc3va6pt.js +2 -0
- package/dist/runtime-check-bcs9vc31.js +2 -0
- package/dist/sealed-account-ycx7cfmh.js +2 -0
- package/dist/serve-gybtxfhe.js +30 -0
- package/dist/serve-manager-y583rzeg.js +2 -0
- package/dist/serve-payer-z61n9qt1.js +2 -0
- package/dist/swap-7h203xka.js +49 -0
- package/dist/test-create-prompt-fdtvr457.js +32 -0
- package/dist/test-sr2cphp1.js +110 -0
- package/dist/transfer-ftpr5p84.js +32 -0
- package/dist/transfer-request-pbtf7qt8.js +2 -0
- package/dist/wallet-11ej36j3.js +33 -0
- package/dist/wallet-1n657wjk.js +4 -0
- package/dist/wallet-3bmeys56.js +4 -0
- package/dist/wallet-3qw465k0.js +3 -0
- package/dist/wallet-50qp35yf.js +3 -0
- package/dist/wallet-56gd7q8n.js +3 -0
- package/dist/wallet-64k8pxzd.js +3 -0
- package/dist/wallet-6vz9m65h.js +3 -0
- package/dist/wallet-7m1tvbsv.js +386 -0
- package/dist/wallet-b1v87xw6.js +3 -0
- package/dist/wallet-b7grv9vr.js +89 -0
- package/dist/wallet-config-w1w2ryv3.js +2 -0
- package/dist/wallet-create-brh55b4c.js +2 -0
- package/dist/wallet-csq2jnjv.js +58 -0
- package/dist/wallet-dmk3g8wb.js +4 -0
- package/dist/wallet-fb292x9c.js +203 -0
- package/dist/wallet-fxbfef5d.js +3 -0
- package/dist/wallet-hh8sn1zx.js +4 -0
- package/dist/wallet-hrarrm8j.js +3 -0
- package/dist/wallet-hrz0vezs.js +23 -0
- package/dist/wallet-ke9fpmrp.js +3 -0
- package/dist/wallet-khvrzs3r.js +11 -0
- package/dist/wallet-r5s7ppf3.js +3 -0
- package/dist/wallet-rsjfsjg5.js +7 -0
- package/dist/wallet-rzq4akdz.js +3 -0
- package/dist/wallet-tdtnx9g9.js +14 -0
- package/dist/wallet-vn9pp5nm.js +4 -0
- package/dist/wallet-wafaf7cc.js +6 -0
- package/dist/wallet-wez4z95e.js +15 -0
- package/dist/wallet-wrakcchp.js +3 -0
- package/dist/wallet-wybe948x.js +3 -0
- package/dist/wallet-yjt60vht.js +195 -0
- package/dist/wallet-z1s08pnt.js +3 -0
- package/dist/wallet-z7aqejee.js +4 -0
- package/dist/wallet-zry57pyk.js +3 -0
- package/dist/wallet.js +7 -1876
- package/docs/SKILL-CORE.md +10 -4
- package/docs/SKILL.md +54 -11
- package/npm-shrinkwrap.json +4175 -0
- package/package.json +31 -27
package/NOTICE
CHANGED
|
@@ -2,7 +2,7 @@ midnight-wallet-cli
|
|
|
2
2
|
Copyright 2026 Norman Lopez (nel349)
|
|
3
3
|
|
|
4
4
|
This product includes software developed by Norman Lopez
|
|
5
|
-
(https://github.com/
|
|
5
|
+
(https://github.com/kuiralabs/midnight-cli).
|
|
6
6
|
|
|
7
7
|
Licensed under the Apache License, Version 2.0.
|
|
8
8
|
If you port, mirror, or otherwise derive from this software, the
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# midnight-wallet-cli
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/midnight-wallet-cli)
|
|
6
6
|
[](https://npm-stat.com/charts.html?package=midnight-wallet-cli)
|
|
@@ -13,7 +13,7 @@ A standalone CLI wallet for the Midnight blockchain. Manage wallets, check balan
|
|
|
13
13
|
Built for two audiences: **beginners** starting their first Midnight project (a local chain + funded wallets + contract deploy in minutes), and **AI agents** (Cursor, Claude Code, any MCP client) using the same primitives via a built-in MCP server.
|
|
14
14
|
|
|
15
15
|
> [!IMPORTANT]
|
|
16
|
-
> **0.6.0 (prerelease, `npm install -g midnight-wallet-cli@next`) is ledger-9 only.** It is built on wallet-sdk 2.0.0-rc.0, ledger-v9 1.0.0-rc.5, midnight-js 5.0.0-rc.1 and compact-runtime 0.20.0 (contracts compiled with Compact 0.35 / language 0.27). It refuses any chain still on ledger 8, which today includes `preview` and `preprod`: stay on 0.5.x (`npm install -g midnight-wallet-cli@latest`) for those.
|
|
16
|
+
> **0.6.0 (prerelease, `npm install -g midnight-wallet-cli@next`) is ledger-9 only.** It is built on wallet-sdk 2.0.0-rc.0, ledger-v9 1.0.0-rc.5, midnight-js 5.0.0-rc.1 and compact-runtime 0.20.0 (contracts compiled with Compact 0.35 / language 0.27). `stagenet` runs on the beta set instead (wallet-sdk 5.0 beta split packages, ledger-v9 1.0.0-rc.3, midnight-js 5.0.0-beta.6, compact-runtime 0.18.0-rc.1, contracts compiled with compactc 0.33), which mn loads for that network alone. It refuses any chain still on ledger 8, which today includes `preview` and `preprod`: stay on 0.5.x (`npm install -g midnight-wallet-cli@latest`) for those.
|
|
17
17
|
>
|
|
18
18
|
> `midnight localnet up` is refused on this build, because no published indexer image runs ledger 9 yet. Run a ledger-9 stack yourself (node 2.1.0-rc.2, proof-server 9.0.0-rc.8, a 4.4 indexer) and point mn at it. On the default ports (node 9944, indexer 8088, proof server 6300) `--network undeployed` reaches it with no configuration. On other ports pass `--node`, `--indexer-ws` and `--proof-server` per command, or save them once with `midnight config set node <url>`, `midnight config set indexer-ws <url>` and `midnight config set proof-server <url>`.
|
|
19
19
|
|
|
@@ -26,37 +26,35 @@ npm install -g midnight-wallet-cli@next # this ledger-9 prerelease
|
|
|
26
26
|
|
|
27
27
|
This installs two commands: `midnight` (or `mn` for short) and `midnight-wallet-mcp`.
|
|
28
28
|
|
|
29
|
+
Install the prerelease with npm (or run it with `npx`). It ships an `npm-shrinkwrap.json` that keeps each SDK set's packages apart; bun's installer ignores it, and a command whose SDK set it then mixes up is refused, saying so (`MIXED_SDK_LAYOUT`; under bun today, every stagenet command).
|
|
30
|
+
|
|
29
31
|
## Commands
|
|
30
32
|
|
|
33
|
+
<!-- commands: generated by npm run readme-commands -->
|
|
31
34
|
| Command | Description |
|
|
32
35
|
|---------|-------------|
|
|
33
|
-
| `midnight wallet generate
|
|
34
|
-
| `midnight
|
|
35
|
-
| `midnight wallet
|
|
36
|
-
| `midnight
|
|
37
|
-
| `midnight
|
|
38
|
-
| `midnight
|
|
39
|
-
| `midnight
|
|
40
|
-
| `midnight
|
|
41
|
-
| `midnight
|
|
42
|
-
| `midnight dust register` | Register
|
|
43
|
-
| `midnight
|
|
44
|
-
| `midnight
|
|
45
|
-
| `midnight
|
|
46
|
-
| `midnight
|
|
47
|
-
| `midnight
|
|
48
|
-
| `midnight
|
|
49
|
-
| `midnight
|
|
50
|
-
| `midnight
|
|
51
|
-
| `midnight
|
|
52
|
-
| `midnight
|
|
53
|
-
| `midnight
|
|
54
|
-
|
|
55
|
-
| `midnight config get/set/unset` | Manage persistent config (network, wallet, endpoints) |
|
|
56
|
-
| `midnight cache clear` | Clear wallet state cache |
|
|
57
|
-
| `midnight localnet up/stop/down/status/logs/clean` | Manage a local Midnight network via Docker (`up` is refused on this ledger-9 build) |
|
|
58
|
-
| `midnight help [command]` | Show usage for all or a specific command |
|
|
59
|
-
| `midnight manual` | Full reference manual (every command, every flag) |
|
|
36
|
+
| `midnight wallet <generate\|list\|use\|info\|remove\|seed\|protect> [args]` | Manage named wallets (generate, list, use, info, remove, seed, protect) |
|
|
37
|
+
| `midnight generate [--network <name>] [--seed <hex>] [--mnemonic "..."] [--output <file>] [--force]` | (Deprecated — use "midnight wallet generate <name>" instead) |
|
|
38
|
+
| `midnight info [--wallet <name\|file>]` | Display wallet address, network, creation date (no secrets shown) |
|
|
39
|
+
| `midnight balance [address] [--network <name>] [--indexer-ws <url>]` | Check unshielded + shielded balance (full wallet sync) |
|
|
40
|
+
| `midnight address --seed <hex> [--network <name>] [--index <n>]` | Derive and display an unshielded address from a seed |
|
|
41
|
+
| `midnight genesis-address [--network <name>]` | Display the genesis wallet address (seed 0x01) for a network |
|
|
42
|
+
| `midnight inspect-cost [--network <name>] [--node <url>] [--indexer-ws <url>] [--proof-server <url>]` | Display the chain's current block limits, from its latest block's ledger parameters |
|
|
43
|
+
| `midnight airdrop <amount> [--shielded] [--wallet <name\|file\|address>]` | Fund a wallet from the genesis wallet (undeployed network only) |
|
|
44
|
+
| `midnight transfer <to> <amount> [--shielded] [--wallet <name\|file>] [--proof-server <url>] [--node <url>] [--indexer-ws <url>]` | Send NIGHT tokens to another address (unshielded or --shielded) |
|
|
45
|
+
| `midnight dust <register\|status\|export> [--wallet <name\|file>] [--seed <hex> (export only)] [--proof-server <url>] [--node <url>] [--indexer-ws <url>] [--no-cache (status only)]` | Register UTXOs for dust (fee token) generation, check status, or export a restorable snapshot |
|
|
46
|
+
| `midnight config <get\|set\|unset> <key> [value] [--network <name>]` | Manage persistent config (default network, endpoints, etc.) |
|
|
47
|
+
| `midnight cache clear [--network <name>] [--wallet <name\|file>]` | Manage wallet state cache (clear cached sync data) |
|
|
48
|
+
| `midnight serve [--port <n>] [--wallet <name\|file>] [--network <name>] [--proof-server <url>] [--node <url>] [--indexer-ws <url>] [--approve-all \| --approve-fees [--max-fee <DUST>] [--max-pending <n>]] [--no-auto-approve-reads] [--json]` | Start DApp Connector server over WebSocket JSON-RPC |
|
|
49
|
+
| `midnight test <create\|run\|list\|results> [options]` | Generate and run E2E test suites for Midnight dApps |
|
|
50
|
+
| `midnight dev [path]` | Iteration loop for Compact contract development (localnet + compile-on-save + one-key deploy) |
|
|
51
|
+
| `midnight contract <inspect\|deploy\|call\|state> [options]` | Inspect, deploy, call, and query Midnight smart contracts |
|
|
52
|
+
| `midnight swap <make\|inspect\|take\|cancel\|list> [options]` | Private swaps of shielded tokens, through offer files (experimental) |
|
|
53
|
+
| `midnight grant <deploy\|deposit\|status\|list\|issue\|revoke\|revoke-all\|export\|import\|device> [options]` | This wallet's account, and the grants that let an agent spend from it (experimental) |
|
|
54
|
+
| `midnight localnet <up\|stop\|down\|status\|logs\|clean>` | Manage a local Midnight network via Docker Compose (up is refused on this ledger-9 build) |
|
|
55
|
+
| `midnight help [command]` | Show usage for all commands or a specific command |
|
|
56
|
+
| `midnight manual [--no-pager] [--raw] [--json]` | Full reference manual (long form, paged through $PAGER) |
|
|
57
|
+
<!-- commands: end -->
|
|
60
58
|
|
|
61
59
|
## Quick Start
|
|
62
60
|
|
|
@@ -88,6 +86,11 @@ Both run ledger 8 today, so this build refuses them; use 0.5.x there. Once a net
|
|
|
88
86
|
midnight wallet generate alice
|
|
89
87
|
midnight config set network preprod # or: preview
|
|
90
88
|
|
|
89
|
+
# Preprod only: its indexer and node are served by Blockfrost, which needs
|
|
90
|
+
# your own project id. Create a "Midnight Preprod" project at https://blockfrost.io
|
|
91
|
+
# and set its id once (it starts with nightpreprod):
|
|
92
|
+
midnight config set blockfrost-project-id <project id>
|
|
93
|
+
|
|
91
94
|
# 2. Get test tokens from the faucet
|
|
92
95
|
# preprod: https://faucet.preprod.midnight.network/
|
|
93
96
|
# preview: https://faucet.preview.midnight.network/
|
|
@@ -106,14 +109,29 @@ midnight transfer mn_addr_preprod1... 100
|
|
|
106
109
|
| Network | Description |
|
|
107
110
|
|---------|-------------|
|
|
108
111
|
| `undeployed` | Local network. On this build: a ledger-9 stack you run yourself (`midnight localnet up` is refused) |
|
|
109
|
-
| `preprod` | Midnight pre-production testnet (ledger 8 today: refused by this build, use 0.5.x) |
|
|
112
|
+
| `preprod` | Midnight pre-production testnet (ledger 8 today: refused by this build, use 0.5.x). Its indexer and node are served by Blockfrost: needs a project id |
|
|
110
113
|
| `preview` | Midnight preview testnet (ledger 8 today: refused by this build, use 0.5.x) |
|
|
114
|
+
| `stagenet` | Sig Network's testnet, on the beta SDK set: mn runs it through its beta engine, picked by the network. NIGHT from https://faucet.stagenet.shielded.tools; no shielded faucet, so shielded sync is off by default. Its proof server must match its node (`midnightntwrk/proof-server:9.0.0-rc.5_experimental`). `mn grant` is refused there for now |
|
|
115
|
+
|
|
116
|
+
Wallets are network-agnostic — one seed derives addresses for all four networks. Use `--network <name>` on any command, or persist it with `midnight config set network preview`.
|
|
111
117
|
|
|
112
|
-
|
|
118
|
+
### Preprod and Blockfrost
|
|
119
|
+
|
|
120
|
+
Midnight shut its own preprod indexer down on 2026-10-09; [Blockfrost serves it now](https://docs.midnight.network/guides/networks-and-environments), along with the node RPC, and every request needs your own project id. Create a project for Midnight Preprod at [blockfrost.io](https://blockfrost.io) and give mn its id:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
midnight config set blockfrost-project-id <project id> # or: export BLOCKFROST_PROJECT_ID=<project id> (MN_BLOCKFROST_PROJECT_ID wins if both are set)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
- Without one, a command that reaches preprod stops with `BLOCKFROST_PROJECT_ID_REQUIRED` and these instructions. A refused id is `BLOCKFROST_PROJECT_ID_REJECTED`. Requests count against your Blockfrost plan. (On this ledger-9 build preprod is then refused as a ledger-8 chain, until it forks.)
|
|
127
|
+
- The project id is a secret. mn keeps it in `~/.midnight/config.json` (mode 0600), shows it masked in `config get`, and hides it in everything it prints, errors and `--verbose` logs included.
|
|
128
|
+
- `mn serve` gives a connected dApp the wallet's indexer and node URLs (the DApp connector's `getConfiguration`), and on preprod those carry your project id: connect only dApps you trust with it.
|
|
129
|
+
- An old `indexer-ws` setting that points at `indexer.preprod.midnight.network` fails with `ENDPOINT_SHUT_DOWN`: remove it with `midnight config unset indexer-ws --network preprod`.
|
|
130
|
+
- Preview and the local network need no project id.
|
|
113
131
|
|
|
114
132
|
## Native dust acceleration
|
|
115
133
|
|
|
116
|
-
The first dust sync for a wallet on a hosted network replays the chain's full dust event history, the slow part of a cold start. On 0.5.x a native (Rust)
|
|
134
|
+
The first dust sync for a wallet on a hosted network replays the chain's full dust event history, the slow part of a cold start. On 0.5.x a native (Rust) reader does this several times faster than the WASM one (preprod's 1.6M events in about 5 minutes; preview's 144k in about 30 seconds against about 2 minutes), installed as a per-platform `optionalDependency` (`@nel349/dust-sync-<os>-<arch>`).
|
|
117
135
|
|
|
118
136
|
**Not on this ledger-9 build.** The accelerator is built against ledger 8, so this prerelease does not ship it (no `@nel349/dust-sync-*` dependencies) and never runs it: dust sync always uses the WASM reader, and `MN_DUST_SYNC_BIN` and `MN_DISABLE_NATIVE_DUST` are ignored.
|
|
119
137
|
|
|
@@ -134,7 +152,7 @@ midnight serve --approve-fees
|
|
|
134
152
|
|
|
135
153
|
Read methods never prompt. Every write prompts in the terminal (and is rejected without one), balancing included: `balanceUnsealedTransaction` / `balanceSealedTransaction` reserve the wallet's coins, sign, and return a finished transaction the dApp could submit through any node itself.
|
|
136
154
|
|
|
137
|
-
`--approve-fees` is for an agent that builds and proves its own ledger-9 transaction (its own value already balanced) and only needs the Dust fee paid. `balanceUnsealedTransaction` / `balanceSealedTransaction` then add only Dust, and are auto-approved only when the transaction spends none of this wallet's funds, has no unsigned unshielded input, needs no non-Dust value and is not a rewards claim; otherwise they are refused, listing every reason. `submitTransaction` is auto-approved only for a transaction this server balanced that way on the same connection. Everything else still prompts in the terminal (and is rejected without one). It 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.
|
|
155
|
+
`--approve-fees` is for an agent that builds and proves its own ledger-9 transaction (its own value already balanced) and only needs the Dust fee paid. `balanceUnsealedTransaction` / `balanceSealedTransaction` then add only Dust, and are auto-approved only when the transaction spends none of this wallet's funds, has no unsigned unshielded input, needs no non-Dust value and is not a rewards claim; otherwise they are refused, listing every reason. `submitTransaction` is auto-approved only for a transaction this server balanced that way on the same connection. Everything else still prompts in the terminal (and is rejected without one). It 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. A fee the wallet's Dust doesn't cover yet is another case: the wallet's NIGHT is still generating it. `mn serve` works out what the fee takes and waits when the rest is at most two minutes away; when it is further, it refuses at once with `DUST_REQUIRED` and the time ("the wallet has 0.18 DUST and the fee takes 1.65. Its registered NIGHT generates the rest in about 4 minutes"), so an agent knows when to retry. 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.
|
|
138
156
|
|
|
139
157
|
To connect from your DApp, install the connector package:
|
|
140
158
|
|
|
@@ -251,9 +269,11 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
|
251
269
|
|
|
252
270
|
> **Tip:** If you haven't installed globally, use `"command": "npx"` with `"args": ["-y", "midnight-wallet-cli@latest", "--mcp"]` instead (`midnight-wallet-cli@next` for this ledger-9 prerelease).
|
|
253
271
|
|
|
272
|
+
> **Passphrase:** mn keeps every secret (wallet seeds, account owner keys) encrypted under one passphrase, which the MCP server cannot ask for. Give it the passphrase in its environment, `"env": { "MN_PASSPHRASE": "<your passphrase>" }`, to let it sign; without it, tools that need a secret are refused and change nothing. The passphrase then sits in that config file, so keep the file readable by you alone. Set the passphrase first in a terminal with `midnight wallet protect`.
|
|
273
|
+
|
|
254
274
|
### Available MCP Tools
|
|
255
275
|
|
|
256
|
-
Once connected, your AI agent gets access to
|
|
276
|
+
Once connected, your AI agent gets access to 38 tools:
|
|
257
277
|
|
|
258
278
|
| Tool | Description |
|
|
259
279
|
|------|-------------|
|
|
@@ -287,6 +307,14 @@ Once connected, your AI agent gets access to 30 tools:
|
|
|
287
307
|
| `midnight_contract_deploy` | Deploy a compiled contract (returns pending token; confirm with `midnight_confirm_operation`) |
|
|
288
308
|
| `midnight_contract_call` | Call a circuit on a deployed contract (returns pending token; auto-coerces numbers/`"123n"` strings to BigInt and `[0–255]` arrays to Uint8Array) |
|
|
289
309
|
| `midnight_test_create` | Generate a CLI or browser test scaffold from the compiled contract |
|
|
310
|
+
| `midnight_grant_status` | Experimental. The wallet's account: address, owner key, what it holds, number of grants |
|
|
311
|
+
| `midnight_grant_list` | Experimental. Every grant on the account, with its limits and whether it is live |
|
|
312
|
+
| `midnight_grant_request` | Experimental. What issuing from an agent's grant request link would grant (who spends, who they can pay, the limits); issues nothing |
|
|
313
|
+
| `midnight_grant_deploy` | Experimental. Deploy the wallet's account and activate its owner key (returns pending token) |
|
|
314
|
+
| `midnight_grant_deposit` | Experimental. Move shielded NIGHT from the wallet into its account, for grants to spend (returns pending token) |
|
|
315
|
+
| `midnight_grant_issue` | Experimental. Issue the grant a request link asks for (returns pending token) |
|
|
316
|
+
| `midnight_grant_revoke` | Experimental. Revoke one grant by id or slot (returns pending token) |
|
|
317
|
+
| `midnight_grant_revoke_all` | Experimental. Revoke every grant on the account (returns pending token) |
|
|
290
318
|
|
|
291
319
|
Every response carries `_serverVersion` so a stale MCP server (CLI on disk says X, responses still say Y) is detectable — see "Stale MCP server" in `docs/SKILL.md`.
|
|
292
320
|
|
|
@@ -316,11 +344,11 @@ Every tool error returns `{ error: true, code: <CODE>, message: <human prose> }`
|
|
|
316
344
|
|
|
317
345
|
## Issues & Feedback
|
|
318
346
|
|
|
319
|
-
Found a bug or have a feature request? [Open an issue](https://github.com/
|
|
347
|
+
Found a bug or have a feature request? [Open an issue](https://github.com/kuiralabs/midnight-cli/issues).
|
|
320
348
|
|
|
321
349
|
## Requirements
|
|
322
350
|
|
|
323
|
-
- Node.js >=
|
|
351
|
+
- Node.js >= 22
|
|
324
352
|
- Docker (for `midnight localnet` commands; `up` is refused on this build)
|
|
325
353
|
- A ledger-9 chain to talk to: node, indexer (4.4) and proof server. The proof server defaults to `localhost:6300` and is required for transactions on every network
|
|
326
354
|
|
|
@@ -329,10 +357,10 @@ Found a bug or have a feature request? [Open an issue](https://github.com/nel349
|
|
|
329
357
|
Working on the CLI itself? Clone, install, build, test:
|
|
330
358
|
|
|
331
359
|
```bash
|
|
332
|
-
git clone https://github.com/
|
|
333
|
-
cd midnight-
|
|
360
|
+
git clone https://github.com/kuiralabs/midnight-cli.git
|
|
361
|
+
cd midnight-cli
|
|
334
362
|
npm install
|
|
335
|
-
npm run build # bun build → dist/wallet.js + dist/mcp-server.js
|
|
363
|
+
npm run build # bun build → dist/wallet.js + dist/mcp-server.js, sharing code-split chunks
|
|
336
364
|
npm test # vitest run
|
|
337
365
|
npm run typecheck # tsc --noEmit
|
|
338
366
|
```
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{k as _}from"./wallet-b1v87xw6.js";import"./wallet-wybe948x.js";import{A as F,B as V,C,D as A,E as N,F as K,H as h,I as R,K as E,r as B,s as O,u as P,y as L}from"./wallet-fxbfef5d.js";import{S as I}from"./wallet-zry57pyk.js";import"./wallet-vn9pp5nm.js";import"./wallet-56gd7q8n.js";import*as G from"node:fs";import{anyEngine as g}from"@kuiralabs/midnight-cli-core/lib/engine";import*as Q from"node:path";import{ownerDeviceFromSecret as D}from"@kuiralabs/midnight-account-chain/owner";import{UsageError as Z}from"@kuiralabs/midnight-cli-core/lib/errors";import{FileExistsError as b,writeJsonDurably as f}from"@kuiralabs/midnight-cli-core/lib/durable-file";import{openSecret as u,sealSecret as y}from"@kuiralabs/midnight-cli-core/lib/keystore";var U="mn-account-backup",S=1,w=(j,T="")=>G.readdirSync(Q.join(j,T),{withFileTypes:!0}).flatMap((W)=>{let H=Q.join(T,W.name);return W.isDirectory()?w(j,H):[H]}),k=(j,T,W)=>{let H=N(j,T).read();return H.length>0?H:[R(j,T,W)]},v=(j,T)=>{if(!B(j))throw new Z(`The account in ${j} is not protected. Encrypt it first: midnight wallet protect`);return L(j,T)};async function d(j,T,W,H,{forDevice:X}={}){let q=v(j,W),Y=F(j,q).readOwner(),z=V(j,q).read();if(Y===void 0||z===void 0)throw new Z(`The account in ${j} has not been deployed yet: there is nothing to back up.`);let M=_(j,()=>"").database,$={record:Y,roster:F(j,q).readRoster(),...X===void 0?{device:{arm:z.arm,secret:z.secretText(),readSecret:Buffer.from(h(j,q)).toString("hex")}}:{},devices:[...new Set([...k(j,q,z),...X===void 0?[]:[I(X,X.readKey)]])],privateStatePassword:A(j,q,(await g()).contracts.acceptsPrivateStatePassword),privateState:G.existsSync(M)?Object.fromEntries(w(M).map((m)=>[m,G.readFileSync(Q.join(M,m)).toString("base64")])):{}},x={kind:U,v:S,network:T,contractAddress:Y.contractAddress,sealed:y(Buffer.from(JSON.stringify($),"utf8"),W,"account-backup")},J=Q.resolve(H);try{f(J,x,{exclusive:!0})}catch(m){if(m instanceof b)throw new Z(`${J} already exists; a backup is never written over a file.`);throw m}return{contractAddress:Y.contractAddress,file:J}}async function i(j,T,W,H){let X=JSON.parse(G.readFileSync(Q.resolve(H),"utf8"));if(X.kind!==U||X.v!==S)throw new Z(`${H} is not an account backup mn can read.`);if(X.network!==T)throw new Z(`${H} is a backup of an account on ${X.network}, not on ${T}.`);let q=JSON.parse(u(X.sealed,W,"account-backup").toString("utf8")),Y=_(j,()=>"").database,z;if(q.device===void 0){if(!K(j))throw new Z(`${H} was made for another device to join the account. Make this machine's device first, with: midnight grant device new`);z=L(j,W);let $=V(j,z).read(),x=$===void 0?void 0:R(j,z,$);if(x===void 0||!q.devices.includes(x))throw new Z(`${H} was made for another device, not this machine's (${x??"none"}).`);if(G.existsSync(Y))throw new Z(`The wallet already holds a private state in ${j}; a backup is never imported over one.`)}else{if(B(j)||P(j)||G.existsSync(Q.join(j,"owner.json"))||G.existsSync(Y))throw new Z(`The wallet already has an account in ${j}; a backup is never imported over one.`);z=O(j,W),V(j,z).keep(D(q.device.arm,q.device.secret)),E(j,z,new Uint8Array(Buffer.from(q.device.readSecret,"hex")))}let M=F(j,z);N(j,z).write(q.devices),C(j,z,q.privateStatePassword);for(let[$,x]of Object.entries(q.privateState)){let J=Q.join(Y,$);if(!J.startsWith(Y+Q.sep))throw Error(`The backup names a private-state file outside its database: ${$}`);G.mkdirSync(Q.dirname(J),{recursive:!0,mode:448}),G.writeFileSync(J,Buffer.from(x,"base64"),{mode:384})}return M.writeRoster(q.roster),M.writeOwner(q.record),{contractAddress:q.record.contractAddress}}export{i as importAccount,d as exportAccount};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{bc as c}from"./wallet-56gd7q8n.js";var l={name:"accounts",async protect(r,a,s){let{protectAllAccounts:n}=await import("./protect-account-cjt1kprd.js"),o=await n(r,a,s);return{report:o,items:o.map((e)=>{let t=`account of ${e.wallet} on ${e.network}`;if("error"in e)return{subject:t,error:e.error};return e.outcome==="sealed-now"?{subject:t,outcome:"sealed-now",sealedNote:"owner key, records and private state encrypted"}:{subject:t,outcome:"already-sealed"}})}}};export{l as accountProtector};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{qa as j,ra as R,sa as k}from"./wallet-csq2jnjv.js";import"./wallet-hh8sn1zx.js";import"./wallet-1n657wjk.js";import{Qa as N}from"./wallet-rsjfsjg5.js";import{_a as A}from"./wallet-yjt60vht.js";import"./wallet-11ej36j3.js";import{fb as y}from"./wallet-ke9fpmrp.js";import"./wallet-56gd7q8n.js";import{existsSync as h,readFileSync as p}from"node:fs";async function v(K,J,Z=1e4){try{let O=await fetch(K,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({query:"query($address: HexEncoded!) { contractAction(address: $address) { address } }",variables:{address:J}}),signal:AbortSignal.timeout(Z)});if(!O.ok)return;let X=await O.json();if(X.errors!==void 0||X.data===void 0||X.data===null)return;return X.data.contractAction!==null&&X.data.contractAction!==void 0}catch{return}}import{existsSync as C,mkdirSync as m,readFileSync as w,writeFileSync as S}from"node:fs";import{join as M}from"node:path";function g(K,J){return M(K,"tests","results",`.contract-cache-${J}.json`)}function W(K,J,Z){let O=g(K,J);if(!C(O))return;try{let X=JSON.parse(w(O,"utf-8"));if(X.network!==Z)return;return X.address}catch{return}}function P(K,J,Z,O){m(M(K,"tests","results"),{recursive:!0});let X={address:O,network:Z,timestamp:new Date().toISOString()};S(g(K,J),JSON.stringify(X,null,2)+`
|
|
3
|
+
`)}async function XJ(K){let{actions:J,config:Z,dappDir:O,suiteName:X,networkConfig:_,servePort:$,redeploy:Y,onActionStart:b,onActionComplete:z,onMessage:F}=K,L=[],B=Z.network??"undeployed",G;if(!Y){if(G=W(O,X,B),G&&await v(_.indexer,G)===!1)F?.(`The contract cached at ${G.slice(0,16)}... is not on this chain; deploying again`),G=void 0}let{info:T}=N(O),D=r(T),Q;for(let q of J){b?.(q);let V=Date.now();if(Q&&(q.type==="contract-call"||q.type==="contract-state")){let E={id:q.id,type:q.type,status:"skip",duration:0,message:`cascaded skip — depends on ${Q}`};L.push(E),z?.(q,E);continue}try{let E=await f(q,{dappDir:O,network:B,networkConfig:_,managedDir:T.managedDir,contractName:T.name,servePort:$,contractAddress:G,witnessDeps:D,onMessage:F});if(E.contractAddress){if(G=E.contractAddress,P(O,X,B,G),q.type==="contract-deploy")Q=void 0}let U=Date.now()-V,H={...E,duration:U};if(L.push(H),z?.(q,H),E.status==="skip"&&q.type==="contract-call")Q=`skipped action "${q.id}"`}catch(E){let U=Date.now()-V,H={id:q.id,type:q.type,status:"fail",duration:U,message:E.message};L.push(H),z?.(q,H);break}}return L}async function f(K,J){switch(K.type){case"contract-deploy":return x(K,J);case"contract-call":return d(K,J);case"contract-state":return u(K,J);case"wallet-cmd":return l(K,J);default:throw Error(`Unknown action type: ${K.type}`)}}async function x(K,J){if(J.contractAddress)return{id:K.id,type:K.type,status:"pass",duration:0,contractAddress:J.contractAddress,message:`Reusing cached contract ${J.contractAddress.slice(0,16)}...`};let Z=await R({dappDir:J.dappDir,network:J.network,networkConfig:J.networkConfig,managedDir:J.managedDir,contractName:J.contractName,servePort:J.servePort,onMessage:J.onMessage});return{id:K.id,type:K.type,status:"pass",duration:0,contractAddress:Z.contractAddress,message:`Deployed at ${Z.contractAddress.slice(0,16)}...`}}async function d(K,J){if(!J.contractAddress)throw Error(`Action "${K.id}": no contract address. Add a contract-deploy action first.`);if(!K.circuit)throw Error(`Action "${K.id}": missing circuit name.`);let Z=J.witnessDeps.get(K.circuit);if(Z&&Z.length>0)return{id:K.id,type:K.type,status:"skip",duration:0,message:"not CLI-testable — circuit reads private state via witness "+`${Z.join(", ")}. Cover with mn test create --strategy ui.`};let O;try{O=await j({dappDir:J.dappDir,network:J.network,networkConfig:J.networkConfig,managedDir:J.managedDir,contractName:J.contractName,contractAddress:J.contractAddress,onMessage:()=>{}})}catch{}let X=K.args?Object.values(K.args):[];await k({dappDir:J.dappDir,network:J.network,networkConfig:J.networkConfig,managedDir:J.managedDir,contractName:J.contractName,contractAddress:J.contractAddress,circuit:K.circuit,args:X,servePort:J.servePort,onMessage:J.onMessage});let _;try{_=await j({dappDir:J.dappDir,network:J.network,networkConfig:J.networkConfig,managedDir:J.managedDir,contractName:J.contractName,contractAddress:J.contractAddress,onMessage:()=>{}})}catch{}return{id:K.id,type:K.type,status:"pass",duration:0,message:`${K.circuit} called`,stateBefore:O,stateAfter:_}}async function u(K,J){if(!J.contractAddress)throw Error(`Action "${K.id}": no contract address. Add a contract-deploy action first.`);let Z=await j({dappDir:J.dappDir,network:J.network,networkConfig:J.networkConfig,managedDir:J.managedDir,contractName:J.contractName,contractAddress:J.contractAddress,onMessage:J.onMessage});if(K.assert){let O=[];for(let[X,_]of Object.entries(K.assert)){let $=Z.fields[X];if($===void 0){let Y=Z.maps[X];if(Y)I(X,BigInt(Y.size),_,O);else O.push(`Field "${X}" not found in ledger state`);continue}try{let Y=BigInt($);I(X,Y,_,O)}catch{I(X,$,_,O)}}if(O.length>0)throw Error(`State assertion failed:
|
|
4
|
+
${O.join(`
|
|
5
|
+
`)}`)}return{id:K.id,type:K.type,status:"pass",duration:0,message:`State checked (${Object.keys(Z.fields).length} fields, ${Object.keys(Z.maps).length} maps)`,stateAfter:Z}}function I(K,J,Z,O){for(let[X,_]of Object.entries(Z)){let $=typeof _==="number"?BigInt(_):_;if(typeof J==="bigint"&&(typeof $==="bigint"||typeof $==="number")){let Y=BigInt($);switch(X){case">":if(!(J>Y))O.push(`${K}: expected > ${Y}, got ${J}`);break;case">=":if(!(J>=Y))O.push(`${K}: expected >= ${Y}, got ${J}`);break;case"<":if(!(J<Y))O.push(`${K}: expected < ${Y}, got ${J}`);break;case"<=":if(!(J<=Y))O.push(`${K}: expected <= ${Y}, got ${J}`);break;case"==":if(J!==Y)O.push(`${K}: expected == ${Y}, got ${J}`);break;case"!=":if(J===Y)O.push(`${K}: expected != ${Y}, got ${J}`);break;default:O.push(`${K}: unknown operator "${X}"`)}}else{let Y=String($);switch(X){case"==":if(J!==Y)O.push(`${K}: expected == "${Y}", got "${J}"`);break;case"!=":if(J===Y)O.push(`${K}: expected != "${Y}", got "${J}"`);break;default:O.push(`${K}: operator "${X}" not supported for string values`)}}}}async function l(K,J){return{id:K.id,type:K.type,status:"pass",duration:0,message:`wallet-cmd: ${K.cmd??"no command"} (not yet implemented)`}}function r(K){if(K.witnesses.length===0)return new Map;let J=A(K.managedDir);if(!J||!h(J))return new Map;let Z=p(J,"utf-8"),O=K.witnesses.map((X)=>X.name);return y(Z,O).byCircuit}function YJ(K,J){if(!K||!J)return[];let Z=[],O=new Set([...Object.keys(K.fields),...Object.keys(J.fields)]);for(let _ of O){let $=K.fields[_]??"(absent)",Y=J.fields[_]??"(absent)";if($!==Y)Z.push({field:_,before:$,after:Y})}let X=new Set([...Object.keys(K.maps),...Object.keys(J.maps)]);for(let _ of X){let $=K.maps[_]?.size??"0",Y=J.maps[_]?.size??"0";if($!==Y)Z.push({field:`${_} (entries)`,before:$,after:Y})}return Z}export{XJ as runActions,YJ as diffState};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{yb as H}from"./wallet-wafaf7cc.js";import"./wallet-wez4z95e.js";import"./wallet-vn9pp5nm.js";import"./wallet-3qw465k0.js";import"./wallet-56gd7q8n.js";import{getFlag as K,hasFlag as L}from"@kuiralabs/midnight-cli-core/lib/argv";import{engineFor as M}from"@kuiralabs/midnight-cli-core/lib/engine";import{resolveNetworkName as O}from"@kuiralabs/midnight-cli-core/lib/resolve-network";import{keyValue as C,divider as Q,formatAddress as R}from"@kuiralabs/midnight-cli-core/ui/format";import{dim as T}from"@kuiralabs/midnight-cli-core/ui/colors";async function U(q,j){let J=await H(q,{requireExplicit:!0,label:"address"}),D=K(q,"index"),p=D!==void 0?parseInt(D,10):0;if(isNaN(p)||p<0||!Number.isInteger(Number(D??"0")))throw Error("Key index must be a non-negative integer");let z=O({args:q}),E=(await M(z)).keys.unshieldedAddress(J,z,p),G=`m/44'/2400'/0'/NightExternal/${p}`;if(L(q,"json")){j.output.result({address:E,network:z,index:p,path:G});return}j.output.stdout(E+`
|
|
3
|
+
`),j.output.stderr(`
|
|
4
|
+
`),j.output.stderr(C("Network",z)+`
|
|
5
|
+
`),j.output.stderr(C("Index",p.toString())+`
|
|
6
|
+
`),j.output.stderr(C("Address",R(E))+`
|
|
7
|
+
`),j.output.stderr(C("Path",T(G))+`
|
|
8
|
+
`),j.output.stderr(Q()+`
|
|
9
|
+
|
|
10
|
+
`)}export{U as default};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{Wa as a,Xa as b,Ya as c,Za as d,_a as e}from"./wallet-yjt60vht.js";import"./wallet-11ej36j3.js";import"./wallet-ke9fpmrp.js";import"./wallet-56gd7q8n.js";export{b as isClaudeAvailable,d as generateUiScaffoldWithAI,c as generateCliScaffoldWithAI,e as findContractSourcePath,a as claudeSubprocessRunner};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{Bb as b,Cb as E,Db as M,zb as D}from"./wallet-wez4z95e.js";import"./wallet-vn9pp5nm.js";import"./wallet-3qw465k0.js";import"./wallet-56gd7q8n.js";import{getFlag as T,hasFlag as _,rejectNoCacheForWrites as v}from"@kuiralabs/midnight-cli-core/lib/argv";import{resolveNetwork as A}from"@kuiralabs/midnight-cli-core/lib/resolve-network";import{applyEndpointOverrides as F}from"@kuiralabs/midnight-cli-core/lib/network";import{GENESIS_SEED as S}from"@kuiralabs/midnight-cli-core/lib/constants";import{engineFor as B}from"@kuiralabs/midnight-cli-core/lib/engine";import{parseAmount as p,nightToMicro as u}from"@kuiralabs/midnight-cli-core/lib/amount";import{header as P,keyValue as I,divider as V,formatAddress as y,successMessage as C}from"@kuiralabs/midnight-cli-core/ui/format";import{bold as f,dim as O}from"@kuiralabs/midnight-cli-core/ui/colors";async function k(z,J){v(z);let K=z.subcommand;if(!K)throw Error(`Missing amount.
|
|
3
|
+
Usage: midnight airdrop <amount> [--wallet <name|file|address>]
|
|
4
|
+
Example: midnight airdrop 1000
|
|
5
|
+
Example: midnight airdrop 1000 --wallet alice
|
|
6
|
+
Example: midnight airdrop 1000 --wallet mn_addr_undeployed1...`);let R=p(K),{name:Q,config:q}=A({args:z});if(F(q,{proofServer:T(z,"proof-server"),node:T(z,"node"),indexerWS:T(z,"indexer-ws")},Q),Q!=="undeployed")throw Error(`Airdrop is only available on the "undeployed" network (local devnet).
|
|
7
|
+
Current network: "${Q}"
|
|
8
|
+
On preprod/preview, use a faucet or transfer from another wallet.`);let Z=T(z,"wallet"),U=_(z,"shielded")||Z!==void 0&&Z.startsWith("mn_shield-addr_"),Y=await N(z,Q,q,U);if(U)return x(z,Y,R,Q,q,J);return h(z,Y,R,Q,q,J)}function w(z){return z.startsWith("mn_addr_")||z.startsWith("mn_shield-addr_")}async function N(z,J,K,R){let Q=T(z,"wallet");if(Q!==void 0&&w(Q))return H(Q,J,R);let q=M(Q);if(R){let Z=await E(q,J);if(Z===void 0)throw Error(`Wallet ${q} keeps no shielded address for ${J}.`);return{kind:"wallet",bech32m:(await H(Z,J,!0)).bech32m,walletPath:q}}return{kind:"address",address:await b(q,J)}}async function H(z,J,K){let R=z.startsWith("mn_shield-addr_");if(K&&!R)throw Error(`--shielded was passed but --wallet is an unshielded address.
|
|
9
|
+
Pass a shielded address (mn_shield-addr_...) or drop --shielded.
|
|
10
|
+
Got: ${z}`);let Q=K?`mn_shield-addr_${J}1`:`mn_addr_${J}1`;if(!z.startsWith(Q))throw Error(`Address does not match network "${J}".
|
|
11
|
+
Expected prefix: ${Q}
|
|
12
|
+
Got: ${z}`);if(K){try{(await B(J)).keys.assertAddress(z,"shielded",J)}catch(q){throw Error(`Invalid shielded address: ${q.message}`)}return{kind:"address",bech32m:z}}return{kind:"address",address:z}}async function h(z,J,K,R,Q,q){let Z=J.address;q.output.stderr(`
|
|
13
|
+
`+P("Airdrop")+`
|
|
14
|
+
|
|
15
|
+
`),q.output.stderr(I("Network",R)+`
|
|
16
|
+
`),q.output.stderr(I("From",O("genesis (seed 0x01)"))+`
|
|
17
|
+
`),q.output.stderr(I("To",y(Z,!0))+`
|
|
18
|
+
`),q.output.stderr(I("Amount",f(K+" NIGHT"))+`
|
|
19
|
+
`),q.output.stderr(`
|
|
20
|
+
`);let U=q.progress.start("Starting genesis wallet...");try{let Y=await(await B(R)).wallet.airdrop({networkConfig:Q,recipientAddress:Z,amountNight:K,signal:q.signal,log:q.diagnostics.line,sdkWarnings:q.sdkWarnings,onSync(G,X){if(X>0){let $=Math.round(G/X*100);U.update(`Syncing genesis wallet... ${$}%`)}},onDust(G){U.update(`Dust: ${G}`)},onProving(){U.update("Generating ZK proof (this may take a few minutes)...")},onSubmitting(){U.update("Submitting and waiting for finalization (typically 12 to 30s)...")},onSubmittingTick(G){let X=Math.floor(G/1000),$=Math.floor(X/60).toString().padStart(2,"0"),j=(X%60).toString().padStart(2,"0");U.update(`Submitting and waiting for finalization... ${$}:${j} elapsed (typically 12 to 30s)`)},onSyncWarning(G,X){U.update(`Syncing genesis wallet... (${X}, retrying)`)}});if(U.stop("Transaction submitted"),_(z,"json")){q.output.result({txHash:Y.txHash,amount:K,recipient:Z,network:R});return}q.output.stdout(Y.txHash+`
|
|
21
|
+
`),q.output.stderr(`
|
|
22
|
+
`+C(`Airdropped ${K} NIGHT to your wallet`,Y.txHash)+`
|
|
23
|
+
`),q.output.stderr(`
|
|
24
|
+
`+V()+`
|
|
25
|
+
`),q.output.stderr(O(" Verify: midnight balance")+`
|
|
26
|
+
`),q.output.stderr(O(" Register dust: midnight dust register")+`
|
|
27
|
+
`),q.output.stderr(O(" Note: registering pays its fee from Dust this NIGHT generates, so it waits longer the less NIGHT")+`
|
|
28
|
+
`+O(" there is (about a minute for 1000 NIGHT). dust register says how long.")+`
|
|
29
|
+
|
|
30
|
+
`)}catch(Y){throw U.fail("Failed"),Y}}async function x(z,J,K,R,Q,q){let Z=u(K),U=Buffer.from(S,"hex"),Y=J.bech32m;if(J.kind==="wallet")D(J.walletPath,R,Y);q.output.stderr(`
|
|
31
|
+
`+P("Shielded Airdrop")+`
|
|
32
|
+
|
|
33
|
+
`),q.output.stderr(I("Network",R)+`
|
|
34
|
+
`),q.output.stderr(I("From",O("genesis shielded (seed 0x01)"))+`
|
|
35
|
+
`),q.output.stderr(I("To",y(Y,!0))+`
|
|
36
|
+
`),q.output.stderr(I("Amount",f(K+" NIGHT (shielded)"))+`
|
|
37
|
+
`),q.output.stderr(`
|
|
38
|
+
`);let G=q.sdkWarnings.listen(void 0),X=q.progress.start("Syncing genesis wallet...");try{let $=await(await B(R)).wallet.shieldedTransfer({seed:U,network:R,networkConfig:Q,recipient:Y,amount:Z,progress:X,waitForDustToCover:!1,insufficient:(j)=>`Genesis wallet has insufficient shielded balance: ${j} NIGHT available, ${K} NIGHT requested`,log:q.diagnostics.line,signal:q.signal,onStatus:(j)=>X.update(j),onSyncProgress:(j,L)=>{if(L>0){let W=Math.min(Math.round(j/L*100),100);X.update(W>=100?"Syncing genesis wallet...":`Syncing genesis wallet... ${W}%`)}},onSyncDetail:(j)=>X.update(`Syncing genesis wallet... (waiting on: ${j})`)});if(X.stop("Transaction submitted"),_(z,"json")){q.output.result({txHash:$,amount:K,shieldedAddress:Y,network:R,type:"shielded"});return}q.output.stdout($+`
|
|
39
|
+
`),q.output.stderr(`
|
|
40
|
+
`+C(`Airdropped ${K} shielded NIGHT to your wallet`,$)+`
|
|
41
|
+
`),q.output.stderr(`
|
|
42
|
+
`+V()+`
|
|
43
|
+
`),q.output.stderr(O(" Verify: midnight balance --shielded")+`
|
|
44
|
+
|
|
45
|
+
`)}catch($){throw X.fail("Failed"),$}finally{G()}}export{k as default};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{xb as o}from"./wallet-wafaf7cc.js";import{Ib as g,zb as x}from"./wallet-wez4z95e.js";import"./wallet-vn9pp5nm.js";import"./wallet-3qw465k0.js";import"./wallet-56gd7q8n.js";import{getFlag as U,hasFlag as R,isMinimalMode as c}from"@kuiralabs/midnight-cli-core/lib/argv";import{isValidNetworkName as t}from"@kuiralabs/midnight-cli-core/lib/network";import{resolveNetwork as l}from"@kuiralabs/midnight-cli-core/lib/resolve-network";import{applyEndpointOverrides as d}from"@kuiralabs/midnight-cli-core/lib/network";import{shieldedSyncEnabled as e,shieldedDisabledReason as jj}from"@kuiralabs/midnight-cli-core/lib/shielded-policy";import{isNativeToken as y}from"@kuiralabs/midnight-chain/lib/balance-subscription";import{engineFor as m}from"@kuiralabs/midnight-cli-core/lib/engine";import{assertLedgerSupported as qj,fetchProtocolVersion as zj}from"@kuiralabs/midnight-chain/lib/ledger-guard";import{getChainGenesisHash as Kj}from"@kuiralabs/midnight-chain/lib/chain-id";function p(q={}){let j=Math.min(Math.max(q.windowMs??15000,1000),60000),z=[],X=null,_=(Y)=>{let I=Y-j;while(z.length>0&&z[0].t<I)z.shift()},H=()=>{let Y=z[z.length-1],I=z[0],K=Y.highest>0?Math.min(100,Math.round(Y.applied/Y.highest*100)):null,Q=null,Z=null;if(z.length>=2){let $=Y.applied-I.applied,W=Y.t-I.t;if(W>=1000&&$>0){Q=$/(W/1000);let J=Math.max(0,Y.highest-Y.applied);Z=J>0?J/Q:0}}return{applied:Y.applied,highest:Y.highest,percent:K,ratePerSec:Q,etaSec:Z}};return{sample(Y){return z.push(Y),_(Y.t),X=H(),X},snapshot(){return X},reset(){z.length=0,X=null}}}function h(q,j="Syncing"){let z=[j];if(q.percent!==null)z.push(`${q.percent}%`);else if(q.highest===0)z.push(`${q.applied} events`);if(q.etaSec!==null&&q.etaSec>0)z.push(`ETA ${s(q.etaSec)}`);if(q.ratePerSec!==null&&q.ratePerSec>0)z.push(`${Math.round(q.ratePerSec)} evt/s`);return z.join(" · ")}function s(q){if(!Number.isFinite(q)||q<0)return"?";if(q<60)return`${Math.ceil(q)}s`;let j=Math.floor(q/60),z=Math.round(q-j*60);if(j<60)return z>0?`${j}m ${z}s`:`${j}m`;let X=Math.floor(j/60),_=j-X*60;return _>0?`${X}h ${_}m`:`${X}h`}import{header as i,keyValue as G,divider as r,formatNight as u,formatAddress as k,toNight as B}from"@kuiralabs/midnight-cli-core/ui/format";import{bold as O,dim as C}from"@kuiralabs/midnight-cli-core/ui/colors";async function Qj(q,j){if(q.subcommand)return Yj(q,j);return n(q,j)}function Xj(q){let j=q.match(/^mn_addr_([a-z]+)1/);if(!j)return null;let z=j[1];return t(z)?z:null}async function Yj(q,j){let z=q.subcommand;j.diagnostics.line("balance",`address=${z}`);let X=Xj(z),_=U(q,"network");if(_&&X&&_!==X)throw Error(`Address belongs to ${X} but --network is ${_}.
|
|
3
|
+
Drop --network (we'll infer from the address) or pass an address for ${_}.`);if(!_&&X)q={...q,flags:{...q.flags,network:X}};let{name:H,config:Y}=l({args:q});if(R(q,"shielded")){let K=await g(z);if(K){j.diagnostics.line("balance",`shielded positional → wallet ${K.wallet.name} on ${K.network}`);let Q={...q,flags:{...q.flags,wallet:K.wallet.file,network:K.network}};return n(Q,j)}throw Error("Shielded balances are private — they can only be read with the wallet's secret key, "+`not from an address alone.
|
|
4
|
+
This address isn't one of your wallets. Check its shielded balance from the wallet that owns it:
|
|
5
|
+
midnight balance --wallet <name> --shielded --network ${H}`)}d(Y,{proofServer:U(q,"proof-server"),node:U(q,"node"),indexerWS:U(q,"indexer-ws")},H);let I=j.progress.start(`Checking balance on ${H}...`);try{let K=await(await m(H)).wallet.unshieldedBalance(z,Y,{forceFresh:R(q,"no-cache"),signal:j.signal,log:j.diagnostics.line,onProgress:(Q,Z)=>{if(Z>0){let $=Math.round(Q/Z*100);I.update(`Syncing transactions... ${$}%`)}}});if(I.stop(`Synced ${K.txCount} transactions`),R(q,"json")){let Q={};for(let[$,W]of K.balances){let J=y($)?"NIGHT":$;Q[J]=y($)?B(W):W.toString()}let Z=Q.NIGHT!==void 0?{NIGHT:Q.NIGHT}:{};if(c(q)){j.output.result({network:H,balances:Q,...Z,utxoCount:K.utxoCount});return}j.output.result({address:z,network:H,balances:Q,...Z,utxoCount:K.utxoCount,txCount:K.txCount});return}if(K.balances.size===0)j.output.stdout(`0
|
|
6
|
+
`);else for(let[Q,Z]of K.balances)j.output.stdout(`${y(Q)?"NIGHT":Q}=${Z}
|
|
7
|
+
`);if(j.output.stderr(`
|
|
8
|
+
`+i("Balance")+`
|
|
9
|
+
|
|
10
|
+
`),j.output.stderr(G("Address",k(z))+`
|
|
11
|
+
`),j.output.stderr(G("Network",H)+`
|
|
12
|
+
`),j.output.stderr(G("UTXOs",K.utxoCount.toString())+`
|
|
13
|
+
`),j.output.stderr(G("Transactions",K.txCount.toString())+`
|
|
14
|
+
`),j.output.stderr(`
|
|
15
|
+
`),K.balances.size===0)j.output.stderr(` ${C("No balance found")}
|
|
16
|
+
`);else for(let[Q,Z]of K.balances)if(y(Q))j.output.stderr(G("NIGHT",O(u(Z)))+`
|
|
17
|
+
`);else{let $=Q.slice(0,8)+"…"+Q.slice(-8);j.output.stderr(G(`Token ${$}`,O(Z.toString()))+`
|
|
18
|
+
`)}j.output.stderr(`
|
|
19
|
+
`+r()+`
|
|
20
|
+
|
|
21
|
+
`)}catch(K){throw I.fail("Failed"),K}}async function n(q,j){let{name:z,config:X}=l({args:q});j.diagnostics.line("balance",`network=${z} indexerWS=${X.indexerWS}`);let{seed:_,walletPath:H,config:Y}=await o(q);j.diagnostics.line("balance",`wallet path=${H??"(from --seed/MN_SEED)"}`);let I=await m(z),K=Y?.addresses[z]??I.keys.unshieldedAddress(_,z),Q=Y?.shieldedAddresses?.[z]??"";d(X,{proofServer:U(q,"proof-server"),node:U(q,"node"),indexerWS:U(q,"indexer-ws")},z);let Z=j.sdkWarnings.listen(void 0),$=R(q,"no-cache"),W=R(q,"json"),J=I.ledger.nightTokenId(),D=null;try{if(!W){if(j.output.stderr(`
|
|
22
|
+
`+i("Balance")+`
|
|
23
|
+
|
|
24
|
+
`),j.output.stderr(G("Address",k(K))+`
|
|
25
|
+
`),Q)j.output.stderr(G("Shielded",k(Q))+`
|
|
26
|
+
`);j.output.stderr(G("Network",z)+`
|
|
27
|
+
`),j.output.stderr(`
|
|
28
|
+
`+O("Unshielded")+`
|
|
29
|
+
`)}if(!W)D=j.progress.start("Checking unshielded...");j.diagnostics.line("balance",`phase=unshielded forceFresh=${$}`);let M=await(await m(z)).wallet.unshieldedBalance(K,X,{forceFresh:$,signal:j.signal,log:j.diagnostics.line}),E=M.balances.get(J)??0n,b=M.utxoCount;if(j.diagnostics.line("balance",`unshielded fromCache=${M.fromCache} utxos=${b} txs=${M.txCount}`),D)if(D.stop("Unshielded ready"),D=null,E>0n)j.output.stderr(G(" NIGHT",O(u(E)))+`
|
|
30
|
+
`),j.output.stderr(G(" UTXOs",b.toString())+`
|
|
31
|
+
`);else j.output.stderr(` ${C("No unshielded balance")}
|
|
32
|
+
`);if(!W)j.output.stdout(`NIGHT=${E}
|
|
33
|
+
`),j.output.stderr(`
|
|
34
|
+
`+O("Shielded")+`
|
|
35
|
+
`);let T=e(z,R(q,"force-shielded")),f=Q,L=0n,v=0,S=0,A=new Map;if(T){if(!W)D=j.progress.start("Syncing shielded...");let P=p();if(f=I.keys.shieldedAddress(_,z),H)x(H,z,f);await qj(z,X,zj,j.signal);let V=await Kj(X.node,j.signal)??void 0,F=await I.readers.shieldedBalance(_,z,X.indexerWS,{forceFresh:$,chainId:V,signal:j.signal,onProgress:(N,w)=>{if(!D)return;let a=P.sample({applied:N,highest:w,t:Date.now()});D.update(h(a,"Syncing shielded"))}});if(L=F.balance,v=F.availableCoins,A=F.tokens,S=0,D){if(D.stop("Shielded ready"),D=null,L>0n)j.output.stderr(G(" NIGHT",O(u(L)))+`
|
|
36
|
+
`),j.output.stderr(G(" Coins",`${v} available, ${S} pending`)+`
|
|
37
|
+
`);for(let[N,w]of A)j.output.stderr(G(" Token",`${O(w.toString())} ${C(N)}`)+`
|
|
38
|
+
`);if(L===0n&&A.size===0)j.output.stderr(` ${C("No shielded balance")}
|
|
39
|
+
`)}}else if(!W)j.output.stderr(` ${C("Skipped — "+jj(z))}
|
|
40
|
+
`);if(W){let P=Object.fromEntries([...A].map(([V,F])=>[V,F.toString()]));if(c(q)){j.output.result({network:z,unshielded:{NIGHT:B(E),utxoCount:b},shielded:{NIGHT:B(L),availableCoins:v,pendingCoins:S,tokens:P},shieldedSynced:T});return}j.output.result({address:K,shieldedAddress:f,network:z,unshielded:{NIGHT:B(E),utxoCount:b},shielded:{NIGHT:B(L),availableCoins:v,pendingCoins:S,tokens:P},shieldedSynced:T});return}j.output.stdout(`SHIELDED_NIGHT=${T?L:"skipped"}
|
|
41
|
+
`);for(let[P,V]of A)j.output.stdout(`SHIELDED_${P}=${V}
|
|
42
|
+
`);j.output.stderr(`
|
|
43
|
+
`+r()+`
|
|
44
|
+
|
|
45
|
+
`)}catch(M){throw D?.fail("Failed"),M}finally{Z()}}export{Qj as default};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{hb as L}from"./wallet-r5s7ppf3.js";import{Db as T,Qb as V}from"./wallet-wez4z95e.js";import"./wallet-vn9pp5nm.js";import"./wallet-3qw465k0.js";import"./wallet-56gd7q8n.js";import{getFlag as R,hasFlag as _}from"@kuiralabs/midnight-cli-core/lib/argv";import{UsageError as $,throwIfCancelled as p}from"@kuiralabs/midnight-cli-core/lib/errors";import{clearWalletCache as E}from"@kuiralabs/midnight-cli-core/lib/wallet-cache";import{clearDustDirectCache as I,clearNativeDustCheckpoint as S,clearShieldedDirectCache as U}from"@kuiralabs/midnight-cli-core/lib/reader-cache-files";import{engineFor as j}from"@kuiralabs/midnight-cli-core/lib/engine";import{resolveNetworkName as v}from"@kuiralabs/midnight-cli-core/lib/resolve-network";import{green as K}from"@kuiralabs/midnight-cli-core/ui/colors";async function M(A,z){if(A.subcommand!=="clear")throw new $("Usage: midnight cache clear [--network <name>] [--wallet <name|file>]");let B=R(A,"wallet"),G=R(A,"network"),H=_(A,"json");if(B){let X=T(B),J=await V(X);p(z.signal);let q=v({args:A}),Y=J.addresses[q];E(Y,q);let{keys:O}=await j(q),Q=O.dustPublicKeyHex(Buffer.from(J.seed,"hex"));I(q,Q),S(q,Q);let Z=O.shieldedCoinPublicKeyHex(Buffer.from(J.seed,"hex"));if(U(q,Z),H){z.output.result({action:"clear",scope:"wallet",wallet:B,network:q});return}z.output.stderr(K("✓")+` Cache cleared for wallet "${B}" on ${q}
|
|
3
|
+
`)}else if(G){if(L(G),H){z.output.result({action:"clear",scope:"network",network:G});return}z.output.stderr(K("✓")+` Cache cleared for network "${G}"
|
|
4
|
+
`)}else{if(L(void 0),H){z.output.result({action:"clear",scope:"all"});return}z.output.stderr(K("✓")+` Cache cleared
|
|
5
|
+
`)}}export{M as default};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{Fa as F,Ga as w}from"./wallet-64k8pxzd.js";import{Ha as k,Ia as D,Ja as p,Ka as m}from"./wallet-wrakcchp.js";import"./wallet-hh8sn1zx.js";import{Oa as j}from"./wallet-1n657wjk.js";import{Qa as b,Sa as C,Ta as v,Ua as f,Va as y}from"./wallet-rsjfsjg5.js";import{bc as S}from"./wallet-56gd7q8n.js";import{resolve as l}from"node:path";import{getFlag as P,hasFlag as I,requireFlag as i}from"@kuiralabs/midnight-cli-core/lib/argv";import{CancelledError as o,UsageError as n,throwIfCancelled as s}from"@kuiralabs/midnight-cli-core/lib/errors";import{untilCancelled as c}from"@kuiralabs/midnight-cli-core/lib/sleep";import{header as q,keyValue as E}from"@kuiralabs/midnight-cli-core/ui/format";import{bold as O,dim as K,teal as T,yellow as u,green as g}from"@kuiralabs/midnight-cli-core/ui/colors";import{payerFor as h,resolvePayingTarget as V}from"@kuiralabs/midnight-cli-core/lib/payer";async function M({request:Q,target:z,wallet:G,payer:Z,progress:H,sdkWarnings:Y,signal:X}){let{dappDir:_,info:$,address:J,circuit:B,callArgs:L}=Q,{runCall:U}=await import("./runner-jc3va6pt.js");return F({target:z,wallet:G,payer:Z,progress:H,sdkWarnings:Y,signal:X},{running:`Calling ${B}...`,done:`${B} called`,failed:"Call failed"},async(R,A)=>{let W=await U({dappDir:_,network:z.network,networkConfig:z.networkConfig,managedDir:$.managedDir,contractName:$.name,contractAddress:J,circuit:B,args:L,servePort:R,onMessage:(N)=>A.update(N),signal:X});return{contractName:$.name,circuit:B,address:J,network:z.network,status:W.status}})}import{engineFor as a}from"@kuiralabs/midnight-cli-core/lib/engine";var d=["inspect","deploy","call","state"];function r(Q){return d.includes(Q)}async function e(Q,z){let G=Q.subcommand;if(!G||!r(G))throw new n(`Usage: midnight contract <${d.join("|")}>
|
|
3
|
+
|
|
4
|
+
inspect Show circuits, witnesses, and types for a compiled contract
|
|
5
|
+
deploy Deploy a contract to the network
|
|
6
|
+
call Call a circuit on a deployed contract
|
|
7
|
+
state Read the ledger state of a deployed contract
|
|
8
|
+
|
|
9
|
+
Run "midnight help contract" for more info.`);switch(G){case"inspect":return t(Q,z);case"deploy":return zz(Q,h("contract deploy",z),z);case"call":return Qz(Q,h("contract call",z),z);case"state":return Xz(Q,z)}}async function t(Q,z){let G=I(Q,"json"),Z=D(Q),H=P(Q,"name"),{info:Y}=b(Z,H);if(G){z.output.result(y(Y));return}if(z.output.stderr(`
|
|
10
|
+
`+q(`Contract: ${Y.name}`)+`
|
|
11
|
+
|
|
12
|
+
`),z.output.stderr(E("Compiler",Y.compilerVersion)+`
|
|
13
|
+
`),z.output.stderr(E("Language",Y.languageVersion)+`
|
|
14
|
+
`),z.output.stderr(E("Runtime",Y.runtimeVersion)+`
|
|
15
|
+
`),z.output.stderr(`
|
|
16
|
+
`+O(" Circuits")+`
|
|
17
|
+
`),Y.circuits.length===0)z.output.stderr(K(" (none)")+`
|
|
18
|
+
`);else for(let X of Y.circuits){let _=C(X),$=v(X),J=X.pure?T($):u($);z.output.stderr(` ${_} ${K("—")} ${J}
|
|
19
|
+
`)}if(z.output.stderr(`
|
|
20
|
+
`+O(" Witnesses")+`
|
|
21
|
+
`),Y.witnesses.length===0)z.output.stderr(K(" (none)")+`
|
|
22
|
+
`);else for(let X of Y.witnesses)z.output.stderr(` ${f(X)}
|
|
23
|
+
`);if(Y.siblings.length>0){z.output.stderr(`
|
|
24
|
+
`+O(" Other contracts in this project")+`
|
|
25
|
+
`);for(let X of Y.siblings)z.output.stderr(` ${T(X)}
|
|
26
|
+
`);z.output.stderr(`
|
|
27
|
+
`+K(" Inspect a sibling: mn contract inspect --name <name>")+`
|
|
28
|
+
`)}z.output.stderr(`
|
|
29
|
+
`)}async function zz(Q,z,G){let Z=I(Q,"json"),H=p(Q),{info:Y,constructorArgs:X}=H;if(!Z)G.output.stderr(`
|
|
30
|
+
`+q("Contract Deploy")+`
|
|
31
|
+
|
|
32
|
+
`);let _=V(Q,"contract","deploy"),{network:$}=_;if(await j(Y,$),!Z){if(G.output.stderr(E("Contract",Y.name)+`
|
|
33
|
+
`),G.output.stderr(E("Network",$)+`
|
|
34
|
+
`),X.length>0)G.output.stderr(E("Constructor args",String(X.length))+`
|
|
35
|
+
`);G.output.stderr(`
|
|
36
|
+
`)}let J=await w({request:H,target:_,wallet:P(Q,"wallet"),payer:z,progress:(B)=>Z?G.progress.silent():G.progress.start(B),sdkWarnings:G.sdkWarnings,signal:G.signal});if(Z)G.output.result({subcommand:"deploy",contractName:J.contractName,address:J.address,network:$});else G.output.stderr(`
|
|
37
|
+
`),G.output.stderr(E("Address",J.address)+`
|
|
38
|
+
`),G.output.stderr(`
|
|
39
|
+
`+g(" ✓ Deploy successful")+`
|
|
40
|
+
`),Gz(G.output,J.address,Y.circuits,$),G.output.stdout(J.address+`
|
|
41
|
+
`)}function Gz(Q,z,G,Z){let H=Z==="undeployed"?"":` --network ${Z}`;Q.stderr(`
|
|
42
|
+
`+K(" Next:")+`
|
|
43
|
+
`),Q.stderr(K(" mn contract state --address ")+T(z)+K(H)+`
|
|
44
|
+
`);let Y=G.find((X)=>X.arguments.length===0);if(Y)Q.stderr(K(" mn contract call --address ")+T(z)+K(" --circuit ")+T(Y.name)+K(H)+`
|
|
45
|
+
`);Q.stderr(`
|
|
46
|
+
`)}async function Qz(Q,z,G){let Z=I(Q,"json"),H=m(Q),{info:Y,address:X,circuit:_}=H;if(!Z)G.output.stderr(`
|
|
47
|
+
`+q("Contract Call")+`
|
|
48
|
+
|
|
49
|
+
`);let $=V(Q,"contract","call"),{network:J}=$;if(await j(Y,J),!Z)G.output.stderr(E("Contract",Y.name)+`
|
|
50
|
+
`),G.output.stderr(E("Circuit",_)+`
|
|
51
|
+
`),G.output.stderr(E("Address",X.slice(0,20)+"...")+`
|
|
52
|
+
|
|
53
|
+
`);let B=await M({request:H,target:$,wallet:P(Q,"wallet"),payer:z,progress:(L)=>Z?G.progress.silent():G.progress.start(L),sdkWarnings:G.sdkWarnings,signal:G.signal});if(Z)G.output.result({subcommand:"call",contractName:B.contractName,circuit:_,address:X,network:J,status:B.status});else G.output.stderr(`
|
|
54
|
+
`+g(" ✓ Circuit call successful")+`
|
|
55
|
+
|
|
56
|
+
`)}async function Xz(Q,z){let G=I(Q,"json"),Z=l(P(Q,"path")??process.cwd()),H=D(Q),Y=P(Q,"name"),X=i(Q,"address","contract address");k(X);let{runState:_}=await import("./runner-jc3va6pt.js"),{network:$,networkConfig:J}=V(Q,"contract","state");if(!G)z.output.stderr(`
|
|
57
|
+
`+q("Contract State")+`
|
|
58
|
+
|
|
59
|
+
`),z.output.stderr(E("Address",X.slice(0,20)+"...")+`
|
|
60
|
+
`),z.output.stderr(E("Network",$)+`
|
|
61
|
+
|
|
62
|
+
`);let B=G?z.progress.silent():z.progress.start("Querying contract state...");try{let{info:L}=b(H,Y),U=await _({dappDir:Z,network:$,networkConfig:J,managedDir:L.managedDir,contractName:L.name,contractAddress:X,onMessage:(R)=>B.update(R),signal:z.signal});if(B.stop("State retrieved"),G)z.output.result({subcommand:"state",address:X,network:$,...U});else{let R=Object.keys(U.fields).length>0,A=Object.keys(U.maps).length>0;if(R||A){z.output.stderr(O(" Ledger State")+`
|
|
63
|
+
`);for(let[W,N]of Object.entries(U.fields))z.output.stderr(` ${W}: ${T(N)}
|
|
64
|
+
`);for(let[W,N]of Object.entries(U.maps))z.output.stderr(` ${W}: ${K(`Map (${N.size} entries)`)}
|
|
65
|
+
`)}else z.output.stderr(K(" (no ledger fields found)")+`
|
|
66
|
+
`);z.output.stderr(`
|
|
67
|
+
`)}}catch(L){if(L instanceof o)throw L;s(z.signal),B.stop(u("⚠")+" Parsed state unavailable, showing raw");let U=await c((await a($)).contracts.rawState(J,X),z.signal);if(!U)throw Error(`No contract found at address ${X} on ${$}`);if(G)z.output.result({subcommand:"state",address:X,network:$,raw:U});else{z.output.stderr(O(" Raw State")+`
|
|
68
|
+
`),z.output.stderr(K(" (run from dApp root for parsed ledger fields)")+`
|
|
69
|
+
`);for(let R of x(U," "))z.output.stderr(R+`
|
|
70
|
+
`);z.output.stderr(`
|
|
71
|
+
`)}}}function x(Q,z){switch(Q.type){case"null":return[z+K("null")];case"cell":return[z+"cell "+T(Q.value.map((G)=>"0x"+G).join(" "))];case"map":return[z+K(`Map (${Q.size} entries)`)];case"boundedMerkleTree":return[z+K(`Merkle tree (height ${Q.height}, root ${Q.root===null?"none":"0x"+Q.root.join("")})`)];case"array":return Q.items.flatMap((G,Z)=>{let H=x(G,z+" ");return G.type==="array"?[z+`[${Z}]`,...H]:[z+`[${Z}] `+H[0].trimStart()]})}}export{e as default};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import"./wallet-56gd7q8n.js";import{existsSync as G,mkdirSync as J,readFileSync as O,writeFileSync as A}from"node:fs";import{join as X}from"node:path";function E(q,K){let{dappDir:M,force:H=!1}=K,z=X(M,"tests","suites",q.suiteName),Q=X(M,"dapp.test.json"),W=[{path:X(z,"suite.json"),kind:"json",body:q.suite},{path:X(z,"assertions.json"),kind:"json",body:q.assertions}];if(q.actions)W.push({path:X(z,"actions.json"),kind:"json",body:q.actions});if(q.prompt)W.push({path:X(z,"prompt.md"),kind:"text",body:q.prompt});if(!H){let R=W.filter((V)=>G(V.path)).map((V)=>V.path);if(R.length>0)throw Error(`Suite "${q.suiteName}" already exists at ${z}.
|
|
3
|
+
Pick a different suite name (--suite <name>) or pass --force to overwrite.
|
|
4
|
+
Existing files:
|
|
5
|
+
`+R.map((V)=>` - ${V}`).join(`
|
|
6
|
+
`))}let $=v(Q,q,H);J(z,{recursive:!0});let Y=[],m=[];if($.action==="write")A(Q,JSON.stringify($.config,null,2)+`
|
|
7
|
+
`),Y.push(Q);else m.push(Q);for(let R of W){let V=R.kind==="json"?JSON.stringify(R.body,null,2)+`
|
|
8
|
+
`:R.body;A(R.path,V),Y.push(R.path)}return{written:Y,preserved:m}}var b=["port","buildCmd","buildDir","url"],Z="build-and-serve";function N(q,K){if(!K.prep.includes(Z))return null;let M={};for(let z of b)if(K[z]!==void 0&&q[z]===void 0)Object.assign(M,{[z]:K[z]});let H=Array.isArray(q.prep)?q.prep:[];if(!H.includes(Z))M.prep=[...H,Z];return Object.keys(M).length>0?M:null}function v(q,K,M){if(M||!G(q))return{action:"write",config:K.dappConfig};let H;try{H=JSON.parse(O(q,"utf-8"))}catch(Q){let W=Q instanceof Error?Q.message:String(Q);throw Error(`${q} exists but is not valid JSON: ${W}
|
|
9
|
+
Fix or remove it (or pass --force to overwrite).`)}if(H.name!==K.dappConfig.name)throw Error(`${q} exists with name "${String(H.name)}" but this scaffold targets "${K.dappConfig.name}". Use --force to overwrite, or run from the right project directory.`);let z=N(H,K.dappConfig);return z===null?{action:"preserve"}:{action:"write",config:{...H,...z}}}export{E as writeScaffold,N as uiSettingsToAdd};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{Ga as z}from"./wallet-64k8pxzd.js";import{Ja as A}from"./wallet-wrakcchp.js";import"./wallet-hh8sn1zx.js";import"./wallet-rsjfsjg5.js";import"./wallet-56gd7q8n.js";import{resolvePayingTarget as J}from"@kuiralabs/midnight-cli-core/lib/payer";async function N(B,f,E,F,G,H,I){let x={command:"contract",subcommand:"deploy",positionals:[],flags:{path:B,wallet:f,network:E}};return z({request:A(x),target:J(x,"contract","deploy"),wallet:f,payer:F,progress:()=>G,sdkWarnings:H,signal:I})}export{N as deployDevContract};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{Ma as Kz,Na as Qz}from"./wallet-hh8sn1zx.js";import{tb as p,ub as n,vb as a}from"./wallet-z7aqejee.js";import{Db as I,Eb as d,Fb as l,Mb as F,Qb as c}from"./wallet-wez4z95e.js";import{Ub as Gz,Yb as Hz,Zb as m}from"./wallet-vn9pp5nm.js";import"./wallet-3qw465k0.js";import{bc as Bz}from"./wallet-56gd7q8n.js";import{resolve as sz,relative as zz}from"node:path";import{payerFor as rz}from"@kuiralabs/midnight-cli-core/lib/payer";import{existsSync as f,readFileSync as Nz,readdirSync as Tz,statSync as _z}from"node:fs";import{dirname as Ez,join as A,resolve as y}from"node:path";var Rz=["compact","compile"],Iz=["test:dev","test"],Wz=[".","contract/src","contract","src"],Az=4,Cz=new Set(["node_modules",".git","dist","build","managed","target"]);function j(z){let Z=y(z),X=new Set,$=new Set;for(let V of Wz){let L=y(Z,V);if(!f(L))continue;k(L,0,X,$)}if(X.size===0)throw Error(`No .compact source files found under ${Z}
|
|
3
|
+
Run "mn dev" from a Midnight project directory (expected .compact files in ./, ./src, ./contract, or ./contract/src).`);let B=Sz([...$],Z),G=B?.dir??Z,K=B?.packageJson??D(A(Z,"package.json")),H=B?.script??b(K),Q=[...X].filter((V)=>P(V,G)).sort(),q=[...$].filter((V)=>P(V,G)).sort(),U=Fz(K);return{projectRoot:G,sourceFiles:Q.length>0?Q:[...X].sort(),sourceDirs:q.length>0?q:[...$].sort(),compileScript:H,hasNpmCompileScript:H!==null,testScript:U,packageJson:K}}function Fz(z){for(let Z of Iz)if(w(z,Z))return Z;return null}function P(z,Z){if(z===Z)return!0;let X=Z.endsWith("/")?Z:Z+"/";return z.startsWith(X)}function Sz(z,Z){for(let X of z){let $=X;while(!0){let B=A($,"package.json"),G=D(B),K=b(G);if(G&&K)return{dir:$,packageJson:G,script:K};if($===Z)break;let H=Ez($);if(H===$)break;$=H}}return null}function b(z){for(let Z of Rz)if(w(z,Z))return Z;return null}function D(z){if(!f(z))return null;try{let Z=JSON.parse(Nz(z,"utf-8"));return typeof Z==="object"&&Z!==null&&!Array.isArray(Z)?Z:null}catch{return null}}function w(z,Z){if(!z)return!1;let X=z.scripts;if(!X||typeof X!=="object")return!1;return typeof X[Z]==="string"}function k(z,Z,X,$){if(Z>Az)return;let B;try{B=Tz(z)}catch{return}for(let G of B){if(G.startsWith(".")||Cz.has(G))continue;let K=A(z,G),H=!1;try{H=_z(K).isDirectory()}catch{continue}if(H)k(K,Z+1,X,$);else if(G.endsWith(".compact"))X.add(K),$.add(z)}}import{spawn as vz}from"node:child_process";async function x(z){let{bin:Z,args:X,label:$}=yz(z),B=Date.now();return new Promise((G,K)=>{let H=vz(Z,X,{cwd:z.project.projectRoot,stdio:["ignore","pipe","pipe"]}),Q="",q="";H.stdout?.on("data",(V)=>{Q+=V.toString()}),H.stderr?.on("data",(V)=>{q+=V.toString()});let U=()=>{H.kill("SIGTERM")};if(z.signal)if(z.signal.aborted)U();else z.signal.addEventListener("abort",U,{once:!0});H.on("error",(V)=>{z.signal?.removeEventListener("abort",U),K(Error(`Failed to spawn "${$}": ${V.message}`))}),H.on("close",(V)=>{z.signal?.removeEventListener("abort",U),G({success:V===0,durationMs:Date.now()-B,command:$,stdout:Q,stderr:q,exitCode:V??-1})})})}function yz(z){if(z.commandOverride){let{bin:Z,args:X}=z.commandOverride;return{bin:Z,args:X,label:[Z,...X].join(" ")}}if(z.project.compileScript){let Z=z.project.compileScript;return{bin:"npm",args:["run",Z,"--silent"],label:`npm run ${Z}`}}throw Error(`No compile script found in package.json.
|
|
4
|
+
Add one of:
|
|
5
|
+
"compact": "compact compile src/<your>.compact src/managed/<your>"
|
|
6
|
+
"compile": "compact compile src/<your>.compact src/managed/<your>"
|
|
7
|
+
create-mn-app and midnight-starship templates ship with this script already wired.`)}import{spawn as Pz}from"node:child_process";async function h(z){let{bin:Z,args:X,label:$}=fz(z),B=Date.now();return new Promise((G,K)=>{let H=Pz(Z,X,{cwd:z.project.projectRoot,stdio:["ignore",z.output??"ignore",z.output??"ignore"]}),Q=()=>{H.kill("SIGTERM")};if(z.signal)if(z.signal.aborted)Q();else z.signal.addEventListener("abort",Q,{once:!0});H.on("error",(q)=>{z.signal?.removeEventListener("abort",Q),K(Error(`Failed to spawn "${$}": ${q.message}`))}),H.on("close",(q)=>{z.signal?.removeEventListener("abort",Q),G({success:q===0,durationMs:Date.now()-B,command:$,exitCode:q??-1})})})}function fz(z){if(z.commandOverride){let{bin:X,args:$}=z.commandOverride;return{bin:X,args:$,label:[X,...$].join(" ")}}if(!z.project.testScript)throw Error(`No test script found in package.json.
|
|
8
|
+
Add a "test:dev" or "test" script that runs your contract tests
|
|
9
|
+
(e.g. "test": "vitest run"), then press t again.`);let Z=z.project.testScript;return{bin:"npm",args:["run",Z,"--silent"],label:`npm run ${Z}`}}import{watch as jz}from"node:fs";import{join as bz}from"node:path";function g(z){let Z=z.debounceMs??300,X=[],$=new Set,B=null,G=()=>{if(B=null,$.size===0)return;let K=[...$];$.clear();try{Promise.resolve(z.onChange(K)).catch((H)=>{z.onError?.(H instanceof Error?H:Error(String(H)))})}catch(H){z.onError?.(H instanceof Error?H:Error(String(H)))}};for(let K of z.dirs)try{let H=jz(K,{persistent:!0},(Q,q)=>{if(!q)return;if(!q.endsWith(z.extension))return;if($.add(bz(K,q)),B)clearTimeout(B);B=setTimeout(G,Z)});H.on("error",(Q)=>{z.onError?.(Q instanceof Error?Q:Error(String(Q)))}),X.push(H)}catch(H){z.onError?.(H instanceof Error?H:Error(String(H)))}return{stop:()=>{if(B)clearTimeout(B),B=null;for(let K of X)try{K.close()}catch{}}}}import{resolveNetwork as Dz}from"@kuiralabs/midnight-cli-core/lib/resolve-network";import{assertLedger9StackReachable as wz}from"@kuiralabs/midnight-chain/lib/ledger-guard";async function u(z){let{name:Z,config:X}=Dz({args:{command:"dev",subcommand:void 0,positionals:[],flags:{network:"undeployed"}}});return z?.(`Checking the ledger-9 stack at ${X.node}`),await wz(Z,X),{state:"already-running"}}import{existsSync as kz}from"node:fs";import{engineFor as i}from"@kuiralabs/midnight-cli-core/lib/engine";import{checkBalance as xz}from"@kuiralabs/midnight-chain/lib/balance-subscription";import{resolveNetwork as hz}from"@kuiralabs/midnight-cli-core/lib/resolve-network";import{throwIfCancelled as C}from"@kuiralabs/midnight-cli-core/lib/errors";var o=["dev-alice","dev-bob","dev-carol"],s=1000;function gz(z,Z){return{generate:lz,airdrop:(X,$,B)=>cz(z,X,$,B,Z),registerDust:(X,$)=>nz(z,X,$,Z),needsDust:(X,$)=>pz(z,X,$)}}async function r(z){let Z="steps"in z?z.steps:gz(dz(),z.sdkWarnings),X=[],$=[],B=uz();try{for(let G of z.names){if(C(z.signal),t(G)){if(await Z.needsDust(G,z.signal)){$.push(G);continue}z.onProgress?.(G,"done","reused"),X.push({name:G,state:"reused"});continue}z.onProgress?.(G,"creating","created"),await Z.generate(G,z.signal),z.onProgress?.(G,"funding","created"),await Z.airdrop(G,z.amountNight,z.signal),$.push(G)}for(let G of $)C(z.signal),z.onProgress?.(G,"dust","created"),await Z.registerDust(G,z.signal),z.onProgress?.(G,"done","created"),X.push({name:G,state:"created"})}finally{mz(B)}return z.names.flatMap((G)=>X.filter((K)=>K.name===G))}function uz(){try{return d()}catch{return null}}function mz(z){if(!z)return;if(!t(z))return;try{l(z)}catch{}}function t(z){return kz(p(z))}function dz(){return hz({args:{command:"dev",subcommand:void 0,positionals:[],flags:{network:"undeployed"}}}).config}async function lz(z,Z){let X=await m();C(Z),await a(z,n(),X)}async function cz(z,Z,X,$,B){let G=(await F(I(Z))).addresses.undeployed;await(await i("undeployed")).wallet.airdrop({networkConfig:z,recipientAddress:G,amountNight:X,signal:$,sdkWarnings:B})}async function pz(z,Z,X){let $=(await F(I(Z))).addresses.undeployed,{registeredUtxos:B,unregisteredUtxos:G}=await xz($,z.indexerWS,void 0,X);return B===0&&G>0}async function nz(z,Z,X,$){let{seed:B}=await c(I(Z));await(await i("undeployed")).wallet.registerDust(Buffer.from(B,"hex"),z,{signal:X,sdkWarnings:$})}import{notice as az}from"@kuiralabs/midnight-cli-core/lib/notices";var iz="\x03",oz=typeof process.stdin.isTTY==="boolean"&&process.stdin.isTTY===!0;function e(z){if(!oz)return{stop(){}};let Z=process.stdin,X=Z.isRaw;Z.setRawMode(!0),Z.resume(),Z.setEncoding("utf8");let $=!1,B=(G)=>{if($)return;if(G===iz){z.onInterrupt();return}let K=G.toLowerCase(),H=z.actions[K];if(!H){z.onUnknown?.(G);return}Promise.resolve().then(H).catch((Q)=>{let q=Q instanceof Error?Q:Error(String(Q));if(z.onError)z.onError(K,q);else az(`key handler error (${K}): ${q.message}`)})};return Z.on("data",B),{stop(){if($)return;$=!0,Z.off("data",B);try{Z.setRawMode(X)}catch{}}}}import{header as tz,divider as ez,keyValue as S}from"@kuiralabs/midnight-cli-core/ui/format";import{bold as v,dim as Y,red as E,teal as qz,yellow as _}from"@kuiralabs/midnight-cli-core/ui/colors";var Zz="dev-alice",$z="undeployed";async function zZ(z,Z){let{signal:X}=Z,$=sz(z.positionals[0]??process.cwd());Z.output.stderr(`
|
|
10
|
+
`+tz("mn dev")+`
|
|
11
|
+
|
|
12
|
+
`);let B=j($);if(!B.compileScript)throw Error(`No compile script found in ${B.projectRoot}/package.json.
|
|
13
|
+
mn dev looks for a "compact" or "compile" npm script that invokes the
|
|
14
|
+
Compact toolchain. Add one of:
|
|
15
|
+
"scripts": { "compact": "compact compile src/my.compact src/managed/my" }
|
|
16
|
+
"scripts": { "compile": "compact compile src/my.compact src/managed/my" }
|
|
17
|
+
create-mn-app and midnight-starship templates ship with this already wired.`);Z.output.stderr(S("Project",B.projectRoot)+`
|
|
18
|
+
`),Z.output.stderr(S("Sources",`${B.sourceFiles.length} .compact file(s)`)+`
|
|
19
|
+
`),Z.output.stderr(S("Compile",`npm run ${B.compileScript}`)+`
|
|
20
|
+
|
|
21
|
+
`);let G=Z.progress.start("Checking localnet...");try{let M=await u((J)=>G.update(J)),O={"already-running":"Ledger-9 stack reachable"}[M.state];G.stop(O)}catch(M){throw G.fail("Localnet setup failed"),M}let K=Z.progress.start("Provisioning dev wallets...");try{let M=await r({names:o,amountNight:s,signal:X,sdkWarnings:Z.sdkWarnings,onProgress:(T,Jz)=>{let Lz={creating:"generating",funding:"airdropping",dust:"registering dust",done:"ready"}[Jz];K.update(`${T}: ${Lz}`)}}),O=M.filter((T)=>T.state==="created").length,J=M.length-O,Oz=[O?`${O} created`:"",J?`${J} reused`:""].filter(Boolean).join(", ");K.stop(`Dev wallets: ${M.map((T)=>T.name).join(", ")} (${Oz})`)}catch(M){throw K.fail("Wallet provisioning failed"),M}let H=null,Q=!1,q=!1,U=!1,V=!1;if(H=await Xz(B,Z),!H.success)Z.output.stderr(Y(`
|
|
22
|
+
Fix the errors above and save — mn dev will recompile automatically.
|
|
23
|
+
`));let L=async()=>{if(Q||q)return;if(U){V=!0;return}U=!0;try{H=await Xz(B,Z)}finally{if(U=!1,V)V=!1,L()}},Yz=g({dirs:B.sourceDirs,extension:".compact",onChange:async(M)=>{let O=M.map((J)=>zz(B.projectRoot,J)).join(", ");Z.output.stderr(`
|
|
24
|
+
`+Y(` Changed: ${O}`)+`
|
|
25
|
+
`),await L()},onError:(M)=>{Z.output.stderr(E(" watch error: ")+M.message+`
|
|
26
|
+
`)}});Z.output.stderr(`
|
|
27
|
+
`+ez()+`
|
|
28
|
+
`);let Vz=B.sourceDirs.map((M)=>zz(B.projectRoot,M)||".").join(", ");Z.output.stderr(Y(" Watching ")+qz(Vz)+Y(" — save to recompile.")+`
|
|
29
|
+
`);let Mz=B.testScript?v("[t]")+Y(` test (${B.testScript}) `):"";if(Z.output.stderr(Y(" ")+v("[d]")+Y(" deploy ")+Mz+v("[q]")+Y(` quit
|
|
30
|
+
|
|
31
|
+
`)),Gz())await Hz();let N=new AbortController,R=()=>{if(!N.signal.aborted)N.abort()},Uz=e({actions:{d:async()=>{if(Q){Z.output.stderr(Y(` Deploy already in flight — ignoring key press.
|
|
32
|
+
`));return}if(q){Z.output.stderr(Y(` Tests are running — wait for them to finish before deploying.
|
|
33
|
+
`));return}if(!H?.success){Z.output.stderr(_(` Cannot deploy — last compile did not succeed. Fix and save first.
|
|
34
|
+
`));return}Q=!0;try{await ZZ(B,Z)}finally{Q=!1}},t:async()=>{if(q){Z.output.stderr(Y(` Tests already in flight — ignoring key press.
|
|
35
|
+
`));return}if(Q){Z.output.stderr(Y(` Deploy in flight — wait for it to finish before running tests.
|
|
36
|
+
`));return}if(!B.testScript){Z.output.stderr(_(` No test script found. Add "test:dev" or "test" to package.json.
|
|
37
|
+
`));return}if(!H?.success){Z.output.stderr(_(` Cannot run tests — last compile did not succeed. Fix and save first.
|
|
38
|
+
`));return}q=!0;try{await $Z(Z.output,B,N.signal)}finally{q=!1}},q:()=>R()},onInterrupt:R});await new Promise((M)=>{let O=()=>{Uz.stop(),Yz.stop(),Z.output.stderr(`
|
|
39
|
+
`+Y(" mn dev stopped.")+`
|
|
40
|
+
`),M()};if(N.signal.aborted){O();return}if(N.signal.addEventListener("abort",O,{once:!0}),X?.aborted){R();return}X?.addEventListener("abort",R,{once:!0})})}async function ZZ(z,Z){let X=await XZ(z.projectRoot);if(X.length>0&&!Kz(z.projectRoot)){let B=Qz({projectRoot:z.projectRoot,witnessNames:X});Z.output.stderr(_(` ✗ Cannot auto-deploy:
|
|
41
|
+
`));for(let G of B.split(`
|
|
42
|
+
`))Z.output.stderr(Y(` ${G}
|
|
43
|
+
`));return}let $=Z.progress.start(`Deploying with ${Zz} on ${$z}...`);try{let{deployDevContract:B}=await import("./deploy-wj9dmx17.js"),G=await B(z.projectRoot,Zz,$z,rz("dev deploy",Z),Z.progress.silent(),Z.sdkWarnings,Z.signal);$.stop("Deployed"),Z.output.stderr(` ${Y("address")} ${qz(G.address)}
|
|
44
|
+
`)}catch(B){$.fail("Deploy failed");let G=B instanceof Error?B.message:String(B);Z.output.stderr(E(" "+G)+`
|
|
45
|
+
`)}}async function $Z(z,Z,X){z.stderr(Y(`
|
|
46
|
+
Running npm run ${Z.testScript}...
|
|
47
|
+
`));try{let $=await h({project:Z,signal:X,output:"inherit"});if($.success)z.stderr(` ${Y("─")} Tests passed ${Y(`(${W($.durationMs)})`)}
|
|
48
|
+
`);else z.stderr(` ${Y("─")} ${E("Tests failed")} ${Y(`(exit ${$.exitCode}, ${W($.durationMs)})`)}
|
|
49
|
+
`)}catch($){let B=$ instanceof Error?$.message:String($);z.stderr(E(" Test runner error: ")+B+`
|
|
50
|
+
`)}}async function XZ(z){try{let{findContractInfo:Z}=await import("./inspect-cge38gtw.js"),{info:X}=Z(z);return X.witnesses.map(($)=>$.name)}catch{return[]}}async function Xz(z,Z){let X=Z.progress.start("Compiling...");try{let $=await x({project:z,signal:Z.signal});if($.success)X.stop(`Compiled ${Y(`(${W($.durationMs)})`)}`);else if(X.fail(`Compile failed ${Y(`(${W($.durationMs)})`)}`),$.stderr.trim())Z.output.stderr(Y(" ─ stderr ─")+`
|
|
51
|
+
`),Z.output.stderr(_(BZ($.stderr.trim()," "))+`
|
|
52
|
+
`);return $}catch($){X.fail("Compile error");let B=$ instanceof Error?$.message:String($);return Z.output.stderr(E(" "+B)+`
|
|
53
|
+
`),{success:!1,durationMs:0,command:"",stdout:"",stderr:B,exitCode:-1}}}function W(z){if(z<1000)return`${z}ms`;return`${(z/1000).toFixed(2)}s`}function BZ(z,Z){return z.split(`
|
|
54
|
+
`).map((X)=>Z+X).join(`
|
|
55
|
+
`)}export{zZ as default};
|