midnight-wallet-cli 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # midnight-wallet-cli
2
2
 
3
+ ![midnight-wallet-cli demo](https://raw.githubusercontent.com/nel349/midnight-wallet-cli-hub/main/docs/midnight-cli-gif.gif)
4
+
3
5
  [![npm version](https://badge.fury.io/js/midnight-wallet-cli.svg)](https://www.npmjs.com/package/midnight-wallet-cli)
4
6
  [![npm downloads](https://img.shields.io/npm/dm/midnight-wallet-cli)](https://npm-stat.com/charts.html?package=midnight-wallet-cli)
5
7
  [![License](https://img.shields.io/npm/l/midnight-wallet-cli)](https://www.apache.org/licenses/LICENSE-2.0)
@@ -36,6 +38,7 @@ This installs two commands: `midnight` (or `mn` for short) and `midnight-wallet-
36
38
  | `midnight inspect-cost` | Display current block cost limits |
37
39
  | `midnight serve` | Start DApp Connector server (WebSocket JSON-RPC) |
38
40
  | `midnight config get/set` | Manage persistent config (network, wallet, endpoints) |
41
+ | `midnight cache clear` | Clear wallet state cache |
39
42
  | `midnight localnet up/stop/down/status` | Manage a local Midnight network via Docker |
40
43
  | `midnight help [command]` | Show usage for all or a specific command |
41
44
 
@@ -44,7 +47,7 @@ This installs two commands: `midnight` (or `mn` for short) and `midnight-wallet-
44
47
  ### Preprod (testnet)
45
48
 
46
49
  ```bash
47
- # Generate a wallet on preprod
50
+ # Generate a wallet
48
51
  midnight wallet generate alice --network preprod
49
52
 
50
53
  # Check balance
@@ -73,10 +76,42 @@ midnight transfer mn_addr_undeployed1... 100
73
76
 
74
77
  | Network | Description |
75
78
  |---------|-------------|
76
- | `preprod` | Midnight pre-production testnet |
77
79
  | `undeployed` | Local network via Docker (`midnight localnet up`) |
80
+ | `preprod` | Midnight pre-production testnet |
81
+ | `preview` | Midnight preview testnet |
82
+
83
+ Wallets are network-agnostic — one seed derives addresses for all three networks. Use `--network <name>` on any command, or persist it with `midnight config set network preview`.
84
+
85
+ ## DApp Connector
86
+
87
+ `midnight serve` starts a WebSocket JSON-RPC server that implements the same `ConnectedAPI` interface as the Lace browser wallet. Any DApp can connect to it — no browser extension needed.
88
+
89
+ ```bash
90
+ # Start the connector server
91
+ midnight serve --network preview
92
+
93
+ # Or auto-approve all requests (dev only)
94
+ midnight serve --network preview --approve-all
95
+ ```
96
+
97
+ To connect from your DApp, install the connector package:
98
+
99
+ ```bash
100
+ npm install midnight-wallet-connector
101
+ ```
102
+
103
+ ```typescript
104
+ import { createWalletClient } from 'midnight-wallet-connector';
105
+
106
+ const wallet = await createWalletClient({
107
+ url: 'ws://localhost:9932',
108
+ networkId: 'Preview',
109
+ });
110
+
111
+ const balances = await wallet.getUnshieldedBalances();
112
+ ```
78
113
 
79
- Use `--network <name>` to select a network, or persist it with `midnight config set network preprod`.
114
+ See the [midnight-wallet-connector](https://www.npmjs.com/package/midnight-wallet-connector) package for the full API, and [midnight-starship](https://github.com/nel349/midnight-starship) for a working example DApp.
80
115
 
81
116
  ## JSON Output for Automation
82
117
 
@@ -176,7 +211,7 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
176
211
 
177
212
  ### Available MCP Tools
178
213
 
179
- Once connected, your AI agent gets access to 22 tools:
214
+ Once connected, your AI agent gets access to 24 tools:
180
215
 
181
216
  | Tool | Description |
182
217
  |------|-------------|
@@ -197,6 +232,8 @@ Once connected, your AI agent gets access to 22 tools:
197
232
  | `midnight_dust_status` | Check dust status |
198
233
  | `midnight_config_get` | Read config value |
199
234
  | `midnight_config_set` | Write config value |
235
+ | `midnight_config_unset` | Remove config value |
236
+ | `midnight_cache_clear` | Clear wallet state cache |
200
237
  | `midnight_localnet_up` | Start local network |
201
238
  | `midnight_localnet_stop` | Stop local network |
202
239
  | `midnight_localnet_down` | Remove local network |
@@ -368,5 +368,5 @@ Usage: midnight wallet remove <name>`);if(S2(Z),I($,"json")){M({wallet:Z,removed
368
368
  `),process.stderr.write(H(" Dashboard: ")+r(l0)+`
369
369
 
370
370
  `)};if(W(),X){let P=setInterval(async()=>{try{let[x,...F]=await Promise.all([Promise.all([W1("/api/status"),W1("/api/issues")]).catch(()=>null),...J.map((O)=>X3(O))]);if(x)[Y,G]=x;for(let O=0;O<J.length;O++)U[J[O]]=F[O];process.stderr.write("\x1B[2J\x1B[H"),W()}catch{process.stderr.write(H(" Refresh failed — retrying in 30s")+`
371
- `)}},30000);await new Promise(()=>{process.on("SIGINT",()=>{clearInterval(P),process.exit(0)})})}let B=J.reduce((P,x)=>{let F={...Y?.networks[x]??{},...U[x]??{}},O=X2(F);if(O==="down")return"down";if(O==="degraded"&&P!=="down")return"degraded";return P},"up");if(B==="down")process.exitCode=2;else if(B==="degraded")process.exitCode=1}var x7,A7,Z3,E7=15000,L1=5000,Q3=1e4;var Y3=E(()=>{Q0();c();B0();x7={preprod:{faucet:"https://faucet.preprod.midnight.network/",explorer:"https://preprod.midnightexplorer.com/"},preview:{faucet:"https://faucet.preview.midnight.network/",explorer:null},undeployed:{faucet:"",explorer:""}},A7={indexer:"Indexer",rpc:"RPC Node",faucet:"Faucet",explorer:"Explorer",chain:"Chain",dust:"Dust Generation",wallet:"Wallet Ops",dapp:"DApp Flow"},Z3={up:S("UP"),down:a("DOWN"),degraded:R("\x1B[33mDEGRADED\x1B[0m"),unknown:H("—")}});import{Server as k7}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as w7}from"@modelcontextprotocol/sdk/server/stdio.js";import{ListToolsRequestSchema as h7,CallToolRequestSchema as f7}from"@modelcontextprotocol/sdk/types.js";async function N($,Z,Q){let X=[];M1((q)=>X.push(q));let z=process.stderr.write;process.stderr.write=()=>!0;try{Z.flags.json=!0,await $(Z,Q);let q=X.join("").trim();if(!q)return{};return JSON.parse(q)}finally{M1(null),process.stderr.write=z}}var n={INVALID_ARGS:"INVALID_ARGS",WALLET_NOT_FOUND:"WALLET_NOT_FOUND",NETWORK_ERROR:"NETWORK_ERROR",INSUFFICIENT_BALANCE:"INSUFFICIENT_BALANCE",TX_REJECTED:"TX_REJECTED",STALE_UTXO:"STALE_UTXO",PROOF_TIMEOUT:"PROOF_TIMEOUT",DUST_REQUIRED:"DUST_REQUIRED",CANCELLED:"CANCELLED",UNKNOWN:"UNKNOWN"};function j2($){let Z=($.message??"").toLowerCase();if(Z.includes("operation cancelled")||Z.includes("operation aborted")||Z==="cancelled"||Z==="aborted")return{exitCode:7,errorCode:n.CANCELLED};if(Z.includes("wallet file not found")||Z.includes("wallet")&&Z.includes("not found"))return{exitCode:3,errorCode:n.WALLET_NOT_FOUND};if(Z.includes("missing required flag")||Z.includes("missing amount")||Z.includes("missing recipient")||Z.includes("missing config key")||Z.includes("missing or invalid subcommand")||Z.includes("unknown command")||Z.includes("cannot specify both")||Z.includes("invalid bip-39")||Z.includes("seed must be")||Z.includes("key index must be")||Z.includes("usage:"))return{exitCode:2,errorCode:n.INVALID_ARGS};if(Z.includes("proof")&&Z.includes("timeout"))return{exitCode:6,errorCode:n.PROOF_TIMEOUT};if(Z.includes("stale utxo")||Z.includes("error code 115")||Z.includes("errorcode: 115"))return{exitCode:6,errorCode:n.STALE_UTXO};if(Z.includes("no dust")||Z.includes("dust")&&(Z.includes("required")||Z.includes("available")||Z.includes("insufficient")))return{exitCode:5,errorCode:n.DUST_REQUIRED};if(Z.includes("insufficient")||Z.includes("not enough"))return{exitCode:5,errorCode:n.INSUFFICIENT_BALANCE};if(Z.includes("rejected")||Z.includes("transaction failed"))return{exitCode:6,errorCode:n.TX_REJECTED};if(Z.includes("econnrefused")||Z.includes("enotfound")||Z.includes("etimedout")||Z.includes("websocket")||Z.includes("connection refused")||Z.includes("network")&&Z.includes("error"))return{exitCode:4,errorCode:n.NETWORK_ERROR};return{exitCode:1,errorCode:n.UNKNOWN}}var p0={name:"midnight-wallet-cli",version:"0.2.0",type:"module",description:"Git-style CLI wallet for the Midnight blockchain",license:"Apache-2.0",workspaces:["packages/*"],bin:{midnight:"dist/wallet.js",mn:"dist/wallet.js","midnight-wallet-cli":"dist/wallet.js","midnight-wallet-mcp":"dist/mcp-server.js"},files:["dist"],scripts:{wallet:"tsx src/wallet.ts",build:'bun build src/wallet.ts --outfile dist/wallet.js --target node --format esm --packages external --minify --banner "#!/usr/bin/env node" && bun build src/mcp-server.ts --outfile dist/mcp-server.js --target node --format esm --packages external --minify --banner "#!/usr/bin/env node"',mcp:"tsx src/mcp-server.ts",prepublishOnly:"npm run build && npm run test",test:"vitest run","test:watch":"vitest",typecheck:"tsc --noEmit"},dependencies:{"@midnight-ntwrk/dapp-connector-api":"^4.0.1","@midnight-ntwrk/ledger-v7":"^7.0.2","@midnight-ntwrk/midnight-js-network-id":"3.0.0","@midnight-ntwrk/midnight-js-types":"3.0.0","@midnight-ntwrk/wallet-sdk-abstractions":"^2.0.0","@midnight-ntwrk/wallet-sdk-address-format":"^3.0.1","@midnight-ntwrk/wallet-sdk-dust-wallet":"^2.0.0","@midnight-ntwrk/wallet-sdk-facade":"^2.0.0","@midnight-ntwrk/wallet-sdk-hd":"^3.0.1","@midnight-ntwrk/wallet-sdk-shielded":"^2.0.0","@midnight-ntwrk/wallet-sdk-unshielded-wallet":"^2.0.0","@modelcontextprotocol/sdk":"^1.27.1","@scure/bip39":"^2.0.1",rxjs:"^7.8.1",ws:"^8.19.0"},devDependencies:{"@types/node":"^22.19.13","@types/ws":"^8.18.1",tsx:"^4.21.0",typescript:"^5.9.3",vitest:"^3.2.4"}};var t7=p0.name,V2=p0.version,r7=p0.description;function i($,Z,Q){let X={json:!0},z=[];for(let[q,Y]of Object.entries(Z)){if(Y===void 0||Y===null)continue;if(typeof Y==="boolean"){if(Y)X[q]=!0}else X[q]=String(Y)}return{command:$,subcommand:Q,positionals:z,flags:X}}var p7={generate:()=>Promise.resolve().then(() => (m2(),u2)),info:()=>Promise.resolve().then(() => (d2(),g2)),balance:()=>Promise.resolve().then(() => (a2(),r2)),address:()=>Promise.resolve().then(() => ($$(),e2)),"genesis-address":()=>Promise.resolve().then(() => (X$(),Q$)),"inspect-cost":()=>Promise.resolve().then(() => (G$(),Y$)),airdrop:()=>Promise.resolve().then(() => (_$(),M$)),transfer:()=>Promise.resolve().then(() => (x$(),R$)),dust:()=>Promise.resolve().then(() => (C$(),D$)),cache:()=>Promise.resolve().then(() => (b$(),y$)),config:()=>Promise.resolve().then(() => (k$(),v$)),localnet:()=>Promise.resolve().then(() => (n$(),o$)),wallet:()=>Promise.resolve().then(() => ($3(),e$)),status:()=>Promise.resolve().then(() => (Y3(),q3))};async function y($){let Z=p7[$];if(!Z)throw new Error(`Unknown command handler: ${$}`);return(await Z()).default}var G3=[{name:"midnight_generate",description:"Generate a new wallet (deprecated — use midnight_wallet_generate instead)",inputSchema:{type:"object",properties:{network:{type:"string",description:"Network: preprod, preview, undeployed",enum:["preprod","preview","undeployed"]},seed:{type:"string",description:"Restore from existing seed (64-char hex)"},mnemonic:{type:"string",description:"Restore from BIP-39 mnemonic (24 words)"},output:{type:"string",description:"Custom output path (deprecated — use midnight_wallet_generate instead)"},force:{type:"string",description:'Set to "true" to overwrite existing wallet file'}}},async handler($){let Z=i("generate",$);if($.force==="true"||$.force===!0)Z.flags.force=!0;let Q=await y("generate");return N(Q,Z)}},{name:"midnight_wallet_generate",description:"Create a new named wallet and set it as active",inputSchema:{type:"object",properties:{name:{type:"string",description:'Wallet name (e.g. "alice", "dev")'},network:{type:"string",description:"Network: preprod, preview, undeployed",enum:["preprod","preview","undeployed"]},seed:{type:"string",description:"Restore from existing seed (64-char hex)"},mnemonic:{type:"string",description:"Restore from BIP-39 mnemonic (24 words)"},force:{type:"string",description:'Set to "true" to overwrite existing wallet'}},required:["name"]},async handler($){let Z=$.name,Q=i("wallet",$,"generate");if(Q.positionals=[Z],delete Q.flags.name,$.force==="true"||$.force===!0)Q.flags.force=!0;let X=await y("wallet");return N(X,Q)}},{name:"midnight_wallet_list",description:"List all wallets with name, address, network, and active marker",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"wallet",subcommand:"list",positionals:[],flags:{json:!0}},Z=await y("wallet");return N(Z,$)}},{name:"midnight_wallet_use",description:"Set the active wallet by name",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name to activate"}},required:["name"]},async handler($){let Q={command:"wallet",subcommand:"use",positionals:[$.name],flags:{json:!0}},X=await y("wallet");return N(X,Q)}},{name:"midnight_wallet_info",description:"Show details for a named wallet or the active wallet",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name (default: active wallet)"}}},async handler($){let Z=$.name,Q={command:"wallet",subcommand:"info",positionals:Z?[Z]:[],flags:{json:!0}},X=await y("wallet");return N(X,Q)}},{name:"midnight_wallet_remove",description:"Remove a named wallet (refuses active or last wallet)",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name to remove"}},required:["name"]},async handler($){let Q={command:"wallet",subcommand:"remove",positionals:[$.name],flags:{json:!0}},X=await y("wallet");return N(X,Q)}},{name:"midnight_info",description:"Display wallet address, network, creation date (no secrets shown)",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"}}},async handler($){let Z=i("info",$),Q=await y("info");return N(Q,Z)}},{name:"midnight_balance",description:"Check unshielded balance via indexer subscription",inputSchema:{type:"object",properties:{address:{type:"string",description:"Address to check (or reads from wallet file)"},wallet:{type:"string",description:"Wallet name or path"},network:{type:"string",description:"Override network detection",enum:["preprod","preview","undeployed"]},"indexer-ws":{type:"string",description:"Custom indexer WebSocket URL"}}},async handler($){let Z=$.address,Q=i("balance",$,Z);delete Q.flags.address;let X=await y("balance");return N(X,Q)}},{name:"midnight_address",description:"Derive and display an unshielded address from a seed",inputSchema:{type:"object",properties:{seed:{type:"string",description:"Seed to derive from (required, 64-char hex)"},network:{type:"string",description:"Network for address prefix",enum:["preprod","preview","undeployed"]},index:{type:"string",description:"Key derivation index (default: 0)"}},required:["seed"]},async handler($){let Z=i("address",$),Q=await y("address");return N(Q,Z)}},{name:"midnight_genesis_address",description:"Display the genesis wallet address (seed 0x01) for a network",inputSchema:{type:"object",properties:{network:{type:"string",description:"Network for address prefix",enum:["preprod","preview","undeployed"]}}},async handler($){let Z=i("genesis-address",$),Q=await y("genesis-address");return N(Q,Z)}},{name:"midnight_inspect_cost",description:"Display current block limits derived from LedgerParameters",inputSchema:{type:"object",properties:{}},async handler(){let $=i("inspect-cost",{}),Z=await y("inspect-cost");return N(Z,$)}},{name:"midnight_airdrop",description:"Fund your wallet from the genesis wallet (undeployed network only)",inputSchema:{type:"object",properties:{amount:{type:"string",description:"Amount in NIGHT to airdrop"},wallet:{type:"string",description:"Wallet name or path"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}},required:["amount"]},async handler($){let Z=$.amount,Q=i("airdrop",$,Z);delete Q.flags.amount;let X=await y("airdrop");return N(X,Q)}},{name:"midnight_transfer",description:"Send NIGHT tokens to another address",inputSchema:{type:"object",properties:{to:{type:"string",description:"Recipient bech32m address"},amount:{type:"string",description:"Amount in NIGHT to send"},wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}},required:["to","amount"]},async handler($){let{to:Z,amount:Q}=$,X=i("transfer",$,Z);X.positionals=[Q],delete X.flags.to,delete X.flags.amount;let z=await y("transfer");return N(z,X)}},{name:"midnight_dust_register",description:"Register NIGHT UTXOs for dust (fee token) generation",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}}},async handler($){let Z=i("dust",$,"register"),Q=await y("dust");return N(Q,Z)}},{name:"midnight_dust_status",description:"Check dust registration status and balance",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}}},async handler($){let Z=i("dust",$,"status"),Q=await y("dust");return N(Q,Z)}},{name:"midnight_config_get",description:"Read a persistent config value",inputSchema:{type:"object",properties:{key:{type:"string",description:'Config key to read (e.g. "network")'}},required:["key"]},async handler($){let Q={command:"config",subcommand:"get",positionals:[$.key],flags:{json:!0}},X=await y("config");return N(X,Q)}},{name:"midnight_config_set",description:"Write a persistent config value",inputSchema:{type:"object",properties:{key:{type:"string",description:'Config key to set (e.g. "network")'},value:{type:"string",description:"Config value to set"}},required:["key","value"]},async handler($){let{key:Z,value:Q}=$,X={command:"config",subcommand:"set",positionals:[Z,Q],flags:{json:!0}},z=await y("config");return N(z,X)}},{name:"midnight_cache_clear",description:"Clear cached wallet sync state",inputSchema:{type:"object",properties:{network:{type:"string",description:"Only clear cache for this network",enum:["preprod","preview","undeployed"]},wallet:{type:"string",description:"Only clear cache for this wallet (name or path)"}}},async handler($){let Z=i("cache",$,"clear"),Q=await y("cache");return N(Q,Z)}},{name:"midnight_config_unset",description:"Reset a persistent config value to its default",inputSchema:{type:"object",properties:{key:{type:"string",description:"Config key to reset"}},required:["key"]},async handler($){let Q={command:"config",subcommand:"unset",positionals:[$.key],flags:{json:!0}},X=await y("config");return N(X,Q)}},{name:"midnight_localnet_up",description:"Start a local Midnight network via Docker Compose",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"up",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}},{name:"midnight_localnet_stop",description:"Stop local network containers (preserves state for fast restart)",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"stop",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}},{name:"midnight_localnet_down",description:"Remove local network containers, networks, and volumes (full teardown)",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"down",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}},{name:"midnight_localnet_status",description:"Show local network service status and ports",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"status",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}},{name:"midnight_localnet_clean",description:"Remove conflicting containers from other setups",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"clean",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}}],q2=new k7({name:"midnight-wallet-cli",version:V2},{capabilities:{tools:{}}});q2.setRequestHandler(h7,async()=>{return{tools:G3.map(($)=>({name:$.name,description:$.description,inputSchema:$.inputSchema}))}});q2.setRequestHandler(f7,async($)=>{let{name:Z,arguments:Q}=$.params,X=G3.find((z)=>z.name===Z);if(!X)return{content:[{type:"text",text:`Unknown tool: ${Z}`}],isError:!0};try{let z=await X.handler(Q??{});return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){let q=z instanceof Error?z:new Error(String(z)),{errorCode:Y}=j2(q);return{content:[{type:"text",text:JSON.stringify({error:!0,code:Y,message:q.message})}],isError:!0}}});async function u7(){let $=new w7;await q2.connect($)}u7().catch(($)=>{process.stderr.write(`MCP server error: ${$.message}
371
+ `)}},30000);await new Promise(()=>{process.on("SIGINT",()=>{clearInterval(P),process.exit(0)})})}let B=J.reduce((P,x)=>{let F={...Y?.networks[x]??{},...U[x]??{}},O=X2(F);if(O==="down")return"down";if(O==="degraded"&&P!=="down")return"degraded";return P},"up");if(B==="down")process.exitCode=2;else if(B==="degraded")process.exitCode=1}var x7,A7,Z3,E7=15000,L1=5000,Q3=1e4;var Y3=E(()=>{Q0();c();B0();x7={preprod:{faucet:"https://faucet.preprod.midnight.network/",explorer:"https://preprod.midnightexplorer.com/"},preview:{faucet:"https://faucet.preview.midnight.network/",explorer:null},undeployed:{faucet:"",explorer:""}},A7={indexer:"Indexer",rpc:"RPC Node",faucet:"Faucet",explorer:"Explorer",chain:"Chain",dust:"Dust Generation",wallet:"Wallet Ops",dapp:"DApp Flow"},Z3={up:S("UP"),down:a("DOWN"),degraded:R("\x1B[33mDEGRADED\x1B[0m"),unknown:H("—")}});import{Server as k7}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as w7}from"@modelcontextprotocol/sdk/server/stdio.js";import{ListToolsRequestSchema as h7,CallToolRequestSchema as f7}from"@modelcontextprotocol/sdk/types.js";async function N($,Z,Q){let X=[];M1((q)=>X.push(q));let z=process.stderr.write;process.stderr.write=()=>!0;try{Z.flags.json=!0,await $(Z,Q);let q=X.join("").trim();if(!q)return{};return JSON.parse(q)}finally{M1(null),process.stderr.write=z}}var n={INVALID_ARGS:"INVALID_ARGS",WALLET_NOT_FOUND:"WALLET_NOT_FOUND",NETWORK_ERROR:"NETWORK_ERROR",INSUFFICIENT_BALANCE:"INSUFFICIENT_BALANCE",TX_REJECTED:"TX_REJECTED",STALE_UTXO:"STALE_UTXO",PROOF_TIMEOUT:"PROOF_TIMEOUT",DUST_REQUIRED:"DUST_REQUIRED",CANCELLED:"CANCELLED",UNKNOWN:"UNKNOWN"};function j2($){let Z=($.message??"").toLowerCase();if(Z.includes("operation cancelled")||Z.includes("operation aborted")||Z==="cancelled"||Z==="aborted")return{exitCode:7,errorCode:n.CANCELLED};if(Z.includes("wallet file not found")||Z.includes("wallet")&&Z.includes("not found"))return{exitCode:3,errorCode:n.WALLET_NOT_FOUND};if(Z.includes("missing required flag")||Z.includes("missing amount")||Z.includes("missing recipient")||Z.includes("missing config key")||Z.includes("missing or invalid subcommand")||Z.includes("unknown command")||Z.includes("cannot specify both")||Z.includes("invalid bip-39")||Z.includes("seed must be")||Z.includes("key index must be")||Z.includes("usage:"))return{exitCode:2,errorCode:n.INVALID_ARGS};if(Z.includes("proof")&&Z.includes("timeout"))return{exitCode:6,errorCode:n.PROOF_TIMEOUT};if(Z.includes("stale utxo")||Z.includes("error code 115")||Z.includes("errorcode: 115"))return{exitCode:6,errorCode:n.STALE_UTXO};if(Z.includes("no dust")||Z.includes("dust")&&(Z.includes("required")||Z.includes("available")||Z.includes("insufficient")))return{exitCode:5,errorCode:n.DUST_REQUIRED};if(Z.includes("insufficient")||Z.includes("not enough"))return{exitCode:5,errorCode:n.INSUFFICIENT_BALANCE};if(Z.includes("rejected")||Z.includes("transaction failed"))return{exitCode:6,errorCode:n.TX_REJECTED};if(Z.includes("econnrefused")||Z.includes("enotfound")||Z.includes("etimedout")||Z.includes("websocket")||Z.includes("connection refused")||Z.includes("network")&&Z.includes("error"))return{exitCode:4,errorCode:n.NETWORK_ERROR};return{exitCode:1,errorCode:n.UNKNOWN}}var p0={name:"midnight-wallet-cli",version:"0.2.2",type:"module",description:"Git-style CLI wallet for the Midnight blockchain",license:"Apache-2.0",workspaces:["packages/*"],bin:{midnight:"dist/wallet.js",mn:"dist/wallet.js","midnight-wallet-cli":"dist/wallet.js","midnight-wallet-mcp":"dist/mcp-server.js"},files:["dist"],scripts:{wallet:"tsx src/wallet.ts",build:'bun build src/wallet.ts --outfile dist/wallet.js --target node --format esm --packages external --minify --banner "#!/usr/bin/env node" && bun build src/mcp-server.ts --outfile dist/mcp-server.js --target node --format esm --packages external --minify --banner "#!/usr/bin/env node"',mcp:"tsx src/mcp-server.ts",prepublishOnly:"npm run build && npm run test",test:"vitest run","test:watch":"vitest",typecheck:"tsc --noEmit"},dependencies:{"@midnight-ntwrk/dapp-connector-api":"^4.0.1","@midnight-ntwrk/ledger-v7":"^7.0.2","@midnight-ntwrk/midnight-js-network-id":"3.0.0","@midnight-ntwrk/midnight-js-types":"3.0.0","@midnight-ntwrk/wallet-sdk-abstractions":"^2.0.0","@midnight-ntwrk/wallet-sdk-address-format":"^3.0.1","@midnight-ntwrk/wallet-sdk-dust-wallet":"^2.0.0","@midnight-ntwrk/wallet-sdk-facade":"^2.0.0","@midnight-ntwrk/wallet-sdk-hd":"^3.0.1","@midnight-ntwrk/wallet-sdk-shielded":"^2.0.0","@midnight-ntwrk/wallet-sdk-unshielded-wallet":"^2.0.0","@modelcontextprotocol/sdk":"^1.27.1","@scure/bip39":"^2.0.1",rxjs:"^7.8.1",ws:"^8.19.0"},devDependencies:{"@types/node":"^22.19.13","@types/ws":"^8.18.1",tsx:"^4.21.0",typescript:"^5.9.3",vitest:"^3.2.4"}};var t7=p0.name,V2=p0.version,r7=p0.description;function i($,Z,Q){let X={json:!0},z=[];for(let[q,Y]of Object.entries(Z)){if(Y===void 0||Y===null)continue;if(typeof Y==="boolean"){if(Y)X[q]=!0}else X[q]=String(Y)}return{command:$,subcommand:Q,positionals:z,flags:X}}var p7={generate:()=>Promise.resolve().then(() => (m2(),u2)),info:()=>Promise.resolve().then(() => (d2(),g2)),balance:()=>Promise.resolve().then(() => (a2(),r2)),address:()=>Promise.resolve().then(() => ($$(),e2)),"genesis-address":()=>Promise.resolve().then(() => (X$(),Q$)),"inspect-cost":()=>Promise.resolve().then(() => (G$(),Y$)),airdrop:()=>Promise.resolve().then(() => (_$(),M$)),transfer:()=>Promise.resolve().then(() => (x$(),R$)),dust:()=>Promise.resolve().then(() => (C$(),D$)),cache:()=>Promise.resolve().then(() => (b$(),y$)),config:()=>Promise.resolve().then(() => (k$(),v$)),localnet:()=>Promise.resolve().then(() => (n$(),o$)),wallet:()=>Promise.resolve().then(() => ($3(),e$)),status:()=>Promise.resolve().then(() => (Y3(),q3))};async function y($){let Z=p7[$];if(!Z)throw new Error(`Unknown command handler: ${$}`);return(await Z()).default}var G3=[{name:"midnight_generate",description:"Generate a new wallet (deprecated — use midnight_wallet_generate instead)",inputSchema:{type:"object",properties:{network:{type:"string",description:"Network: preprod, preview, undeployed",enum:["preprod","preview","undeployed"]},seed:{type:"string",description:"Restore from existing seed (64-char hex)"},mnemonic:{type:"string",description:"Restore from BIP-39 mnemonic (24 words)"},output:{type:"string",description:"Custom output path (deprecated — use midnight_wallet_generate instead)"},force:{type:"string",description:'Set to "true" to overwrite existing wallet file'}}},async handler($){let Z=i("generate",$);if($.force==="true"||$.force===!0)Z.flags.force=!0;let Q=await y("generate");return N(Q,Z)}},{name:"midnight_wallet_generate",description:"Create a new named wallet and set it as active",inputSchema:{type:"object",properties:{name:{type:"string",description:'Wallet name (e.g. "alice", "dev")'},network:{type:"string",description:"Network: preprod, preview, undeployed",enum:["preprod","preview","undeployed"]},seed:{type:"string",description:"Restore from existing seed (64-char hex)"},mnemonic:{type:"string",description:"Restore from BIP-39 mnemonic (24 words)"},force:{type:"string",description:'Set to "true" to overwrite existing wallet'}},required:["name"]},async handler($){let Z=$.name,Q=i("wallet",$,"generate");if(Q.positionals=[Z],delete Q.flags.name,$.force==="true"||$.force===!0)Q.flags.force=!0;let X=await y("wallet");return N(X,Q)}},{name:"midnight_wallet_list",description:"List all wallets with name, address, network, and active marker",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"wallet",subcommand:"list",positionals:[],flags:{json:!0}},Z=await y("wallet");return N(Z,$)}},{name:"midnight_wallet_use",description:"Set the active wallet by name",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name to activate"}},required:["name"]},async handler($){let Q={command:"wallet",subcommand:"use",positionals:[$.name],flags:{json:!0}},X=await y("wallet");return N(X,Q)}},{name:"midnight_wallet_info",description:"Show details for a named wallet or the active wallet",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name (default: active wallet)"}}},async handler($){let Z=$.name,Q={command:"wallet",subcommand:"info",positionals:Z?[Z]:[],flags:{json:!0}},X=await y("wallet");return N(X,Q)}},{name:"midnight_wallet_remove",description:"Remove a named wallet (refuses active or last wallet)",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name to remove"}},required:["name"]},async handler($){let Q={command:"wallet",subcommand:"remove",positionals:[$.name],flags:{json:!0}},X=await y("wallet");return N(X,Q)}},{name:"midnight_info",description:"Display wallet address, network, creation date (no secrets shown)",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"}}},async handler($){let Z=i("info",$),Q=await y("info");return N(Q,Z)}},{name:"midnight_balance",description:"Check unshielded balance via indexer subscription",inputSchema:{type:"object",properties:{address:{type:"string",description:"Address to check (or reads from wallet file)"},wallet:{type:"string",description:"Wallet name or path"},network:{type:"string",description:"Override network detection",enum:["preprod","preview","undeployed"]},"indexer-ws":{type:"string",description:"Custom indexer WebSocket URL"}}},async handler($){let Z=$.address,Q=i("balance",$,Z);delete Q.flags.address;let X=await y("balance");return N(X,Q)}},{name:"midnight_address",description:"Derive and display an unshielded address from a seed",inputSchema:{type:"object",properties:{seed:{type:"string",description:"Seed to derive from (required, 64-char hex)"},network:{type:"string",description:"Network for address prefix",enum:["preprod","preview","undeployed"]},index:{type:"string",description:"Key derivation index (default: 0)"}},required:["seed"]},async handler($){let Z=i("address",$),Q=await y("address");return N(Q,Z)}},{name:"midnight_genesis_address",description:"Display the genesis wallet address (seed 0x01) for a network",inputSchema:{type:"object",properties:{network:{type:"string",description:"Network for address prefix",enum:["preprod","preview","undeployed"]}}},async handler($){let Z=i("genesis-address",$),Q=await y("genesis-address");return N(Q,Z)}},{name:"midnight_inspect_cost",description:"Display current block limits derived from LedgerParameters",inputSchema:{type:"object",properties:{}},async handler(){let $=i("inspect-cost",{}),Z=await y("inspect-cost");return N(Z,$)}},{name:"midnight_airdrop",description:"Fund your wallet from the genesis wallet (undeployed network only)",inputSchema:{type:"object",properties:{amount:{type:"string",description:"Amount in NIGHT to airdrop"},wallet:{type:"string",description:"Wallet name or path"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}},required:["amount"]},async handler($){let Z=$.amount,Q=i("airdrop",$,Z);delete Q.flags.amount;let X=await y("airdrop");return N(X,Q)}},{name:"midnight_transfer",description:"Send NIGHT tokens to another address",inputSchema:{type:"object",properties:{to:{type:"string",description:"Recipient bech32m address"},amount:{type:"string",description:"Amount in NIGHT to send"},wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}},required:["to","amount"]},async handler($){let{to:Z,amount:Q}=$,X=i("transfer",$,Z);X.positionals=[Q],delete X.flags.to,delete X.flags.amount;let z=await y("transfer");return N(z,X)}},{name:"midnight_dust_register",description:"Register NIGHT UTXOs for dust (fee token) generation",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}}},async handler($){let Z=i("dust",$,"register"),Q=await y("dust");return N(Q,Z)}},{name:"midnight_dust_status",description:"Check dust registration status and balance",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}}},async handler($){let Z=i("dust",$,"status"),Q=await y("dust");return N(Q,Z)}},{name:"midnight_config_get",description:"Read a persistent config value",inputSchema:{type:"object",properties:{key:{type:"string",description:'Config key to read (e.g. "network")'}},required:["key"]},async handler($){let Q={command:"config",subcommand:"get",positionals:[$.key],flags:{json:!0}},X=await y("config");return N(X,Q)}},{name:"midnight_config_set",description:"Write a persistent config value",inputSchema:{type:"object",properties:{key:{type:"string",description:'Config key to set (e.g. "network")'},value:{type:"string",description:"Config value to set"}},required:["key","value"]},async handler($){let{key:Z,value:Q}=$,X={command:"config",subcommand:"set",positionals:[Z,Q],flags:{json:!0}},z=await y("config");return N(z,X)}},{name:"midnight_cache_clear",description:"Clear cached wallet sync state",inputSchema:{type:"object",properties:{network:{type:"string",description:"Only clear cache for this network",enum:["preprod","preview","undeployed"]},wallet:{type:"string",description:"Only clear cache for this wallet (name or path)"}}},async handler($){let Z=i("cache",$,"clear"),Q=await y("cache");return N(Q,Z)}},{name:"midnight_config_unset",description:"Reset a persistent config value to its default",inputSchema:{type:"object",properties:{key:{type:"string",description:"Config key to reset"}},required:["key"]},async handler($){let Q={command:"config",subcommand:"unset",positionals:[$.key],flags:{json:!0}},X=await y("config");return N(X,Q)}},{name:"midnight_localnet_up",description:"Start a local Midnight network via Docker Compose",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"up",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}},{name:"midnight_localnet_stop",description:"Stop local network containers (preserves state for fast restart)",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"stop",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}},{name:"midnight_localnet_down",description:"Remove local network containers, networks, and volumes (full teardown)",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"down",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}},{name:"midnight_localnet_status",description:"Show local network service status and ports",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"status",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}},{name:"midnight_localnet_clean",description:"Remove conflicting containers from other setups",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"clean",positionals:[],flags:{json:!0}},Z=await y("localnet");return N(Z,$)}}],q2=new k7({name:"midnight-wallet-cli",version:V2},{capabilities:{tools:{}}});q2.setRequestHandler(h7,async()=>{return{tools:G3.map(($)=>({name:$.name,description:$.description,inputSchema:$.inputSchema}))}});q2.setRequestHandler(f7,async($)=>{let{name:Z,arguments:Q}=$.params,X=G3.find((z)=>z.name===Z);if(!X)return{content:[{type:"text",text:`Unknown tool: ${Z}`}],isError:!0};try{let z=await X.handler(Q??{});return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){let q=z instanceof Error?z:new Error(String(z)),{errorCode:Y}=j2(q);return{content:[{type:"text",text:JSON.stringify({error:!0,code:Y,message:q.message})}],isError:!0}}});async function u7(){let $=new w7;await q2.connect($)}u7().catch(($)=>{process.stderr.write(`MCP server error: ${$.message}
372
372
  `),process.exit(1)});
package/dist/wallet.js CHANGED
@@ -1,31 +1,31 @@
1
1
  #!/usr/bin/env node
2
- var h9=Object.defineProperty;var e=($,Z)=>{for(var Q in Z)h9($,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:(X)=>Z[Q]=()=>X})};var x=($,Z)=>()=>($&&(Z=$($=0)),Z);function C$($){let Z=$??process.argv.slice(2),Q=[],X={},z=0;while(z<Z.length){let Y=Z[z];if(Y.startsWith("--")){let J=Y.slice(2),G=Z[z+1];if(G!==void 0&&!G.startsWith("-"))X[J]=G,z+=2;else X[J]=!0,z+=1}else if(Y.startsWith("-")&&Y.length===2){let J=Y.slice(1),G=Z[z+1];if(G!==void 0&&!G.startsWith("-"))X[J]=G,z+=2;else X[J]=!0,z+=1}else Q.push(Y),z+=1}return{command:Q[0],subcommand:Q[1],positionals:Q.slice(2),flags:X}}function N($,Z){let Q=$.flags[Z];if(Q===void 0||Q===!0)return;return Q}function R($,Z){return Z in $.flags}function i0($){return R($,"verbose")}function x$($,Z,Q){let X=N($,Z);if(X===void 0)throw new Error(`Missing required flag: --${Z} <${Q}>`);return X}function y0($){if(!$||$!==$.trim())return!1;if(/[\/\\]/.test($))return!1;if($.endsWith(".json"))return!1;if($==="."||$==="..")return!1;if(/[\x00-\x1f]/.test($))return!1;return!0}var R1="0000000000000000000000000000000000000000000000000000000000000001",y$="0000000000000000000000000000000000000000000000000000000000000000",J2=6,G2=1e6,b$=300000000000000n,S$=5,X1=800000000000000n,v$=300000,D1=30000,k$=120000,w$=1e4,K2=120000,A1=300000,q2=60000,z1=10,f$=3,h$=600000,U2=15000,p$=115,J0=".midnight",N1="wallet.json",u$="config.json",P0=448,C0=384,m$="localnet",V2=1,j2="cache",E1="wallets",Y1="default",J1=10,B2=3000,g$=120000,c$=9932,C1="https://midnight-comp-tracker.vercel.app";function R0(){return!("NO_COLOR"in process.env)}function o0($,Z){if(!R0())return $;return`\x1B[38;5;${Z}m${$}\x1B[0m`}function y($){if(!R0())return $;return`\x1B[1m${$}\x1B[0m`}function B($){if(!R0())return $;return`\x1B[2m${$}\x1B[0m`}function t($){return o0($,38)}function c($){return o0($,196)}function u($){return o0($,40)}function O0($){return o0($,226)}function G1($){return o0($,15)}function D0($){return o0($,245)}function f($,Z=l$){let Q=` ${$} `,X=Z-Q.length;if(X<=0)return y(Q);let z=Math.floor(X/2),Y=X-z;return y("═".repeat(z)+Q+"═".repeat(Y))}function h($=l$){return B("─".repeat($))}function T($,Z,Q=16){let X=($+":").padEnd(Q);return` ${D0(X)}${Z}`}function q1($){let Z=$<0n,Q=Z?-$:$,X=BigInt(10**J2),z=Q/X,J=(Q%X).toString().padStart(J2,"0");return`${Z?"-":""}${z}.${J}`}function x1($){return`${q1($)} NIGHT`}function y1($){let Z=$<0n,Q=Z?-$:$,X=10n**BigInt(d$),z=Q/X,G=(Q%X).toString().padStart(d$,"0").replace(/0+$/,"").padEnd(6,"0");return`${Z?"-":""}${z}.${G}`}function b1($){return`${y1($)} DUST`}function l($,Z=!1){let Q=Z&&$.length>20?$.slice(0,10)+"…"+$.slice(-8):$;return t(Q)}function p9($,Z){if(K1($).length<=Z)return[$];let X=$.split(/(\s+)/),z=[],Y="",J=0;for(let G of X){let q=K1(G).length;if(J+q>Z&&J>0)z.push(Y),Y=G.trimStart(),J=K1(Y).length;else Y+=G,J+=q}if(Y.length>0)z.push(Y);return z}function W2($,Z="light",Q=70){let X=Z==="heavy"?{tl:"╔",tr:"╗",bl:"╚",br:"╝",h:"═",v:"║"}:{tl:"┌",tr:"┐",bl:"└",br:"┘",h:"─",v:"│"},z=Q-4,Y=[];for(let W of $){let j=W.split(`
3
- `);for(let V of j)Y.push(...p9(V,z))}let J=Math.max(...Y.map((W)=>K1(W).length)),G=Math.max(J+2,20),q=X.tl+X.h.repeat(G)+X.tr,K=X.bl+X.h.repeat(G)+X.br,U=Y.map((W)=>{let j=K1(W).length,V=G-j-2;return`${X.v} ${W}${" ".repeat(Math.max(0,V))} ${X.v}`});return[q,...U,K].join(`
2
+ var h9=Object.defineProperty;var e=($,Z)=>{for(var Q in Z)h9($,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:(X)=>Z[Q]=()=>X})};var x=($,Z)=>()=>($&&(Z=$($=0)),Z);function C$($){let Z=$??process.argv.slice(2),Q=[],X={},z=0;while(z<Z.length){let Y=Z[z];if(Y.startsWith("--")){let J=Y.slice(2),G=Z[z+1];if(G!==void 0&&!G.startsWith("-"))X[J]=G,z+=2;else X[J]=!0,z+=1}else if(Y.startsWith("-")&&Y.length===2){let J=Y.slice(1),G=Z[z+1];if(G!==void 0&&!G.startsWith("-"))X[J]=G,z+=2;else X[J]=!0,z+=1}else Q.push(Y),z+=1}return{command:Q[0],subcommand:Q[1],positionals:Q.slice(2),flags:X}}function N($,Z){let Q=$.flags[Z];if(Q===void 0||Q===!0)return;return Q}function R($,Z){return Z in $.flags}function i0($){return R($,"verbose")}function x$($,Z,Q){let X=N($,Z);if(X===void 0)throw new Error(`Missing required flag: --${Z} <${Q}>`);return X}function y0($){if(!$||$!==$.trim())return!1;if(/[\/\\]/.test($))return!1;if($.endsWith(".json"))return!1;if($==="."||$==="..")return!1;if(/[\x00-\x1f]/.test($))return!1;return!0}var R2="0000000000000000000000000000000000000000000000000000000000000001",y$="0000000000000000000000000000000000000000000000000000000000000000",J1=6,G1=1e6,b$=300000000000000n,S$=5,X2=800000000000000n,v$=300000,D2=30000,k$=120000,w$=1e4,K1=120000,A2=300000,q1=60000,z2=10,f$=3,h$=600000,U1=15000,p$=115,J0=".midnight",N2="wallet.json",u$="config.json",P0=448,C0=384,m$="localnet",V1=1,j1="cache",E2="wallets",Y2="default",J2=10,B1=3000,g$=120000,c$=9932,C2="https://midnight-comp-tracker.vercel.app";function R0(){return!("NO_COLOR"in process.env)}function o0($,Z){if(!R0())return $;return`\x1B[38;5;${Z}m${$}\x1B[0m`}function y($){if(!R0())return $;return`\x1B[1m${$}\x1B[0m`}function B($){if(!R0())return $;return`\x1B[2m${$}\x1B[0m`}function t($){return o0($,38)}function c($){return o0($,196)}function u($){return o0($,40)}function O0($){return o0($,226)}function G2($){return o0($,15)}function D0($){return o0($,245)}function f($,Z=l$){let Q=` ${$} `,X=Z-Q.length;if(X<=0)return y(Q);let z=Math.floor(X/2),Y=X-z;return y("═".repeat(z)+Q+"═".repeat(Y))}function h($=l$){return B("─".repeat($))}function T($,Z,Q=16){let X=($+":").padEnd(Q);return` ${D0(X)}${Z}`}function q2($){let Z=$<0n,Q=Z?-$:$,X=BigInt(10**J1),z=Q/X,J=(Q%X).toString().padStart(J1,"0");return`${Z?"-":""}${z}.${J}`}function x2($){return`${q2($)} NIGHT`}function y2($){let Z=$<0n,Q=Z?-$:$,X=10n**BigInt(d$),z=Q/X,G=(Q%X).toString().padStart(d$,"0").replace(/0+$/,"").padEnd(6,"0");return`${Z?"-":""}${z}.${G}`}function b2($){return`${y2($)} DUST`}function l($,Z=!1){let Q=Z&&$.length>20?$.slice(0,10)+"…"+$.slice(-8):$;return t(Q)}function p9($,Z){if(K2($).length<=Z)return[$];let X=$.split(/(\s+)/),z=[],Y="",J=0;for(let G of X){let q=K2(G).length;if(J+q>Z&&J>0)z.push(Y),Y=G.trimStart(),J=K2(Y).length;else Y+=G,J+=q}if(Y.length>0)z.push(Y);return z}function W1($,Z="light",Q=70){let X=Z==="heavy"?{tl:"╔",tr:"╗",bl:"╚",br:"╝",h:"═",v:"║"}:{tl:"┌",tr:"┐",bl:"└",br:"┘",h:"─",v:"│"},z=Q-4,Y=[];for(let W of $){let j=W.split(`
3
+ `);for(let V of j)Y.push(...p9(V,z))}let J=Math.max(...Y.map((W)=>K2(W).length)),G=Math.max(J+2,20),q=X.tl+X.h.repeat(G)+X.tr,K=X.bl+X.h.repeat(G)+X.br,U=Y.map((W)=>{let j=K2(W).length,V=G-j-2;return`${X.v} ${W}${" ".repeat(Math.max(0,V))} ${X.v}`});return[q,...U,K].join(`
4
4
  `)}function i$($,Z){let X=$.split(`
5
- `).map((Y,J)=>J===0?c(y("Error: "))+c(Y):c(Y));if(Z)X.push(""),X.push(B("Suggestion: ")+Z);let z=W2(X,"heavy");if(R0())return z.replace(/[╔╗╚╝═║]/g,(Y)=>c(Y));return z}function b0($,Z){let X=[`${u("✓")} ${$}`];if(Z)X.push(T("Transaction",t(Z)));return X.join(`
6
- `)}var l$=60,d$=15,K1=($)=>$.replace(/\x1b\[[0-9;]*m/g,"");var s=()=>{};function U1($){let Z=($.message??"").toLowerCase();if(Z.includes("operation cancelled")||Z.includes("operation aborted")||Z==="cancelled"||Z==="aborted")return{exitCode:7,errorCode:I0.CANCELLED};if(Z.includes("wallet file not found")||Z.includes("wallet")&&Z.includes("not found"))return{exitCode:3,errorCode:I0.WALLET_NOT_FOUND};if(Z.includes("missing required flag")||Z.includes("missing amount")||Z.includes("missing recipient")||Z.includes("missing config key")||Z.includes("missing or invalid subcommand")||Z.includes("unknown command")||Z.includes("cannot specify both")||Z.includes("invalid bip-39")||Z.includes("seed must be")||Z.includes("key index must be")||Z.includes("usage:"))return{exitCode:2,errorCode:I0.INVALID_ARGS};if(Z.includes("proof")&&Z.includes("timeout"))return{exitCode:6,errorCode:I0.PROOF_TIMEOUT};if(Z.includes("stale utxo")||Z.includes("error code 115")||Z.includes("errorcode: 115"))return{exitCode:6,errorCode:I0.STALE_UTXO};if(Z.includes("no dust")||Z.includes("dust")&&(Z.includes("required")||Z.includes("available")||Z.includes("insufficient")))return{exitCode:5,errorCode:I0.DUST_REQUIRED};if(Z.includes("insufficient")||Z.includes("not enough"))return{exitCode:5,errorCode:I0.INSUFFICIENT_BALANCE};if(Z.includes("rejected")||Z.includes("transaction failed"))return{exitCode:6,errorCode:I0.TX_REJECTED};if(Z.includes("econnrefused")||Z.includes("enotfound")||Z.includes("etimedout")||Z.includes("websocket")||Z.includes("connection refused")||Z.includes("network")&&Z.includes("error"))return{exitCode:4,errorCode:I0.NETWORK_ERROR};return{exitCode:1,errorCode:I0.UNKNOWN}}var I0;var H2=x(()=>{I0={INVALID_ARGS:"INVALID_ARGS",WALLET_NOT_FOUND:"WALLET_NOT_FOUND",NETWORK_ERROR:"NETWORK_ERROR",INSUFFICIENT_BALANCE:"INSUFFICIENT_BALANCE",TX_REJECTED:"TX_REJECTED",STALE_UTXO:"STALE_UTXO",PROOF_TIMEOUT:"PROOF_TIMEOUT",DUST_REQUIRED:"DUST_REQUIRED",CANCELLED:"CANCELLED",UNKNOWN:"UNKNOWN"}});function o$(){let $=process.stderr.write;return process.stderr.write=()=>!0,()=>{process.stderr.write=$}}function L2($){V1=$}function E($){let Z=JSON.stringify($)+`
7
- `;if(V1)V1(Z);else process.stdout.write(Z)}function n$($,Z,Q){let X=JSON.stringify({error:!0,code:Z,message:$.message,exitCode:Q})+`
8
- `;if(V1)V1(X);else process.stdout.write(X)}var V1=null;var S1;var a$=x(()=>{S1={name:"midnight-wallet-cli",version:"0.2.0",type:"module",description:"Git-style CLI wallet for the Midnight blockchain",license:"Apache-2.0",workspaces:["packages/*"],bin:{midnight:"dist/wallet.js",mn:"dist/wallet.js","midnight-wallet-cli":"dist/wallet.js","midnight-wallet-mcp":"dist/mcp-server.js"},files:["dist"],scripts:{wallet:"tsx src/wallet.ts",build:'bun build src/wallet.ts --outfile dist/wallet.js --target node --format esm --packages external --minify --banner "#!/usr/bin/env node" && bun build src/mcp-server.ts --outfile dist/mcp-server.js --target node --format esm --packages external --minify --banner "#!/usr/bin/env node"',mcp:"tsx src/mcp-server.ts",prepublishOnly:"npm run build && npm run test",test:"vitest run","test:watch":"vitest",typecheck:"tsc --noEmit"},dependencies:{"@midnight-ntwrk/dapp-connector-api":"^4.0.1","@midnight-ntwrk/ledger-v7":"^7.0.2","@midnight-ntwrk/midnight-js-network-id":"3.0.0","@midnight-ntwrk/midnight-js-types":"3.0.0","@midnight-ntwrk/wallet-sdk-abstractions":"^2.0.0","@midnight-ntwrk/wallet-sdk-address-format":"^3.0.1","@midnight-ntwrk/wallet-sdk-dust-wallet":"^2.0.0","@midnight-ntwrk/wallet-sdk-facade":"^2.0.0","@midnight-ntwrk/wallet-sdk-hd":"^3.0.1","@midnight-ntwrk/wallet-sdk-shielded":"^2.0.0","@midnight-ntwrk/wallet-sdk-unshielded-wallet":"^2.0.0","@modelcontextprotocol/sdk":"^1.27.1","@scure/bip39":"^2.0.1",rxjs:"^7.8.1",ws:"^8.19.0"},devDependencies:{"@types/node":"^22.19.13","@types/ws":"^8.18.1",tsx:"^4.21.0",typescript:"^5.9.3",vitest:"^3.2.4"}}});var t$,S0,s$;var v1=x(()=>{a$();t$=S1.name,S0=S1.version,s$=S1.description});import{execSync as m9}from"child_process";function A0($){return r$.includes($)}function F2($){return{...g9[$]}}function k1(){return r$}function c9(){try{let $=m9('docker ps --format "{{.Image}}|{{.Ports}}"',{encoding:"utf-8",timeout:5000}),Z={};for(let Q of $.trim().split(`
9
- `)){if(!Q)continue;let[X,z]=Q.split("|"),Y=(J)=>{let G=new RegExp(`0\\.0\\.0\\.0:(\\d+)->${J}/tcp`),q=z?.match(G);return q?parseInt(q[1],10):void 0};if(X.includes("indexer-standalone")||X.includes("indexer")){let J=Y(8088);if(J)Z.indexerPort=J}if(X.includes("midnight-node")){let J=Y(9944);if(J)Z.nodePort=J}if(X.includes("proof-server")){let J=Y(6300);if(J)Z.proofServerPort=J}}return Z}catch{return{}}}function e$($){let Z=F2($);if($==="undeployed"){let Q=c9();if(Q.indexerPort)Z.indexer=`http://localhost:${Q.indexerPort}/api/v3/graphql`,Z.indexerWS=`ws://localhost:${Q.indexerPort}/api/v3/graphql/ws`;if(Q.nodePort)Z.node=`ws://localhost:${Q.nodePort}`;if(Q.proofServerPort)Z.proofServer=`http://localhost:${Q.proofServerPort}`}return Z}function _0($,Z,Q){let X=G0(Q);if($.proofServer=Z.proofServer??X["proof-server"]??$.proofServer,$.node=Z.node??X.node??$.node,$.indexerWS=Z.indexerWS??X["indexer-ws"]??$.indexerWS,Z.indexerWS??X["indexer-ws"]){let z=$.indexerWS;$.indexer=z.replace(/^wss:/,"https:").replace(/^ws:/,"http:").replace(/\/ws$/,"")}return $}var g9,r$;var T0=x(()=>{n0();g9={preprod:{indexer:"https://indexer.preprod.midnight.network/api/v3/graphql",indexerWS:"wss://indexer.preprod.midnight.network/api/v3/graphql/ws",node:"wss://rpc.preprod.midnight.network",proofServer:"http://localhost:6300",networkId:"PreProd"},preview:{indexer:"https://indexer.preview.midnight.network/api/v3/graphql",indexerWS:"wss://indexer.preview.midnight.network/api/v3/graphql/ws",node:"wss://rpc.preview.midnight.network",proofServer:"http://localhost:6300",networkId:"Preview"},undeployed:{indexer:"http://localhost:8088/api/v3/graphql",indexerWS:"ws://localhost:8088/api/v3/graphql/ws",node:"ws://localhost:9944",proofServer:"http://localhost:6300",networkId:"Undeployed"}},r$=["preprod","preview","undeployed"]});var Q7={};e(Q7,{unsetConfigValue:()=>T2,setConfigValue:()=>_2,saveCliConfig:()=>a0,loadCliConfig:()=>G0,getValidConfigKeys:()=>f1,getConfigValue:()=>I2});import*as N0 from"fs";import*as P2 from"path";import{homedir as d9}from"os";function l9($){return/^(https?|wss?):\/\/\S+/.test($)}function $7($){return $??P2.join(d9(),J0)}function Z7($){return P2.join($7($),u$)}function i9($){let Z=$7($);if(!N0.existsSync(Z))N0.mkdirSync(Z,{recursive:!0,mode:P0})}function G0($){let Z=Z7($);if(!N0.existsSync(Z))return{...j1};let Q;try{Q=N0.readFileSync(Z,"utf-8")}catch{return{...j1}}let X;try{X=JSON.parse(Q)}catch{return{...j1}}let z={network:X.network&&A0(X.network)?X.network:j1.network};if(X["proof-server"]&&typeof X["proof-server"]==="string")z["proof-server"]=X["proof-server"];if(X.node&&typeof X.node==="string")z.node=X.node;if(X["indexer-ws"]&&typeof X["indexer-ws"]==="string")z["indexer-ws"]=X["indexer-ws"];if(X.wallet&&typeof X.wallet==="string")z.wallet=X.wallet;return z}function a0($,Z){i9(Z);let Q=Z7(Z);N0.writeFileSync(Q,JSON.stringify($,null,2)+`
10
- `,{mode:C0})}function I2($,Z){let Q=G0(Z);if($==="network")return Q.network;if($==="wallet")return Q.wallet??"(not set)";if(O2.has($)){let X=Q[$];return typeof X==="string"?X:"(not set)"}throw new Error(`Unknown config key: "${$}"
11
- Valid keys: ${w1.join(", ")}`)}function _2($,Z,Q){let X=G0(Q);if($==="network"){if(!A0(Z))throw new Error(`Invalid network: "${Z}"
5
+ `).map((Y,J)=>J===0?c(y("Error: "))+c(Y):c(Y));if(Z)X.push(""),X.push(B("Suggestion: ")+Z);let z=W1(X,"heavy");if(R0())return z.replace(/[╔╗╚╝═║]/g,(Y)=>c(Y));return z}function b0($,Z){let X=[`${u("✓")} ${$}`];if(Z)X.push(T("Transaction",t(Z)));return X.join(`
6
+ `)}var l$=60,d$=15,K2=($)=>$.replace(/\x1b\[[0-9;]*m/g,"");var s=()=>{};function U2($){let Z=($.message??"").toLowerCase();if(Z.includes("operation cancelled")||Z.includes("operation aborted")||Z==="cancelled"||Z==="aborted")return{exitCode:7,errorCode:I0.CANCELLED};if(Z.includes("wallet file not found")||Z.includes("wallet")&&Z.includes("not found"))return{exitCode:3,errorCode:I0.WALLET_NOT_FOUND};if(Z.includes("missing required flag")||Z.includes("missing amount")||Z.includes("missing recipient")||Z.includes("missing config key")||Z.includes("missing or invalid subcommand")||Z.includes("unknown command")||Z.includes("cannot specify both")||Z.includes("invalid bip-39")||Z.includes("seed must be")||Z.includes("key index must be")||Z.includes("usage:"))return{exitCode:2,errorCode:I0.INVALID_ARGS};if(Z.includes("proof")&&Z.includes("timeout"))return{exitCode:6,errorCode:I0.PROOF_TIMEOUT};if(Z.includes("stale utxo")||Z.includes("error code 115")||Z.includes("errorcode: 115"))return{exitCode:6,errorCode:I0.STALE_UTXO};if(Z.includes("no dust")||Z.includes("dust")&&(Z.includes("required")||Z.includes("available")||Z.includes("insufficient")))return{exitCode:5,errorCode:I0.DUST_REQUIRED};if(Z.includes("insufficient")||Z.includes("not enough"))return{exitCode:5,errorCode:I0.INSUFFICIENT_BALANCE};if(Z.includes("rejected")||Z.includes("transaction failed"))return{exitCode:6,errorCode:I0.TX_REJECTED};if(Z.includes("econnrefused")||Z.includes("enotfound")||Z.includes("etimedout")||Z.includes("websocket")||Z.includes("connection refused")||Z.includes("network")&&Z.includes("error"))return{exitCode:4,errorCode:I0.NETWORK_ERROR};return{exitCode:1,errorCode:I0.UNKNOWN}}var I0;var H1=x(()=>{I0={INVALID_ARGS:"INVALID_ARGS",WALLET_NOT_FOUND:"WALLET_NOT_FOUND",NETWORK_ERROR:"NETWORK_ERROR",INSUFFICIENT_BALANCE:"INSUFFICIENT_BALANCE",TX_REJECTED:"TX_REJECTED",STALE_UTXO:"STALE_UTXO",PROOF_TIMEOUT:"PROOF_TIMEOUT",DUST_REQUIRED:"DUST_REQUIRED",CANCELLED:"CANCELLED",UNKNOWN:"UNKNOWN"}});function o$(){let $=process.stderr.write;return process.stderr.write=()=>!0,()=>{process.stderr.write=$}}function L1($){V2=$}function E($){let Z=JSON.stringify($)+`
7
+ `;if(V2)V2(Z);else process.stdout.write(Z)}function n$($,Z,Q){let X=JSON.stringify({error:!0,code:Z,message:$.message,exitCode:Q})+`
8
+ `;if(V2)V2(X);else process.stdout.write(X)}var V2=null;var S2;var a$=x(()=>{S2={name:"midnight-wallet-cli",version:"0.2.2",type:"module",description:"Git-style CLI wallet for the Midnight blockchain",license:"Apache-2.0",workspaces:["packages/*"],bin:{midnight:"dist/wallet.js",mn:"dist/wallet.js","midnight-wallet-cli":"dist/wallet.js","midnight-wallet-mcp":"dist/mcp-server.js"},files:["dist"],scripts:{wallet:"tsx src/wallet.ts",build:'bun build src/wallet.ts --outfile dist/wallet.js --target node --format esm --packages external --minify --banner "#!/usr/bin/env node" && bun build src/mcp-server.ts --outfile dist/mcp-server.js --target node --format esm --packages external --minify --banner "#!/usr/bin/env node"',mcp:"tsx src/mcp-server.ts",prepublishOnly:"npm run build && npm run test",test:"vitest run","test:watch":"vitest",typecheck:"tsc --noEmit"},dependencies:{"@midnight-ntwrk/dapp-connector-api":"^4.0.1","@midnight-ntwrk/ledger-v7":"^7.0.2","@midnight-ntwrk/midnight-js-network-id":"3.0.0","@midnight-ntwrk/midnight-js-types":"3.0.0","@midnight-ntwrk/wallet-sdk-abstractions":"^2.0.0","@midnight-ntwrk/wallet-sdk-address-format":"^3.0.1","@midnight-ntwrk/wallet-sdk-dust-wallet":"^2.0.0","@midnight-ntwrk/wallet-sdk-facade":"^2.0.0","@midnight-ntwrk/wallet-sdk-hd":"^3.0.1","@midnight-ntwrk/wallet-sdk-shielded":"^2.0.0","@midnight-ntwrk/wallet-sdk-unshielded-wallet":"^2.0.0","@modelcontextprotocol/sdk":"^1.27.1","@scure/bip39":"^2.0.1",rxjs:"^7.8.1",ws:"^8.19.0"},devDependencies:{"@types/node":"^22.19.13","@types/ws":"^8.18.1",tsx:"^4.21.0",typescript:"^5.9.3",vitest:"^3.2.4"}}});var t$,S0,s$;var v2=x(()=>{a$();t$=S2.name,S0=S2.version,s$=S2.description});import{execSync as m9}from"child_process";function A0($){return r$.includes($)}function F1($){return{...g9[$]}}function k2(){return r$}function c9(){try{let $=m9('docker ps --format "{{.Image}}|{{.Ports}}"',{encoding:"utf-8",timeout:5000}),Z={};for(let Q of $.trim().split(`
9
+ `)){if(!Q)continue;let[X,z]=Q.split("|"),Y=(J)=>{let G=new RegExp(`0\\.0\\.0\\.0:(\\d+)->${J}/tcp`),q=z?.match(G);return q?parseInt(q[1],10):void 0};if(X.includes("indexer-standalone")||X.includes("indexer")){let J=Y(8088);if(J)Z.indexerPort=J}if(X.includes("midnight-node")){let J=Y(9944);if(J)Z.nodePort=J}if(X.includes("proof-server")){let J=Y(6300);if(J)Z.proofServerPort=J}}return Z}catch{return{}}}function e$($){let Z=F1($);if($==="undeployed"){let Q=c9();if(Q.indexerPort)Z.indexer=`http://localhost:${Q.indexerPort}/api/v3/graphql`,Z.indexerWS=`ws://localhost:${Q.indexerPort}/api/v3/graphql/ws`;if(Q.nodePort)Z.node=`ws://localhost:${Q.nodePort}`;if(Q.proofServerPort)Z.proofServer=`http://localhost:${Q.proofServerPort}`}return Z}function _0($,Z,Q){let X=G0(Q);if($.proofServer=Z.proofServer??X["proof-server"]??$.proofServer,$.node=Z.node??X.node??$.node,$.indexerWS=Z.indexerWS??X["indexer-ws"]??$.indexerWS,Z.indexerWS??X["indexer-ws"]){let z=$.indexerWS;$.indexer=z.replace(/^wss:/,"https:").replace(/^ws:/,"http:").replace(/\/ws$/,"")}return $}var g9,r$;var T0=x(()=>{n0();g9={preprod:{indexer:"https://indexer.preprod.midnight.network/api/v3/graphql",indexerWS:"wss://indexer.preprod.midnight.network/api/v3/graphql/ws",node:"wss://rpc.preprod.midnight.network",proofServer:"http://localhost:6300",networkId:"PreProd"},preview:{indexer:"https://indexer.preview.midnight.network/api/v3/graphql",indexerWS:"wss://indexer.preview.midnight.network/api/v3/graphql/ws",node:"wss://rpc.preview.midnight.network",proofServer:"http://localhost:6300",networkId:"Preview"},undeployed:{indexer:"http://localhost:8088/api/v3/graphql",indexerWS:"ws://localhost:8088/api/v3/graphql/ws",node:"ws://localhost:9944",proofServer:"http://localhost:6300",networkId:"Undeployed"}},r$=["preprod","preview","undeployed"]});var Q7={};e(Q7,{unsetConfigValue:()=>T1,setConfigValue:()=>_1,saveCliConfig:()=>a0,loadCliConfig:()=>G0,getValidConfigKeys:()=>f2,getConfigValue:()=>I1});import*as N0 from"fs";import*as P1 from"path";import{homedir as d9}from"os";function l9($){return/^(https?|wss?):\/\/\S+/.test($)}function $7($){return $??P1.join(d9(),J0)}function Z7($){return P1.join($7($),u$)}function i9($){let Z=$7($);if(!N0.existsSync(Z))N0.mkdirSync(Z,{recursive:!0,mode:P0})}function G0($){let Z=Z7($);if(!N0.existsSync(Z))return{...j2};let Q;try{Q=N0.readFileSync(Z,"utf-8")}catch{return{...j2}}let X;try{X=JSON.parse(Q)}catch{return{...j2}}let z={network:X.network&&A0(X.network)?X.network:j2.network};if(X["proof-server"]&&typeof X["proof-server"]==="string")z["proof-server"]=X["proof-server"];if(X.node&&typeof X.node==="string")z.node=X.node;if(X["indexer-ws"]&&typeof X["indexer-ws"]==="string")z["indexer-ws"]=X["indexer-ws"];if(X.wallet&&typeof X.wallet==="string")z.wallet=X.wallet;return z}function a0($,Z){i9(Z);let Q=Z7(Z);N0.writeFileSync(Q,JSON.stringify($,null,2)+`
10
+ `,{mode:C0})}function I1($,Z){let Q=G0(Z);if($==="network")return Q.network;if($==="wallet")return Q.wallet??"(not set)";if(O1.has($)){let X=Q[$];return typeof X==="string"?X:"(not set)"}throw new Error(`Unknown config key: "${$}"
11
+ Valid keys: ${w2.join(", ")}`)}function _1($,Z,Q){let X=G0(Q);if($==="network"){if(!A0(Z))throw new Error(`Invalid network: "${Z}"
12
12
  Valid networks: preprod, preview, undeployed`);X.network=Z}else if($==="wallet"){if(!y0(Z))throw new Error(`Invalid wallet name: "${Z}"
13
- Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);X.wallet=Z}else if(O2.has($)){if(!l9(Z))throw new Error(`Invalid URL for "${$}": "${Z}"
13
+ Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);X.wallet=Z}else if(O1.has($)){if(!l9(Z))throw new Error(`Invalid URL for "${$}": "${Z}"
14
14
  Must start with http://, https://, ws://, or wss://`);X[$]=Z}else throw new Error(`Unknown config key: "${$}"
15
- Valid keys: ${w1.join(", ")}`);a0(X,Q)}function T2($,Z){let Q=G0(Z);if($==="network")Q.network=j1.network;else if($==="wallet")delete Q.wallet;else if(O2.has($))delete Q[$];else throw new Error(`Unknown config key: "${$}"
16
- Valid keys: ${w1.join(", ")}`);a0(Q,Z)}function f1(){return w1}var j1,w1,O2;var n0=x(()=>{T0();j1={network:"undeployed"},w1=["network","proof-server","node","indexer-ws","wallet"],O2=new Set(["proof-server","node","indexer-ws"])});import{HDWallet as o9,Roles as n9}from"@midnight-ntwrk/wallet-sdk-hd";import{createKeystore as a9,PublicKey as t9}from"@midnight-ntwrk/wallet-sdk-unshielded-wallet";import{NetworkId as M2}from"@midnight-ntwrk/wallet-sdk-abstractions";function v0($,Z,Q=0){let X=s9[Z],z=o9.fromSeed($);if(z.type!=="seedOk")throw new Error("Invalid seed for HD wallet");let Y=z.hdWallet.selectAccount(0).selectRole(n9.NightExternal).deriveKeyAt(Q);if(Y.type==="keyOutOfBounds")throw new Error(`Key index ${Q} out of bounds`);let J=a9(Y.key,X);return t9.fromKeyStore(J).address}function k0($,Z=0){let Q={};for(let X of k1())Q[X]=v0($,X,Z);return Q}var s9;var w0=x(()=>{T0();s9={preprod:M2.NetworkId.PreProd,preview:M2.NetworkId.Preview,undeployed:M2.NetworkId.Undeployed}});import*as w from"fs";import*as Z0 from"path";import{homedir as r9}from"os";function R2(){return Z0.join(r9(),J0)}function f0(){return Z0.join(R2(),E1)}function D2(){return Z0.join(R2(),N1)}function X7(){let $=R2();if(!w.existsSync($))w.mkdirSync($,{recursive:!0,mode:P0})}function e9(){X7();let $=f0();if(!w.existsSync($))w.mkdirSync($,{recursive:!0,mode:P0})}function $Z($){return $.includes("/")||$.includes("\\")||$.endsWith(".json")}function Q0($){if($!==void 0){if($Z($))return Z0.resolve($);return Z0.join(f0(),`${$}.json`)}let Q=G0().wallet??Y1;return Z0.join(f0(),`${Q}.json`)}function B1(){return G0().wallet??Y1}function A2($){if(!y0($))throw new Error(`Invalid wallet name: "${$}"
15
+ Valid keys: ${w2.join(", ")}`);a0(X,Q)}function T1($,Z){let Q=G0(Z);if($==="network")Q.network=j2.network;else if($==="wallet")delete Q.wallet;else if(O1.has($))delete Q[$];else throw new Error(`Unknown config key: "${$}"
16
+ Valid keys: ${w2.join(", ")}`);a0(Q,Z)}function f2(){return w2}var j2,w2,O1;var n0=x(()=>{T0();j2={network:"undeployed"},w2=["network","proof-server","node","indexer-ws","wallet"],O1=new Set(["proof-server","node","indexer-ws"])});import{HDWallet as o9,Roles as n9}from"@midnight-ntwrk/wallet-sdk-hd";import{createKeystore as a9,PublicKey as t9}from"@midnight-ntwrk/wallet-sdk-unshielded-wallet";import{NetworkId as M1}from"@midnight-ntwrk/wallet-sdk-abstractions";function v0($,Z,Q=0){let X=s9[Z],z=o9.fromSeed($);if(z.type!=="seedOk")throw new Error("Invalid seed for HD wallet");let Y=z.hdWallet.selectAccount(0).selectRole(n9.NightExternal).deriveKeyAt(Q);if(Y.type==="keyOutOfBounds")throw new Error(`Key index ${Q} out of bounds`);let J=a9(Y.key,X);return t9.fromKeyStore(J).address}function k0($,Z=0){let Q={};for(let X of k2())Q[X]=v0($,X,Z);return Q}var s9;var w0=x(()=>{T0();s9={preprod:M1.NetworkId.PreProd,preview:M1.NetworkId.Preview,undeployed:M1.NetworkId.Undeployed}});import*as w from"fs";import*as Z0 from"path";import{homedir as r9}from"os";function R1(){return Z0.join(r9(),J0)}function f0(){return Z0.join(R1(),E2)}function D1(){return Z0.join(R1(),N2)}function X7(){let $=R1();if(!w.existsSync($))w.mkdirSync($,{recursive:!0,mode:P0})}function e9(){X7();let $=f0();if(!w.existsSync($))w.mkdirSync($,{recursive:!0,mode:P0})}function $Z($){return $.includes("/")||$.includes("\\")||$.endsWith(".json")}function Q0($){if($!==void 0){if($Z($))return Z0.resolve($);return Z0.join(f0(),`${$}.json`)}let Q=G0().wallet??Y2;return Z0.join(f0(),`${Q}.json`)}function B2(){return G0().wallet??Y2}function A1($){if(!y0($))throw new Error(`Invalid wallet name: "${$}"
17
17
  Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Z=Z0.join(f0(),`${$}.json`);if(!w.existsSync(Z))throw new Error(`Wallet "${$}" not found.
18
- Run "midnight wallet list" to see available wallets.`);let Q=G0();Q.wallet=$,a0(Q)}function z7(){let $=f0();if(!w.existsSync($))return[];let Z=B1();return w.readdirSync($).filter((X)=>X.endsWith(".json")).sort().map((X)=>{let z=X.replace(/\.json$/,""),Y=Z0.join($,X);try{let J=JSON.parse(w.readFileSync(Y,"utf-8")),G;if(J.addresses)G=J.addresses;else if(J.address&&J.seed)try{let q=Buffer.from(J.seed,"hex");G=k0(q)}catch{G={undeployed:J.address,preprod:"(unknown)",preview:"(unknown)"}}else G={undeployed:"(unknown)",preprod:"(unknown)",preview:"(unknown)"};return{name:z,addresses:G,isActive:z===Z}}catch{return{name:z,addresses:{undeployed:"(invalid)",preprod:"(invalid)",preview:"(invalid)"},isActive:z===Z}}})}function Y7($){if(!y0($))throw new Error(`Invalid wallet name: "${$}"
18
+ Run "midnight wallet list" to see available wallets.`);let Q=G0();Q.wallet=$,a0(Q)}function z7(){let $=f0();if(!w.existsSync($))return[];let Z=B2();return w.readdirSync($).filter((X)=>X.endsWith(".json")).sort().map((X)=>{let z=X.replace(/\.json$/,""),Y=Z0.join($,X);try{let J=JSON.parse(w.readFileSync(Y,"utf-8")),G;if(J.addresses)G=J.addresses;else if(J.address&&J.seed)try{let q=Buffer.from(J.seed,"hex");G=k0(q)}catch{G={undeployed:J.address,preprod:"(unknown)",preview:"(unknown)"}}else G={undeployed:"(unknown)",preprod:"(unknown)",preview:"(unknown)"};return{name:z,addresses:G,isActive:z===Z}}catch{return{name:z,addresses:{undeployed:"(invalid)",preprod:"(invalid)",preview:"(invalid)"},isActive:z===Z}}})}function Y7($){if(!y0($))throw new Error(`Invalid wallet name: "${$}"
19
19
  Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Z=f0(),Q=Z0.join(Z,`${$}.json`);if(!w.existsSync(Q))throw new Error(`Wallet "${$}" not found.
20
- Run "midnight wallet list" to see available wallets.`);let X=B1();if($===X)throw new Error(`Cannot remove the active wallet "${$}".
20
+ Run "midnight wallet list" to see available wallets.`);let X=B2();if($===X)throw new Error(`Cannot remove the active wallet "${$}".
21
21
  Switch to another wallet first: midnight wallet use <other-wallet>`);if(w.readdirSync(Z).filter((Y)=>Y.endsWith(".json")).length<=1)throw new Error(`Cannot remove "${$}" — it is the only wallet.
22
- `+"Create another wallet first: midnight wallet generate <name>");w.unlinkSync(Q)}function J7(){let $=D2();if(!w.existsSync($))return;let Z=f0();if(w.existsSync(Z)){if(w.readdirSync(Z).filter((Y)=>Y.endsWith(".json")).length>0)return}e9();let Q=Z0.join(Z,`${Y1}.json`);w.copyFileSync($,Q),w.chmodSync(Q,C0),w.unlinkSync($);let X=G0();X.wallet=Y1,a0(X)}function X0($){let Z=$?Z0.resolve($):D2();if(!w.existsSync(Z))throw new Error(`Wallet file not found: ${Z}
22
+ `+"Create another wallet first: midnight wallet generate <name>");w.unlinkSync(Q)}function J7(){let $=D1();if(!w.existsSync($))return;let Z=f0();if(w.existsSync(Z)){if(w.readdirSync(Z).filter((Y)=>Y.endsWith(".json")).length>0)return}e9();let Q=Z0.join(Z,`${Y2}.json`);w.copyFileSync($,Q),w.chmodSync(Q,C0),w.unlinkSync($);let X=G0();X.wallet=Y2,a0(X)}function X0($){let Z=$?Z0.resolve($):D1();if(!w.existsSync(Z))throw new Error(`Wallet file not found: ${Z}
23
23
  Generate a wallet first: midnight wallet generate <name> --network <name>`);let Q;try{Q=w.readFileSync(Z,"utf-8")}catch(Y){throw new Error(`Failed to read wallet file: ${Z}
24
24
  ${Y.message}`)}let X;try{X=JSON.parse(Q)}catch{throw new Error(`Invalid JSON in wallet file: ${Z}`)}if(!X.seed||!X.createdAt){let Y=["seed","createdAt"];if(!X.addresses)Y.push("address");let J=Y.filter((G)=>!X[G]);if(J.length>0)throw new Error(`Wallet file is missing required fields (${J.join(", ")}): ${Z}`)}if(!/^[0-9a-fA-F]+$/.test(X.seed))throw new Error(`Invalid seed format in wallet file (expected hex string): ${Z}`);if(!X.addresses){if(!X.address)throw new Error(`Wallet file is missing required fields (address): ${Z}`);let Y=Buffer.from(X.seed,"hex"),J=k0(Y),G={seed:X.seed,addresses:J,createdAt:X.createdAt};if(X.mnemonic)G.mnemonic=X.mnemonic;let q={...X,addresses:J};return w.writeFileSync(Z,JSON.stringify(q,null,2)+`
25
- `,{mode:C0}),G}if(typeof X.addresses!=="object")throw new Error(`Wallet file has invalid addresses field: ${Z}`);let z={seed:X.seed,addresses:X.addresses,createdAt:X.createdAt};if(X.mnemonic)z.mnemonic=X.mnemonic;return z}function h1($,Z){let Q=Z?Z0.resolve(Z):D2();if(!Z)X7();else{let X=Z0.dirname(Q);if(!w.existsSync(X))w.mkdirSync(X,{recursive:!0,mode:P0})}return w.writeFileSync(Q,JSON.stringify($,null,2)+`
26
- `,{mode:C0}),Q}var W0=x(()=>{n0();w0()});async function m($,Z,Q){let X=[];L2((Y)=>X.push(Y));let z=process.stderr.write;process.stderr.write=()=>!0;try{Z.flags.json=!0,await $(Z,Q);let Y=X.join("").trim();if(!Y)return{};return JSON.parse(Y)}finally{L2(null),process.stderr.write=z}}var G7=()=>{};function K0($){let Z=N($.args,"network");if(Z!==void 0){if(!A0(Z))throw new Error(`Invalid network: "${Z}"
27
- Valid networks: ${k1().join(", ")}`);return Z}let Q=G0($.configDir);if(Q.network&&A0(Q.network))return Q.network;return"undeployed"}function U0($){let Z=K0($),Q=e$(Z);return{name:Z,config:Q}}var V0=x(()=>{T0();n0()});var N2={};e(N2,{default:()=>V7});import*as U7 from"fs";import*as p1 from"path";import{homedir as ZZ}from"os";import{generateMnemonic as QZ,mnemonicToSeedSync as K7,validateMnemonic as XZ}from"@scure/bip39";import{wordlist as q7}from"@scure/bip39/wordlists/english.js";async function V7($){let Z=K0({args:$}),Q=N($,"output"),X=N($,"seed"),z=N($,"mnemonic");if(X!==void 0&&z!==void 0)throw new Error("Cannot specify both --seed and --mnemonic. Use one or the other.");let Y=Q?p1.resolve(Q):p1.join(ZZ(),J0,N1);if(U7.existsSync(Y)&&!R($,"force"))throw new Error(`Wallet file already exists: ${Y}
28
- Use --force to overwrite, or --output <file> to save to a different path.`);let J,G;if(X!==void 0){let j=X.replace(/^0x/,"");if(j.length!==64||!/^[0-9a-fA-F]+$/.test(j))throw new Error("Seed must be a 64-character hex string (32 bytes)");J=Buffer.from(j,"hex")}else if(z!==void 0){if(!XZ(z,q7))throw new Error("Invalid BIP-39 mnemonic. Expected 12 or 24 words from the English wordlist.");G=z,J=Buffer.from(K7(G).slice(0,32))}else G=QZ(q7,256),J=Buffer.from(K7(G).slice(0,32));let q=k0(J),K=q[Z],U={seed:J.toString("hex"),addresses:q,createdAt:new Date().toISOString()};if(G)U.mnemonic=G;let W=h1(U,Q);if(R($,"json")){let j={addresses:q,activeAddress:K,activeNetwork:Z,seed:J.toString("hex"),file:W,createdAt:U.createdAt};if(G)j.mnemonic=G;E(j);return}if(process.stdout.write(K+`
25
+ `,{mode:C0}),G}if(typeof X.addresses!=="object")throw new Error(`Wallet file has invalid addresses field: ${Z}`);let z={seed:X.seed,addresses:X.addresses,createdAt:X.createdAt};if(X.mnemonic)z.mnemonic=X.mnemonic;return z}function h2($,Z){let Q=Z?Z0.resolve(Z):D1();if(!Z)X7();else{let X=Z0.dirname(Q);if(!w.existsSync(X))w.mkdirSync(X,{recursive:!0,mode:P0})}return w.writeFileSync(Q,JSON.stringify($,null,2)+`
26
+ `,{mode:C0}),Q}var W0=x(()=>{n0();w0()});async function m($,Z,Q){let X=[];L1((Y)=>X.push(Y));let z=process.stderr.write;process.stderr.write=()=>!0;try{Z.flags.json=!0,await $(Z,Q);let Y=X.join("").trim();if(!Y)return{};return JSON.parse(Y)}finally{L1(null),process.stderr.write=z}}var G7=()=>{};function K0($){let Z=N($.args,"network");if(Z!==void 0){if(!A0(Z))throw new Error(`Invalid network: "${Z}"
27
+ Valid networks: ${k2().join(", ")}`);return Z}let Q=G0($.configDir);if(Q.network&&A0(Q.network))return Q.network;return"undeployed"}function U0($){let Z=K0($),Q=e$(Z);return{name:Z,config:Q}}var V0=x(()=>{T0();n0()});var N1={};e(N1,{default:()=>V7});import*as U7 from"fs";import*as p2 from"path";import{homedir as ZZ}from"os";import{generateMnemonic as QZ,mnemonicToSeedSync as K7,validateMnemonic as XZ}from"@scure/bip39";import{wordlist as q7}from"@scure/bip39/wordlists/english.js";async function V7($){let Z=K0({args:$}),Q=N($,"output"),X=N($,"seed"),z=N($,"mnemonic");if(X!==void 0&&z!==void 0)throw new Error("Cannot specify both --seed and --mnemonic. Use one or the other.");let Y=Q?p2.resolve(Q):p2.join(ZZ(),J0,N2);if(U7.existsSync(Y)&&!R($,"force"))throw new Error(`Wallet file already exists: ${Y}
28
+ Use --force to overwrite, or --output <file> to save to a different path.`);let J,G;if(X!==void 0){let j=X.replace(/^0x/,"");if(j.length!==64||!/^[0-9a-fA-F]+$/.test(j))throw new Error("Seed must be a 64-character hex string (32 bytes)");J=Buffer.from(j,"hex")}else if(z!==void 0){if(!XZ(z,q7))throw new Error("Invalid BIP-39 mnemonic. Expected 12 or 24 words from the English wordlist.");G=z,J=Buffer.from(K7(G).slice(0,32))}else G=QZ(q7,256),J=Buffer.from(K7(G).slice(0,32));let q=k0(J),K=q[Z],U={seed:J.toString("hex"),addresses:q,createdAt:new Date().toISOString()};if(G)U.mnemonic=G;let W=h2(U,Q);if(R($,"json")){let j={addresses:q,activeAddress:K,activeNetwork:Z,seed:J.toString("hex"),file:W,createdAt:U.createdAt};if(G)j.mnemonic=G;E(j);return}if(process.stdout.write(K+`
29
29
  `),process.stderr.write(`
30
30
  `+f("Wallet Generated")+`
31
31
 
@@ -43,7 +43,7 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
43
43
  `),process.stderr.write(B(" Next: midnight info | midnight balance")+`
44
44
 
45
45
  `),process.stderr.write(u("✓")+` Wallet saved
46
- `)}var E2=x(()=>{w0();V0();W0();s()});var C2={};e(C2,{default:()=>j7});async function j7($){let Z=Q0(N($,"wallet")),Q=X0(Z),X=K0({args:$}),z=Q.addresses[X];if(R($,"json")){E({addresses:Q.addresses,activeNetwork:X,activeAddress:z,createdAt:Q.createdAt,file:Z});return}process.stdout.write(z+`
46
+ `)}var E1=x(()=>{w0();V0();W0();s()});var C1={};e(C1,{default:()=>j7});async function j7($){let Z=Q0(N($,"wallet")),Q=X0(Z),X=K0({args:$}),z=Q.addresses[X];if(R($,"json")){E({addresses:Q.addresses,activeNetwork:X,activeAddress:z,createdAt:Q.createdAt,file:Z});return}process.stdout.write(z+`
47
47
  `),process.stderr.write(`
48
48
  `+f("Wallet Info")+`
49
49
 
@@ -56,7 +56,7 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
56
56
  `),process.stderr.write(`
57
57
  `+h()+`
58
58
 
59
- `)}var x2=x(()=>{W0();V0();s();s()});import zZ from"ws";function B7($,Z,Q){return new Promise((X,z)=>{let Y=new zZ(Z,["graphql-transport-ws"]),J=new Map,G=0,q=0,K=0,U=!1,W=!1,j,V=()=>{let D=new Map,P=0;for(let M of J.values())if(!M.spent){P++;let C=D.get(M.tokenType)??0n;D.set(M.tokenType,C+M.value)}return{balances:D,utxoCount:P,txCount:G,highestTxId:q}},H=()=>{clearTimeout(j)},F=()=>{if(!W&&U&&(q===0||K>=q))W=!0,H(),Y.send(JSON.stringify({id:"1",type:"complete"})),Y.close(),X(V())};Y.on("open",()=>{Y.send(JSON.stringify({type:"connection_init"}))}),Y.on("message",(D)=>{let P=JSON.parse(D.toString());switch(P.type){case"connection_ack":Y.send(JSON.stringify({id:"1",type:"subscribe",payload:{query:YZ,variables:{address:$}}}));break;case"next":{if(P.payload?.errors){let C=P.payload.errors[0]?.message||"Unknown GraphQL error";if(!W)W=!0,H(),Y.close(),z(new Error(`GraphQL error: ${C}`));return}let M=P.payload?.data?.unshieldedTransactions;if(!M)return;if(M.__typename==="UnshieldedTransaction"){G++;let C=M;K=Math.max(K,C.transaction.id);for(let A of C.createdUtxos){let k=`${A.intentHash}:${A.outputIndex}`;J.set(k,{value:BigInt(A.value),tokenType:A.tokenType,spent:!1})}for(let A of C.spentUtxos){let k=`${A.intentHash}:${A.outputIndex}`,$0=J.get(k);if($0)$0.spent=!0}if(Q)Q(K,q);F()}else if(M.__typename==="UnshieldedTransactionsProgress")q=M.highestTransactionId,U=!0,F();break}case"error":if(!W)W=!0,H(),Y.close(),z(new Error(`GraphQL subscription error: ${JSON.stringify(P.payload)}`));break;case"complete":break}}),Y.on("error",(D)=>{if(!W)W=!0,H(),z(new Error(`WebSocket connection failed: ${D.message}`))}),Y.on("close",()=>{if(!W)W=!0,H(),z(new Error(`Indexer closed the connection before balance sync completed. Indexer: ${Z}`))}),j=setTimeout(()=>{if(!W)W=!0,Y.close(),z(new Error(`Balance check timed out after ${q2/1000}s. Indexer: ${Z}`))},q2)})}function W1($){return $===y$}var YZ=`
59
+ `)}var x1=x(()=>{W0();V0();s();s()});import zZ from"ws";function B7($,Z,Q){return new Promise((X,z)=>{let Y=new zZ(Z,["graphql-transport-ws"]),J=new Map,G=0,q=0,K=0,U=!1,W=!1,j,V=()=>{let D=new Map,P=0;for(let M of J.values())if(!M.spent){P++;let C=D.get(M.tokenType)??0n;D.set(M.tokenType,C+M.value)}return{balances:D,utxoCount:P,txCount:G,highestTxId:q}},H=()=>{clearTimeout(j)},F=()=>{if(!W&&U&&(q===0||K>=q))W=!0,H(),Y.send(JSON.stringify({id:"1",type:"complete"})),Y.close(),X(V())};Y.on("open",()=>{Y.send(JSON.stringify({type:"connection_init"}))}),Y.on("message",(D)=>{let P=JSON.parse(D.toString());switch(P.type){case"connection_ack":Y.send(JSON.stringify({id:"1",type:"subscribe",payload:{query:YZ,variables:{address:$}}}));break;case"next":{if(P.payload?.errors){let C=P.payload.errors[0]?.message||"Unknown GraphQL error";if(!W)W=!0,H(),Y.close(),z(new Error(`GraphQL error: ${C}`));return}let M=P.payload?.data?.unshieldedTransactions;if(!M)return;if(M.__typename==="UnshieldedTransaction"){G++;let C=M;K=Math.max(K,C.transaction.id);for(let A of C.createdUtxos){let k=`${A.intentHash}:${A.outputIndex}`;J.set(k,{value:BigInt(A.value),tokenType:A.tokenType,spent:!1})}for(let A of C.spentUtxos){let k=`${A.intentHash}:${A.outputIndex}`,$0=J.get(k);if($0)$0.spent=!0}if(Q)Q(K,q);F()}else if(M.__typename==="UnshieldedTransactionsProgress")q=M.highestTransactionId,U=!0,F();break}case"error":if(!W)W=!0,H(),Y.close(),z(new Error(`GraphQL subscription error: ${JSON.stringify(P.payload)}`));break;case"complete":break}}),Y.on("error",(D)=>{if(!W)W=!0,H(),z(new Error(`WebSocket connection failed: ${D.message}`))}),Y.on("close",()=>{if(!W)W=!0,H(),z(new Error(`Indexer closed the connection before balance sync completed. Indexer: ${Z}`))}),j=setTimeout(()=>{if(!W)W=!0,Y.close(),z(new Error(`Balance check timed out after ${q1/1000}s. Indexer: ${Z}`))},q1)})}function W2($){return $===y$}var YZ=`
60
60
  subscription UnshieldedTransactions($address: UnshieldedAddress!) {
61
61
  unshieldedTransactions(address: $address) {
62
62
  __typename
@@ -70,12 +70,12 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
70
70
  }
71
71
  }
72
72
  }
73
- `;var W7=()=>{};function F7(){return H1}function L7($){return $.replace(/\x1b\[[0-9;]*m/g,"")}function i($){let Z=!1;if(!R0()){let G=$;process.stderr.write(`⠋ ${G}`);let q={update(K){G=K,process.stderr.write(`\r⠋ ${G}\x1B[K`)},stop(K){if(Z)return;Z=!0,H1=null,process.stderr.write(`\r✓ ${K??G}\x1B[K
73
+ `;var W7=()=>{};function F7(){return H2}function L7($){return $.replace(/\x1b\[[0-9;]*m/g,"")}function i($){let Z=!1;if(!R0()){let G=$;process.stderr.write(`⠋ ${G}`);let q={update(K){G=K,process.stderr.write(`\r⠋ ${G}\x1B[K`)},stop(K){if(Z)return;Z=!0,H2=null,process.stderr.write(`\r✓ ${K??G}\x1B[K
74
74
  `)},log(K){process.stderr.write(`\r\x1B[K${K}
75
- `),process.stderr.write(`⠋ ${G}`)}};return H1=q,q}let Q=0,X=$,z=()=>{let G=t(H7[Q]),K=(process.stderr.columns||80)-4,U=X;if(L7(U).length>K)U=L7(U).slice(0,K);process.stderr.write(`\r${G} ${U}\x1B[K`),Q=(Q+1)%H7.length};z();let Y=setInterval(z,JZ),J={update(G){X=G},stop(G){if(Z)return;Z=!0,clearInterval(Y),H1=null;let q=G??X;process.stderr.write(`\r\x1B[32m✓\x1B[0m ${q}\x1B[K
75
+ `),process.stderr.write(`⠋ ${G}`)}};return H2=q,q}let Q=0,X=$,z=()=>{let G=t(H7[Q]),K=(process.stderr.columns||80)-4,U=X;if(L7(U).length>K)U=L7(U).slice(0,K);process.stderr.write(`\r${G} ${U}\x1B[K`),Q=(Q+1)%H7.length};z();let Y=setInterval(z,JZ),J={update(G){X=G},stop(G){if(Z)return;Z=!0,clearInterval(Y),H2=null;let q=G??X;process.stderr.write(`\r\x1B[32m✓\x1B[0m ${q}\x1B[K
76
76
  `)},log(G){process.stderr.write(`\r\x1B[K${G}
77
- `),z()}};return H1=J,J}var H7,JZ=80,H1=null;var x0=x(()=>{H7=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"]});var y2={};e(y2,{default:()=>P7});async function P7($){let{name:Z,config:Q}=U0({args:$}),X;if($.subcommand)X=$.subcommand;else X=X0(Q0(N($,"wallet"))).addresses[Z];if(!X)throw new Error("No address provided and no wallet file found.");_0(Q,{proofServer:N($,"proof-server"),node:N($,"node"),indexerWS:N($,"indexer-ws")});let z=i(`Checking balance on ${Z}...`);try{let Y=await B7(X,Q.indexerWS,(J,G)=>{if(G>0){let q=Math.round(J/G*100);z.update(`Syncing transactions... ${q}%`)}});if(z.stop(`Synced ${Y.txCount} transactions`),R($,"json")){let J={};for(let[G,q]of Y.balances){let K=W1(G)?"NIGHT":G;J[K]=W1(G)?q1(q):q.toString()}E({address:X,network:Z,balances:J,utxoCount:Y.utxoCount,txCount:Y.txCount});return}if(Y.balances.size===0)process.stdout.write(`0
78
- `);else for(let[J,G]of Y.balances)if(W1(J))process.stdout.write(`NIGHT=${G}
77
+ `),z()}};return H2=J,J}var H7,JZ=80,H2=null;var x0=x(()=>{H7=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"]});var y1={};e(y1,{default:()=>P7});async function P7($){let{name:Z,config:Q}=U0({args:$}),X;if($.subcommand)X=$.subcommand;else X=X0(Q0(N($,"wallet"))).addresses[Z];if(!X)throw new Error("No address provided and no wallet file found.");_0(Q,{proofServer:N($,"proof-server"),node:N($,"node"),indexerWS:N($,"indexer-ws")});let z=i(`Checking balance on ${Z}...`);try{let Y=await B7(X,Q.indexerWS,(J,G)=>{if(G>0){let q=Math.round(J/G*100);z.update(`Syncing transactions... ${q}%`)}});if(z.stop(`Synced ${Y.txCount} transactions`),R($,"json")){let J={};for(let[G,q]of Y.balances){let K=W2(G)?"NIGHT":G;J[K]=W2(G)?q2(q):q.toString()}E({address:X,network:Z,balances:J,utxoCount:Y.utxoCount,txCount:Y.txCount});return}if(Y.balances.size===0)process.stdout.write(`0
78
+ `);else for(let[J,G]of Y.balances)if(W2(J))process.stdout.write(`NIGHT=${G}
79
79
  `);else process.stdout.write(`${J}=${G}
80
80
  `);if(process.stderr.write(`
81
81
  `+f("Balance")+`
@@ -86,12 +86,12 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
86
86
  `),process.stderr.write(T("Transactions",Y.txCount.toString())+`
87
87
  `),process.stderr.write(`
88
88
  `),Y.balances.size===0)process.stderr.write(` ${B("No balance found")}
89
- `);else for(let[J,G]of Y.balances)if(W1(J))process.stderr.write(T("NIGHT",y(x1(G)))+`
89
+ `);else for(let[J,G]of Y.balances)if(W2(J))process.stderr.write(T("NIGHT",y(x2(G)))+`
90
90
  `);else{let q=J.slice(0,8)+"…"+J.slice(-8);process.stderr.write(T(`Token ${q}`,y(G.toString()))+`
91
91
  `)}process.stderr.write(`
92
92
  `+h()+`
93
93
 
94
- `)}catch(Y){throw z.stop("Failed"),Y}}var b2=x(()=>{W0();V0();T0();W7();s();x0()});var S2={};e(S2,{default:()=>O7});async function O7($){let Z=x$($,"seed","hex").replace(/^0x/,"");if(Z.length!==64||!/^[0-9a-fA-F]+$/.test(Z))throw new Error("Seed must be a 64-character hex string (32 bytes)");let Q=N($,"index"),X=Q!==void 0?parseInt(Q,10):0;if(isNaN(X)||X<0||!Number.isInteger(Number(Q??"0")))throw new Error("Key index must be a non-negative integer");let z=Buffer.from(Z,"hex"),Y=K0({args:$}),J=v0(z,Y,X),G=`m/44'/2400'/0'/NightExternal/${X}`;if(R($,"json")){E({address:J,network:Y,index:X,path:G});return}process.stdout.write(J+`
94
+ `)}catch(Y){throw z.stop("Failed"),Y}}var b1=x(()=>{W0();V0();T0();W7();s();x0()});var S1={};e(S1,{default:()=>O7});async function O7($){let Z=x$($,"seed","hex").replace(/^0x/,"");if(Z.length!==64||!/^[0-9a-fA-F]+$/.test(Z))throw new Error("Seed must be a 64-character hex string (32 bytes)");let Q=N($,"index"),X=Q!==void 0?parseInt(Q,10):0;if(isNaN(X)||X<0||!Number.isInteger(Number(Q??"0")))throw new Error("Key index must be a non-negative integer");let z=Buffer.from(Z,"hex"),Y=K0({args:$}),J=v0(z,Y,X),G=`m/44'/2400'/0'/NightExternal/${X}`;if(R($,"json")){E({address:J,network:Y,index:X,path:G});return}process.stdout.write(J+`
95
95
  `),process.stderr.write(`
96
96
  `),process.stderr.write(T("Network",Y)+`
97
97
  `),process.stderr.write(T("Index",X.toString())+`
@@ -99,14 +99,14 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
99
99
  `),process.stderr.write(T("Path",B(G))+`
100
100
  `),process.stderr.write(h()+`
101
101
 
102
- `)}var v2=x(()=>{w0();V0();s()});var k2={};e(k2,{default:()=>I7});async function I7($){let Z=K0({args:$}),Q=Buffer.from(R1,"hex"),X=v0(Q,Z);if(R($,"json")){E({address:X,network:Z});return}process.stdout.write(X+`
102
+ `)}var v1=x(()=>{w0();V0();s()});var k1={};e(k1,{default:()=>I7});async function I7($){let Z=K0({args:$}),Q=Buffer.from(R2,"hex"),X=v0(Q,Z);if(R($,"json")){E({address:X,network:Z});return}process.stdout.write(X+`
103
103
  `),process.stderr.write(`
104
104
  `),process.stderr.write(T("Network",Z)+`
105
105
  `),process.stderr.write(T("Address",l(X))+`
106
106
  `),process.stderr.write(T("Seed",B("0x01 (genesis)"))+`
107
107
  `),process.stderr.write(h()+`
108
108
 
109
- `)}var w2=x(()=>{w0();V0();s()});var f2={};e(f2,{default:()=>T7});import*as _7 from"@midnight-ntwrk/ledger-v7";function L1($,Z,Q){let X={readTime:0n,computeTime:0n,blockUsage:0n,bytesWritten:0n,bytesChurned:0n};X[Z]=Q;let Y=$.normalizeFullness(X)[Z];return Math.round(Number(Q)/Y)}function GZ($){return{readTime:L1($,"readTime",1000000000n),computeTime:L1($,"computeTime",1000000000n),blockUsage:L1($,"blockUsage",10000n),bytesWritten:L1($,"bytesWritten",10000n),bytesChurned:L1($,"bytesChurned",1000000n)}}async function T7($){let Z=_7.LedgerParameters.initialParameters(),Q=GZ(Z);if(R($,"json")){E(Q);return}for(let[X,z]of Object.entries(Q))process.stdout.write(`${X}=${z}
109
+ `)}var w1=x(()=>{w0();V0();s()});var f1={};e(f1,{default:()=>T7});import*as _7 from"@midnight-ntwrk/ledger-v7";function L2($,Z,Q){let X={readTime:0n,computeTime:0n,blockUsage:0n,bytesWritten:0n,bytesChurned:0n};X[Z]=Q;let Y=$.normalizeFullness(X)[Z];return Math.round(Number(Q)/Y)}function GZ($){return{readTime:L2($,"readTime",1000000000n),computeTime:L2($,"computeTime",1000000000n),blockUsage:L2($,"blockUsage",10000n),bytesWritten:L2($,"bytesWritten",10000n),bytesChurned:L2($,"bytesChurned",1000000n)}}async function T7($){let Z=_7.LedgerParameters.initialParameters(),Q=GZ(Z);if(R($,"json")){E(Q);return}for(let[X,z]of Object.entries(Q))process.stdout.write(`${X}=${z}
110
110
  `);process.stderr.write(`
111
111
  `+f("Block Limits")+`
112
112
 
@@ -118,20 +118,20 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
118
118
  `),process.stderr.write(B(" bytesWritten is typically the tightest constraint")+`
119
119
  `),process.stderr.write(B(" for large contract deployments.")+`
120
120
 
121
- `)}var KZ;var h2=x(()=>{s();KZ={readTime:"picoseconds",computeTime:"picoseconds",blockUsage:"bytes",bytesWritten:"bytes",bytesChurned:"bytes"}});import{HDWallet as qZ,Roles as p2}from"@midnight-ntwrk/wallet-sdk-hd";function u2($,Z){let Q=qZ.fromSeed($);if(Q.type!=="seedOk")throw new Error("Invalid seed for HD wallet");let X=Q.hdWallet.selectAccount(0).selectRole(Z).deriveKeyAt(0);if(X.type==="keyOutOfBounds")throw new Error("Key derivation out of bounds");return X.key}function M7($){return u2($,p2.Zswap)}function R7($){return u2($,p2.NightExternal)}function D7($){return u2($,p2.Dust)}var A7=()=>{};function t0(){N7=!0}function v($,Z){if(!N7)return;let Q=new Date().toISOString().slice(11,23);process.stderr.write(B(` [${Q}] ${$}: ${Z}`)+`
122
- `)}var N7=!1;var s0=()=>{};import{ShieldedWallet as E7}from"@midnight-ntwrk/wallet-sdk-shielded";import{UnshieldedWallet as C7,createKeystore as UZ,PublicKey as VZ,InMemoryTransactionHistoryStorage as jZ}from"@midnight-ntwrk/wallet-sdk-unshielded-wallet";import{DustWallet as x7}from"@midnight-ntwrk/wallet-sdk-dust-wallet";import{WalletFacade as y7}from"@midnight-ntwrk/wallet-sdk-facade";import*as r0 from"@midnight-ntwrk/ledger-v7";import{NetworkId as m2}from"@midnight-ntwrk/wallet-sdk-abstractions";import*as Y0 from"rxjs";async function h0($,Z,Q){let X=BZ[Z.networkId];if(X===void 0)throw new Error(`Unknown networkId: ${Z.networkId}`);v("facade",`Building facade for network ${Z.networkId}`),v("facade",`Node: ${Z.node}`),v("facade",`Indexer: ${Z.indexerWS}`),v("facade",`Proof server: ${Z.proofServer}`);let z=M7($),Y=R7($),J=D7($),G=r0.ZswapSecretKeys.fromSeed(z),q=r0.DustSecretKey.fromSeed(J),K=UZ(Y,X),U={networkId:X,indexerClientConnection:{indexerHttpUrl:Z.indexer,indexerWsUrl:Z.indexerWS},costParameters:{additionalFeeOverhead:b$,feeBlocksMargin:S$},txHistoryStorage:new jZ,provingServerUrl:new URL(Z.proofServer),relayURL:new URL(Z.node)},W=()=>y7.init({configuration:U,shielded:(H)=>E7(H).startWithSecretKeys(G),unshielded:(H)=>C7(H).startWithPublicKey(VZ.fromKeyStore(K)),dust:(H)=>x7(H).startWithSecretKey(q,r0.LedgerParameters.initialParameters().dust)}),j=!1,V;if(Q){v("facade","Restoring from cache...");try{V=await y7.init({configuration:U,shielded:(H)=>E7(H).restore(Q.shielded),unshielded:(H)=>C7(H).restore(Q.unshielded),dust:(H)=>x7(H).restore(Q.dust)}),j=!0,v("facade","Cache restore successful")}catch(H){v("facade",`Cache restore failed: ${H.message}`),process.stderr.write(` Cache restore failed, building from scratch: ${H.message}
123
- `),V=await W()}}else v("facade","No cache, building fresh"),V=await W();return{facade:V,keystore:K,zswapSecretKeys:G,dustSecretKey:q,restoredFromCache:j}}function b7($,Z="full"){let Q=$.unshielded?.progress?.isStrictlyComplete()??!1,X=$.dust?.state?.progress?.isStrictlyComplete()??!1;if(!X)try{let Y=$.dust?.state?.progress;if(Y&&Y.highestRelevantWalletIndex>0&&Y.appliedIndex>=Y.highestRelevantWalletIndex)X=!0}catch{}if(Z==="lite")return Q&&X;return($.shielded?.state?.progress?.isStrictlyComplete()??!1)&&Q&&X}function WZ($){if($.dust?.state?.progress?.isStrictlyComplete())return!1;try{let Z=$.dust?.state?.progress;if(Z&&Z.highestRelevantWalletIndex>0&&Z.appliedIndex>=Z.highestRelevantWalletIndex)return!1}catch{}return!0}async function p0($,Z={}){let{onProgress:Q,onSyncDetail:X,timeoutMs:z,syncMode:Y="full"}=Z,{facade:J,zswapSecretKeys:G,dustSecretKey:q}=$;v("sync","Starting facade (connecting to node and indexer)..."),await J.start(G,q),v("sync","Facade started, subscribing to state...");let K=z??v$;return v("sync",`Sync timeout: ${K/1000}s, mode: ${Y}`),new Promise((U,W)=>{let j=!1,V=0,H="",F=null,D=setTimeout(()=>{if(!j){if(v("sync",`Sync timed out after ${K/1000}s (${V} emissions)`),F)try{let P=F.unshielded?.progress;v("sync",` unshielded: applied=${P?.appliedId} highest=${P?.highestTransactionId} complete=${P?.isStrictlyComplete()}`);let M=F.dust?.state?.progress;if(v("sync",` dust: applied=${M?.appliedIndex} highest=${M?.highestRelevantWalletIndex} complete=${M?.isStrictlyComplete?.()} connected=${M?.isConnected}`),Y==="full"){let C=F.shielded?.state?.progress;v("sync",` shielded: complete=${C?.isStrictlyComplete()}`)}}catch{}W(new Error("Wallet sync timed out"))}},K);$.keepAlive=J.state().subscribe({next:(P)=>{if(j)return;if(V++,F=P,Q){let C=P.unshielded.progress;if(C){let A=Number(C.appliedId),k=Number(C.highestTransactionId);Q(Math.min(A,k),k)}}let M=[];try{if(Y==="full"&&!P.shielded?.state?.progress?.isStrictlyComplete())M.push("shielded");if(WZ(P))M.push("dust");if(!P.unshielded?.progress?.isStrictlyComplete())M.push("unshielded")}catch{}if(M.length>0){X?.(M.join(", "));let C=M.join(",");if(V===1||C!==H||V%100===0)v("sync",`Waiting on: ${M.join(", ")} (emission #${V})`),H=C}if(b7(P,Y))j=!0,clearTimeout(D),v("sync",`Sync complete after ${V} emissions`),U(P)},error:(P)=>{if(!j)v("sync",`Sync error: ${P.message}`),clearTimeout(D),W(P)}})})}async function g2($){let Z=(Q)=>{let X=Q.unshielded?.progress?.isStrictlyComplete()??!1,z=Q.dust?.state?.progress?.isStrictlyComplete()??!1;return X&&z};try{return await Y0.firstValueFrom($.facade.state().pipe(Y0.filter(Z),Y0.timeout(15000)))}catch{return await Y0.firstValueFrom($.facade.state())}}async function S7($,Z=60000){let Q=(X)=>{try{let z=X.dust;return z?.availableCoins?.length>0||z?.balance(new Date)>0n}catch{return!1}};try{return await Y0.firstValueFrom($.facade.state().pipe(Y0.filter(Q),Y0.timeout(Z)))}catch{return await Y0.firstValueFrom($.facade.state())}}async function c2($,Z="full"){return Y0.firstValueFrom($.facade.state().pipe(Y0.filter((Q)=>b7(Q,Z)),Y0.timeout(w$)))}async function u0($){$.keepAlive?.unsubscribe(),await Promise.race([$.facade.stop(),new Promise((Z)=>setTimeout(Z,5000))])}function e0($){let Z=(X)=>{let z=X?._tag;if(typeof z==="string"&&z.startsWith("Wallet.")){let Y=X?.message??"transient error";$?.(z,Y);return}Q("Unhandled rejection:",X),process.exit(1)},Q=console.error;return console.error=(...X)=>{let z=X[0];if(typeof z==="object"&&z?._tag?.startsWith("Wallet.")){$?.(z._tag,z?.message??"transient error");return}if(typeof z==="string"&&z.startsWith("Wallet.")){$?.("Wallet.Sync","transient error");return}Q(...X)},process.on("unhandledRejection",Z),()=>{process.removeListener("unhandledRejection",Z),console.error=Q}}var BZ;var u1=x(()=>{A7();s0();BZ={PreProd:m2.NetworkId.PreProd,Preview:m2.NetworkId.Preview,Undeployed:m2.NetworkId.Undeployed}});import{existsSync as g1,mkdirSync as HZ,writeFileSync as LZ,readFileSync as FZ,unlinkSync as m1,readdirSync as d2,renameSync as PZ}from"node:fs";import{join as m0,dirname as OZ}from"node:path";import{homedir as v7}from"node:os";import{randomBytes as IZ}from"node:crypto";function l2($,Z,Q){let X=Q??m0(v7(),J0,j2),z=$.slice(0,20);return m0(X,Z,`${z}.json`)}function g0($,Z,Q){let X=l2($,Z,Q);if(!g1(X))return null;try{let z=FZ(X,"utf-8"),Y=JSON.parse(z);if(Y.version!==V2)return null;if(Y.network!==Z)return null;if(Y.address!==$)return null;if(!Y.wallets||typeof Y.wallets.shielded!=="string"||typeof Y.wallets.unshielded!=="string"||typeof Y.wallets.dust!=="string")return null;return Y.wallets}catch{return null}}async function E0($,Z,Q,X){let[z,Y,J]=await Promise.all([Q.shielded.serializeState(),Q.unshielded.serializeState(),Q.dust.serializeState()]),G={version:V2,network:Z,address:$,timestamp:new Date().toISOString(),wallets:{shielded:z,unshielded:Y,dust:J}},q=l2($,Z,X),K=OZ(q);if(!g1(K))HZ(K,{recursive:!0,mode:P0});let U=q+`.tmp.${IZ(4).toString("hex")}`;try{LZ(U,JSON.stringify(G),{mode:C0}),PZ(U,q)}catch(W){try{m1(U)}catch{}throw W}}function c1($,Z,Q){let X=Q??m0(v7(),J0,j2);if($&&Z){let z=l2($,Z,Q);try{m1(z)}catch{}return}if(Z){let z=m0(X,Z);if(!g1(z))return;try{for(let Y of d2(z))if(Y.endsWith(".json"))m1(m0(z,Y))}catch{}return}if(!g1(X))return;try{for(let z of d2(X)){let Y=m0(X,z);try{for(let J of d2(Y))if(J.endsWith(".json"))m1(m0(Y,J))}catch{}}}catch{}}var F1=()=>{};import*as n2 from"@midnight-ntwrk/ledger-v7";import{MidnightBech32m as _Z,UnshieldedAddress as TZ}from"@midnight-ntwrk/wallet-sdk-address-format";import{NetworkId as i2}from"@midnight-ntwrk/wallet-sdk-abstractions";function RZ($){if($<=0)throw new Error("Amount must be greater than 0");if(!Number.isFinite($))throw new Error("Amount must be a finite number");let Z=$.toFixed(6),[Q,X]=Z.split("."),z=Q+(X??"").padEnd(6,"0"),Y=BigInt(z);if(Y<=0n)throw new Error("Amount too small — minimum is 0.000001 NIGHT");return Y}function l1($){let Z=Number($);if(Number.isNaN(Z)||!Number.isFinite(Z))throw new Error(`Invalid amount: "${$}" — must be a positive number`);if(Z<=0)throw new Error(`Invalid amount: "${$}" — must be greater than 0`);return Z}function DZ($,Z){let Q=MZ[Z.networkId];if(Q===void 0)throw new Error(`Unknown networkId: ${Z.networkId}`);try{return _Z.parse($).decode(TZ,Q)}catch(X){throw new Error(`Invalid recipient address: ${X.message}
124
- Expected a bech32m address for network "${Z.networkId}"`)}}function AZ($){let Z=$;while(Z){let Q=String(Z?.message??"").toLowerCase();if(Q.includes("submission error"))return!0;if(Q.includes("transaction")&&Q.includes("invalid"))return!0;if(Q.includes("138"))return!0;let X=Z?._tag;if(X==="TransactionInvalidError"||X==="SubmissionError")return!0;Z=Z.cause}return!1}function k7($){let Z=$?.message?.toLowerCase()??"";return Z.includes("not enough dust")||Z.includes("dust generated")||Z.includes("insufficient funds")||Z.includes("no dust tokens")||AZ($)}function d1($){let Z=$<0n?-$:$,Q=Z/1000000000000000n,X=Z%1000000000000000n;return`${$<0n?"-":""}${Q}.${X.toString().padStart(15,"0").slice(0,6)}`}function o2($){let Z=Math.round($/1000);if(Z<60)return`${Z}s`;let Q=Math.floor(Z/60),X=Z%60;return`${Q}m ${X}s`}function P1(){let{warn:$,error:Z}=console,Q=(X)=>X.some((z)=>String(z).includes("RPC-CORE"));return console.warn=(...X)=>{if(!Q(X))$(...X)},console.error=(...X)=>{if(!Q(X))Z(...X)},()=>{console.warn=$,console.error=Z}}async function NZ($,Z,Q){let X=new Date(Date.now()+z1*60*1000);await Promise.race([$.facade.dust.waitForSyncedState(),new Promise((K,U)=>setTimeout(()=>U(new Error("Insufficient funds: dust wallet sync timed out")),D1))]);let z=await $.facade.dust.createDustGenerationTransaction(new Date,X,Z,$.keystore.getPublicKey(),Q),Y=z.intents?.get(1);if(!Y)throw new Error("Dust generation intent not found on transaction");let J=$.keystore.signData(Y.signatureData(1)),G=await $.facade.dust.addDustGenerationSignature(z,J),q=await $.facade.finalizeTransaction(G);return await $.facade.submitTransaction(q)}async function EZ($,Z,Q,X){let z=Date.now(),Y=z+h$,J,G=!1,q=setInterval(()=>{if(G&&X){let K=o2(Date.now()-z);X(`Waiting for dust generation capacity (${K} elapsed, ~5 min on fresh wallets)...`)}},1000);try{while(Date.now()<Y)try{return await NZ($,Z,Q)}catch(K){if(J=K,k7(K)&&Date.now()+U2<Y){G=!0;let U=o2(Date.now()-z);X?.(`Waiting for dust generation capacity (${U} elapsed, ~5 min on fresh wallets)...`),await new Promise((W)=>setTimeout(W,U2));continue}throw K}throw J??new Error("Dust registration timed out")}finally{clearInterval(q)}}async function i1($,Z,Q){let X=Q??await $.facade.waitForSyncedState();if(X.dust.availableCoins.length>0||X.dust.balance(new Date)>0n)return Z?.("Dust available"),{alreadyAvailable:!0};let z=X.unshielded.availableCoins.filter((G)=>G.meta?.registeredForDustGeneration!==!0),Y;if(z.length>0){Z?.(`Registering ${z.length} UTXO(s) for dust generation...`);let G=z.map((q)=>({...q.utxo,ctime:new Date(q.meta.ctime)}));Y=await EZ($,G,X.dust.address,Z)}else Z?.("UTXOs already registered, waiting for dust generation...");Z?.("Waiting for dust tokens...");let J=Date.now();while(Date.now()-J<K2){try{if((await Promise.race([$.facade.waitForSyncedState(),new Promise((q,K)=>setTimeout(()=>K(new Error("Poll sync timed out")),D1))])).dust.balance(new Date)>0n)return Z?.("Dust available"),{alreadyAvailable:!1,txHash:Y}}catch{}await new Promise((G)=>setTimeout(G,5000))}throw new Error("Timed out waiting for dust tokens. Try running: midnight dust register")}async function CZ($,Z,Q,X,z,Y){let J=Date.now(),G=J+K2,q,K=0;while(!0)try{if(q)await c2($,"lite");let U=new Date(Date.now()+z1*60*1000);v("transfer","Building transfer transaction...");let W=await $.facade.transferTransaction([{type:"unshielded",outputs:[{amount:Q,receiverAddress:Z,type:n2.unshieldedToken().raw}]}],{shieldedSecretKeys:$.zswapSecretKeys,dustSecretKey:$.dustSecretKey},{ttl:U,payFees:!0});v("transfer","Signing recipe...");let j=await $.facade.signRecipe(W,(F)=>$.keystore.signData(F));v("transfer","Generating ZK proof..."),X?.();let V=await Promise.race([$.facade.finalizeRecipe(j),new Promise((F,D)=>{setTimeout(()=>D(new Error("ZK proof generation timed out")),A1)})]);v("transfer","Submitting transaction to node..."),z?.();let H=await $.facade.submitTransaction(V);return v("transfer",`Transaction submitted: ${H}`),H}catch(U){if(q=U,(U?.code===p$||U?.message?.includes("115")||U?.message?.toLowerCase().includes("stale"))&&++K<f$)continue;if(k7(U)&&Date.now()<G){let j=o2(Date.now()-J);Y?.(`Dust insufficient, re-ensuring (${j} elapsed)...`);try{let V=await c2($,"lite"),H=V.dust.balance(new Date);if(H>0n&&H<X1)throw new Error(`Insufficient dust for transaction fees.
125
- Available: ${d1(H)} DUST, need ≥${d1(X1)} DUST.
121
+ `)}var KZ;var h1=x(()=>{s();KZ={readTime:"picoseconds",computeTime:"picoseconds",blockUsage:"bytes",bytesWritten:"bytes",bytesChurned:"bytes"}});import{HDWallet as qZ,Roles as p1}from"@midnight-ntwrk/wallet-sdk-hd";function u1($,Z){let Q=qZ.fromSeed($);if(Q.type!=="seedOk")throw new Error("Invalid seed for HD wallet");let X=Q.hdWallet.selectAccount(0).selectRole(Z).deriveKeyAt(0);if(X.type==="keyOutOfBounds")throw new Error("Key derivation out of bounds");return X.key}function M7($){return u1($,p1.Zswap)}function R7($){return u1($,p1.NightExternal)}function D7($){return u1($,p1.Dust)}var A7=()=>{};function t0(){N7=!0}function v($,Z){if(!N7)return;let Q=new Date().toISOString().slice(11,23);process.stderr.write(B(` [${Q}] ${$}: ${Z}`)+`
122
+ `)}var N7=!1;var s0=()=>{};import{ShieldedWallet as E7}from"@midnight-ntwrk/wallet-sdk-shielded";import{UnshieldedWallet as C7,createKeystore as UZ,PublicKey as VZ,InMemoryTransactionHistoryStorage as jZ}from"@midnight-ntwrk/wallet-sdk-unshielded-wallet";import{DustWallet as x7}from"@midnight-ntwrk/wallet-sdk-dust-wallet";import{WalletFacade as y7}from"@midnight-ntwrk/wallet-sdk-facade";import*as r0 from"@midnight-ntwrk/ledger-v7";import{NetworkId as m1}from"@midnight-ntwrk/wallet-sdk-abstractions";import*as Y0 from"rxjs";async function h0($,Z,Q){let X=BZ[Z.networkId];if(X===void 0)throw new Error(`Unknown networkId: ${Z.networkId}`);v("facade",`Building facade for network ${Z.networkId}`),v("facade",`Node: ${Z.node}`),v("facade",`Indexer: ${Z.indexerWS}`),v("facade",`Proof server: ${Z.proofServer}`);let z=M7($),Y=R7($),J=D7($),G=r0.ZswapSecretKeys.fromSeed(z),q=r0.DustSecretKey.fromSeed(J),K=UZ(Y,X),U={networkId:X,indexerClientConnection:{indexerHttpUrl:Z.indexer,indexerWsUrl:Z.indexerWS},costParameters:{additionalFeeOverhead:b$,feeBlocksMargin:S$},txHistoryStorage:new jZ,provingServerUrl:new URL(Z.proofServer),relayURL:new URL(Z.node)},W=()=>y7.init({configuration:U,shielded:(H)=>E7(H).startWithSecretKeys(G),unshielded:(H)=>C7(H).startWithPublicKey(VZ.fromKeyStore(K)),dust:(H)=>x7(H).startWithSecretKey(q,r0.LedgerParameters.initialParameters().dust)}),j=!1,V;if(Q){v("facade","Restoring from cache...");try{V=await y7.init({configuration:U,shielded:(H)=>E7(H).restore(Q.shielded),unshielded:(H)=>C7(H).restore(Q.unshielded),dust:(H)=>x7(H).restore(Q.dust)}),j=!0,v("facade","Cache restore successful")}catch(H){v("facade",`Cache restore failed: ${H.message}`),process.stderr.write(` Cache restore failed, building from scratch: ${H.message}
123
+ `),V=await W()}}else v("facade","No cache, building fresh"),V=await W();return{facade:V,keystore:K,zswapSecretKeys:G,dustSecretKey:q,restoredFromCache:j}}function b7($,Z="full"){let Q=$.unshielded?.progress?.isStrictlyComplete()??!1,X=$.dust?.state?.progress?.isStrictlyComplete()??!1;if(!X)try{let Y=$.dust?.state?.progress;if(Y&&Y.highestRelevantWalletIndex>0&&Y.appliedIndex>=Y.highestRelevantWalletIndex)X=!0}catch{}if(Z==="lite")return Q&&X;return($.shielded?.state?.progress?.isStrictlyComplete()??!1)&&Q&&X}function WZ($){if($.dust?.state?.progress?.isStrictlyComplete())return!1;try{let Z=$.dust?.state?.progress;if(Z&&Z.highestRelevantWalletIndex>0&&Z.appliedIndex>=Z.highestRelevantWalletIndex)return!1}catch{}return!0}async function p0($,Z={}){let{onProgress:Q,onSyncDetail:X,timeoutMs:z,syncMode:Y="full"}=Z,{facade:J,zswapSecretKeys:G,dustSecretKey:q}=$;v("sync","Starting facade (connecting to node and indexer)..."),await J.start(G,q),v("sync","Facade started, subscribing to state...");let K=z??v$;return v("sync",`Sync timeout: ${K/1000}s, mode: ${Y}`),new Promise((U,W)=>{let j=!1,V=0,H="",F=null,D=setTimeout(()=>{if(!j){if(v("sync",`Sync timed out after ${K/1000}s (${V} emissions)`),F)try{let P=F.unshielded?.progress;v("sync",` unshielded: applied=${P?.appliedId} highest=${P?.highestTransactionId} complete=${P?.isStrictlyComplete()}`);let M=F.dust?.state?.progress;if(v("sync",` dust: applied=${M?.appliedIndex} highest=${M?.highestRelevantWalletIndex} complete=${M?.isStrictlyComplete?.()} connected=${M?.isConnected}`),Y==="full"){let C=F.shielded?.state?.progress;v("sync",` shielded: complete=${C?.isStrictlyComplete()}`)}}catch{}W(new Error("Wallet sync timed out"))}},K);$.keepAlive=J.state().subscribe({next:(P)=>{if(j)return;if(V++,F=P,Q){let C=P.unshielded.progress;if(C){let A=Number(C.appliedId),k=Number(C.highestTransactionId);Q(Math.min(A,k),k)}}let M=[];try{if(Y==="full"&&!P.shielded?.state?.progress?.isStrictlyComplete())M.push("shielded");if(WZ(P))M.push("dust");if(!P.unshielded?.progress?.isStrictlyComplete())M.push("unshielded")}catch{}if(M.length>0){X?.(M.join(", "));let C=M.join(",");if(V===1||C!==H||V%100===0)v("sync",`Waiting on: ${M.join(", ")} (emission #${V})`),H=C}if(b7(P,Y))j=!0,clearTimeout(D),v("sync",`Sync complete after ${V} emissions`),U(P)},error:(P)=>{if(!j)v("sync",`Sync error: ${P.message}`),clearTimeout(D),W(P)}})})}async function g1($){let Z=(Q)=>{let X=Q.unshielded?.progress?.isStrictlyComplete()??!1,z=Q.dust?.state?.progress?.isStrictlyComplete()??!1;return X&&z};try{return await Y0.firstValueFrom($.facade.state().pipe(Y0.filter(Z),Y0.timeout(15000)))}catch{return await Y0.firstValueFrom($.facade.state())}}async function S7($,Z=60000){let Q=(X)=>{try{let z=X.dust;return z?.availableCoins?.length>0||z?.balance(new Date)>0n}catch{return!1}};try{return await Y0.firstValueFrom($.facade.state().pipe(Y0.filter(Q),Y0.timeout(Z)))}catch{return await Y0.firstValueFrom($.facade.state())}}async function c1($,Z="full"){return Y0.firstValueFrom($.facade.state().pipe(Y0.filter((Q)=>b7(Q,Z)),Y0.timeout(w$)))}async function u0($){$.keepAlive?.unsubscribe(),await Promise.race([$.facade.stop(),new Promise((Z)=>setTimeout(Z,5000))])}function e0($){let Z=(X)=>{let z=X?._tag;if(typeof z==="string"&&z.startsWith("Wallet.")){let Y=X?.message??"transient error";$?.(z,Y);return}Q("Unhandled rejection:",X),process.exit(1)},Q=console.error;return console.error=(...X)=>{let z=X[0];if(typeof z==="object"&&z?._tag?.startsWith("Wallet.")){$?.(z._tag,z?.message??"transient error");return}if(typeof z==="string"&&z.startsWith("Wallet.")){$?.("Wallet.Sync","transient error");return}Q(...X)},process.on("unhandledRejection",Z),()=>{process.removeListener("unhandledRejection",Z),console.error=Q}}var BZ;var u2=x(()=>{A7();s0();BZ={PreProd:m1.NetworkId.PreProd,Preview:m1.NetworkId.Preview,Undeployed:m1.NetworkId.Undeployed}});import{existsSync as g2,mkdirSync as HZ,writeFileSync as LZ,readFileSync as FZ,unlinkSync as m2,readdirSync as d1,renameSync as PZ}from"node:fs";import{join as m0,dirname as OZ}from"node:path";import{homedir as v7}from"node:os";import{randomBytes as IZ}from"node:crypto";function l1($,Z,Q){let X=Q??m0(v7(),J0,j1),z=$.slice(0,20);return m0(X,Z,`${z}.json`)}function g0($,Z,Q){let X=l1($,Z,Q);if(!g2(X))return null;try{let z=FZ(X,"utf-8"),Y=JSON.parse(z);if(Y.version!==V1)return null;if(Y.network!==Z)return null;if(Y.address!==$)return null;if(!Y.wallets||typeof Y.wallets.shielded!=="string"||typeof Y.wallets.unshielded!=="string"||typeof Y.wallets.dust!=="string")return null;return Y.wallets}catch{return null}}async function E0($,Z,Q,X){let[z,Y,J]=await Promise.all([Q.shielded.serializeState(),Q.unshielded.serializeState(),Q.dust.serializeState()]),G={version:V1,network:Z,address:$,timestamp:new Date().toISOString(),wallets:{shielded:z,unshielded:Y,dust:J}},q=l1($,Z,X),K=OZ(q);if(!g2(K))HZ(K,{recursive:!0,mode:P0});let U=q+`.tmp.${IZ(4).toString("hex")}`;try{LZ(U,JSON.stringify(G),{mode:C0}),PZ(U,q)}catch(W){try{m2(U)}catch{}throw W}}function c2($,Z,Q){let X=Q??m0(v7(),J0,j1);if($&&Z){let z=l1($,Z,Q);try{m2(z)}catch{}return}if(Z){let z=m0(X,Z);if(!g2(z))return;try{for(let Y of d1(z))if(Y.endsWith(".json"))m2(m0(z,Y))}catch{}return}if(!g2(X))return;try{for(let z of d1(X)){let Y=m0(X,z);try{for(let J of d1(Y))if(J.endsWith(".json"))m2(m0(Y,J))}catch{}}}catch{}}var F2=()=>{};import*as n1 from"@midnight-ntwrk/ledger-v7";import{MidnightBech32m as _Z,UnshieldedAddress as TZ}from"@midnight-ntwrk/wallet-sdk-address-format";import{NetworkId as i1}from"@midnight-ntwrk/wallet-sdk-abstractions";function RZ($){if($<=0)throw new Error("Amount must be greater than 0");if(!Number.isFinite($))throw new Error("Amount must be a finite number");let Z=$.toFixed(6),[Q,X]=Z.split("."),z=Q+(X??"").padEnd(6,"0"),Y=BigInt(z);if(Y<=0n)throw new Error("Amount too small — minimum is 0.000001 NIGHT");return Y}function l2($){let Z=Number($);if(Number.isNaN(Z)||!Number.isFinite(Z))throw new Error(`Invalid amount: "${$}" — must be a positive number`);if(Z<=0)throw new Error(`Invalid amount: "${$}" — must be greater than 0`);return Z}function DZ($,Z){let Q=MZ[Z.networkId];if(Q===void 0)throw new Error(`Unknown networkId: ${Z.networkId}`);try{return _Z.parse($).decode(TZ,Q)}catch(X){throw new Error(`Invalid recipient address: ${X.message}
124
+ Expected a bech32m address for network "${Z.networkId}"`)}}function AZ($){let Z=$;while(Z){let Q=String(Z?.message??"").toLowerCase();if(Q.includes("submission error"))return!0;if(Q.includes("transaction")&&Q.includes("invalid"))return!0;if(Q.includes("138"))return!0;let X=Z?._tag;if(X==="TransactionInvalidError"||X==="SubmissionError")return!0;Z=Z.cause}return!1}function k7($){let Z=$?.message?.toLowerCase()??"";return Z.includes("not enough dust")||Z.includes("dust generated")||Z.includes("insufficient funds")||Z.includes("no dust tokens")||AZ($)}function d2($){let Z=$<0n?-$:$,Q=Z/1000000000000000n,X=Z%1000000000000000n;return`${$<0n?"-":""}${Q}.${X.toString().padStart(15,"0").slice(0,6)}`}function o1($){let Z=Math.round($/1000);if(Z<60)return`${Z}s`;let Q=Math.floor(Z/60),X=Z%60;return`${Q}m ${X}s`}function P2(){let{warn:$,error:Z}=console,Q=(X)=>X.some((z)=>String(z).includes("RPC-CORE"));return console.warn=(...X)=>{if(!Q(X))$(...X)},console.error=(...X)=>{if(!Q(X))Z(...X)},()=>{console.warn=$,console.error=Z}}async function NZ($,Z,Q){let X=new Date(Date.now()+z2*60*1000);await Promise.race([$.facade.dust.waitForSyncedState(),new Promise((K,U)=>setTimeout(()=>U(new Error("Insufficient funds: dust wallet sync timed out")),D2))]);let z=await $.facade.dust.createDustGenerationTransaction(new Date,X,Z,$.keystore.getPublicKey(),Q),Y=z.intents?.get(1);if(!Y)throw new Error("Dust generation intent not found on transaction");let J=$.keystore.signData(Y.signatureData(1)),G=await $.facade.dust.addDustGenerationSignature(z,J),q=await $.facade.finalizeTransaction(G);return await $.facade.submitTransaction(q)}async function EZ($,Z,Q,X){let z=Date.now(),Y=z+h$,J,G=!1,q=setInterval(()=>{if(G&&X){let K=o1(Date.now()-z);X(`Waiting for dust generation capacity (${K} elapsed, ~5 min on fresh wallets)...`)}},1000);try{while(Date.now()<Y)try{return await NZ($,Z,Q)}catch(K){if(J=K,k7(K)&&Date.now()+U1<Y){G=!0;let U=o1(Date.now()-z);X?.(`Waiting for dust generation capacity (${U} elapsed, ~5 min on fresh wallets)...`),await new Promise((W)=>setTimeout(W,U1));continue}throw K}throw J??new Error("Dust registration timed out")}finally{clearInterval(q)}}async function i2($,Z,Q){let X=Q??await $.facade.waitForSyncedState();if(X.dust.availableCoins.length>0||X.dust.balance(new Date)>0n)return Z?.("Dust available"),{alreadyAvailable:!0};let z=X.unshielded.availableCoins.filter((G)=>G.meta?.registeredForDustGeneration!==!0),Y;if(z.length>0){Z?.(`Registering ${z.length} UTXO(s) for dust generation...`);let G=z.map((q)=>({...q.utxo,ctime:new Date(q.meta.ctime)}));Y=await EZ($,G,X.dust.address,Z)}else Z?.("UTXOs already registered, waiting for dust generation...");Z?.("Waiting for dust tokens...");let J=Date.now();while(Date.now()-J<K1){try{if((await Promise.race([$.facade.waitForSyncedState(),new Promise((q,K)=>setTimeout(()=>K(new Error("Poll sync timed out")),D2))])).dust.balance(new Date)>0n)return Z?.("Dust available"),{alreadyAvailable:!1,txHash:Y}}catch{}await new Promise((G)=>setTimeout(G,5000))}throw new Error("Timed out waiting for dust tokens. Try running: midnight dust register")}async function CZ($,Z,Q,X,z,Y){let J=Date.now(),G=J+K1,q,K=0;while(!0)try{if(q)await c1($,"lite");let U=new Date(Date.now()+z2*60*1000);v("transfer","Building transfer transaction...");let W=await $.facade.transferTransaction([{type:"unshielded",outputs:[{amount:Q,receiverAddress:Z,type:n1.unshieldedToken().raw}]}],{shieldedSecretKeys:$.zswapSecretKeys,dustSecretKey:$.dustSecretKey},{ttl:U,payFees:!0});v("transfer","Signing recipe...");let j=await $.facade.signRecipe(W,(F)=>$.keystore.signData(F));v("transfer","Generating ZK proof..."),X?.();let V=await Promise.race([$.facade.finalizeRecipe(j),new Promise((F,D)=>{setTimeout(()=>D(new Error("ZK proof generation timed out")),A2)})]);v("transfer","Submitting transaction to node..."),z?.();let H=await $.facade.submitTransaction(V);return v("transfer",`Transaction submitted: ${H}`),H}catch(U){if(q=U,(U?.code===p$||U?.message?.includes("115")||U?.message?.toLowerCase().includes("stale"))&&++K<f$)continue;if(k7(U)&&Date.now()<G){let j=o1(Date.now()-J);Y?.(`Dust insufficient, re-ensuring (${j} elapsed)...`);try{let V=await c1($,"lite"),H=V.dust.balance(new Date);if(H>0n&&H<X2)throw new Error(`Insufficient dust for transaction fees.
125
+ Available: ${d2(H)} DUST, need ≥${d2(X2)} DUST.
126
126
  Dust regenerates over time from registered NIGHT UTXOs.
127
- Check status: midnight dust status`);await i1($,Y,V)}catch(V){if(String(V?.message).startsWith("Insufficient dust"))throw V;await new Promise((H)=>setTimeout(H,5000))}continue}throw U}}async function o1($){let{seedBuffer:Z,networkConfig:Q,recipientAddress:X,amountNight:z,signal:Y,onSync:J,onSyncDetail:G,onDust:q,onProving:K,onSubmitting:U,onSyncWarning:W,noCache:j,walletAddress:V,networkName:H}=$,F=RZ(z),D=DZ(X,Q),P=e0(W),M=P1(),C=!j&&V&&H,A=C?g0(V,H):null;v("transfer","Building facade...");let k=await h0(Z,Q,A),$0=!1,n=async()=>{if(!$0){$0=!0;try{await u0(k)}catch{}}},B0=()=>{n()};Y?.addEventListener("abort",B0,{once:!0});try{let z0=Q.networkId!=="Undeployed",L0=z0?k$:D1,d=3,r;v("transfer",`Sync timeout: ${L0/1000}s (${z0?"remote":"local"} network)`);for(let O=1;O<=3;O++)try{r=await p0(k,{onProgress:J,onSyncDetail:G,timeoutMs:L0,syncMode:"lite"});break}catch(_){if(Y?.aborted)throw new Error("Operation cancelled");if(O<3&&String(_?.message).includes("timed out")){if(C)try{v("transfer","Saving partial sync progress to cache..."),await E0(V,H,k.facade)}catch{}q?.(`Sync timed out, retrying (attempt ${O+1}/3)...`),await u0(k).catch(()=>{});let b=C?g0(V,H):null;k=await h0(Z,Q,b);continue}throw _}if(Y?.aborted)throw new Error("Operation cancelled");v("transfer","Sync complete, checking balance...");let o=r.unshielded.balances[n2.unshieldedToken().raw]??0n;if(v("transfer",`Balance: ${Number(o)/G2} NIGHT`),o<F){let O=Number(o)/G2;throw new Error(`Insufficient balance: ${O.toFixed(6)} NIGHT available, ${z} NIGHT requested`)}if(Y?.aborted)throw new Error("Operation cancelled");v("transfer","Ensuring dust availability..."),await i1(k,q,r),v("transfer","Dust available");let I=r.dust.balance(new Date);if(I>0n&&I<X1)throw new Error(`Insufficient dust for transaction fees.
128
- Available: ${d1(I)} DUST, need ≥${d1(X1)} DUST.
127
+ Check status: midnight dust status`);await i2($,Y,V)}catch(V){if(String(V?.message).startsWith("Insufficient dust"))throw V;await new Promise((H)=>setTimeout(H,5000))}continue}throw U}}async function o2($){let{seedBuffer:Z,networkConfig:Q,recipientAddress:X,amountNight:z,signal:Y,onSync:J,onSyncDetail:G,onDust:q,onProving:K,onSubmitting:U,onSyncWarning:W,noCache:j,walletAddress:V,networkName:H}=$,F=RZ(z),D=DZ(X,Q),P=e0(W),M=P2(),C=!j&&V&&H,A=C?g0(V,H):null;v("transfer","Building facade...");let k=await h0(Z,Q,A),$0=!1,n=async()=>{if(!$0){$0=!0;try{await u0(k)}catch{}}},B0=()=>{n()};Y?.addEventListener("abort",B0,{once:!0});try{let z0=Q.networkId!=="Undeployed",L0=z0?k$:D2,d=3,r;v("transfer",`Sync timeout: ${L0/1000}s (${z0?"remote":"local"} network)`);for(let O=1;O<=3;O++)try{r=await p0(k,{onProgress:J,onSyncDetail:G,timeoutMs:L0,syncMode:"lite"});break}catch(_){if(Y?.aborted)throw new Error("Operation cancelled");if(O<3&&String(_?.message).includes("timed out")){if(C)try{v("transfer","Saving partial sync progress to cache..."),await E0(V,H,k.facade)}catch{}q?.(`Sync timed out, retrying (attempt ${O+1}/3)...`),await u0(k).catch(()=>{});let b=C?g0(V,H):null;k=await h0(Z,Q,b);continue}throw _}if(Y?.aborted)throw new Error("Operation cancelled");v("transfer","Sync complete, checking balance...");let o=r.unshielded.balances[n1.unshieldedToken().raw]??0n;if(v("transfer",`Balance: ${Number(o)/G1} NIGHT`),o<F){let O=Number(o)/G1;throw new Error(`Insufficient balance: ${O.toFixed(6)} NIGHT available, ${z} NIGHT requested`)}if(Y?.aborted)throw new Error("Operation cancelled");v("transfer","Ensuring dust availability..."),await i2(k,q,r),v("transfer","Dust available");let I=r.dust.balance(new Date);if(I>0n&&I<X2)throw new Error(`Insufficient dust for transaction fees.
128
+ Available: ${d2(I)} DUST, need ≥${d2(X2)} DUST.
129
129
  Dust regenerates over time from registered NIGHT UTXOs.
130
- Check status: midnight dust status`);if(Y?.aborted)throw new Error("Operation cancelled");v("transfer","Building and submitting transaction...");let L=await CZ(k,D,F,K,U,q);if(C)try{await E0(V,H,k.facade)}catch{}return{txHash:L,amountMicroNight:F}}finally{Y?.removeEventListener("abort",B0),M(),P(),await n()}}var MZ;var O1=x(()=>{u1();F1();s0();MZ={PreProd:i2.NetworkId.PreProd,Preview:i2.NetworkId.Preview,Undeployed:i2.NetworkId.Undeployed}});var a2={};e(a2,{default:()=>w7});async function w7($,Z){let Q=$.subcommand;if(!Q)throw new Error(`Missing amount.
130
+ Check status: midnight dust status`);if(Y?.aborted)throw new Error("Operation cancelled");v("transfer","Building and submitting transaction...");let L=await CZ(k,D,F,K,U,q);if(C)try{await E0(V,H,k.facade)}catch{}return{txHash:L,amountMicroNight:F}}finally{Y?.removeEventListener("abort",B0),M(),P(),await n()}}var MZ;var O2=x(()=>{u2();F2();s0();MZ={PreProd:i1.NetworkId.PreProd,Preview:i1.NetworkId.Preview,Undeployed:i1.NetworkId.Undeployed}});var a1={};e(a1,{default:()=>w7});async function w7($,Z){let Q=$.subcommand;if(!Q)throw new Error(`Missing amount.
131
131
  Usage: midnight airdrop <amount>
132
- Example: midnight airdrop 1000`);let X=l1(Q),z=X0(Q0(N($,"wallet"))),{name:Y,config:J}=U0({args:$});if(_0(J,{proofServer:N($,"proof-server"),node:N($,"node"),indexerWS:N($,"indexer-ws")}),Y!=="undeployed")throw new Error(`Airdrop is only available on the "undeployed" network (local devnet).
132
+ Example: midnight airdrop 1000`);let X=l2(Q),z=X0(Q0(N($,"wallet"))),{name:Y,config:J}=U0({args:$});if(_0(J,{proofServer:N($,"proof-server"),node:N($,"node"),indexerWS:N($,"indexer-ws")}),Y!=="undeployed")throw new Error(`Airdrop is only available on the "undeployed" network (local devnet).
133
133
  Current network: "${Y}"
134
- On preprod/preview, use a faucet or transfer from another wallet.`);let G=R($,"no-cache"),q=z.addresses[Y],K=Buffer.from(R1,"hex"),U=v0(K,Y);process.stderr.write(`
134
+ On preprod/preview, use a faucet or transfer from another wallet.`);let G=R($,"no-cache"),q=z.addresses[Y],K=Buffer.from(R2,"hex"),U=v0(K,Y);process.stderr.write(`
135
135
  `+f("Airdrop")+`
136
136
 
137
137
  `),process.stderr.write(T("Network",Y)+`
@@ -139,7 +139,7 @@ On preprod/preview, use a faucet or transfer from another wallet.`);let G=R($,"n
139
139
  `),process.stderr.write(T("To",l(q,!0))+`
140
140
  `),process.stderr.write(T("Amount",y(X+" NIGHT"))+`
141
141
  `),process.stderr.write(`
142
- `);let W=i("Starting genesis wallet...");try{let j=await o1({seedBuffer:K,networkConfig:J,recipientAddress:q,amountNight:X,signal:Z,noCache:G,walletAddress:U,networkName:Y,onSync(V,H){if(H>0){let F=Math.round(V/H*100);W.update(`Syncing genesis wallet... ${F}%`)}},onDust(V){W.update(`Dust: ${V}`)},onProving(){W.update("Generating ZK proof (this may take a few minutes)...")},onSubmitting(){W.update("Submitting transaction...")},onSyncWarning(V,H){W.update(`Syncing genesis wallet... (${H}, retrying)`)}});if(W.stop("Transaction submitted"),R($,"json")){E({txHash:j.txHash,amount:X,recipient:q,network:Y});return}process.stdout.write(j.txHash+`
142
+ `);let W=i("Starting genesis wallet...");try{let j=await o2({seedBuffer:K,networkConfig:J,recipientAddress:q,amountNight:X,signal:Z,noCache:G,walletAddress:U,networkName:Y,onSync(V,H){if(H>0){let F=Math.round(V/H*100);W.update(`Syncing genesis wallet... ${F}%`)}},onDust(V){W.update(`Dust: ${V}`)},onProving(){W.update("Generating ZK proof (this may take a few minutes)...")},onSubmitting(){W.update("Submitting transaction...")},onSyncWarning(V,H){W.update(`Syncing genesis wallet... (${H}, retrying)`)}});if(W.stop("Transaction submitted"),R($,"json")){E({txHash:j.txHash,amount:X,recipient:q,network:Y});return}process.stdout.write(j.txHash+`
143
143
  `),process.stderr.write(`
144
144
  `+b0(`Airdropped ${X} NIGHT to your wallet`,j.txHash)+`
145
145
  `),process.stderr.write(`
@@ -152,11 +152,11 @@ On preprod/preview, use a faucet or transfer from another wallet.`);let G=R($,"n
152
152
  `)}catch(j){if(W.stop("Failed"),j instanceof Error&&j.message.toLowerCase().includes("dust"))throw new Error(`${j.message}
153
153
 
154
154
  On a fresh localnet, the minimum airdrop is ~1 NIGHT.
155
- Try: midnight airdrop 1`);throw j}}var t2=x(()=>{W0();V0();T0();w0();O1();s();x0()});var s2={};e(s2,{default:()=>f7});async function f7($,Z){let Q=$.subcommand,X=$.positionals[0];if(!Q)throw new Error(`Missing recipient address.
155
+ Try: midnight airdrop 1`);throw j}}var t1=x(()=>{W0();V0();T0();w0();O2();s();x0()});var s1={};e(s1,{default:()=>f7});async function f7($,Z){let Q=$.subcommand,X=$.positionals[0];if(!Q)throw new Error(`Missing recipient address.
156
156
  Usage: midnight transfer <to> <amount>
157
157
  Example: midnight transfer mn_addr_undeployed1... 100`);if(!X)throw new Error(`Missing amount.
158
158
  Usage: midnight transfer <to> <amount>
159
- Example: midnight transfer mn_addr_undeployed1... 100`);let z=l1(X),Y=Q0(N($,"wallet")),J=X0(Y),G=Buffer.from(J.seed,"hex"),{name:q,config:K}=U0({args:$}),U=J.addresses[q];_0(K,{proofServer:N($,"proof-server"),node:N($,"node"),indexerWS:N($,"indexer-ws")}),process.stderr.write(`
159
+ Example: midnight transfer mn_addr_undeployed1... 100`);let z=l2(X),Y=Q0(N($,"wallet")),J=X0(Y),G=Buffer.from(J.seed,"hex"),{name:q,config:K}=U0({args:$}),U=J.addresses[q];_0(K,{proofServer:N($,"proof-server"),node:N($,"node"),indexerWS:N($,"indexer-ws")}),process.stderr.write(`
160
160
  `+f("Transfer")+`
161
161
 
162
162
  `),process.stderr.write(T("Network",q)+`
@@ -164,57 +164,57 @@ Example: midnight transfer mn_addr_undeployed1... 100`);let z=l1(X),Y=Q0(N($,"wa
164
164
  `),process.stderr.write(T("To",l(Q,!0))+`
165
165
  `),process.stderr.write(T("Amount",y(z+" NIGHT"))+`
166
166
  `),process.stderr.write(`
167
- `);let W=R($,"no-cache");if(i0($))t0();let j=i("Starting wallet...");try{let V=await o1({seedBuffer:G,networkConfig:K,recipientAddress:Q,amountNight:z,signal:Z,noCache:W,walletAddress:U,networkName:q,onSync(H,F){if(F>0){let D=Math.min(Math.round(H/F*100),100);j.update(D>=100?"Syncing wallet...":`Syncing wallet... ${D}%`)}},onSyncDetail(H){j.update(`Syncing wallet... (waiting on: ${H})`)},onDust(H){j.update(`Dust: ${H}`)},onProving(){j.update("Generating ZK proof (this may take a few minutes)...")},onSubmitting(){j.update("Submitting transaction...")},onSyncWarning(H,F){j.update(`Syncing wallet... (${F}, retrying)`)}});if(j.stop("Transaction submitted"),R($,"json")){E({txHash:V.txHash,amount:z,recipient:Q,network:q});return}process.stdout.write(V.txHash+`
167
+ `);let W=R($,"no-cache");if(i0($))t0();let j=i("Starting wallet...");try{let V=await o2({seedBuffer:G,networkConfig:K,recipientAddress:Q,amountNight:z,signal:Z,noCache:W,walletAddress:U,networkName:q,onSync(H,F){if(F>0){let D=Math.min(Math.round(H/F*100),100);j.update(D>=100?"Syncing wallet...":`Syncing wallet... ${D}%`)}},onSyncDetail(H){j.update(`Syncing wallet... (waiting on: ${H})`)},onDust(H){j.update(`Dust: ${H}`)},onProving(){j.update("Generating ZK proof (this may take a few minutes)...")},onSubmitting(){j.update("Submitting transaction...")},onSyncWarning(H,F){j.update(`Syncing wallet... (${F}, retrying)`)}});if(j.stop("Transaction submitted"),R($,"json")){E({txHash:V.txHash,amount:z,recipient:Q,network:q});return}process.stdout.write(V.txHash+`
168
168
  `),process.stderr.write(`
169
169
  `+b0(`Transferred ${z} NIGHT`,V.txHash)+`
170
170
  `),process.stderr.write(`
171
171
  `+h()+`
172
172
  `),process.stderr.write(B(" Verify: midnight balance")+`
173
173
 
174
- `)}catch(V){throw j.stop("Failed"),V}}var r2=x(()=>{s0();W0();V0();T0();O1();s();x0()});var e2={};e(e2,{default:()=>p7});import*as h7 from"@midnight-ntwrk/ledger-v7";async function p7($,Z){let Q=$.subcommand;if(!Q||Q!=="register"&&Q!=="status")throw new Error(`Missing or invalid subcommand.
174
+ `)}catch(V){throw j.stop("Failed"),V}}var r1=x(()=>{s0();W0();V0();T0();O2();s();x0()});var e1={};e(e1,{default:()=>p7});import*as h7 from"@midnight-ntwrk/ledger-v7";async function p7($,Z){let Q=$.subcommand;if(!Q||Q!=="register"&&Q!=="status")throw new Error(`Missing or invalid subcommand.
175
175
  Usage:
176
176
  midnight dust register Register NIGHT UTXOs for dust generation
177
- midnight dust status Check dust registration status`);let X=Q0(N($,"wallet")),z=X0(X),Y=Buffer.from(z.seed,"hex"),{name:J,config:G}=U0({args:$}),q=z.addresses[J];_0(G,{proofServer:N($,"proof-server"),node:N($,"node"),indexerWS:N($,"indexer-ws")});let K=R($,"no-cache");if(i0($))t0();let U=K?null:g0(q,J),W=await h0(Y,G,U),j=async()=>{try{await u0(W)}catch{}},V=()=>{j()};Z?.addEventListener("abort",V,{once:!0});let H={},F=e0((M,C)=>{H.current?.(M,C)}),D=P1(),P=R($,"json");try{if(Q==="register")await xZ(W,J,q,K,P,Z,H);else await yZ(W,J,q,K,P,Z,H)}finally{Z?.removeEventListener("abort",V),D(),F(),await j()}}async function xZ($,Z,Q,X,z,Y,J){process.stderr.write(`
177
+ midnight dust status Check dust registration status`);let X=Q0(N($,"wallet")),z=X0(X),Y=Buffer.from(z.seed,"hex"),{name:J,config:G}=U0({args:$}),q=z.addresses[J];_0(G,{proofServer:N($,"proof-server"),node:N($,"node"),indexerWS:N($,"indexer-ws")});let K=R($,"no-cache");if(i0($))t0();let U=K?null:g0(q,J),W=await h0(Y,G,U),j=async()=>{try{await u0(W)}catch{}},V=()=>{j()};Z?.addEventListener("abort",V,{once:!0});let H={},F=e0((M,C)=>{H.current?.(M,C)}),D=P2(),P=R($,"json");try{if(Q==="register")await xZ(W,J,q,K,P,Z,H);else await yZ(W,J,q,K,P,Z,H)}finally{Z?.removeEventListener("abort",V),D(),F(),await j()}}async function xZ($,Z,Q,X,z,Y,J){process.stderr.write(`
178
178
  `+f("Dust Register")+`
179
179
 
180
180
  `),process.stderr.write(T("Network",Z)+`
181
181
 
182
- `);let G=i($.restoredFromCache?"Restoring from cache...":"Syncing wallet...");if(J)J.current=(q,K)=>G.update(`Syncing wallet... (${K}, retrying)`);try{let q=await p0($,{syncMode:"lite",onProgress:(j,V)=>{if(V>0){let H=Math.min(Math.round(j/V*100),100);G.update(H>=100?"Syncing wallet...":`Syncing wallet... ${H}%`)}},onSyncDetail:(j)=>{G.update(`Syncing wallet... (waiting on: ${j})`)}});if(Y?.aborted)throw new Error("Operation cancelled");G.update("Checking dust status...");let K=await i1($,(j)=>{G.update(j)},q);if(Y?.aborted)throw new Error("Operation cancelled");let W=(await g2($)).dust.balance(new Date);if(!X)try{await E0(Q,Z,$.facade)}catch{}if(K.alreadyAvailable)G.stop("Dust already available");else G.stop("Dust registration complete");if(z){let j={subcommand:"register",dustBalance:y1(W)};if(K.txHash)j.txHash=K.txHash;E(j);return}if(process.stdout.write(W.toString()+`
182
+ `);let G=i($.restoredFromCache?"Restoring from cache...":"Syncing wallet...");if(J)J.current=(q,K)=>G.update(`Syncing wallet... (${K}, retrying)`);try{let q=await p0($,{syncMode:"lite",onProgress:(j,V)=>{if(V>0){let H=Math.min(Math.round(j/V*100),100);G.update(H>=100?"Syncing wallet...":`Syncing wallet... ${H}%`)}},onSyncDetail:(j)=>{G.update(`Syncing wallet... (waiting on: ${j})`)}});if(Y?.aborted)throw new Error("Operation cancelled");G.update("Checking dust status...");let K=await i2($,(j)=>{G.update(j)},q);if(Y?.aborted)throw new Error("Operation cancelled");let W=(await g1($)).dust.balance(new Date);if(!X)try{await E0(Q,Z,$.facade)}catch{}if(K.alreadyAvailable)G.stop("Dust already available");else G.stop("Dust registration complete");if(z){let j={subcommand:"register",dustBalance:y2(W)};if(K.txHash)j.txHash=K.txHash;E(j);return}if(process.stdout.write(W.toString()+`
183
183
  `),K.alreadyAvailable)process.stderr.write(`
184
- `+b0(`Dust tokens already available: ${b1(W)}`)+`
184
+ `+b0(`Dust tokens already available: ${b2(W)}`)+`
185
185
 
186
186
  `);else process.stderr.write(`
187
- `+b0(`Dust tokens available: ${b1(W)}`)+`
187
+ `+b0(`Dust tokens available: ${b2(W)}`)+`
188
188
 
189
189
  `)}catch(q){throw G.stop("Failed"),q}}async function yZ($,Z,Q,X,z,Y,J){process.stderr.write(`
190
190
  `+f("Dust Status")+`
191
191
 
192
192
  `),process.stderr.write(T("Network",Z)+`
193
193
 
194
- `);let G=i($.restoredFromCache?"Restoring from cache...":"Syncing wallet...");if(J)J.current=(q,K)=>G.update(`Syncing wallet... (${K}, retrying)`);try{if(await p0($,{syncMode:"lite",onProgress:(F,D)=>{if(D>0){let P=Math.min(Math.round(F/D*100),100);G.update(P>=100?"Syncing wallet...":`Syncing wallet... ${P}%`)}},onSyncDetail:(F)=>{G.update(`Syncing wallet... (waiting on: ${F})`)}}),Y?.aborted)throw new Error("Operation cancelled");G.update("Checking dust status...");let q=await g2($);if(!X)try{await E0(Q,Z,$.facade)}catch{}let K=q.dust.balance(new Date),U=q.dust.availableCoins.length>0,W=q.unshielded.availableCoins,j=W.filter((F)=>F.meta?.registeredForDustGeneration!==!0),V=W.length-j.length,H=q.unshielded.balances[h7.unshieldedToken().raw]??0n;if(G.stop("Done"),z){E({subcommand:"status",dustBalance:y1(K),registered:V,unregistered:j.length,nightBalance:q1(H),dustAvailable:U});return}process.stdout.write(`dust=${K}
194
+ `);let G=i($.restoredFromCache?"Restoring from cache...":"Syncing wallet...");if(J)J.current=(q,K)=>G.update(`Syncing wallet... (${K}, retrying)`);try{if(await p0($,{syncMode:"lite",onProgress:(F,D)=>{if(D>0){let P=Math.min(Math.round(F/D*100),100);G.update(P>=100?"Syncing wallet...":`Syncing wallet... ${P}%`)}},onSyncDetail:(F)=>{G.update(`Syncing wallet... (waiting on: ${F})`)}}),Y?.aborted)throw new Error("Operation cancelled");G.update("Checking dust status...");let q=await g1($);if(!X)try{await E0(Q,Z,$.facade)}catch{}let K=q.dust.balance(new Date),U=q.dust.availableCoins.length>0,W=q.unshielded.availableCoins,j=W.filter((F)=>F.meta?.registeredForDustGeneration!==!0),V=W.length-j.length,H=q.unshielded.balances[h7.unshieldedToken().raw]??0n;if(G.stop("Done"),z){E({subcommand:"status",dustBalance:y2(K),registered:V,unregistered:j.length,nightBalance:q2(H),dustAvailable:U});return}process.stdout.write(`dust=${K}
195
195
  `),process.stdout.write(`registered=${V}
196
196
  `),process.stdout.write(`unregistered=${j.length}
197
- `),process.stderr.write(T("NIGHT Balance",y(x1(H)))+`
198
- `),process.stderr.write(T("Dust Balance",y(b1(K)))+`
197
+ `),process.stderr.write(T("NIGHT Balance",y(x2(H)))+`
198
+ `),process.stderr.write(T("Dust Balance",y(b2(K)))+`
199
199
  `),process.stderr.write(T("Dust Available",U?"yes":"no")+`
200
200
  `),process.stderr.write(T("Registered",V.toString()+" UTXO(s)")+`
201
201
  `),process.stderr.write(T("Unregistered",j.length.toString()+" UTXO(s)")+`
202
202
  `),process.stderr.write(`
203
203
  `+h()+`
204
204
 
205
- `)}catch(q){throw G.stop("Failed"),q}}var $$=x(()=>{s0();W0();V0();T0();u1();F1();O1();s();x0()});var Z$={};e(Z$,{default:()=>u7});async function u7($){if($.subcommand!=="clear")throw new Error("Usage: midnight cache clear [--network <name>] [--wallet <name|file>]");let Q=N($,"wallet"),X=N($,"network"),z=R($,"json");if(Q){let Y=Q0(Q),J=X0(Y),{name:G}=U0({args:$}),q=J.addresses[G];if(c1(q,G),z){E({action:"clear",scope:"wallet",wallet:Q,network:G});return}process.stderr.write(u("✓")+` Cache cleared for wallet "${Q}" on ${G}
206
- `)}else if(X){if(c1(void 0,X),z){E({action:"clear",scope:"network",network:X});return}process.stderr.write(u("✓")+` Cache cleared for network "${X}"
207
- `)}else{if(c1(),z){E({action:"clear",scope:"all"});return}process.stderr.write(u("✓")+` Cache cleared
208
- `)}}var Q$=x(()=>{F1();W0();V0()});var X$={};e(X$,{default:()=>m7});async function m7($){let Z=$.subcommand;if(!Z||!["get","set","unset"].includes(Z))throw new Error(`Usage: midnight config <get|set|unset> <key> [value]
209
- Valid keys: ${f1().join(", ")}`);let Q=$.positionals[0];if(!Q)throw new Error(`Missing config key.
210
- Valid keys: ${f1().join(", ")}`);if(Z==="get"){let X=I2(Q);if(R($,"json")){E({action:"get",key:Q,value:X});return}process.stdout.write(X+`
211
- `)}else if(Z==="unset"){T2(Q);let X=Q==="network"?"(default)":"(removed)";if(R($,"json")){E({action:"unset",key:Q,value:X});return}process.stderr.write(u("✓")+` ${Q} ${X}
205
+ `)}catch(q){throw G.stop("Failed"),q}}var $$=x(()=>{s0();W0();V0();T0();u2();F2();O2();s();x0()});var Z$={};e(Z$,{default:()=>u7});async function u7($){if($.subcommand!=="clear")throw new Error("Usage: midnight cache clear [--network <name>] [--wallet <name|file>]");let Q=N($,"wallet"),X=N($,"network"),z=R($,"json");if(Q){let Y=Q0(Q),J=X0(Y),{name:G}=U0({args:$}),q=J.addresses[G];if(c2(q,G),z){E({action:"clear",scope:"wallet",wallet:Q,network:G});return}process.stderr.write(u("✓")+` Cache cleared for wallet "${Q}" on ${G}
206
+ `)}else if(X){if(c2(void 0,X),z){E({action:"clear",scope:"network",network:X});return}process.stderr.write(u("✓")+` Cache cleared for network "${X}"
207
+ `)}else{if(c2(),z){E({action:"clear",scope:"all"});return}process.stderr.write(u("✓")+` Cache cleared
208
+ `)}}var Q$=x(()=>{F2();W0();V0()});var X$={};e(X$,{default:()=>m7});async function m7($){let Z=$.subcommand;if(!Z||!["get","set","unset"].includes(Z))throw new Error(`Usage: midnight config <get|set|unset> <key> [value]
209
+ Valid keys: ${f2().join(", ")}`);let Q=$.positionals[0];if(!Q)throw new Error(`Missing config key.
210
+ Valid keys: ${f2().join(", ")}`);if(Z==="get"){let X=I1(Q);if(R($,"json")){E({action:"get",key:Q,value:X});return}process.stdout.write(X+`
211
+ `)}else if(Z==="unset"){T1(Q);let X=Q==="network"?"(default)":"(removed)";if(R($,"json")){E({action:"unset",key:Q,value:X});return}process.stderr.write(u("✓")+` ${Q} ${X}
212
212
  `)}else{let X=$.positionals[1];if(X===void 0)throw new Error(`Missing value for config set.
213
- Usage: midnight config set ${Q} <value>`);if(_2(Q,X),R($,"json")){E({action:"set",key:Q,value:X});return}process.stderr.write(u("✓")+` ${Q} = ${X}
214
- `)}}var z$=x(()=>{n0()});import{execSync as I1}from"child_process";import{existsSync as g7,mkdirSync as bZ,readFileSync as SZ,writeFileSync as c7}from"fs";import{homedir as vZ}from"os";import{join as J$}from"path";function l7(){try{return I1("docker compose version",{...a1,timeout:1e4}).trim()}catch{try{throw I1("docker --version",{...a1,timeout:5000}),new Error(`Docker Compose v2 is required.
213
+ Usage: midnight config set ${Q} <value>`);if(_1(Q,X),R($,"json")){E({action:"set",key:Q,value:X});return}process.stderr.write(u("✓")+` ${Q} = ${X}
214
+ `)}}var z$=x(()=>{n0()});import{execSync as I2}from"child_process";import{existsSync as g7,mkdirSync as bZ,readFileSync as SZ,writeFileSync as c7}from"fs";import{homedir as vZ}from"os";import{join as J$}from"path";function l7(){try{return I2("docker compose version",{...a2,timeout:1e4}).trim()}catch{try{throw I2("docker --version",{...a2,timeout:5000}),new Error(`Docker Compose v2 is required.
215
215
  Install it from https://docs.docker.com/compose/install/`)}catch($){if($ instanceof Error&&$.message.includes("Docker Compose v2"))throw $;throw new Error(`Docker is required but was not found.
216
- Install Docker from https://docs.docker.com/get-docker/`)}}}function i7(){if(g7(Y$)&&g7(n1)&&SZ(Y$,"utf-8").trim()===d7)return!1;return bZ(G$,{recursive:!0,mode:P0}),c7(n1,kZ,"utf-8"),c7(Y$,d7,"utf-8"),!0}function $1($){return I1(`docker compose -f "${n1}" ${$}`,a1)}function t1(){try{let $=$1("ps --format json");if(!$.trim())return[];let Z=$.trim().split(`
217
- `),Q=[];for(let X of Z){if(!X.trim())continue;try{let z=JSON.parse(X),Y=z.Service??"unknown";Q.push({name:Y,state:z.State??"unknown",health:z.Health??"",port:wZ[Y]??"",image:z.Image??""})}catch{}}return Q}catch{return[]}}function o7($=120000,Z=3000){let Q=Date.now()+$;while(Date.now()<Q){let X=t1();if(X.length===3&&X.every((Y)=>Y.state==="running")){if(X.every((J)=>J.health==="healthy"||J.health===""))return!0}I1(`sleep ${Z/1000}`,{timeout:Z+1000})}return!1}function K$(){return n1}function n7(){let $=[];for(let Z of fZ)try{I1(`docker rm -f "${Z}"`,{...a1,timeout:1e4}),$.push(Z)}catch{}return $}var d7="2.0.0",G$,n1,Y$,kZ=`services:
216
+ Install Docker from https://docs.docker.com/get-docker/`)}}}function i7(){if(g7(Y$)&&g7(n2)&&SZ(Y$,"utf-8").trim()===d7)return!1;return bZ(G$,{recursive:!0,mode:P0}),c7(n2,kZ,"utf-8"),c7(Y$,d7,"utf-8"),!0}function $2($){return I2(`docker compose -f "${n2}" ${$}`,a2)}function t2(){try{let $=$2("ps --format json");if(!$.trim())return[];let Z=$.trim().split(`
217
+ `),Q=[];for(let X of Z){if(!X.trim())continue;try{let z=JSON.parse(X),Y=z.Service??"unknown";Q.push({name:Y,state:z.State??"unknown",health:z.Health??"",port:wZ[Y]??"",image:z.Image??""})}catch{}}return Q}catch{return[]}}function o7($=120000,Z=3000){let Q=Date.now()+$;while(Date.now()<Q){let X=t2();if(X.length===3&&X.every((Y)=>Y.state==="running")){if(X.every((J)=>J.health==="healthy"||J.health===""))return!0}I2(`sleep ${Z/1000}`,{timeout:Z+1000})}return!1}function K$(){return n2}function n7(){let $=[];for(let Z of fZ)try{I2(`docker rm -f "${Z}"`,{...a2,timeout:1e4}),$.push(Z)}catch{}return $}var d7="2.0.0",G$,n2,Y$,kZ=`services:
218
218
  proof-server:
219
219
  image: 'midnightntwrk/proof-server:8.0.0-rc.5'
220
220
  container_name: "proof-server"
@@ -256,20 +256,20 @@ Install Docker from https://docs.docker.com/get-docker/`)}}}function i7(){if(g7(
256
256
  start_period: 5s
257
257
  environment:
258
258
  CFG_PRESET: "dev"
259
- `,a1,wZ,fZ;var a7=x(()=>{G$=J$(vZ(),J0,m$),n1=J$(G$,"compose.yml"),Y$=J$(G$,".version"),a1={encoding:"utf-8",timeout:30000};wZ={node:"9944",indexer:"8088","proof-server":"6300"};fZ=["node","indexer","proof-server"]});var q$={};e(q$,{default:()=>r7});import{spawn as hZ}from"child_process";function pZ($){return t7.includes($)}function s7($){let Z=[];for(let Q of $){let X=Q.state==="running"?u:c,z=Q.health?` (${Q.health})`:"",Y=Q.port?`:${Q.port}`:"",J=Q.image?` ${B(Q.image)}`:"";if(Z.push(` ${Q.name.padEnd(16)}${X(Q.state)}${B(z)}${B(Y)}`),J)Z.push(J)}return Z.join(`
259
+ `,a2,wZ,fZ;var a7=x(()=>{G$=J$(vZ(),J0,m$),n2=J$(G$,"compose.yml"),Y$=J$(G$,".version"),a2={encoding:"utf-8",timeout:30000};wZ={node:"9944",indexer:"8088","proof-server":"6300"};fZ=["node","indexer","proof-server"]});var q$={};e(q$,{default:()=>r7});import{spawn as hZ}from"child_process";function pZ($){return t7.includes($)}function s7($){let Z=[];for(let Q of $){let X=Q.state==="running"?u:c,z=Q.health?` (${Q.health})`:"",Y=Q.port?`:${Q.port}`:"",J=Q.image?` ${B(Q.image)}`:"";if(Z.push(` ${Q.name.padEnd(16)}${X(Q.state)}${B(z)}${B(Y)}`),J)Z.push(J)}return Z.join(`
260
260
  `)}async function uZ($){if(i7())process.stderr.write(B(` Wrote compose.yml to ${K$()}`)+`
261
- `);let Q=i("Starting local network...");try{if($1("up -d"),Q.update("Waiting for services to be healthy..."),!o7(120000))Q.stop(O0("Services started but not all healthy yet")),process.stderr.write(`
261
+ `);let Q=i("Starting local network...");try{if($2("up -d"),Q.update("Waiting for services to be healthy..."),!o7(120000))Q.stop(O0("Services started but not all healthy yet")),process.stderr.write(`
262
262
  `+B(" Tip: run ")+y("midnight localnet logs")+B(" to check for errors")+`
263
263
  `);else Q.stop("Local network is running")}catch(z){if(Q.stop(c("Failed to start local network")),z instanceof Error){if(z.message.includes("is already in use by container"))throw new Error(`Container name conflict — containers with the same names already exist
264
264
  `+`(likely from a previous midnight-local-network setup).
265
265
 
266
266
  Run "midnight localnet clean" to remove them, then try again.`);if(z.message.includes("address already in use"))throw new Error(`Port conflict detected — another process is using a required port.
267
- `+"Check ports 9944, 8088, and 6300, then try again.")}throw z}let X=t1();if($){E({subcommand:"up",services:X.map((z)=>({name:z.name,state:z.state,port:z.port,health:z.health,image:z.image}))});return}if(X.length>0)process.stderr.write(`
267
+ `+"Check ports 9944, 8088, and 6300, then try again.")}throw z}let X=t2();if($){E({subcommand:"up",services:X.map((z)=>({name:z.name,state:z.state,port:z.port,health:z.health,image:z.image}))});return}if(X.length>0)process.stderr.write(`
268
268
  `+s7(X)+`
269
269
  `);for(let z of X)process.stdout.write(`${z.name}=${z.state}:${z.port}
270
270
  `);process.stderr.write(`
271
271
  `+B(" Next: ")+y("midnight wallet generate dev --network undeployed")+`
272
- `)}async function mZ($){let Z=i("Stopping local network...");try{if($1("stop"),Z.stop("Local network stopped (containers preserved)"),$){E({subcommand:"stop",status:"stopped"});return}}catch(Q){throw Z.stop(c("Failed to stop local network")),Q}}async function gZ($){let Z=i("Tearing down local network...");try{if($1("down --volumes"),Z.stop("Local network removed (containers, networks, volumes)"),$){E({subcommand:"down",status:"removed"});return}}catch(Q){throw Z.stop(c("Failed to tear down local network")),Q}}async function cZ($){let Z=t1();if($){E({subcommand:"status",services:Z.map((Q)=>({name:Q.name,state:Q.state,port:Q.port,health:Q.health,image:Q.image}))});return}if(Z.length===0){process.stderr.write(`
272
+ `)}async function mZ($){let Z=i("Stopping local network...");try{if($2("stop"),Z.stop("Local network stopped (containers preserved)"),$){E({subcommand:"stop",status:"stopped"});return}}catch(Q){throw Z.stop(c("Failed to stop local network")),Q}}async function gZ($){let Z=i("Tearing down local network...");try{if($2("down --volumes"),Z.stop("Local network removed (containers, networks, volumes)"),$){E({subcommand:"down",status:"removed"});return}}catch(Q){throw Z.stop(c("Failed to tear down local network")),Q}}async function cZ($){let Z=t2();if($){E({subcommand:"status",services:Z.map((Q)=>({name:Q.name,state:Q.state,port:Q.port,health:Q.health,image:Q.image}))});return}if(Z.length===0){process.stderr.write(`
273
273
  `+f("Localnet Status")+`
274
274
 
275
275
  `),process.stderr.write(B(" No services running.")+`
@@ -283,7 +283,7 @@ Run "midnight localnet clean" to remove them, then try again.`);if(z.message.inc
283
283
  `+h()+`
284
284
 
285
285
  `);for(let Q of Z)process.stdout.write(`${Q.name}=${Q.state}:${Q.port}
286
- `)}async function dZ($){let Z=i("Removing conflicting containers...");try{try{$1("down")}catch{}let Q=n7();if(Q.length>0)Z.stop(`Removed ${Q.length} container${Q.length>1?"s":""}: ${Q.join(", ")}`);else Z.stop("No conflicting containers found");if($){E({subcommand:"clean",status:"cleaned",removed:Q});return}}catch(Q){throw Z.stop(c("Failed to clean up")),Q}}async function lZ(){let $=K$(),Z=hZ("docker",["compose","-f",$,"logs","-f"],{stdio:"inherit"});return new Promise((Q,X)=>{Z.on("close",(z)=>{if(z===0||z===130||z===null)Q();else X(new Error(`docker compose logs exited with code ${z}`))}),Z.on("error",X)})}async function r7($){let Z=$.subcommand;if(!Z||!pZ(Z))throw new Error(`Usage: midnight localnet <${t7.join("|")}>
286
+ `)}async function dZ($){let Z=i("Removing conflicting containers...");try{try{$2("down")}catch{}let Q=n7();if(Q.length>0)Z.stop(`Removed ${Q.length} container${Q.length>1?"s":""}: ${Q.join(", ")}`);else Z.stop("No conflicting containers found");if($){E({subcommand:"clean",status:"cleaned",removed:Q});return}}catch(Q){throw Z.stop(c("Failed to clean up")),Q}}async function lZ(){let $=K$(),Z=hZ("docker",["compose","-f",$,"logs","-f"],{stdio:"inherit"});return new Promise((Q,X)=>{Z.on("close",(z)=>{if(z===0||z===130||z===null)Q();else X(new Error(`docker compose logs exited with code ${z}`))}),Z.on("error",X)})}async function r7($){let Z=$.subcommand;if(!Z||!pZ(Z))throw new Error(`Usage: midnight localnet <${t7.join("|")}>
287
287
 
288
288
  Subcommands:
289
289
  up Start the local network
@@ -300,8 +300,8 @@ Example: midnight localnet up`);l7();let Q=R($,"json");switch(process.stderr.wri
300
300
  Available: generate, list, use, info, remove
301
301
  Run "midnight help wallet" for usage.`)}}async function aZ($){let Z=$.positionals[0];if(!Z)throw new Error(`Missing wallet name.
302
302
  Usage: midnight wallet generate <name> [--network <name>]`);if(!y0(Z))throw new Error(`Invalid wallet name: "${Z}"
303
- Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Q=K0({args:$}),X=N($,"seed"),z=N($,"mnemonic");if(X!==void 0&&z!==void 0)throw new Error("Cannot specify both --seed and --mnemonic. Use one or the other.");let Y=V$.join(iZ(),J0,E1),J=V$.join(Y,`${Z}.json`);if(Z9.existsSync(J)&&!R($,"force"))throw new Error(`Wallet "${Z}" already exists: ${J}
304
- Use --force to overwrite.`);let G,q;if(X!==void 0){let V=X.replace(/^0x/,"");if(V.length!==64||!/^[0-9a-fA-F]+$/.test(V))throw new Error("Seed must be a 64-character hex string (32 bytes)");G=Buffer.from(V,"hex")}else if(z!==void 0){if(!nZ(z,$9))throw new Error("Invalid BIP-39 mnemonic. Expected 12 or 24 words from the English wordlist.");q=z,G=Buffer.from(e7(q).slice(0,32))}else q=oZ($9,256),G=Buffer.from(e7(q).slice(0,32));let K=k0(G),U=K[Q],W={seed:G.toString("hex"),addresses:K,createdAt:new Date().toISOString()};if(q)W.mnemonic=q;let j=h1(W,J);if(A2(Z),R($,"json")){let V={name:Z,addresses:K,activeAddress:U,activeNetwork:Q,seed:G.toString("hex"),file:j,createdAt:W.createdAt,active:!0};if(q)V.mnemonic=q;E(V);return}if(process.stdout.write(U+`
303
+ Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Q=K0({args:$}),X=N($,"seed"),z=N($,"mnemonic");if(X!==void 0&&z!==void 0)throw new Error("Cannot specify both --seed and --mnemonic. Use one or the other.");let Y=V$.join(iZ(),J0,E2),J=V$.join(Y,`${Z}.json`);if(Z9.existsSync(J)&&!R($,"force"))throw new Error(`Wallet "${Z}" already exists: ${J}
304
+ Use --force to overwrite.`);let G,q;if(X!==void 0){let V=X.replace(/^0x/,"");if(V.length!==64||!/^[0-9a-fA-F]+$/.test(V))throw new Error("Seed must be a 64-character hex string (32 bytes)");G=Buffer.from(V,"hex")}else if(z!==void 0){if(!nZ(z,$9))throw new Error("Invalid BIP-39 mnemonic. Expected 12 or 24 words from the English wordlist.");q=z,G=Buffer.from(e7(q).slice(0,32))}else q=oZ($9,256),G=Buffer.from(e7(q).slice(0,32));let K=k0(G),U=K[Q],W={seed:G.toString("hex"),addresses:K,createdAt:new Date().toISOString()};if(q)W.mnemonic=q;let j=h2(W,J);if(A1(Z),R($,"json")){let V={name:Z,addresses:K,activeAddress:U,activeNetwork:Q,seed:G.toString("hex"),file:j,createdAt:W.createdAt,active:!0};if(q)V.mnemonic=q;E(V);return}if(process.stdout.write(U+`
305
305
  `),process.stderr.write(`
306
306
  `+f("Wallet Generated")+`
307
307
 
@@ -334,8 +334,8 @@ Use --force to overwrite.`);let G,q;if(X!==void 0){let V=X.replace(/^0x/,"");if(
334
334
  `),process.stderr.write(B(" ● = active wallet")+`
335
335
 
336
336
  `)}async function sZ($){let Z=$.positionals[0];if(!Z)throw new Error(`Missing wallet name.
337
- Usage: midnight wallet use <name>`);if(A2(Z),R($,"json")){E({wallet:Z,active:!0});return}process.stderr.write(u("✓")+` Active wallet set to "${Z}"
338
- `)}async function rZ($){let Z=$.positionals[0]??B1(),Q=Q0(Z),X=X0(Q),z=Z===B1(),Y=K0({args:$}),J=X.addresses[Y];if(R($,"json")){E({name:Z,addresses:X.addresses,activeAddress:J,activeNetwork:Y,createdAt:X.createdAt,file:Q,active:z});return}process.stdout.write(J+`
337
+ Usage: midnight wallet use <name>`);if(A1(Z),R($,"json")){E({wallet:Z,active:!0});return}process.stderr.write(u("✓")+` Active wallet set to "${Z}"
338
+ `)}async function rZ($){let Z=$.positionals[0]??B2(),Q=Q0(Z),X=X0(Q),z=Z===B2(),Y=K0({args:$}),J=X.addresses[Y];if(R($,"json")){E({name:Z,addresses:X.addresses,activeAddress:J,activeNetwork:Y,createdAt:X.createdAt,file:Q,active:z});return}process.stdout.write(J+`
339
339
  `),process.stderr.write(`
340
340
  `+f("Wallet Info")+`
341
341
 
@@ -350,7 +350,7 @@ Usage: midnight wallet use <name>`);if(A2(Z),R($,"json")){E({wallet:Z,active:!0}
350
350
 
351
351
  `)}async function eZ($){let Z=$.positionals[0];if(!Z)throw new Error(`Missing wallet name.
352
352
  Usage: midnight wallet remove <name>`);if(Y7(Z),R($,"json")){E({wallet:Z,removed:!0});return}process.stderr.write(u("✓")+` Wallet "${Z}" removed
353
- `)}var B$=x(()=>{w0();V0();W0();s()});var G9={};e(G9,{default:()=>J9});function H$($){let Z=Date.now()-new Date($).getTime();if(Z<60000)return"just now";if(Z<3600000)return`${Math.floor(Z/60000)}m ago`;if(Z<86400000)return`${Math.floor(Z/3600000)}h ago`;return`${Math.floor(Z/86400000)}d ago`}function W$($){let Z=!1,Q=!1;for(let X of Object.values($)){if(X.status==="down")Z=!0;if(X.status==="degraded")Q=!0}if(Z)return"down";if(Q)return"degraded";return"up"}async function s1($){let Z=`${C1}${$}`,Q=await fetch(Z,{signal:AbortSignal.timeout(1e4)});if(!Q.ok)throw new Error(`Dashboard returned HTTP ${Q.status} for ${$}`);return Q.json()}async function XQ($){let Z=N($,"network");if(Z)return Z;try{let{loadCliConfig:Q}=await Promise.resolve().then(() => (n0(),Q7)),X=Q();if(X.network&&A0(X.network))return X.network}catch{}return}async function e1($,Z={}){let Q=new AbortController,X=setTimeout(()=>Q.abort(),QQ),z=Date.now();try{return{response:await fetch($,{...Z,signal:Q.signal}),latencyMs:Date.now()-z}}finally{clearTimeout(X)}}async function zQ($){let Z=new Date().toISOString();try{let{response:Q,latencyMs:X}=await e1($,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:"{ block { height } }"})});if(!Q.ok){if(Q.status===403)return{status:"degraded",latencyMs:X,lastChecked:Z,notes:"HTTP 403 — likely WAF blocking"};return{status:"down",latencyMs:X,lastChecked:Z,notes:`HTTP ${Q.status}`}}let z=await Q.json();if(!z?.data)return{status:"down",latencyMs:X,lastChecked:Z,notes:"No data field"};let Y=z.data?.block?.height;return{status:X>r1?"degraded":"up",latencyMs:X,lastChecked:Z,...Y!==void 0?{blockHeight:Y}:{},...X>r1?{notes:`Slow (${X}ms)`}:{}}}catch(Q){return{status:"down",latencyMs:0,lastChecked:Z,notes:Q.message}}}async function YQ($){let Z=new Date().toISOString(),Q=$.replace(/^wss:/,"https:").replace(/^ws:/,"http:");try{let{response:X,latencyMs:z}=await e1(Q,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"system_health",params:[]})});if(!X.ok){if(X.status===403)return{status:"degraded",latencyMs:z,lastChecked:Z,notes:"HTTP 403 — likely WAF blocking"};return{status:"down",latencyMs:z,lastChecked:Z,notes:`HTTP ${X.status}`}}let J=(await X.json())?.result;if(!J)return{status:"down",latencyMs:z,lastChecked:Z,notes:"No result in response"};let G=J.peers??0,q=J.isSyncing??!1,K="up",U;if(q)K="degraded",U="Node is syncing";else if(G===0)K="degraded",U="No peers";return{status:K,latencyMs:z,lastChecked:Z,peers:G,isSyncing:q,...U?{notes:U}:{}}}catch(X){return{status:"down",latencyMs:0,lastChecked:Z,notes:X.message}}}async function JQ($){let Z=new Date().toISOString();if(!$)return{status:"unknown",latencyMs:0,lastChecked:Z,notes:"No faucet URL"};try{let{response:Q,latencyMs:X}=await e1($);if(!Q.ok)return{status:"down",latencyMs:X,lastChecked:Z,notes:`HTTP ${Q.status}`};return{status:X>z9?"degraded":"up",latencyMs:X,lastChecked:Z,...X>z9?{notes:`Slow (${X}ms)`}:{}}}catch(Q){return{status:"down",latencyMs:0,lastChecked:Z,notes:Q.message}}}async function GQ($){let Z=new Date().toISOString();if(!$)return{status:"unknown",latencyMs:0,lastChecked:Z,notes:"URL not configured"};try{let{response:Q,latencyMs:X}=await e1($);if(!Q.ok)return{status:"down",latencyMs:X,lastChecked:Z,notes:`HTTP ${Q.status}`};let z=await Q.text();if(!z||z.length===0)return{status:"down",latencyMs:X,lastChecked:Z,notes:"Empty response"};return{status:X>r1?"degraded":"up",latencyMs:X,lastChecked:Z,...X>r1?{notes:`Slow (${X}ms)`}:{}}}catch(Q){return{status:"down",latencyMs:0,lastChecked:Z,notes:Q.message}}}async function Y9($){if(!A0($))return{};let Z=F2($),Q=$Q[$];if(!Q)return{};let[X,z,Y,J]=await Promise.all([zQ(Z.indexer),YQ(Z.node),JQ(Q.faucet),GQ(Q.explorer)]);return{indexer:X,rpc:z,faucet:Y,explorer:J}}function KQ($,Z,Q){process.stderr.write(`
353
+ `)}var B$=x(()=>{w0();V0();W0();s()});var G9={};e(G9,{default:()=>J9});function H$($){let Z=Date.now()-new Date($).getTime();if(Z<60000)return"just now";if(Z<3600000)return`${Math.floor(Z/60000)}m ago`;if(Z<86400000)return`${Math.floor(Z/3600000)}h ago`;return`${Math.floor(Z/86400000)}d ago`}function W$($){let Z=!1,Q=!1;for(let X of Object.values($)){if(X.status==="down")Z=!0;if(X.status==="degraded")Q=!0}if(Z)return"down";if(Q)return"degraded";return"up"}async function s2($){let Z=`${C2}${$}`,Q=await fetch(Z,{signal:AbortSignal.timeout(1e4)});if(!Q.ok)throw new Error(`Dashboard returned HTTP ${Q.status} for ${$}`);return Q.json()}async function XQ($){let Z=N($,"network");if(Z)return Z;try{let{loadCliConfig:Q}=await Promise.resolve().then(() => (n0(),Q7)),X=Q();if(X.network&&A0(X.network))return X.network}catch{}return}async function e2($,Z={}){let Q=new AbortController,X=setTimeout(()=>Q.abort(),QQ),z=Date.now();try{return{response:await fetch($,{...Z,signal:Q.signal}),latencyMs:Date.now()-z}}finally{clearTimeout(X)}}async function zQ($){let Z=new Date().toISOString();try{let{response:Q,latencyMs:X}=await e2($,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:"{ block { height } }"})});if(!Q.ok){if(Q.status===403)return{status:"degraded",latencyMs:X,lastChecked:Z,notes:"HTTP 403 — likely WAF blocking"};return{status:"down",latencyMs:X,lastChecked:Z,notes:`HTTP ${Q.status}`}}let z=await Q.json();if(!z?.data)return{status:"down",latencyMs:X,lastChecked:Z,notes:"No data field"};let Y=z.data?.block?.height;return{status:X>r2?"degraded":"up",latencyMs:X,lastChecked:Z,...Y!==void 0?{blockHeight:Y}:{},...X>r2?{notes:`Slow (${X}ms)`}:{}}}catch(Q){return{status:"down",latencyMs:0,lastChecked:Z,notes:Q.message}}}async function YQ($){let Z=new Date().toISOString(),Q=$.replace(/^wss:/,"https:").replace(/^ws:/,"http:");try{let{response:X,latencyMs:z}=await e2(Q,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"system_health",params:[]})});if(!X.ok){if(X.status===403)return{status:"degraded",latencyMs:z,lastChecked:Z,notes:"HTTP 403 — likely WAF blocking"};return{status:"down",latencyMs:z,lastChecked:Z,notes:`HTTP ${X.status}`}}let J=(await X.json())?.result;if(!J)return{status:"down",latencyMs:z,lastChecked:Z,notes:"No result in response"};let G=J.peers??0,q=J.isSyncing??!1,K="up",U;if(q)K="degraded",U="Node is syncing";else if(G===0)K="degraded",U="No peers";return{status:K,latencyMs:z,lastChecked:Z,peers:G,isSyncing:q,...U?{notes:U}:{}}}catch(X){return{status:"down",latencyMs:0,lastChecked:Z,notes:X.message}}}async function JQ($){let Z=new Date().toISOString();if(!$)return{status:"unknown",latencyMs:0,lastChecked:Z,notes:"No faucet URL"};try{let{response:Q,latencyMs:X}=await e2($);if(!Q.ok)return{status:"down",latencyMs:X,lastChecked:Z,notes:`HTTP ${Q.status}`};return{status:X>z9?"degraded":"up",latencyMs:X,lastChecked:Z,...X>z9?{notes:`Slow (${X}ms)`}:{}}}catch(Q){return{status:"down",latencyMs:0,lastChecked:Z,notes:Q.message}}}async function GQ($){let Z=new Date().toISOString();if(!$)return{status:"unknown",latencyMs:0,lastChecked:Z,notes:"URL not configured"};try{let{response:Q,latencyMs:X}=await e2($);if(!Q.ok)return{status:"down",latencyMs:X,lastChecked:Z,notes:`HTTP ${Q.status}`};let z=await Q.text();if(!z||z.length===0)return{status:"down",latencyMs:X,lastChecked:Z,notes:"Empty response"};return{status:X>r2?"degraded":"up",latencyMs:X,lastChecked:Z,...X>r2?{notes:`Slow (${X}ms)`}:{}}}catch(Q){return{status:"down",latencyMs:0,lastChecked:Z,notes:Q.message}}}async function Y9($){if(!A0($))return{};let Z=F1($),Q=$Q[$];if(!Q)return{};let[X,z,Y,J]=await Promise.all([zQ(Z.indexer),YQ(Z.node),JQ(Q.faucet),GQ(Q.explorer)]);return{indexer:X,rpc:z,faucet:Y,explorer:J}}function KQ($,Z,Q){process.stderr.write(`
354
354
  `+y($)+`
355
355
  `),process.stderr.write(B(" "+"─".repeat(62))+`
356
356
  `);let X=new Set([...Object.keys(Q),...Z?Object.keys(Z):[]]);for(let z of X){let Y=Q[z],J=Z?.[z],G=(ZQ[z]??z).padEnd(18);if(Y){let q=X9[Y.status]??B("—"),K=Y.latencyMs>0?B(` ${Y.latencyMs}ms`):"",U=Y.notes?B(` — ${Y.notes}`):"",W="";if(J&&J.status!==Y.status&&J.status!=="unknown")W=B(` (canary: ${J.status}${J.lastChecked?" "+H$(J.lastChecked):""})`);process.stderr.write(` ${D0(G)}${q}${K}${U}${W}
@@ -360,7 +360,7 @@ Usage: midnight wallet remove <name>`);if(Y7(Z),R($,"json")){E({wallet:Z,removed
360
360
 
361
361
  `);for(let X of Q)process.stderr.write(` ${c(X.id.padEnd(28))}${X.summary}
362
362
  `),process.stderr.write(` ${" ".repeat(28)}${B(X.status)}
363
- `)}async function J9($){let Z=R($,"json"),Q=R($,"all"),X=R($,"watch"),z=await XQ($)??"preprod",Y=i("Checking network status..."),J=null,G=null,q,K;if(Q)K=["preprod","preview"];else K=[z];let[U,...W]=await Promise.all([Promise.all([s1("/api/status"),s1("/api/issues")]).catch((F)=>{return q=F.message,null}),...K.map((F)=>Y9(F))]);if(U)[J,G]=U;Y.stop("Done");let j={};for(let F=0;F<K.length;F++)j[K[F]]=W[F];if(Z){let F={lastUpdated:J?.lastUpdated??null,dashboard:C1,canaryAvailable:J!==null,networks:{}};for(let P of K){let M=j[P]??{},C=J?.networks[P],A={...C,...M};F.networks[P]={overall:W$(A),live:M,canary:C??null}}if(G){let P=Q?void 0:K[0];F.issues=P?G.issues.filter((M)=>M.affects.toLowerCase().includes(P.toLowerCase())):G.issues}if(q)F.canaryError=q;E(F);let D=K.reduce((P,M)=>{let C={...J?.networks[M]??{},...j[M]??{}},A=W$(C);if(A==="down")return"down";if(A==="degraded"&&P!=="down")return"degraded";return P},"up");if(D==="down")process.exitCode=2;else if(D==="degraded")process.exitCode=1;return}let V=()=>{if(process.stderr.write(`
363
+ `)}async function J9($){let Z=R($,"json"),Q=R($,"all"),X=R($,"watch"),z=await XQ($)??"preprod",Y=i("Checking network status..."),J=null,G=null,q,K;if(Q)K=["preprod","preview"];else K=[z];let[U,...W]=await Promise.all([Promise.all([s2("/api/status"),s2("/api/issues")]).catch((F)=>{return q=F.message,null}),...K.map((F)=>Y9(F))]);if(U)[J,G]=U;Y.stop("Done");let j={};for(let F=0;F<K.length;F++)j[K[F]]=W[F];if(Z){let F={lastUpdated:J?.lastUpdated??null,dashboard:C2,canaryAvailable:J!==null,networks:{}};for(let P of K){let M=j[P]??{},C=J?.networks[P],A={...C,...M};F.networks[P]={overall:W$(A),live:M,canary:C??null}}if(G){let P=Q?void 0:K[0];F.issues=P?G.issues.filter((M)=>M.affects.toLowerCase().includes(P.toLowerCase())):G.issues}if(q)F.canaryError=q;E(F);let D=K.reduce((P,M)=>{let C={...J?.networks[M]??{},...j[M]??{}},A=W$(C);if(A==="down")return"down";if(A==="degraded"&&P!=="down")return"degraded";return P},"up");if(D==="down")process.exitCode=2;else if(D==="degraded")process.exitCode=1;return}let V=()=>{if(process.stderr.write(`
364
364
  `+f("Midnight Network Status")+`
365
365
  `),J?.lastUpdated)process.stderr.write(B(` Canary: ${H$(J.lastUpdated)}`)+" ");if(process.stderr.write(B("Live: just now")+`
366
366
  `),q)process.stderr.write(B(` (Dashboard unreachable: ${q})`)+`
@@ -369,20 +369,20 @@ Usage: midnight wallet remove <name>`);if(Y7(Z),R($,"json")){E({wallet:Z,removed
369
369
 
370
370
  `);return}for(let F of K)KQ(F,J?.networks[F],j[F]??{});if(G){let F=Q?void 0:K[0];qQ(G.issues,F)}process.stderr.write(`
371
371
  `+h()+`
372
- `),process.stderr.write(B(" Dashboard: ")+t(C1)+`
373
-
374
- `)};if(V(),X){let F=setInterval(async()=>{try{let[D,...P]=await Promise.all([Promise.all([s1("/api/status"),s1("/api/issues")]).catch(()=>null),...K.map((M)=>Y9(M))]);if(D)[J,G]=D;for(let M=0;M<K.length;M++)j[K[M]]=P[M];process.stderr.write("\x1B[2J\x1B[H"),V()}catch{process.stderr.write(B(" Refresh failed — retrying in 30s")+`
375
- `)}},30000);await new Promise(()=>{process.on("SIGINT",()=>{clearInterval(F),process.exit(0)})})}let H=K.reduce((F,D)=>{let P={...J?.networks[D]??{},...j[D]??{}},M=W$(P);if(M==="down")return"down";if(M==="degraded"&&F!=="down")return"degraded";return F},"up");if(H==="down")process.exitCode=2;else if(H==="degraded")process.exitCode=1}var $Q,ZQ,X9,QQ=15000,r1=5000,z9=1e4;var K9=x(()=>{T0();s();x0();$Q={preprod:{faucet:"https://faucet.preprod.midnight.network/",explorer:"https://preprod.midnightexplorer.com/"},preview:{faucet:"https://faucet.preview.midnight.network/",explorer:null},undeployed:{faucet:"",explorer:""}},ZQ={indexer:"Indexer",rpc:"RPC Node",faucet:"Faucet",explorer:"Explorer",chain:"Chain",dust:"Dust Generation",wallet:"Wallet Ops",dapp:"DApp Flow"},X9={up:u("UP"),down:c("DOWN"),degraded:y("\x1B[33mDEGRADED\x1B[0m"),unknown:B("—")}});var LQ={};import{Server as UQ}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as VQ}from"@modelcontextprotocol/sdk/server/stdio.js";import{ListToolsRequestSchema as jQ,CallToolRequestSchema as BQ}from"@modelcontextprotocol/sdk/types.js";function j0($,Z,Q){let X={json:!0},z=[];for(let[Y,J]of Object.entries(Z)){if(J===void 0||J===null)continue;if(typeof J==="boolean"){if(J)X[Y]=!0}else X[Y]=String(J)}return{command:$,subcommand:Q,positionals:z,flags:X}}async function g($){let Z=WQ[$];if(!Z)throw new Error(`Unknown command handler: ${$}`);return(await Z()).default}async function HQ(){let $=new VQ;await L$.connect($)}var WQ,q9,L$;var U9=x(()=>{G7();H2();v1();WQ={generate:()=>Promise.resolve().then(() => (E2(),N2)),info:()=>Promise.resolve().then(() => (x2(),C2)),balance:()=>Promise.resolve().then(() => (b2(),y2)),address:()=>Promise.resolve().then(() => (v2(),S2)),"genesis-address":()=>Promise.resolve().then(() => (w2(),k2)),"inspect-cost":()=>Promise.resolve().then(() => (h2(),f2)),airdrop:()=>Promise.resolve().then(() => (t2(),a2)),transfer:()=>Promise.resolve().then(() => (r2(),s2)),dust:()=>Promise.resolve().then(() => ($$(),e2)),cache:()=>Promise.resolve().then(() => (Q$(),Z$)),config:()=>Promise.resolve().then(() => (z$(),X$)),localnet:()=>Promise.resolve().then(() => (U$(),q$)),wallet:()=>Promise.resolve().then(() => (B$(),j$)),status:()=>Promise.resolve().then(() => (K9(),G9))};q9=[{name:"midnight_generate",description:"Generate a new wallet (deprecated — use midnight_wallet_generate instead)",inputSchema:{type:"object",properties:{network:{type:"string",description:"Network: preprod, preview, undeployed",enum:["preprod","preview","undeployed"]},seed:{type:"string",description:"Restore from existing seed (64-char hex)"},mnemonic:{type:"string",description:"Restore from BIP-39 mnemonic (24 words)"},output:{type:"string",description:"Custom output path (deprecated — use midnight_wallet_generate instead)"},force:{type:"string",description:'Set to "true" to overwrite existing wallet file'}}},async handler($){let Z=j0("generate",$);if($.force==="true"||$.force===!0)Z.flags.force=!0;let Q=await g("generate");return m(Q,Z)}},{name:"midnight_wallet_generate",description:"Create a new named wallet and set it as active",inputSchema:{type:"object",properties:{name:{type:"string",description:'Wallet name (e.g. "alice", "dev")'},network:{type:"string",description:"Network: preprod, preview, undeployed",enum:["preprod","preview","undeployed"]},seed:{type:"string",description:"Restore from existing seed (64-char hex)"},mnemonic:{type:"string",description:"Restore from BIP-39 mnemonic (24 words)"},force:{type:"string",description:'Set to "true" to overwrite existing wallet'}},required:["name"]},async handler($){let Z=$.name,Q=j0("wallet",$,"generate");if(Q.positionals=[Z],delete Q.flags.name,$.force==="true"||$.force===!0)Q.flags.force=!0;let X=await g("wallet");return m(X,Q)}},{name:"midnight_wallet_list",description:"List all wallets with name, address, network, and active marker",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"wallet",subcommand:"list",positionals:[],flags:{json:!0}},Z=await g("wallet");return m(Z,$)}},{name:"midnight_wallet_use",description:"Set the active wallet by name",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name to activate"}},required:["name"]},async handler($){let Q={command:"wallet",subcommand:"use",positionals:[$.name],flags:{json:!0}},X=await g("wallet");return m(X,Q)}},{name:"midnight_wallet_info",description:"Show details for a named wallet or the active wallet",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name (default: active wallet)"}}},async handler($){let Z=$.name,Q={command:"wallet",subcommand:"info",positionals:Z?[Z]:[],flags:{json:!0}},X=await g("wallet");return m(X,Q)}},{name:"midnight_wallet_remove",description:"Remove a named wallet (refuses active or last wallet)",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name to remove"}},required:["name"]},async handler($){let Q={command:"wallet",subcommand:"remove",positionals:[$.name],flags:{json:!0}},X=await g("wallet");return m(X,Q)}},{name:"midnight_info",description:"Display wallet address, network, creation date (no secrets shown)",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"}}},async handler($){let Z=j0("info",$),Q=await g("info");return m(Q,Z)}},{name:"midnight_balance",description:"Check unshielded balance via indexer subscription",inputSchema:{type:"object",properties:{address:{type:"string",description:"Address to check (or reads from wallet file)"},wallet:{type:"string",description:"Wallet name or path"},network:{type:"string",description:"Override network detection",enum:["preprod","preview","undeployed"]},"indexer-ws":{type:"string",description:"Custom indexer WebSocket URL"}}},async handler($){let Z=$.address,Q=j0("balance",$,Z);delete Q.flags.address;let X=await g("balance");return m(X,Q)}},{name:"midnight_address",description:"Derive and display an unshielded address from a seed",inputSchema:{type:"object",properties:{seed:{type:"string",description:"Seed to derive from (required, 64-char hex)"},network:{type:"string",description:"Network for address prefix",enum:["preprod","preview","undeployed"]},index:{type:"string",description:"Key derivation index (default: 0)"}},required:["seed"]},async handler($){let Z=j0("address",$),Q=await g("address");return m(Q,Z)}},{name:"midnight_genesis_address",description:"Display the genesis wallet address (seed 0x01) for a network",inputSchema:{type:"object",properties:{network:{type:"string",description:"Network for address prefix",enum:["preprod","preview","undeployed"]}}},async handler($){let Z=j0("genesis-address",$),Q=await g("genesis-address");return m(Q,Z)}},{name:"midnight_inspect_cost",description:"Display current block limits derived from LedgerParameters",inputSchema:{type:"object",properties:{}},async handler(){let $=j0("inspect-cost",{}),Z=await g("inspect-cost");return m(Z,$)}},{name:"midnight_airdrop",description:"Fund your wallet from the genesis wallet (undeployed network only)",inputSchema:{type:"object",properties:{amount:{type:"string",description:"Amount in NIGHT to airdrop"},wallet:{type:"string",description:"Wallet name or path"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}},required:["amount"]},async handler($){let Z=$.amount,Q=j0("airdrop",$,Z);delete Q.flags.amount;let X=await g("airdrop");return m(X,Q)}},{name:"midnight_transfer",description:"Send NIGHT tokens to another address",inputSchema:{type:"object",properties:{to:{type:"string",description:"Recipient bech32m address"},amount:{type:"string",description:"Amount in NIGHT to send"},wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}},required:["to","amount"]},async handler($){let{to:Z,amount:Q}=$,X=j0("transfer",$,Z);X.positionals=[Q],delete X.flags.to,delete X.flags.amount;let z=await g("transfer");return m(z,X)}},{name:"midnight_dust_register",description:"Register NIGHT UTXOs for dust (fee token) generation",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}}},async handler($){let Z=j0("dust",$,"register"),Q=await g("dust");return m(Q,Z)}},{name:"midnight_dust_status",description:"Check dust registration status and balance",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}}},async handler($){let Z=j0("dust",$,"status"),Q=await g("dust");return m(Q,Z)}},{name:"midnight_config_get",description:"Read a persistent config value",inputSchema:{type:"object",properties:{key:{type:"string",description:'Config key to read (e.g. "network")'}},required:["key"]},async handler($){let Q={command:"config",subcommand:"get",positionals:[$.key],flags:{json:!0}},X=await g("config");return m(X,Q)}},{name:"midnight_config_set",description:"Write a persistent config value",inputSchema:{type:"object",properties:{key:{type:"string",description:'Config key to set (e.g. "network")'},value:{type:"string",description:"Config value to set"}},required:["key","value"]},async handler($){let{key:Z,value:Q}=$,X={command:"config",subcommand:"set",positionals:[Z,Q],flags:{json:!0}},z=await g("config");return m(z,X)}},{name:"midnight_cache_clear",description:"Clear cached wallet sync state",inputSchema:{type:"object",properties:{network:{type:"string",description:"Only clear cache for this network",enum:["preprod","preview","undeployed"]},wallet:{type:"string",description:"Only clear cache for this wallet (name or path)"}}},async handler($){let Z=j0("cache",$,"clear"),Q=await g("cache");return m(Q,Z)}},{name:"midnight_config_unset",description:"Reset a persistent config value to its default",inputSchema:{type:"object",properties:{key:{type:"string",description:"Config key to reset"}},required:["key"]},async handler($){let Q={command:"config",subcommand:"unset",positionals:[$.key],flags:{json:!0}},X=await g("config");return m(X,Q)}},{name:"midnight_localnet_up",description:"Start a local Midnight network via Docker Compose",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"up",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}},{name:"midnight_localnet_stop",description:"Stop local network containers (preserves state for fast restart)",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"stop",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}},{name:"midnight_localnet_down",description:"Remove local network containers, networks, and volumes (full teardown)",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"down",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}},{name:"midnight_localnet_status",description:"Show local network service status and ports",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"status",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}},{name:"midnight_localnet_clean",description:"Remove conflicting containers from other setups",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"clean",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}}],L$=new UQ({name:"midnight-wallet-cli",version:S0},{capabilities:{tools:{}}});L$.setRequestHandler(jQ,async()=>{return{tools:q9.map(($)=>({name:$.name,description:$.description,inputSchema:$.inputSchema}))}});L$.setRequestHandler(BQ,async($)=>{let{name:Z,arguments:Q}=$.params,X=q9.find((z)=>z.name===Z);if(!X)return{content:[{type:"text",text:`Unknown tool: ${Z}`}],isError:!0};try{let z=await X.handler(Q??{});return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){let Y=z instanceof Error?z:new Error(String(z)),{errorCode:J}=U1(Y);return{content:[{type:"text",text:JSON.stringify({error:!0,code:J,message:Y.message})}],isError:!0}}});HQ().catch(($)=>{process.stderr.write(`MCP server error: ${$.message}
376
- `),process.exit(1)})});function j9($){let Z=Math.max(0,Math.min(1,$)),Q=Z1[0].length,X=Math.floor(Z*Q);return Z1.map((z)=>z.slice(0,X).padEnd(Q))}function B9($){let Z=Math.max(0,Math.min(1,$)),Q=Math.floor($*100);if(Z>=1)return Z1;return Z1.map((X,z)=>Array.from(X).map((Y,J)=>{if(Y===" ")return" ";if(Z<=0)return Z2(z+20,J,0);let G=((z+20)*131+J*997)%100/100;return Z>=G?Y:Z2(z+20,J,Q)}).join(""))}function Z2($,Z,Q){let X=($*131+Z*997+Q*7919)%65537/65537;return V9[Math.floor(X*V9.length)]}function W9($){let Z=Math.max(0,Math.min(1,$)),Q=$2.split(`
377
- `),X=Math.floor($*100);if(Z>=1)return $2;if(Z<=0)return Q.map((z,Y)=>Array.from(z).map((J,G)=>Z2(Y,G,0)).join("")).join(`
378
- `);return Q.map((z,Y)=>Array.from(z).map((J,G)=>{if(J===" ")return" ";let q=(Y*131+G*997)%100/100;return Z>=q?J:Z2(Y,G,X)}).join("")).join(`
379
- `)}var $2,Z1,F$,V9;var P$=x(()=>{$2=[" ████████████ "," ███ ███ "," ███ ██ ███ "," ██ ██ "," ██ ██ ██ "," ██ ██ "," ██ ██ ██ "," ██ ██ "," ██ ██ "," ██ ██ "," ██ ██ "," ███ ███ "," ███ ███ "," ████████████ "].join(`
380
- `),Z1=["█▄ ▄█ █ █▀▄ █▄ █ █ █▀▀ █ █ ▀█▀","█ █ █ █ █ █ █ ██ █ █ █ █▀█ █ ","▀ ▀ ▀ ▀▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ "];F$=[["wallet","Manage named wallets"],["info","Display wallet metadata"],["balance","Check unshielded balance"],["address","Derive address from seed"],["genesis-address","Show genesis address"],["inspect-cost","Display block limits"],["airdrop","Fund from genesis wallet"],["transfer","Send NIGHT tokens"],["dust","Manage dust (fee tokens)"],["config","Manage CLI config"],["cache","Manage wallet cache"],["localnet","Manage local network"],["serve","DApp Connector server"],["status","Network health status"],["help","Show command usage"]],V9=["░","▒","▓","█","·"," "]});function I$($,Z){return new Promise((Q,X)=>{if(Z?.aborted){Q();return}let z=setTimeout(Q,$);Z?.addEventListener("abort",()=>{clearTimeout(z),Q()},{once:!0})})}async function H9($,Z){let X=$2.split(`
372
+ `),process.stderr.write(B(" Dashboard: ")+t(C2)+`
373
+
374
+ `)};if(V(),X){let F=setInterval(async()=>{try{let[D,...P]=await Promise.all([Promise.all([s2("/api/status"),s2("/api/issues")]).catch(()=>null),...K.map((M)=>Y9(M))]);if(D)[J,G]=D;for(let M=0;M<K.length;M++)j[K[M]]=P[M];process.stderr.write("\x1B[2J\x1B[H"),V()}catch{process.stderr.write(B(" Refresh failed — retrying in 30s")+`
375
+ `)}},30000);await new Promise(()=>{process.on("SIGINT",()=>{clearInterval(F),process.exit(0)})})}let H=K.reduce((F,D)=>{let P={...J?.networks[D]??{},...j[D]??{}},M=W$(P);if(M==="down")return"down";if(M==="degraded"&&F!=="down")return"degraded";return F},"up");if(H==="down")process.exitCode=2;else if(H==="degraded")process.exitCode=1}var $Q,ZQ,X9,QQ=15000,r2=5000,z9=1e4;var K9=x(()=>{T0();s();x0();$Q={preprod:{faucet:"https://faucet.preprod.midnight.network/",explorer:"https://preprod.midnightexplorer.com/"},preview:{faucet:"https://faucet.preview.midnight.network/",explorer:null},undeployed:{faucet:"",explorer:""}},ZQ={indexer:"Indexer",rpc:"RPC Node",faucet:"Faucet",explorer:"Explorer",chain:"Chain",dust:"Dust Generation",wallet:"Wallet Ops",dapp:"DApp Flow"},X9={up:u("UP"),down:c("DOWN"),degraded:y("\x1B[33mDEGRADED\x1B[0m"),unknown:B("—")}});var LQ={};import{Server as UQ}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as VQ}from"@modelcontextprotocol/sdk/server/stdio.js";import{ListToolsRequestSchema as jQ,CallToolRequestSchema as BQ}from"@modelcontextprotocol/sdk/types.js";function j0($,Z,Q){let X={json:!0},z=[];for(let[Y,J]of Object.entries(Z)){if(J===void 0||J===null)continue;if(typeof J==="boolean"){if(J)X[Y]=!0}else X[Y]=String(J)}return{command:$,subcommand:Q,positionals:z,flags:X}}async function g($){let Z=WQ[$];if(!Z)throw new Error(`Unknown command handler: ${$}`);return(await Z()).default}async function HQ(){let $=new VQ;await L$.connect($)}var WQ,q9,L$;var U9=x(()=>{G7();H1();v2();WQ={generate:()=>Promise.resolve().then(() => (E1(),N1)),info:()=>Promise.resolve().then(() => (x1(),C1)),balance:()=>Promise.resolve().then(() => (b1(),y1)),address:()=>Promise.resolve().then(() => (v1(),S1)),"genesis-address":()=>Promise.resolve().then(() => (w1(),k1)),"inspect-cost":()=>Promise.resolve().then(() => (h1(),f1)),airdrop:()=>Promise.resolve().then(() => (t1(),a1)),transfer:()=>Promise.resolve().then(() => (r1(),s1)),dust:()=>Promise.resolve().then(() => ($$(),e1)),cache:()=>Promise.resolve().then(() => (Q$(),Z$)),config:()=>Promise.resolve().then(() => (z$(),X$)),localnet:()=>Promise.resolve().then(() => (U$(),q$)),wallet:()=>Promise.resolve().then(() => (B$(),j$)),status:()=>Promise.resolve().then(() => (K9(),G9))};q9=[{name:"midnight_generate",description:"Generate a new wallet (deprecated — use midnight_wallet_generate instead)",inputSchema:{type:"object",properties:{network:{type:"string",description:"Network: preprod, preview, undeployed",enum:["preprod","preview","undeployed"]},seed:{type:"string",description:"Restore from existing seed (64-char hex)"},mnemonic:{type:"string",description:"Restore from BIP-39 mnemonic (24 words)"},output:{type:"string",description:"Custom output path (deprecated — use midnight_wallet_generate instead)"},force:{type:"string",description:'Set to "true" to overwrite existing wallet file'}}},async handler($){let Z=j0("generate",$);if($.force==="true"||$.force===!0)Z.flags.force=!0;let Q=await g("generate");return m(Q,Z)}},{name:"midnight_wallet_generate",description:"Create a new named wallet and set it as active",inputSchema:{type:"object",properties:{name:{type:"string",description:'Wallet name (e.g. "alice", "dev")'},network:{type:"string",description:"Network: preprod, preview, undeployed",enum:["preprod","preview","undeployed"]},seed:{type:"string",description:"Restore from existing seed (64-char hex)"},mnemonic:{type:"string",description:"Restore from BIP-39 mnemonic (24 words)"},force:{type:"string",description:'Set to "true" to overwrite existing wallet'}},required:["name"]},async handler($){let Z=$.name,Q=j0("wallet",$,"generate");if(Q.positionals=[Z],delete Q.flags.name,$.force==="true"||$.force===!0)Q.flags.force=!0;let X=await g("wallet");return m(X,Q)}},{name:"midnight_wallet_list",description:"List all wallets with name, address, network, and active marker",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"wallet",subcommand:"list",positionals:[],flags:{json:!0}},Z=await g("wallet");return m(Z,$)}},{name:"midnight_wallet_use",description:"Set the active wallet by name",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name to activate"}},required:["name"]},async handler($){let Q={command:"wallet",subcommand:"use",positionals:[$.name],flags:{json:!0}},X=await g("wallet");return m(X,Q)}},{name:"midnight_wallet_info",description:"Show details for a named wallet or the active wallet",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name (default: active wallet)"}}},async handler($){let Z=$.name,Q={command:"wallet",subcommand:"info",positionals:Z?[Z]:[],flags:{json:!0}},X=await g("wallet");return m(X,Q)}},{name:"midnight_wallet_remove",description:"Remove a named wallet (refuses active or last wallet)",inputSchema:{type:"object",properties:{name:{type:"string",description:"Wallet name to remove"}},required:["name"]},async handler($){let Q={command:"wallet",subcommand:"remove",positionals:[$.name],flags:{json:!0}},X=await g("wallet");return m(X,Q)}},{name:"midnight_info",description:"Display wallet address, network, creation date (no secrets shown)",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"}}},async handler($){let Z=j0("info",$),Q=await g("info");return m(Q,Z)}},{name:"midnight_balance",description:"Check unshielded balance via indexer subscription",inputSchema:{type:"object",properties:{address:{type:"string",description:"Address to check (or reads from wallet file)"},wallet:{type:"string",description:"Wallet name or path"},network:{type:"string",description:"Override network detection",enum:["preprod","preview","undeployed"]},"indexer-ws":{type:"string",description:"Custom indexer WebSocket URL"}}},async handler($){let Z=$.address,Q=j0("balance",$,Z);delete Q.flags.address;let X=await g("balance");return m(X,Q)}},{name:"midnight_address",description:"Derive and display an unshielded address from a seed",inputSchema:{type:"object",properties:{seed:{type:"string",description:"Seed to derive from (required, 64-char hex)"},network:{type:"string",description:"Network for address prefix",enum:["preprod","preview","undeployed"]},index:{type:"string",description:"Key derivation index (default: 0)"}},required:["seed"]},async handler($){let Z=j0("address",$),Q=await g("address");return m(Q,Z)}},{name:"midnight_genesis_address",description:"Display the genesis wallet address (seed 0x01) for a network",inputSchema:{type:"object",properties:{network:{type:"string",description:"Network for address prefix",enum:["preprod","preview","undeployed"]}}},async handler($){let Z=j0("genesis-address",$),Q=await g("genesis-address");return m(Q,Z)}},{name:"midnight_inspect_cost",description:"Display current block limits derived from LedgerParameters",inputSchema:{type:"object",properties:{}},async handler(){let $=j0("inspect-cost",{}),Z=await g("inspect-cost");return m(Z,$)}},{name:"midnight_airdrop",description:"Fund your wallet from the genesis wallet (undeployed network only)",inputSchema:{type:"object",properties:{amount:{type:"string",description:"Amount in NIGHT to airdrop"},wallet:{type:"string",description:"Wallet name or path"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}},required:["amount"]},async handler($){let Z=$.amount,Q=j0("airdrop",$,Z);delete Q.flags.amount;let X=await g("airdrop");return m(X,Q)}},{name:"midnight_transfer",description:"Send NIGHT tokens to another address",inputSchema:{type:"object",properties:{to:{type:"string",description:"Recipient bech32m address"},amount:{type:"string",description:"Amount in NIGHT to send"},wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}},required:["to","amount"]},async handler($){let{to:Z,amount:Q}=$,X=j0("transfer",$,Z);X.positionals=[Q],delete X.flags.to,delete X.flags.amount;let z=await g("transfer");return m(z,X)}},{name:"midnight_dust_register",description:"Register NIGHT UTXOs for dust (fee token) generation",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}}},async handler($){let Z=j0("dust",$,"register"),Q=await g("dust");return m(Q,Z)}},{name:"midnight_dust_status",description:"Check dust registration status and balance",inputSchema:{type:"object",properties:{wallet:{type:"string",description:"Wallet name or path"},"proof-server":{type:"string",description:"Override proof server URL"},node:{type:"string",description:"Override substrate node RPC URL"},"indexer-ws":{type:"string",description:"Override indexer WebSocket URL"},"no-cache":{type:"string",description:'Set to "true" to bypass wallet state cache'}}},async handler($){let Z=j0("dust",$,"status"),Q=await g("dust");return m(Q,Z)}},{name:"midnight_config_get",description:"Read a persistent config value",inputSchema:{type:"object",properties:{key:{type:"string",description:'Config key to read (e.g. "network")'}},required:["key"]},async handler($){let Q={command:"config",subcommand:"get",positionals:[$.key],flags:{json:!0}},X=await g("config");return m(X,Q)}},{name:"midnight_config_set",description:"Write a persistent config value",inputSchema:{type:"object",properties:{key:{type:"string",description:'Config key to set (e.g. "network")'},value:{type:"string",description:"Config value to set"}},required:["key","value"]},async handler($){let{key:Z,value:Q}=$,X={command:"config",subcommand:"set",positionals:[Z,Q],flags:{json:!0}},z=await g("config");return m(z,X)}},{name:"midnight_cache_clear",description:"Clear cached wallet sync state",inputSchema:{type:"object",properties:{network:{type:"string",description:"Only clear cache for this network",enum:["preprod","preview","undeployed"]},wallet:{type:"string",description:"Only clear cache for this wallet (name or path)"}}},async handler($){let Z=j0("cache",$,"clear"),Q=await g("cache");return m(Q,Z)}},{name:"midnight_config_unset",description:"Reset a persistent config value to its default",inputSchema:{type:"object",properties:{key:{type:"string",description:"Config key to reset"}},required:["key"]},async handler($){let Q={command:"config",subcommand:"unset",positionals:[$.key],flags:{json:!0}},X=await g("config");return m(X,Q)}},{name:"midnight_localnet_up",description:"Start a local Midnight network via Docker Compose",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"up",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}},{name:"midnight_localnet_stop",description:"Stop local network containers (preserves state for fast restart)",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"stop",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}},{name:"midnight_localnet_down",description:"Remove local network containers, networks, and volumes (full teardown)",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"down",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}},{name:"midnight_localnet_status",description:"Show local network service status and ports",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"status",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}},{name:"midnight_localnet_clean",description:"Remove conflicting containers from other setups",inputSchema:{type:"object",properties:{}},async handler(){let $={command:"localnet",subcommand:"clean",positionals:[],flags:{json:!0}},Z=await g("localnet");return m(Z,$)}}],L$=new UQ({name:"midnight-wallet-cli",version:S0},{capabilities:{tools:{}}});L$.setRequestHandler(jQ,async()=>{return{tools:q9.map(($)=>({name:$.name,description:$.description,inputSchema:$.inputSchema}))}});L$.setRequestHandler(BQ,async($)=>{let{name:Z,arguments:Q}=$.params,X=q9.find((z)=>z.name===Z);if(!X)return{content:[{type:"text",text:`Unknown tool: ${Z}`}],isError:!0};try{let z=await X.handler(Q??{});return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){let Y=z instanceof Error?z:new Error(String(z)),{errorCode:J}=U2(Y);return{content:[{type:"text",text:JSON.stringify({error:!0,code:J,message:Y.message})}],isError:!0}}});HQ().catch(($)=>{process.stderr.write(`MCP server error: ${$.message}
376
+ `),process.exit(1)})});function j9($){let Z=Math.max(0,Math.min(1,$)),Q=Z2[0].length,X=Math.floor(Z*Q);return Z2.map((z)=>z.slice(0,X).padEnd(Q))}function B9($){let Z=Math.max(0,Math.min(1,$)),Q=Math.floor($*100);if(Z>=1)return Z2;return Z2.map((X,z)=>Array.from(X).map((Y,J)=>{if(Y===" ")return" ";if(Z<=0)return Z1(z+20,J,0);let G=((z+20)*131+J*997)%100/100;return Z>=G?Y:Z1(z+20,J,Q)}).join(""))}function Z1($,Z,Q){let X=($*131+Z*997+Q*7919)%65537/65537;return V9[Math.floor(X*V9.length)]}function W9($){let Z=Math.max(0,Math.min(1,$)),Q=$1.split(`
377
+ `),X=Math.floor($*100);if(Z>=1)return $1;if(Z<=0)return Q.map((z,Y)=>Array.from(z).map((J,G)=>Z1(Y,G,0)).join("")).join(`
378
+ `);return Q.map((z,Y)=>Array.from(z).map((J,G)=>{if(J===" ")return" ";let q=(Y*131+G*997)%100/100;return Z>=q?J:Z1(Y,G,X)}).join("")).join(`
379
+ `)}var $1,Z2,F$,V9;var P$=x(()=>{$1=[" ████████████ "," ███ ███ "," ███ ██ ███ "," ██ ██ "," ██ ██ ██ "," ██ ██ "," ██ ██ ██ "," ██ ██ "," ██ ██ "," ██ ██ "," ██ ██ "," ███ ███ "," ███ ███ "," ████████████ "].join(`
380
+ `),Z2=["█▄ ▄█ █ █▀▄ █▄ █ █ █▀▀ █ █ ▀█▀","█ █ █ █ █ █ █ ██ █ █ █ █▀█ █ ","▀ ▀ ▀ ▀▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ "];F$=[["wallet","Manage named wallets"],["info","Display wallet metadata"],["balance","Check unshielded balance"],["address","Derive address from seed"],["genesis-address","Show genesis address"],["inspect-cost","Display block limits"],["airdrop","Fund from genesis wallet"],["transfer","Send NIGHT tokens"],["dust","Manage dust (fee tokens)"],["config","Manage CLI config"],["cache","Manage wallet cache"],["localnet","Manage local network"],["serve","DApp Connector server"],["status","Network health status"],["help","Show command usage"]],V9=["░","▒","▓","█","·"," "]});function I$($,Z){return new Promise((Q,X)=>{if(Z?.aborted){Q();return}let z=setTimeout(Q,$);Z?.addEventListener("abort",()=>{clearTimeout(z),Q()},{once:!0})})}async function H9($,Z){let X=$1.split(`
381
381
  `),z=X.length,Y=36,J=Math.max(z,Z?.length??0),G=3;if(!R0()){for(let V=0;V<J;V++){let H=(V<z?X[V]:"").padEnd(35),F=Z?.[V]??"";process.stderr.write(H+F+`
382
- `)}return}function q(V,H){for(let F=0;F<J;F++){let D=F<V.length?G1(V[F]):"",P=H[F]??"";if(P)process.stderr.write(D+"\x1B[36G"+P+`\x1B[K
382
+ `)}return}function q(V,H){for(let F=0;F<J;F++){let D=F<V.length?G2(V[F]):"",P=H[F]??"";if(P)process.stderr.write(D+"\x1B[36G"+P+`\x1B[K
383
383
  `);else process.stderr.write(D+`\x1B[K
384
384
  `)}}function K(){process.stderr.write(`\x1B[${J}A`)}for(let V=0;V<=20;V++){if($?.aborted)break;let H=V/20,D=W9(H).split(`
385
- `);if(V>0)K();q(D,[]),await I$(O$,$)}let U=20;for(let V=0;V<=U;V++){if($?.aborted)break;let H=V/U,F=j9(H);K();let D=new Array(J).fill(null);for(let P=0;P<F.length;P++)D[P]=y(G1(F[P]));q(X,D),await I$(O$,$)}let W=12;for(let V=0;V<=W;V++){if($?.aborted)break;let H=V/W,F=B9(H);K();let D=new Array(J).fill(null);for(let P=0;P<F.length;P++)D[P]=y(G1(F[P]));q(X,D),await I$(O$,$)}K();let j=new Array(J).fill(null);if(Z)for(let V=0;V<Z.length;V++)if(V<3)j[V]=y(G1(Z[V]));else j[V]=Z[V];q(X,j)}var O$=80;var L9=x(()=>{P$()});var P9={};e(P9,{default:()=>F9,COMMAND_SPECS:()=>_1});function FQ(){let $=[];for(let Z of Z1)$.push(Z);$.push(""),$.push(y("Commands"));for(let[Z,Q]of F$)$.push(`${t(Z.padEnd(18))}${Q}`);return $.push(""),$.push(B("midnight (or mn) help <command>")),$.push(B("--json flag available on all commands")),$.push(B("midnight help --agent")+B(" AI & MCP reference")),$}function PQ(){process.stderr.write(`
385
+ `);if(V>0)K();q(D,[]),await I$(O$,$)}let U=20;for(let V=0;V<=U;V++){if($?.aborted)break;let H=V/U,F=j9(H);K();let D=new Array(J).fill(null);for(let P=0;P<F.length;P++)D[P]=y(G2(F[P]));q(X,D),await I$(O$,$)}let W=12;for(let V=0;V<=W;V++){if($?.aborted)break;let H=V/W,F=B9(H);K();let D=new Array(J).fill(null);for(let P=0;P<F.length;P++)D[P]=y(G2(F[P]));q(X,D),await I$(O$,$)}K();let j=new Array(J).fill(null);if(Z)for(let V=0;V<Z.length;V++)if(V<3)j[V]=y(G2(Z[V]));else j[V]=Z[V];q(X,j)}var O$=80;var L9=x(()=>{P$()});var P9={};e(P9,{default:()=>F9,COMMAND_SPECS:()=>_2});function FQ(){let $=[];for(let Z of Z2)$.push(Z);$.push(""),$.push(y("Commands"));for(let[Z,Q]of F$)$.push(`${t(Z.padEnd(18))}${Q}`);return $.push(""),$.push(B("midnight (or mn) help <command>")),$.push(B("--json flag available on all commands")),$.push(B("midnight help --agent")+B(" AI & MCP reference")),$}function PQ(){process.stderr.write(`
386
386
  Commands:
387
387
 
388
388
  `);for(let[$,Z]of F$)process.stderr.write(` ${$.padEnd(18)}${Z}
@@ -405,7 +405,7 @@ Commands:
405
405
  `)}if($.examples&&$.examples.length>0){process.stdout.write(D0("Examples:")+`
406
406
  `);for(let Z of $.examples)process.stdout.write(` ${B("$")} ${Z}
407
407
  `);process.stdout.write(`
408
- `)}}function IQ(){let $={cli:{name:t$,version:S0,description:s$,bin:["midnight","mn"]},globalFlags:[{name:"--json",description:"Output structured JSON to stdout (suppresses all stderr)"},{name:"--wallet <name|file>",description:"Wallet name or path"},{name:"--network <name>",description:"Override network (preprod, preview, undeployed)"},{name:"--version, -v",description:"Print CLI version"},{name:"--help, -h",description:"Show help"}],commands:_1.map((Z)=>({name:Z.name,description:Z.description,usage:Z.usage,flags:Z.flags,examples:Z.examples,jsonFields:Z.jsonFields}))};E($)}function _Q(){let $=`
408
+ `)}}function IQ(){let $={cli:{name:t$,version:S0,description:s$,bin:["midnight","mn"]},globalFlags:[{name:"--json",description:"Output structured JSON to stdout (suppresses all stderr)"},{name:"--wallet <name|file>",description:"Wallet name or path"},{name:"--network <name>",description:"Override network (preprod, preview, undeployed)"},{name:"--version, -v",description:"Print CLI version"},{name:"--help, -h",description:"Show help"}],commands:_2.map((Z)=>({name:Z.name,description:Z.description,usage:Z.usage,flags:Z.flags,examples:Z.examples,jsonFields:Z.jsonFields}))};E($)}function _Q(){let $=`
409
409
  MIDNIGHT CLI — AI Agent & MCP Reference
410
410
  ========================================
411
411
 
@@ -432,7 +432,7 @@ for programmatic discovery of CLI capabilities.
432
432
 
433
433
  COMMANDS & JSON SCHEMAS
434
434
  ───────────────────────
435
- ${_1.filter((Z)=>Z.jsonFields).map((Z)=>{let Q=Object.entries(Z.jsonFields).map(([X,z])=>` ${X.padEnd(20)}${z}`).join(`
435
+ ${_2.filter((Z)=>Z.jsonFields).map((Z)=>{let Q=Object.entries(Z.jsonFields).map(([X,z])=>` ${X.padEnd(20)}${z}`).join(`
436
436
  `);return`
437
437
  ${Z.name}
438
438
  ${Z.usage}
@@ -566,22 +566,22 @@ EXAMPLE WORKFLOW
566
566
  # 4. Transfer tokens
567
567
  midnight transfer mn_addr_... 100 --json
568
568
  # → {"txHash":"...","amount":"100","recipient":"mn_addr_...","network":"undeployed"}
569
- `;process.stdout.write($)}async function F9($){if(R($,"agent")){_Q();return}if(R($,"json")){IQ();return}let Z=$.subcommand;if(Z){let X=_1.find((z)=>z.name===Z);if(!X)throw new Error(`Unknown command: "${Z}"
570
- Available commands: ${_1.map((z)=>z.name).join(", ")}`);OQ(X);return}if(!process.stderr.isTTY){PQ();return}let Q=FQ();await H9(void 0,Q)}var _1;var O9=x(()=>{s();L9();P$();v1();_1=[{name:"wallet",description:"Manage named wallets (generate, list, use, info, remove)",usage:"midnight wallet <generate|list|use|info|remove> [args]",flags:["generate <name> Create a new named wallet and set it as active","list Show all wallets with active marker","use <name> Set active wallet","info [name] Show wallet details (active wallet if no name)","remove <name> Delete a wallet (refuses active or last wallet)","","generate flags:","--network <name> Network: preprod, preview, undeployed","--seed <hex> Restore from existing seed (64-char hex)",'--mnemonic "..." Restore from BIP-39 mnemonic (24 words)',"--force Overwrite existing wallet file"],examples:["midnight wallet generate alice --network preprod","midnight wallet list","midnight wallet use alice","midnight wallet info alice","midnight wallet remove bob"],jsonFields:{name:"Wallet name",address:"Wallet address (bech32m)",network:"Network name",active:"Whether this is the active wallet",wallets:"Array of wallet info objects (list only)"}},{name:"generate",description:'(Deprecated — use "midnight wallet generate <name>" instead)',usage:'midnight generate [--network <name>] [--seed <hex>] [--mnemonic "..."] [--output <file>] [--force]',flags:["--network <name> Network: preprod, preview, undeployed","--seed <hex> Restore from existing seed (64-char hex)",'--mnemonic "..." Restore from BIP-39 mnemonic (24 words)',"--output <file> Custom output path (default: ~/.midnight/wallet.json)","--force Overwrite existing wallet file"],examples:["midnight generate --network preprod"],jsonFields:{address:"Generated wallet address (bech32m)",network:"Network name",seed:"Hex-encoded 32-byte seed",mnemonic:"BIP-39 mnemonic (24 words, only if generated or provided)",file:"Path where wallet file was saved",createdAt:"ISO 8601 creation timestamp"}},{name:"info",description:"Display wallet address, network, creation date (no secrets shown)",usage:"midnight info [--wallet <name|file>]",flags:["--wallet <name|file> Wallet name or path"],examples:["midnight info","midnight info --wallet my-wallet.json"],jsonFields:{address:"Wallet address (bech32m)",network:"Network name",createdAt:"ISO 8601 creation timestamp",file:"Wallet file path"}},{name:"balance",description:"Check unshielded balance via GraphQL subscription",usage:"midnight balance [address] [--network <name>] [--indexer-ws <url>]",flags:["<address> Address to check (or reads from wallet file)","--network <name> Override network detection","--indexer-ws <url> Custom indexer WebSocket URL"],examples:["midnight balance","midnight balance mn_addr_preprod1...","midnight balance --network preprod"],jsonFields:{address:"Checked address (bech32m)",network:"Network name",balances:"Object mapping token type to balance string",utxoCount:"Number of UTXOs",txCount:"Number of transactions synced"}},{name:"address",description:"Derive and display an unshielded address from a seed",usage:"midnight address --seed <hex> [--network <name>] [--index <n>]",flags:["--seed <hex> Seed to derive from (required, 64-char hex)","--network <name> Network for address prefix (default: resolved)","--index <n> Key derivation index (default: 0)"],examples:["midnight address --seed 0123456789abcdef... --network preprod","midnight address --seed 0123456789abcdef... --index 1"],jsonFields:{address:"Derived address (bech32m)",network:"Network name",index:"Key derivation index",path:"BIP-44 derivation path"}},{name:"genesis-address",description:"Display the genesis wallet address (seed 0x01) for a network",usage:"midnight genesis-address [--network <name>]",flags:["--network <name> Network for address prefix (default: resolved)"],examples:["midnight genesis-address --network undeployed","midnight genesis-address --network preprod"],jsonFields:{address:"Genesis wallet address (bech32m)",network:"Network name"}},{name:"inspect-cost",description:"Display current block limits derived from LedgerParameters",usage:"midnight inspect-cost",examples:["midnight inspect-cost"],jsonFields:{readTime:"Read time limit (picoseconds)",computeTime:"Compute time limit (picoseconds)",blockUsage:"Block usage limit (bytes)",bytesWritten:"Bytes written limit (bytes)",bytesChurned:"Bytes churned limit (bytes)"}},{name:"airdrop",description:"Fund your wallet from the genesis wallet (undeployed network only)",usage:"midnight airdrop <amount> [--wallet <name|file>] [--no-cache]",flags:["<amount> Amount in NIGHT to airdrop","--wallet <name|file> Wallet name or path","--no-cache Bypass wallet state cache"],examples:["midnight airdrop 1000","midnight airdrop 0.5 --wallet my-wallet.json"],jsonFields:{txHash:"Transaction hash",amount:"Amount airdropped (NIGHT string)",recipient:"Recipient address (bech32m)",network:"Network name"}},{name:"transfer",description:"Send NIGHT tokens to another address",usage:"midnight transfer <to> <amount> [--wallet <name|file>] [--proof-server <url>] [--node <url>] [--indexer-ws <url>] [--no-cache]",flags:["<to> Recipient bech32m address","<amount> Amount in NIGHT to send","--wallet <name|file> Wallet name or path","--proof-server <url> Override proof server URL","--node <url> Override substrate node RPC URL","--indexer-ws <url> Override indexer WebSocket URL","--no-cache Bypass wallet state cache"],examples:["midnight transfer mn_addr_undeployed1... 100","midnight transfer mn_addr_preprod1... 50 --wallet my-wallet.json"],jsonFields:{txHash:"Transaction hash",amount:"Amount transferred (NIGHT string)",recipient:"Recipient address (bech32m)",network:"Network name"}},{name:"dust",description:"Register UTXOs for dust (fee token) generation or check status",usage:"midnight dust <register|status> [--wallet <name|file>] [--proof-server <url>] [--node <url>] [--indexer-ws <url>] [--no-cache]",flags:["register Register NIGHT UTXOs for dust generation","status Check dust registration status and balance","--wallet <name|file> Wallet name or path","--proof-server <url> Override proof server URL","--node <url> Override substrate node RPC URL","--indexer-ws <url> Override indexer WebSocket URL","--no-cache Bypass wallet state cache"],examples:["midnight dust register","midnight dust status"],jsonFields:{subcommand:"register or status",dustBalance:"Dust balance (raw bigint string)",registered:"Number of registered UTXOs (status only)",unregistered:"Number of unregistered UTXOs (status only)",nightBalance:"NIGHT balance (raw bigint string, status only)",dustAvailable:"Whether dust tokens are available (status only)",txHash:"Registration transaction hash (register only, if submitted)"}},{name:"config",description:"Manage persistent config (default network, endpoints, etc.)",usage:"midnight config <get|set|unset> <key> [value]",flags:["get <key> Read a config value","set <key> <value> Write a config value","unset <key> Reset a config value to its default","","Keys: network, wallet, proof-server, node, indexer-ws"],examples:["midnight config get network","midnight config set network preprod","midnight config set wallet alice","midnight config set proof-server http://localhost:6300","midnight config set node wss://rpc.preprod.midnight.network","midnight config set indexer-ws wss://indexer.preprod.midnight.network/api/v3/graphql/ws","midnight config unset proof-server"],jsonFields:{action:"get, set, or unset",key:"Config key name",value:"Config value"}},{name:"cache",description:"Manage wallet state cache (clear cached sync data)",usage:"midnight cache clear [--network <name>] [--wallet <name|file>]",flags:["clear Clear cached wallet state","--network <name> Only clear cache for this network","--wallet <name|file> Only clear cache for this wallet"],examples:["midnight cache clear","midnight cache clear --network preprod","midnight cache clear --wallet alice"],jsonFields:{action:"clear",scope:"all, network, or wallet",network:"Network name (when scoped)",wallet:"Wallet name (when scoped)"}},{name:"serve",description:"Start DApp Connector server over WebSocket JSON-RPC",usage:"midnight serve [--port <n>] [--wallet <name|file>] [--network <name>] [--proof-server <url>] [--node <url>] [--indexer-ws <url>] [--approve-all] [--no-auto-approve-reads] [--no-cache] [--json]",flags:["--port <n> Server port (default: 9932)","--wallet <name|file> Wallet name or path","--network <name> Override network detection","--proof-server <url> Override proof server URL","--node <url> Override substrate node RPC URL","--indexer-ws <url> Override indexer WebSocket URL","--approve-all Auto-approve all requests (reads + writes)","--no-auto-approve-reads Prompt for read methods too","--no-cache Bypass wallet state cache"],examples:["midnight serve","midnight serve --port 8080","midnight serve --approve-all"],jsonFields:{port:"Server port number",network:"Network name",address:"Wallet address (bech32m)",status:"Server status (listening)"}},{name:"localnet",description:"Manage a local Midnight network via Docker Compose",usage:"midnight localnet <up|stop|down|status|logs|clean>",flags:["up Start the local network (node, indexer, proof server)","stop Stop containers (preserves state for fast restart)","down Remove containers, networks, and volumes (full teardown)","status Show service status and ports","logs Stream service logs (Ctrl+C to stop)","clean Remove conflicting containers from other setups"],examples:["midnight localnet up","midnight localnet stop","midnight localnet status","midnight localnet down","midnight localnet clean"],jsonFields:{subcommand:"up, stop, down, status, or clean",services:"Array of { name, state, port, health? } (up/status only)",status:"Operation result message (stop/down/clean)",removed:"Array of removed container names (clean only)"}},{name:"help",description:"Show usage for all commands or a specific command",usage:"midnight help [command]",examples:["midnight help","midnight help balance"],jsonFields:{cli:"CLI metadata (name, version, description)",globalFlags:"Array of global flag descriptions",commands:"Array of command specs with jsonFields"}}]});import*as I9 from"node:readline";function RQ($){return TQ.has($)}function DQ($){return MQ.has($)}function AQ($){let Z=[],Q=$.dappName?`Request from "${$.dappName}"`:"DApp Request";if(Z.push(y(Q)),Z.push(""),Z.push(` ${B("Action:")} ${t($.method)}`),Z.push(` ${B("Network:")} ${$.network}`),$.details.length>0){Z.push("");for(let X of $.details)Z.push(` ${B(X.label+":")} ${X.value}`)}return Z.push(""),Z.push(` ${u("[A]pprove")} ${c("[R]eject")}`),W2(Z,"heavy")}async function _9($,Z={}){if(Z.approveAll)return process.stderr.write(B(` Auto-approved: ${$.method}`)+`
569
+ `;process.stdout.write($)}async function F9($){if(R($,"agent")){_Q();return}if(R($,"json")){IQ();return}let Z=$.subcommand;if(Z){let X=_2.find((z)=>z.name===Z);if(!X)throw new Error(`Unknown command: "${Z}"
570
+ Available commands: ${_2.map((z)=>z.name).join(", ")}`);OQ(X);return}if(!process.stderr.isTTY){PQ();return}let Q=FQ();await H9(void 0,Q)}var _2;var O9=x(()=>{s();L9();P$();v2();_2=[{name:"wallet",description:"Manage named wallets (generate, list, use, info, remove)",usage:"midnight wallet <generate|list|use|info|remove> [args]",flags:["generate <name> Create a new named wallet and set it as active","list Show all wallets with active marker","use <name> Set active wallet","info [name] Show wallet details (active wallet if no name)","remove <name> Delete a wallet (refuses active or last wallet)","","generate flags:","--network <name> Network: preprod, preview, undeployed","--seed <hex> Restore from existing seed (64-char hex)",'--mnemonic "..." Restore from BIP-39 mnemonic (24 words)',"--force Overwrite existing wallet file"],examples:["midnight wallet generate alice --network preprod","midnight wallet list","midnight wallet use alice","midnight wallet info alice","midnight wallet remove bob"],jsonFields:{name:"Wallet name",address:"Wallet address (bech32m)",network:"Network name",active:"Whether this is the active wallet",wallets:"Array of wallet info objects (list only)"}},{name:"generate",description:'(Deprecated — use "midnight wallet generate <name>" instead)',usage:'midnight generate [--network <name>] [--seed <hex>] [--mnemonic "..."] [--output <file>] [--force]',flags:["--network <name> Network: preprod, preview, undeployed","--seed <hex> Restore from existing seed (64-char hex)",'--mnemonic "..." Restore from BIP-39 mnemonic (24 words)',"--output <file> Custom output path (default: ~/.midnight/wallet.json)","--force Overwrite existing wallet file"],examples:["midnight generate --network preprod"],jsonFields:{address:"Generated wallet address (bech32m)",network:"Network name",seed:"Hex-encoded 32-byte seed",mnemonic:"BIP-39 mnemonic (24 words, only if generated or provided)",file:"Path where wallet file was saved",createdAt:"ISO 8601 creation timestamp"}},{name:"info",description:"Display wallet address, network, creation date (no secrets shown)",usage:"midnight info [--wallet <name|file>]",flags:["--wallet <name|file> Wallet name or path"],examples:["midnight info","midnight info --wallet my-wallet.json"],jsonFields:{address:"Wallet address (bech32m)",network:"Network name",createdAt:"ISO 8601 creation timestamp",file:"Wallet file path"}},{name:"balance",description:"Check unshielded balance via GraphQL subscription",usage:"midnight balance [address] [--network <name>] [--indexer-ws <url>]",flags:["<address> Address to check (or reads from wallet file)","--network <name> Override network detection","--indexer-ws <url> Custom indexer WebSocket URL"],examples:["midnight balance","midnight balance mn_addr_preprod1...","midnight balance --network preprod"],jsonFields:{address:"Checked address (bech32m)",network:"Network name",balances:"Object mapping token type to balance string",utxoCount:"Number of UTXOs",txCount:"Number of transactions synced"}},{name:"address",description:"Derive and display an unshielded address from a seed",usage:"midnight address --seed <hex> [--network <name>] [--index <n>]",flags:["--seed <hex> Seed to derive from (required, 64-char hex)","--network <name> Network for address prefix (default: resolved)","--index <n> Key derivation index (default: 0)"],examples:["midnight address --seed 0123456789abcdef... --network preprod","midnight address --seed 0123456789abcdef... --index 1"],jsonFields:{address:"Derived address (bech32m)",network:"Network name",index:"Key derivation index",path:"BIP-44 derivation path"}},{name:"genesis-address",description:"Display the genesis wallet address (seed 0x01) for a network",usage:"midnight genesis-address [--network <name>]",flags:["--network <name> Network for address prefix (default: resolved)"],examples:["midnight genesis-address --network undeployed","midnight genesis-address --network preprod"],jsonFields:{address:"Genesis wallet address (bech32m)",network:"Network name"}},{name:"inspect-cost",description:"Display current block limits derived from LedgerParameters",usage:"midnight inspect-cost",examples:["midnight inspect-cost"],jsonFields:{readTime:"Read time limit (picoseconds)",computeTime:"Compute time limit (picoseconds)",blockUsage:"Block usage limit (bytes)",bytesWritten:"Bytes written limit (bytes)",bytesChurned:"Bytes churned limit (bytes)"}},{name:"airdrop",description:"Fund your wallet from the genesis wallet (undeployed network only)",usage:"midnight airdrop <amount> [--wallet <name|file>] [--no-cache]",flags:["<amount> Amount in NIGHT to airdrop","--wallet <name|file> Wallet name or path","--no-cache Bypass wallet state cache"],examples:["midnight airdrop 1000","midnight airdrop 0.5 --wallet my-wallet.json"],jsonFields:{txHash:"Transaction hash",amount:"Amount airdropped (NIGHT string)",recipient:"Recipient address (bech32m)",network:"Network name"}},{name:"transfer",description:"Send NIGHT tokens to another address",usage:"midnight transfer <to> <amount> [--wallet <name|file>] [--proof-server <url>] [--node <url>] [--indexer-ws <url>] [--no-cache]",flags:["<to> Recipient bech32m address","<amount> Amount in NIGHT to send","--wallet <name|file> Wallet name or path","--proof-server <url> Override proof server URL","--node <url> Override substrate node RPC URL","--indexer-ws <url> Override indexer WebSocket URL","--no-cache Bypass wallet state cache"],examples:["midnight transfer mn_addr_undeployed1... 100","midnight transfer mn_addr_preprod1... 50 --wallet my-wallet.json"],jsonFields:{txHash:"Transaction hash",amount:"Amount transferred (NIGHT string)",recipient:"Recipient address (bech32m)",network:"Network name"}},{name:"dust",description:"Register UTXOs for dust (fee token) generation or check status",usage:"midnight dust <register|status> [--wallet <name|file>] [--proof-server <url>] [--node <url>] [--indexer-ws <url>] [--no-cache]",flags:["register Register NIGHT UTXOs for dust generation","status Check dust registration status and balance","--wallet <name|file> Wallet name or path","--proof-server <url> Override proof server URL","--node <url> Override substrate node RPC URL","--indexer-ws <url> Override indexer WebSocket URL","--no-cache Bypass wallet state cache"],examples:["midnight dust register","midnight dust status"],jsonFields:{subcommand:"register or status",dustBalance:"Dust balance (raw bigint string)",registered:"Number of registered UTXOs (status only)",unregistered:"Number of unregistered UTXOs (status only)",nightBalance:"NIGHT balance (raw bigint string, status only)",dustAvailable:"Whether dust tokens are available (status only)",txHash:"Registration transaction hash (register only, if submitted)"}},{name:"config",description:"Manage persistent config (default network, endpoints, etc.)",usage:"midnight config <get|set|unset> <key> [value]",flags:["get <key> Read a config value","set <key> <value> Write a config value","unset <key> Reset a config value to its default","","Keys: network, wallet, proof-server, node, indexer-ws"],examples:["midnight config get network","midnight config set network preprod","midnight config set wallet alice","midnight config set proof-server http://localhost:6300","midnight config set node wss://rpc.preprod.midnight.network","midnight config set indexer-ws wss://indexer.preprod.midnight.network/api/v3/graphql/ws","midnight config unset proof-server"],jsonFields:{action:"get, set, or unset",key:"Config key name",value:"Config value"}},{name:"cache",description:"Manage wallet state cache (clear cached sync data)",usage:"midnight cache clear [--network <name>] [--wallet <name|file>]",flags:["clear Clear cached wallet state","--network <name> Only clear cache for this network","--wallet <name|file> Only clear cache for this wallet"],examples:["midnight cache clear","midnight cache clear --network preprod","midnight cache clear --wallet alice"],jsonFields:{action:"clear",scope:"all, network, or wallet",network:"Network name (when scoped)",wallet:"Wallet name (when scoped)"}},{name:"serve",description:"Start DApp Connector server over WebSocket JSON-RPC",usage:"midnight serve [--port <n>] [--wallet <name|file>] [--network <name>] [--proof-server <url>] [--node <url>] [--indexer-ws <url>] [--approve-all] [--no-auto-approve-reads] [--no-cache] [--json]",flags:["--port <n> Server port (default: 9932)","--wallet <name|file> Wallet name or path","--network <name> Override network detection","--proof-server <url> Override proof server URL","--node <url> Override substrate node RPC URL","--indexer-ws <url> Override indexer WebSocket URL","--approve-all Auto-approve all requests (reads + writes)","--no-auto-approve-reads Prompt for read methods too","--no-cache Bypass wallet state cache"],examples:["midnight serve","midnight serve --port 8080","midnight serve --approve-all"],jsonFields:{port:"Server port number",network:"Network name",address:"Wallet address (bech32m)",status:"Server status (listening)"}},{name:"localnet",description:"Manage a local Midnight network via Docker Compose",usage:"midnight localnet <up|stop|down|status|logs|clean>",flags:["up Start the local network (node, indexer, proof server)","stop Stop containers (preserves state for fast restart)","down Remove containers, networks, and volumes (full teardown)","status Show service status and ports","logs Stream service logs (Ctrl+C to stop)","clean Remove conflicting containers from other setups"],examples:["midnight localnet up","midnight localnet stop","midnight localnet status","midnight localnet down","midnight localnet clean"],jsonFields:{subcommand:"up, stop, down, status, or clean",services:"Array of { name, state, port, health? } (up/status only)",status:"Operation result message (stop/down/clean)",removed:"Array of removed container names (clean only)"}},{name:"help",description:"Show usage for all commands or a specific command",usage:"midnight help [command]",examples:["midnight help","midnight help balance"],jsonFields:{cli:"CLI metadata (name, version, description)",globalFlags:"Array of global flag descriptions",commands:"Array of command specs with jsonFields"}}]});import*as I9 from"node:readline";function RQ($){return TQ.has($)}function DQ($){return MQ.has($)}function AQ($){let Z=[],Q=$.dappName?`Request from "${$.dappName}"`:"DApp Request";if(Z.push(y(Q)),Z.push(""),Z.push(` ${B("Action:")} ${t($.method)}`),Z.push(` ${B("Network:")} ${$.network}`),$.details.length>0){Z.push("");for(let X of $.details)Z.push(` ${B(X.label+":")} ${X.value}`)}return Z.push(""),Z.push(` ${u("[A]pprove")} ${c("[R]eject")}`),W1(Z,"heavy")}async function _9($,Z={}){if(Z.approveAll)return process.stderr.write(B(` Auto-approved: ${$.method}`)+`
571
571
  `),"approve";if(Z.autoApproveReads&&RQ($.method))return process.stderr.write(B(` Auto-approved (read-only): ${$.method}`)+`
572
572
  `),"approve";if(Z.autoApproveReads&&DQ($.method))return process.stderr.write(B(` Auto-approved (prep): ${$.method}`)+`
573
573
  `),"approve";if(!process.stdin.isTTY)return process.stderr.write(c(" Cannot prompt for approval: stdin is not a TTY")+`
574
574
  `),process.stderr.write(B(" Use --approve-all for non-interactive environments")+`
575
- `),"reject";if(T1)return process.stderr.write(c(" Rejected: another approval prompt is active")+`
575
+ `),"reject";if(T2)return process.stderr.write(c(" Rejected: another approval prompt is active")+`
576
576
  `),"reject";process.stderr.write(`
577
577
  `+AQ($)+`
578
578
 
579
- `),T1=!0;let Q;try{Q=I9.createInterface({input:process.stdin,output:process.stderr})}catch{return T1=!1,process.stderr.write(c(" Cannot create readline interface")+`
580
- `),"reject"}return new Promise((X)=>{let z=(Y)=>{T1=!1,Q.close(),X(Y)};Q.on("close",()=>{if(T1)z("reject")}),Q.question(O0(" Approve? [A/r] "),(Y)=>{let J=Y.trim().toLowerCase();if(J==="r"||J==="reject")z("reject");else z("approve")})})}var TQ,MQ,T1=!1;var T9=x(()=>{s();TQ=new Set(["getShieldedBalances","getUnshieldedBalances","getDustBalance","getShieldedAddresses","getUnshieldedAddress","getDustAddress","getTxHistory","getConfiguration","getConnectionStatus"]),MQ=new Set(["balanceUnsealedTransaction","balanceSealedTransaction"])});import{WebSocketServer as NQ}from"ws";function CQ($){if(_$($))return EQ[$.code]??-32603;return-32603}function _$($){return typeof $==="object"&&$!==null&&"type"in $&&$.type==="DAppConnectorAPIError"}function xQ($){if(!($ instanceof Error)&&!(typeof $==="object"&&$!==null&&("_tag"in $)))return;let Z=[],Q=$.cause,X=new Set;while(Q&&!X.has(Q)){X.add(Q);let z=Q;if(Q instanceof Error||typeof Q==="object"&&z._tag){let Y=z._tag,J=z.message??"";Z.push(Y?`[${Y}] ${J}`:J),Q=z.cause}else if(typeof Q==="string"){Z.push(Q);break}else{try{Z.push(JSON.stringify(Q))}catch{Z.push(String(Q))}break}}if(Z.length===0)return;return{causes:Z}}function Q2($,Z){if(typeof Z==="bigint")return Z.toString();return Z}function yQ($,Z){return Z}function bQ($){let Z;try{Z=JSON.parse($,yQ)}catch{throw Object.assign(new Error("Parse error"),{rpcCode:-32700})}if(typeof Z!=="object"||Z===null||Z.jsonrpc!=="2.0"||typeof Z.method!=="string")throw Object.assign(new Error("Invalid Request"),{rpcCode:-32600});let Q=Z;if(Q.id===void 0||Q.id===null)throw Object.assign(new Error("Missing request id"),{rpcCode:-32600});return Q}function M9($){let{port:Z,handlers:Q,onConnect:X,onDisconnect:z,onRequest:Y,onResponse:J}=$,G=new Map,q=new NQ({port:Z,host:"127.0.0.1"});q.on("error",(U)=>{process.stderr.write(`WebSocket server error: ${U.message}
581
- `)}),q.on("connection",(U)=>{let W=`conn_${++SQ}`,j={ws:U,id:W,connectedAt:new Date,authenticated:!1,requestCount:0,notify(F,D){if(U.readyState!==U.OPEN)return;let P={jsonrpc:"2.0",method:F,...D&&{params:D}};U.send(JSON.stringify(P,Q2))}};G.set(W,j),X?.(j);let V=!1,H=()=>{if(V)return;V=!0,G.delete(W),z?.(j)};U.on("message",async(F)=>{let D=null,P,M,C=Date.now();try{P=bQ(F.toString("utf-8")),D=P.id,j.requestCount++,Y?.(j,P);let A=Q[P.method];if(!A){let B0={jsonrpc:"2.0",id:P.id,error:{code:-32601,message:`Method not found: ${P.method}`}};U.send(JSON.stringify(B0,Q2));return}M={notify:j.notify.bind(j),connectionId:W,requestId:P.id,metadata:{}};let k=await A(P.params??{},M),$0=Date.now()-C;if(P.method==="connect"&&k&&typeof k==="object")j.authenticated=!0,j.networkId=k.networkId;let n={jsonrpc:"2.0",id:P.id,result:k};U.send(JSON.stringify(n,Q2)),J?.(j,P,$0,k,void 0,M.metadata)}catch(A){let k=Date.now()-C,$0=A?.rpcCode??CQ(A),n=A instanceof Error?A.message:"Internal error",B0=_$(A)?{type:A.type,code:A.code}:xQ(A),z0={jsonrpc:"2.0",id:D,error:{code:$0,message:n,data:B0}};if(U.send(JSON.stringify(z0,Q2)),P){let L0={message:n,code:_$(A)?A.code:void 0};J?.(j,P,k,void 0,L0,M?.metadata)}}}),U.on("close",H),U.on("error",()=>{H();try{U.close()}catch{}})});async function K(){for(let U of G.values())U.ws.close(1001,"Server shutting down");return G.clear(),new Promise((U,W)=>{q.close((j)=>{if(j)W(j);else U()})})}return{wss:q,connections:G,close:K}}function q0($,Z){let Q=new Error(Z);return Q.type="DAppConnectorAPIError",Q.code=$,Q.reason=Z,Q}var EQ,SQ=0;var T$=x(()=>{EQ={Rejected:-32000,PermissionRejected:-32001,Disconnected:-32002,InvalidRequest:-32602,InternalError:-32603}});function R9($){let Z=[],Q,X;function z(){if(Q!==void 0&&X!==void 0){let G=Date.now()-X;Z.push({phase:Q,durationMs:G}),$?.onComplete?.(Q,G),Q=void 0,X=void 0}}function Y(G){z(),Q=G,X=Date.now(),$?.onStart?.(G)}function J(){return[...Z]}return{start:Y,complete:z,getTimings:J}}import{Transaction as D9}from"@midnight-ntwrk/ledger-v7";function wQ($){return Buffer.from($).toString("hex")}function X2($){if(!/^[0-9a-fA-F]*$/.test($))throw new Error("Invalid hex string: contains non-hex characters");if($.length%2!==0)throw new Error("Invalid hex string: odd length");return new Uint8Array(Buffer.from($,"hex"))}function E9($){return wQ($.serialize())}function C9($){return D9.deserialize(A9,N9,kQ,X2($))}function M$($){return D9.deserialize(A9,N9,vQ,X2($))}var A9="signature",N9="proof",vQ="binding",kQ="pre-binding";var x9=()=>{};import{Transaction as fQ}from"@midnight-ntwrk/ledger-v7";function z2($,Z){let Q=[];Q.push({label:"Tx size",value:mQ($.length/2)});let X=hQ($,Z);if(X){let z=pQ(X);if(z.action)Q.push({label:"Type",value:z.action});if(z.circuits.length>0)Q.push({label:"Circuits",value:z.circuits.join(", ")});if(z.ttl)Q.push({label:"TTL",value:z.ttl})}return Q}function hQ($,Z){let Q=uQ($),X=Z==="sealed"?[["signature","proof","binding"],["signature","proof","pre-binding"]]:[["signature","proof","pre-binding"],["signature","pre-proof","pre-binding"]];for(let[z,Y,J]of X)try{return fQ.deserialize(z,Y,J,Q).toString(!0)}catch{}return null}function pQ($){let Z={networkId:null,action:null,circuits:[],ttl:null},Q=$.match(/network_id:\s*"([^"]+)"/);if(Q)Z.networkId=Q[1];if($.includes("Deploy ContractState"))Z.action="Deploy contract";else if($.match(/Call\s/))Z.action="Call contract";let X=/(\w+):\s*<verifier key>/g,z;while((z=X.exec($))!==null)Z.circuits.push(z[1]);if(Z.circuits.length===0){let J=$.match(/Call\s+\S+\s+(\w+)/);if(J)Z.circuits.push(J[1])}let Y=$.match(/ttl:\s*Timestamp\((\d+)\)/);if(Y){let J=parseInt(Y[1],10),G=new Date(J*1000);Z.ttl=G.toISOString().replace("T"," ").slice(0,19)}return Z}function uQ($){return new Uint8Array(Buffer.from($,"hex"))}function mQ($){if($<1024)return`${$} B`;let Z=$/1024;if(Z<1024)return`${Z.toFixed(1)} KB`;return`${(Z/1024).toFixed(1)} MB`}var y9=()=>{};import{DustLocalState as gQ}from"@midnight-ntwrk/ledger-v7";import{CoreWallet as H0}from"@midnight-ntwrk/wallet-sdk-dust-wallet/v1";var c0,cQ,dQ,X8;var b9=x(()=>{c0=new Map,cQ=H0.applyEvents;H0.applyEvents=function $(Z,Q,X,z){let Y=cQ.call(H0,Z,Q,X,z);if(c0.size>0&&Y?.pendingDust){let J=new Set(Y.pendingDust.map((G)=>G.nullifier));for(let G of c0.keys())if(!J.has(G))c0.delete(G)}return Y};dQ=H0.spendCoins;H0.spendCoins=function $(Z,Q,X,z){let Y=null;try{Y=Z.state.serialize()}catch{}let J=dQ.call(H0,Z,Q,X,z),G=J[1]??J;if(Y&&G?.pendingDust){for(let q of G.pendingDust)if(!c0.has(q.nullifier))c0.set(q.nullifier,Y)}return J};X8=H0.revertTransaction;H0.revertTransaction=function $(Z,Q){let X=H0.pendingDustToMap(Z.pendingDust),z=[],Y=Q.intents;if(Y)for(let G of Y.values()){let q=G.dustActions?.spends;if(!q)continue;for(let K of q)if(X.has(K.oldNullifier))z.push(K.oldNullifier)}let J=Z.state;for(let G of z){let q=c0.get(G);if(q){try{J=gQ.deserialize(q)}catch{}c0.delete(G)}}return{...Z,state:J,pendingDust:Z.pendingDust.filter((G)=>!z.includes(G.nullifier))}};H0.applyFailed=H0.revertTransaction});import*as d0 from"rxjs";import{MidnightBech32m as R$,UnshieldedAddress as lQ,ShieldedAddress as iQ}from"@midnight-ntwrk/wallet-sdk-address-format";import{NetworkId as D$}from"@midnight-ntwrk/wallet-sdk-abstractions";function nQ($){let Z=[],Q=$,X=new Set;while(Q&&!X.has(Q)){X.add(Q);let Y=Q;if(Q instanceof Error||typeof Q==="object"&&Y._tag){let J=Y._tag,G=Y.message??"";if(J&&G)Z.push(`[${J}] ${G}`);else if(G)Z.push(G);else if(J)Z.push(`[${J}]`);if(Y.data&&typeof Y.data==="object")try{Z.push(`data=${JSON.stringify(Y.data)}`)}catch{}Q=Y.cause}else if(typeof Q==="string"){Z.push(Q);break}else{try{let J=JSON.stringify(Q);if(J&&J!=="{}")Z.push(J);else Z.push(String(Q))}catch{Z.push(String(Q))}break}}let z=[];for(let Y of Z)if(z.length===0||z[z.length-1]!==Y)z.push(Y);return z.join(" → ")||"Unknown error"}function S9($){let{bundle:Z,networkConfig:Q,approvalOptions:X,callbacks:z}=$,{facade:Y,keystore:J,zswapSecretKeys:G,dustSecretKey:q}=Z,K=oQ[Q.networkId];if(K===void 0)throw new Error(`Unknown networkId: ${Q.networkId}`);let U,W=Y.state().pipe(d0.filter((I)=>I.isSynced)).subscribe((I)=>{U=I});function j(){if(!U)throw q0("Disconnected","Wallet not synced yet");return U}let V={shieldedSecretKeys:G,dustSecretKey:q},H=new Map;function F(I,L,O){let _=H.get(I);if(!_)_=new Map,H.set(I,_);let b=setTimeout(async()=>{if(_.delete(L),_.size===0)H.delete(I);try{await Y.revert(O)}catch{}process.stderr.write(B(` abandoned tx reverted (${I})`)+`
579
+ `),T2=!0;let Q;try{Q=I9.createInterface({input:process.stdin,output:process.stderr})}catch{return T2=!1,process.stderr.write(c(" Cannot create readline interface")+`
580
+ `),"reject"}return new Promise((X)=>{let z=(Y)=>{T2=!1,Q.close(),X(Y)};Q.on("close",()=>{if(T2)z("reject")}),Q.question(O0(" Approve? [A/r] "),(Y)=>{let J=Y.trim().toLowerCase();if(J==="r"||J==="reject")z("reject");else z("approve")})})}var TQ,MQ,T2=!1;var T9=x(()=>{s();TQ=new Set(["getShieldedBalances","getUnshieldedBalances","getDustBalance","getShieldedAddresses","getUnshieldedAddress","getDustAddress","getTxHistory","getConfiguration","getConnectionStatus"]),MQ=new Set(["balanceUnsealedTransaction","balanceSealedTransaction"])});import{WebSocketServer as NQ}from"ws";function CQ($){if(_$($))return EQ[$.code]??-32603;return-32603}function _$($){return typeof $==="object"&&$!==null&&"type"in $&&$.type==="DAppConnectorAPIError"}function xQ($){if(!($ instanceof Error)&&!(typeof $==="object"&&$!==null&&("_tag"in $)))return;let Z=[],Q=$.cause,X=new Set;while(Q&&!X.has(Q)){X.add(Q);let z=Q;if(Q instanceof Error||typeof Q==="object"&&z._tag){let Y=z._tag,J=z.message??"";Z.push(Y?`[${Y}] ${J}`:J),Q=z.cause}else if(typeof Q==="string"){Z.push(Q);break}else{try{Z.push(JSON.stringify(Q))}catch{Z.push(String(Q))}break}}if(Z.length===0)return;return{causes:Z}}function Q1($,Z){if(typeof Z==="bigint")return Z.toString();return Z}function yQ($,Z){return Z}function bQ($){let Z;try{Z=JSON.parse($,yQ)}catch{throw Object.assign(new Error("Parse error"),{rpcCode:-32700})}if(typeof Z!=="object"||Z===null||Z.jsonrpc!=="2.0"||typeof Z.method!=="string")throw Object.assign(new Error("Invalid Request"),{rpcCode:-32600});let Q=Z;if(Q.id===void 0||Q.id===null)throw Object.assign(new Error("Missing request id"),{rpcCode:-32600});return Q}function M9($){let{port:Z,handlers:Q,onConnect:X,onDisconnect:z,onRequest:Y,onResponse:J}=$,G=new Map,q=new NQ({port:Z,host:"127.0.0.1"});q.on("error",(U)=>{process.stderr.write(`WebSocket server error: ${U.message}
581
+ `)}),q.on("connection",(U)=>{let W=`conn_${++SQ}`,j={ws:U,id:W,connectedAt:new Date,authenticated:!1,requestCount:0,notify(F,D){if(U.readyState!==U.OPEN)return;let P={jsonrpc:"2.0",method:F,...D&&{params:D}};U.send(JSON.stringify(P,Q1))}};G.set(W,j),X?.(j);let V=!1,H=()=>{if(V)return;V=!0,G.delete(W),z?.(j)};U.on("message",async(F)=>{let D=null,P,M,C=Date.now();try{P=bQ(F.toString("utf-8")),D=P.id,j.requestCount++,Y?.(j,P);let A=Q[P.method];if(!A){let B0={jsonrpc:"2.0",id:P.id,error:{code:-32601,message:`Method not found: ${P.method}`}};U.send(JSON.stringify(B0,Q1));return}M={notify:j.notify.bind(j),connectionId:W,requestId:P.id,metadata:{}};let k=await A(P.params??{},M),$0=Date.now()-C;if(P.method==="connect"&&k&&typeof k==="object")j.authenticated=!0,j.networkId=k.networkId;let n={jsonrpc:"2.0",id:P.id,result:k};U.send(JSON.stringify(n,Q1)),J?.(j,P,$0,k,void 0,M.metadata)}catch(A){let k=Date.now()-C,$0=A?.rpcCode??CQ(A),n=A instanceof Error?A.message:"Internal error",B0=_$(A)?{type:A.type,code:A.code}:xQ(A),z0={jsonrpc:"2.0",id:D,error:{code:$0,message:n,data:B0}};if(U.send(JSON.stringify(z0,Q1)),P){let L0={message:n,code:_$(A)?A.code:void 0};J?.(j,P,k,void 0,L0,M?.metadata)}}}),U.on("close",H),U.on("error",()=>{H();try{U.close()}catch{}})});async function K(){for(let U of G.values())U.ws.close(1001,"Server shutting down");return G.clear(),new Promise((U,W)=>{q.close((j)=>{if(j)W(j);else U()})})}return{wss:q,connections:G,close:K}}function q0($,Z){let Q=new Error(Z);return Q.type="DAppConnectorAPIError",Q.code=$,Q.reason=Z,Q}var EQ,SQ=0;var T$=x(()=>{EQ={Rejected:-32000,PermissionRejected:-32001,Disconnected:-32002,InvalidRequest:-32602,InternalError:-32603}});function R9($){let Z=[],Q,X;function z(){if(Q!==void 0&&X!==void 0){let G=Date.now()-X;Z.push({phase:Q,durationMs:G}),$?.onComplete?.(Q,G),Q=void 0,X=void 0}}function Y(G){z(),Q=G,X=Date.now(),$?.onStart?.(G)}function J(){return[...Z]}return{start:Y,complete:z,getTimings:J}}import{Transaction as D9}from"@midnight-ntwrk/ledger-v7";function wQ($){return Buffer.from($).toString("hex")}function X1($){if(!/^[0-9a-fA-F]*$/.test($))throw new Error("Invalid hex string: contains non-hex characters");if($.length%2!==0)throw new Error("Invalid hex string: odd length");return new Uint8Array(Buffer.from($,"hex"))}function E9($){return wQ($.serialize())}function C9($){return D9.deserialize(A9,N9,kQ,X1($))}function M$($){return D9.deserialize(A9,N9,vQ,X1($))}var A9="signature",N9="proof",vQ="binding",kQ="pre-binding";var x9=()=>{};import{Transaction as fQ}from"@midnight-ntwrk/ledger-v7";function z1($,Z){let Q=[];Q.push({label:"Tx size",value:mQ($.length/2)});let X=hQ($,Z);if(X){let z=pQ(X);if(z.action)Q.push({label:"Type",value:z.action});if(z.circuits.length>0)Q.push({label:"Circuits",value:z.circuits.join(", ")});if(z.ttl)Q.push({label:"TTL",value:z.ttl})}return Q}function hQ($,Z){let Q=uQ($),X=Z==="sealed"?[["signature","proof","binding"],["signature","proof","pre-binding"]]:[["signature","proof","pre-binding"],["signature","pre-proof","pre-binding"]];for(let[z,Y,J]of X)try{return fQ.deserialize(z,Y,J,Q).toString(!0)}catch{}return null}function pQ($){let Z={networkId:null,action:null,circuits:[],ttl:null},Q=$.match(/network_id:\s*"([^"]+)"/);if(Q)Z.networkId=Q[1];if($.includes("Deploy ContractState"))Z.action="Deploy contract";else if($.match(/Call\s/))Z.action="Call contract";let X=/(\w+):\s*<verifier key>/g,z;while((z=X.exec($))!==null)Z.circuits.push(z[1]);if(Z.circuits.length===0){let J=$.match(/Call\s+\S+\s+(\w+)/);if(J)Z.circuits.push(J[1])}let Y=$.match(/ttl:\s*Timestamp\((\d+)\)/);if(Y){let J=parseInt(Y[1],10),G=new Date(J*1000);Z.ttl=G.toISOString().replace("T"," ").slice(0,19)}return Z}function uQ($){return new Uint8Array(Buffer.from($,"hex"))}function mQ($){if($<1024)return`${$} B`;let Z=$/1024;if(Z<1024)return`${Z.toFixed(1)} KB`;return`${(Z/1024).toFixed(1)} MB`}var y9=()=>{};import{DustLocalState as gQ}from"@midnight-ntwrk/ledger-v7";import{CoreWallet as H0}from"@midnight-ntwrk/wallet-sdk-dust-wallet/v1";var c0,cQ,dQ,X8;var b9=x(()=>{c0=new Map,cQ=H0.applyEvents;H0.applyEvents=function $(Z,Q,X,z){let Y=cQ.call(H0,Z,Q,X,z);if(c0.size>0&&Y?.pendingDust){let J=new Set(Y.pendingDust.map((G)=>G.nullifier));for(let G of c0.keys())if(!J.has(G))c0.delete(G)}return Y};dQ=H0.spendCoins;H0.spendCoins=function $(Z,Q,X,z){let Y=null;try{Y=Z.state.serialize()}catch{}let J=dQ.call(H0,Z,Q,X,z),G=J[1]??J;if(Y&&G?.pendingDust){for(let q of G.pendingDust)if(!c0.has(q.nullifier))c0.set(q.nullifier,Y)}return J};X8=H0.revertTransaction;H0.revertTransaction=function $(Z,Q){let X=H0.pendingDustToMap(Z.pendingDust),z=[],Y=Q.intents;if(Y)for(let G of Y.values()){let q=G.dustActions?.spends;if(!q)continue;for(let K of q)if(X.has(K.oldNullifier))z.push(K.oldNullifier)}let J=Z.state;for(let G of z){let q=c0.get(G);if(q){try{J=gQ.deserialize(q)}catch{}c0.delete(G)}}return{...Z,state:J,pendingDust:Z.pendingDust.filter((G)=>!z.includes(G.nullifier))}};H0.applyFailed=H0.revertTransaction});import*as d0 from"rxjs";import{MidnightBech32m as R$,UnshieldedAddress as lQ,ShieldedAddress as iQ}from"@midnight-ntwrk/wallet-sdk-address-format";import{NetworkId as D$}from"@midnight-ntwrk/wallet-sdk-abstractions";function nQ($){let Z=[],Q=$,X=new Set;while(Q&&!X.has(Q)){X.add(Q);let Y=Q;if(Q instanceof Error||typeof Q==="object"&&Y._tag){let J=Y._tag,G=Y.message??"";if(J&&G)Z.push(`[${J}] ${G}`);else if(G)Z.push(G);else if(J)Z.push(`[${J}]`);if(Y.data&&typeof Y.data==="object")try{Z.push(`data=${JSON.stringify(Y.data)}`)}catch{}Q=Y.cause}else if(typeof Q==="string"){Z.push(Q);break}else{try{let J=JSON.stringify(Q);if(J&&J!=="{}")Z.push(J);else Z.push(String(Q))}catch{Z.push(String(Q))}break}}let z=[];for(let Y of Z)if(z.length===0||z[z.length-1]!==Y)z.push(Y);return z.join(" → ")||"Unknown error"}function S9($){let{bundle:Z,networkConfig:Q,approvalOptions:X,callbacks:z}=$,{facade:Y,keystore:J,zswapSecretKeys:G,dustSecretKey:q}=Z,K=oQ[Q.networkId];if(K===void 0)throw new Error(`Unknown networkId: ${Q.networkId}`);let U,W=Y.state().pipe(d0.filter((I)=>I.isSynced)).subscribe((I)=>{U=I});function j(){if(!U)throw q0("Disconnected","Wallet not synced yet");return U}let V={shieldedSecretKeys:G,dustSecretKey:q},H=new Map;function F(I,L,O){let _=H.get(I);if(!_)_=new Map,H.set(I,_);let b=setTimeout(async()=>{if(_.delete(L),_.size===0)H.delete(I);try{await Y.revert(O)}catch{}process.stderr.write(B(` abandoned tx reverted (${I})`)+`
582
582
  `)},g$);_.set(L,{recipe:O,timer:b})}function D(I,L){let O=H.get(I);if(!O)return;let _=O.get(L);if(_)clearTimeout(_.timer),O.delete(L);if(O.size===0)H.delete(I)}async function P(I){let L=H.get(I);if(!L||L.size===0)return;H.delete(I);for(let[,O]of L){clearTimeout(O.timer);try{await Y.revert(O.recipe)}catch{}}process.stderr.write(B(` reverted ${L.size} pending tx(s) on disconnect`)+`
583
- `)}function M(){return new Date(Date.now()+z1*60*1000)}async function C(I,L){L?.start("signing");let O=await Y.signRecipe(I,(S)=>J.signData(S));L?.start("proving");let _,b=await Promise.race([Y.finalizeRecipe(O),new Promise((S,p)=>{_=setTimeout(()=>p(new Error("ZK proof generation timed out")),A1)})]);return clearTimeout(_),L?.complete(),{hex:E9(b),finalized:b}}async function A(I,L=[],O){O?.notify("approval:pending",{method:I});let _=await _9({method:I,network:Q.networkId,details:L,dappName:O?.connectionId},X),b=_==="reject"?"rejected":"approved";if(O?.notify("approval:resolved",{method:I,result:b}),_==="reject")throw q0("Rejected","User rejected the request")}function k(I){return R$.encode(K,I).asString()}function $0(I){let L={};for(let O of I){let _=O.kind;if(_!=="shielded"&&_!=="unshielded")throw q0("InvalidRequest",`Invalid output kind: "${_}" — must be "shielded" or "unshielded"`);if(!L[_])L[_]=[];let b=BigInt(O.value),S;if(_==="unshielded")S=R$.parse(O.recipient).decode(lQ,K);else S=R$.parse(O.recipient).decode(iQ,K);L[_].push({type:O.type,receiverAddress:S,amount:b})}return Object.entries(L).map(([O,_])=>({type:O,outputs:_}))}function n(I,L){return R9({onStart:(O)=>{let _=L?.connectionId??"unknown";z?.onPhaseStart?.(_,I,O),L?.notify("progress",{method:I,phase:O,status:"started"})},onComplete:(O,_)=>{let b=L?.connectionId??"unknown";z?.onPhaseComplete?.(b,I,O,_),L?.notify("progress",{method:I,phase:O,status:"completed",durationMs:_})}})}function B0(){if(!U)return!1;try{let I=U.dust;return I?.availableCoins?.length>0||I?.balance(new Date)>0n}catch{return!1}}async function z0(I){return new Promise((L)=>{if(B0()){L(!0);return}let O=Y.state().pipe(d0.filter(()=>B0()),d0.take(1),d0.timeout(I)).subscribe({next:()=>{O.unsubscribe(),L(!0)},error:()=>{O.unsubscribe(),L(!1)}})})}async function L0(I){for(let L=1;L<=J1;L++)try{return await I()}catch(O){let _=String(O?.message??O??"");if(!(/no dust tokens/i.test(_)||/dust.*unavailable/i.test(_))||L===J1)throw O;if(process.stderr.write(B(` dust unavailable, waiting for recovery (${L}/${J1})... [${_.slice(0,60)}]`)+`
584
- `),!await z0(B2)&&L<J1)await new Promise((p)=>setTimeout(p,B2))}throw new Error("unreachable")}let d={connect:async(I)=>{let L=String(I.networkId??"");if(L.toLowerCase()!==Q.networkId.toLowerCase())throw q0("InvalidRequest",`Network mismatch: wallet is on ${Q.networkId}, requested ${L}`);return{networkId:Q.networkId}},getUnshieldedBalances:async()=>{return j().unshielded.balances},getShieldedBalances:async()=>{return j().shielded.balances},getDustBalance:async()=>{let L=j().dust.balance(new Date);return{cap:L,balance:L}},getUnshieldedAddress:async()=>{let I=j();return{unshieldedAddress:k(I.unshielded.address)}},getShieldedAddresses:async()=>{let L=j().shielded.address;return{shieldedAddress:k(L),shieldedCoinPublicKey:L.coinPublicKeyString(),shieldedEncryptionPublicKey:L.encryptionPublicKeyString()}},getDustAddress:async()=>{let I=j();return{dustAddress:k(I.dust.address)}},getTxHistory:async(I)=>{let L=j(),O=Number(I.pageNumber??0),_=Number(I.pageSize??20);try{let b=L.unshielded.transactionHistory,S=[],p=0,a=O*_;for await(let F0 of b.getAll()){if(p>=a+_)break;if(p>=a)S.push({txHash:F0.hash,txStatus:F0.status==="SUCCESS"?{status:"finalized"}:{status:"pending"}});p++}return S}catch{return[]}},getConfiguration:async()=>{return{indexerUri:Q.indexer,indexerWsUri:Q.indexerWS,proverServerUri:Q.proofServer,substrateNodeUri:Q.node,networkId:Q.networkId}},getConnectionStatus:async()=>{return{status:"connected",networkId:Q.networkId}},makeTransfer:async(I,L)=>{let O=I.desiredOutputs;if(!Array.isArray(O)||O.length===0)throw q0("InvalidRequest","desiredOutputs must be a non-empty array");let _=n("makeTransfer",L),b=O.map((M1,Q1)=>({label:`Output ${Q1+1}`,value:`${M1.value} → ${String(M1.recipient).slice(0,20)}... (${M1.kind})`}));_.start("approve"),await A("makeTransfer",b,L),_.start("building");let S=$0(O),p=I.options?.payFees??!0,a=await L0(()=>Y.transferTransaction(S,V,{ttl:M(),payFees:p})),{hex:F0,finalized:l0}=await C(a,_);return F(L.connectionId,F0,a),L.metadata.phases=_.getTimings(),{tx:F0}},submitTransaction:async(I,L)=>{let O=String(I.tx??"");if(!O)throw q0("InvalidRequest","tx is required");let _=n("submitTransaction",L);_.start("approve");try{await A("submitTransaction",z2(O,"sealed"),L)}catch(S){let a=H.get(L.connectionId)?.get(O);if(a)try{await Y.revert(a.recipe)}catch{}throw D(L.connectionId,O),S}let b=M$(O);_.start("submitting");try{let S=await Y.submitTransaction(b);return _.complete(),D(L.connectionId,O),L.metadata.phases=_.getTimings(),{txHash:S}}catch(S){_.complete();let a=H.get(L.connectionId)?.get(O);if(a)try{await Y.revert(a.recipe)}catch{}D(L.connectionId,O);let F0=nQ(S),l0=new Error(`Transaction submission failed: ${F0}`);throw l0.cause=S,l0}},balanceUnsealedTransaction:async(I,L)=>{let O=String(I.tx??"");if(!O)throw q0("InvalidRequest","tx is required");let _=n("balanceUnsealedTransaction",L);_.start("approve"),await A("balanceUnsealedTransaction",z2(O,"unsealed"),L),_.start("building");let b=C9(O),S=await L0(()=>Y.balanceUnboundTransaction(b,V,{ttl:M()})),{hex:p,finalized:a}=await C(S,_);return F(L.connectionId,p,S),L.metadata.phases=_.getTimings(),{tx:p}},balanceSealedTransaction:async(I,L)=>{let O=String(I.tx??"");if(!O)throw q0("InvalidRequest","tx is required");let _=n("balanceSealedTransaction",L);_.start("approve"),await A("balanceSealedTransaction",z2(O,"sealed"),L),_.start("building");let b=M$(O),S=await L0(()=>Y.balanceFinalizedTransaction(b,V,{ttl:M()})),{hex:p,finalized:a}=await C(S,_);return F(L.connectionId,p,S),L.metadata.phases=_.getTimings(),{tx:p}},makeIntent:async(I,L)=>{let{desiredInputs:O,desiredOutputs:_,options:b}=I;if(!b)throw q0("InvalidRequest","options is required for makeIntent");let S=n("makeIntent",L);S.start("approve"),await A("makeIntent",[],L),S.start("building");let p={};if(Array.isArray(O))for(let Q1 of O){let Y2=Q1.kind;if(!p[Y2])p[Y2]={};p[Y2][Q1.type]=BigInt(Q1.value)}let a=$0(_??[]),F0=await L0(()=>Y.initSwap(p,a,V,{ttl:M(),payFees:b.payFees??!0})),{hex:l0,finalized:M1}=await C(F0,S);return F(L.connectionId,l0,F0),L.metadata.phases=S.getTimings(),{tx:l0}},signData:async(I,L)=>{let O=String(I.data??""),_=I.options;if(!O||!_?.encoding)throw q0("InvalidRequest","data and options.encoding are required");if(_.keyType&&_.keyType!=="unshielded")throw q0("InvalidRequest",`Unsupported keyType: "${_.keyType}" — only "unshielded" is supported`);await A("signData",[{label:"Encoding",value:_.encoding},{label:"Data",value:O.length>64?O.slice(0,64)+"...":O}],L);let b;switch(_.encoding){case"hex":b=X2(O);break;case"base64":b=new Uint8Array(Buffer.from(O,"base64"));break;case"text":b=new Uint8Array(Buffer.from(O,"utf-8"));break;default:throw q0("InvalidRequest",`Unknown encoding: ${_.encoding}`)}let S=J.signData(b),p=J.getPublicKey();return{data:O,signature:String(S),verifyingKey:String(p)}},getProvingProvider:async()=>{return{provingProvider:"ready",proverServerUri:Q.proofServer}},hintUsage:async(I)=>{let L=I.methodNames??[];process.stderr.write(B(` DApp hints usage: ${L.join(", ")}`)+`
583
+ `)}function M(){return new Date(Date.now()+z2*60*1000)}async function C(I,L){L?.start("signing");let O=await Y.signRecipe(I,(S)=>J.signData(S));L?.start("proving");let _,b=await Promise.race([Y.finalizeRecipe(O),new Promise((S,p)=>{_=setTimeout(()=>p(new Error("ZK proof generation timed out")),A2)})]);return clearTimeout(_),L?.complete(),{hex:E9(b),finalized:b}}async function A(I,L=[],O){O?.notify("approval:pending",{method:I});let _=await _9({method:I,network:Q.networkId,details:L,dappName:O?.connectionId},X),b=_==="reject"?"rejected":"approved";if(O?.notify("approval:resolved",{method:I,result:b}),_==="reject")throw q0("Rejected","User rejected the request")}function k(I){return R$.encode(K,I).asString()}function $0(I){let L={};for(let O of I){let _=O.kind;if(_!=="shielded"&&_!=="unshielded")throw q0("InvalidRequest",`Invalid output kind: "${_}" — must be "shielded" or "unshielded"`);if(!L[_])L[_]=[];let b=BigInt(O.value),S;if(_==="unshielded")S=R$.parse(O.recipient).decode(lQ,K);else S=R$.parse(O.recipient).decode(iQ,K);L[_].push({type:O.type,receiverAddress:S,amount:b})}return Object.entries(L).map(([O,_])=>({type:O,outputs:_}))}function n(I,L){return R9({onStart:(O)=>{let _=L?.connectionId??"unknown";z?.onPhaseStart?.(_,I,O),L?.notify("progress",{method:I,phase:O,status:"started"})},onComplete:(O,_)=>{let b=L?.connectionId??"unknown";z?.onPhaseComplete?.(b,I,O,_),L?.notify("progress",{method:I,phase:O,status:"completed",durationMs:_})}})}function B0(){if(!U)return!1;try{let I=U.dust;return I?.availableCoins?.length>0||I?.balance(new Date)>0n}catch{return!1}}async function z0(I){return new Promise((L)=>{if(B0()){L(!0);return}let O=Y.state().pipe(d0.filter(()=>B0()),d0.take(1),d0.timeout(I)).subscribe({next:()=>{O.unsubscribe(),L(!0)},error:()=>{O.unsubscribe(),L(!1)}})})}async function L0(I){for(let L=1;L<=J2;L++)try{return await I()}catch(O){let _=String(O?.message??O??"");if(!(/no dust tokens/i.test(_)||/dust.*unavailable/i.test(_))||L===J2)throw O;if(process.stderr.write(B(` dust unavailable, waiting for recovery (${L}/${J2})... [${_.slice(0,60)}]`)+`
584
+ `),!await z0(B1)&&L<J2)await new Promise((p)=>setTimeout(p,B1))}throw new Error("unreachable")}let d={connect:async(I)=>{let L=String(I.networkId??"");if(L.toLowerCase()!==Q.networkId.toLowerCase())throw q0("InvalidRequest",`Network mismatch: wallet is on ${Q.networkId}, requested ${L}`);return{networkId:Q.networkId}},getUnshieldedBalances:async()=>{return j().unshielded.balances},getShieldedBalances:async()=>{return j().shielded.balances},getDustBalance:async()=>{let L=j().dust.balance(new Date);return{cap:L,balance:L}},getUnshieldedAddress:async()=>{let I=j();return{unshieldedAddress:k(I.unshielded.address)}},getShieldedAddresses:async()=>{let L=j().shielded.address;return{shieldedAddress:k(L),shieldedCoinPublicKey:L.coinPublicKeyString(),shieldedEncryptionPublicKey:L.encryptionPublicKeyString()}},getDustAddress:async()=>{let I=j();return{dustAddress:k(I.dust.address)}},getTxHistory:async(I)=>{let L=j(),O=Number(I.pageNumber??0),_=Number(I.pageSize??20);try{let b=L.unshielded.transactionHistory,S=[],p=0,a=O*_;for await(let F0 of b.getAll()){if(p>=a+_)break;if(p>=a)S.push({txHash:F0.hash,txStatus:F0.status==="SUCCESS"?{status:"finalized"}:{status:"pending"}});p++}return S}catch{return[]}},getConfiguration:async()=>{return{indexerUri:Q.indexer,indexerWsUri:Q.indexerWS,proverServerUri:Q.proofServer,substrateNodeUri:Q.node,networkId:Q.networkId}},getConnectionStatus:async()=>{return{status:"connected",networkId:Q.networkId}},makeTransfer:async(I,L)=>{let O=I.desiredOutputs;if(!Array.isArray(O)||O.length===0)throw q0("InvalidRequest","desiredOutputs must be a non-empty array");let _=n("makeTransfer",L),b=O.map((M2,Q2)=>({label:`Output ${Q2+1}`,value:`${M2.value} → ${String(M2.recipient).slice(0,20)}... (${M2.kind})`}));_.start("approve"),await A("makeTransfer",b,L),_.start("building");let S=$0(O),p=I.options?.payFees??!0,a=await L0(()=>Y.transferTransaction(S,V,{ttl:M(),payFees:p})),{hex:F0,finalized:l0}=await C(a,_);return F(L.connectionId,F0,a),L.metadata.phases=_.getTimings(),{tx:F0}},submitTransaction:async(I,L)=>{let O=String(I.tx??"");if(!O)throw q0("InvalidRequest","tx is required");let _=n("submitTransaction",L);_.start("approve");try{await A("submitTransaction",z1(O,"sealed"),L)}catch(S){let a=H.get(L.connectionId)?.get(O);if(a)try{await Y.revert(a.recipe)}catch{}throw D(L.connectionId,O),S}let b=M$(O);_.start("submitting");try{let S=await Y.submitTransaction(b);return _.complete(),D(L.connectionId,O),L.metadata.phases=_.getTimings(),{txHash:S}}catch(S){_.complete();let a=H.get(L.connectionId)?.get(O);if(a)try{await Y.revert(a.recipe)}catch{}D(L.connectionId,O);let F0=nQ(S),l0=new Error(`Transaction submission failed: ${F0}`);throw l0.cause=S,l0}},balanceUnsealedTransaction:async(I,L)=>{let O=String(I.tx??"");if(!O)throw q0("InvalidRequest","tx is required");let _=n("balanceUnsealedTransaction",L);_.start("approve"),await A("balanceUnsealedTransaction",z1(O,"unsealed"),L),_.start("building");let b=C9(O),S=await L0(()=>Y.balanceUnboundTransaction(b,V,{ttl:M()})),{hex:p,finalized:a}=await C(S,_);return F(L.connectionId,p,S),L.metadata.phases=_.getTimings(),{tx:p}},balanceSealedTransaction:async(I,L)=>{let O=String(I.tx??"");if(!O)throw q0("InvalidRequest","tx is required");let _=n("balanceSealedTransaction",L);_.start("approve"),await A("balanceSealedTransaction",z1(O,"sealed"),L),_.start("building");let b=M$(O),S=await L0(()=>Y.balanceFinalizedTransaction(b,V,{ttl:M()})),{hex:p,finalized:a}=await C(S,_);return F(L.connectionId,p,S),L.metadata.phases=_.getTimings(),{tx:p}},makeIntent:async(I,L)=>{let{desiredInputs:O,desiredOutputs:_,options:b}=I;if(!b)throw q0("InvalidRequest","options is required for makeIntent");let S=n("makeIntent",L);S.start("approve"),await A("makeIntent",[],L),S.start("building");let p={};if(Array.isArray(O))for(let Q2 of O){let Y1=Q2.kind;if(!p[Y1])p[Y1]={};p[Y1][Q2.type]=BigInt(Q2.value)}let a=$0(_??[]),F0=await L0(()=>Y.initSwap(p,a,V,{ttl:M(),payFees:b.payFees??!0})),{hex:l0,finalized:M2}=await C(F0,S);return F(L.connectionId,l0,F0),L.metadata.phases=S.getTimings(),{tx:l0}},signData:async(I,L)=>{let O=String(I.data??""),_=I.options;if(!O||!_?.encoding)throw q0("InvalidRequest","data and options.encoding are required");if(_.keyType&&_.keyType!=="unshielded")throw q0("InvalidRequest",`Unsupported keyType: "${_.keyType}" — only "unshielded" is supported`);await A("signData",[{label:"Encoding",value:_.encoding},{label:"Data",value:O.length>64?O.slice(0,64)+"...":O}],L);let b;switch(_.encoding){case"hex":b=X1(O);break;case"base64":b=new Uint8Array(Buffer.from(O,"base64"));break;case"text":b=new Uint8Array(Buffer.from(O,"utf-8"));break;default:throw q0("InvalidRequest",`Unknown encoding: ${_.encoding}`)}let S=J.signData(b),p=J.getPublicKey();return{data:O,signature:String(S),verifyingKey:String(p)}},getProvingProvider:async()=>{return{provingProvider:"ready",proverServerUri:Q.proofServer}},hintUsage:async(I)=>{let L=I.methodNames??[];process.stderr.write(B(` DApp hints usage: ${L.join(", ")}`)+`
585
585
  `)}};function r(){W.unsubscribe();for(let[,I]of H)for(let[,L]of I)clearTimeout(L.timer);H.clear()}function o(){for(let[,I]of H)if(I.size>0)return!0;return!1}return{handlers:d,revertPendingTxs:P,hasPendingTxs:o,dispose:r}}var oQ;var v9=x(()=>{T9();T$();x9();y9();b9();oQ={PreProd:D$.NetworkId.PreProd,Preview:D$.NetworkId.Preview,Undeployed:D$.NetworkId.Undeployed}});var w9={};e(w9,{default:()=>k9});async function k9($,Z){let Q=N($,"port"),X=Q?parseInt(Q,10):c$;if(Number.isNaN(X)||X<1||X>65535)throw new Error(`Invalid port: "${Q}" — must be 1-65535`);let z=R($,"approve-all"),Y=z||!R($,"no-auto-approve-reads"),J=R($,"json"),G=X0(Q0(N($,"wallet"))),q=Buffer.from(G.seed,"hex"),{name:K,config:U}=U0({args:$}),W=G.addresses[K];_0(U,{proofServer:N($,"proof-server"),node:N($,"node"),indexerWS:N($,"indexer-ws")}),process.stderr.write(`
586
586
  `+f("DApp Connector Server")+`
587
587
 
@@ -592,7 +592,7 @@ Available commands: ${_1.map((z)=>z.name).join(", ")}`);OQ(X);return}if(!process
592
592
  `),process.stderr.write(T("Auto-approve writes",z?"yes":"no")+`
593
593
  `),process.stderr.write(`
594
594
  `);let j=e0((k,$0)=>{let n=F7();if(n)n.log(B(` SDK: ${$0}`));else process.stderr.write(B(` SDK: ${$0}`)+`
595
- `)}),V=P1(),H=R($,"no-cache");if(i0($))t0();let F=i("Building wallet facade..."),D=H?null:g0(W,K),P=await h0(q,U,D);if(P.restoredFromCache)F.update("Restoring from cache...");let M=async()=>{V(),j();try{await u0(P)}catch{}},C,A;try{F.update("Syncing wallet..."),await p0(P,{onProgress:(d,r)=>{if(r>0){let o=Math.min(Math.round(d/r*100),100);F.update(o>=100?"Syncing wallet...":`Syncing wallet... ${o}%`)}},onSyncDetail:(d)=>{F.update(`Syncing wallet... (waiting on: ${d})`)}}),F.stop("Wallet synced");let k=i("Waiting for dust..."),n=(await S7(P)).dust?.availableCoins?.length>0;if(k.stop(n?"Dust ready":"Dust not yet available (writes may fail)"),!H)try{await E0(W,K,P.facade)}catch{}if(Z?.aborted)throw new Error("Operation cancelled");let B0={approve:"Waiting for approval...",building:"Building transaction...",signing:"Signing...",proving:"Proving (ZK)...",submitting:"Submitting..."},z0;if(A=S9({bundle:P,networkConfig:U,approvalOptions:{approveAll:z,autoApproveReads:Y},callbacks:{onPhaseStart:(d,r,o)=>{if(o==="approve")return;let I=B0[o]??`${o}...`;if(z0)z0.update(I);else z0=i(I)},onPhaseComplete:(d,r,o,I)=>{if(o==="approve")return;if(o==="proving"||o==="submitting")z0?.stop(`${o} ${E$(I)}`),z0=void 0}}}),C=M9({port:X,handlers:A.handlers,onConnect:(d)=>{process.stderr.write(B(` [${A$()}] `)+u("connected")+B(` ${d.id}`)+`
595
+ `)}),V=P2(),H=R($,"no-cache");if(i0($))t0();let F=i("Building wallet facade..."),D=H?null:g0(W,K),P=await h0(q,U,D);if(P.restoredFromCache)F.update("Restoring from cache...");let M=async()=>{V(),j();try{await u0(P)}catch{}},C,A;try{F.update("Syncing wallet..."),await p0(P,{onProgress:(d,r)=>{if(r>0){let o=Math.min(Math.round(d/r*100),100);F.update(o>=100?"Syncing wallet...":`Syncing wallet... ${o}%`)}},onSyncDetail:(d)=>{F.update(`Syncing wallet... (waiting on: ${d})`)}}),F.stop("Wallet synced");let k=i("Waiting for dust..."),n=(await S7(P)).dust?.availableCoins?.length>0;if(k.stop(n?"Dust ready":"Dust not yet available (writes may fail)"),!H)try{await E0(W,K,P.facade)}catch{}if(Z?.aborted)throw new Error("Operation cancelled");let B0={approve:"Waiting for approval...",building:"Building transaction...",signing:"Signing...",proving:"Proving (ZK)...",submitting:"Submitting..."},z0;if(A=S9({bundle:P,networkConfig:U,approvalOptions:{approveAll:z,autoApproveReads:Y},callbacks:{onPhaseStart:(d,r,o)=>{if(o==="approve")return;let I=B0[o]??`${o}...`;if(z0)z0.update(I);else z0=i(I)},onPhaseComplete:(d,r,o,I)=>{if(o==="approve")return;if(o==="proving"||o==="submitting")z0?.stop(`${o} ${E$(I)}`),z0=void 0}}}),C=M9({port:X,handlers:A.handlers,onConnect:(d)=>{process.stderr.write(B(` [${A$()}] `)+u("connected")+B(` ${d.id}`)+`
596
596
  `)},onDisconnect:(d)=>{process.stderr.write(B(` [${A$()}] `)+c("disconnected")+B(` ${d.id}`)+`
597
597
  `),A?.revertPendingTxs(d.id).catch(()=>{})},onRequest:(d,r)=>{process.stderr.write(B(` [${A$()}] ${d.id} #${d.requestCount} → ${r.method}`)+`
598
598
  `)},onResponse:(d,r,o,I,L,O)=>{if(L&&z0)z0.stop("Failed"),z0=void 0;let _=E$(o);if(L){let b=L.code==="Rejected"?"rejected by operator":L.message;if(process.stderr.write(` ${c("✗")} ${B(`${d.id} ← ${r.method} (${_})`)} ${c(b)}
@@ -608,13 +608,13 @@ Available commands: ${_1.map((z)=>z.name).join(", ")}`);OQ(X);return}if(!process
608
608
  `+B(" Shutting down...")+`
609
609
  `),!H&&!A.hasPendingTxs())try{await E0(W,K,P.facade)}catch{}try{await C.close()}catch{}A.dispose(),A=void 0,C=void 0,process.stderr.write(B(" Server stopped.")+`
610
610
 
611
- `)}catch(k){if(F.stop("Failed"),C)try{await C.close()}catch{}throw A?.dispose(),k}finally{await M()}}function A$(){let $=new Date;return`${N$($.getHours())}:${N$($.getMinutes())}:${N$($.getSeconds())}`}function N$($){return $<10?"0"+$:String($)}function E$($){if($<1000)return`${$}ms`;return`${($/1000).toFixed(1)}s`}var f9=x(()=>{s0();W0();V0();T0();u1();F1();O1();v9();T$();s();x0()});s();H2();v1();W0();if(process.argv.includes("--mcp"))await Promise.resolve().then(() => (U9(),LQ));else{let J=function(){z.abort(),setTimeout(()=>process.exit(130),5000).unref()},$=C$(),Z=R($,"json");if(R($,"version")||R($,"v"))process.stdout.write(S0+`
611
+ `)}catch(k){if(F.stop("Failed"),C)try{await C.close()}catch{}throw A?.dispose(),k}finally{await M()}}function A$(){let $=new Date;return`${N$($.getHours())}:${N$($.getMinutes())}:${N$($.getSeconds())}`}function N$($){return $<10?"0"+$:String($)}function E$($){if($<1000)return`${$}ms`;return`${($/1000).toFixed(1)}s`}var f9=x(()=>{s0();W0();V0();T0();u2();F2();O2();v9();T$();s();x0()});s();H1();v2();W0();if(process.argv.includes("--mcp"))await Promise.resolve().then(() => (U9(),LQ));else{let J=function(){z.abort(),setTimeout(()=>process.exit(130),5000).unref()},$=C$(),Z=R($,"json");if(R($,"version")||R($,"v"))process.stdout.write(S0+`
612
612
  `),process.exit(0);if(R($,"help")||R($,"h"))$.command="help";let Q=$.command??"help";J7();let X;if(Z)X=o$();let z=new AbortController,{signal:Y}=z;process.on("SIGINT",J),process.on("SIGTERM",J);async function G(){switch(Q){case"help":{let{default:K}=await Promise.resolve().then(() => (O9(),P9));return K($)}case"wallet":{let{default:K}=await Promise.resolve().then(() => (B$(),j$));return K($)}case"generate":{process.stderr.write(`
613
613
  Note: "midnight generate" is deprecated.
614
614
  Use "midnight wallet generate <name>" instead.
615
615
 
616
- `);let{default:K}=await Promise.resolve().then(() => (E2(),N2));return K($)}case"info":{let{default:K}=await Promise.resolve().then(() => (x2(),C2));return K($)}case"balance":{let{default:K}=await Promise.resolve().then(() => (b2(),y2));return K($)}case"address":{let{default:K}=await Promise.resolve().then(() => (v2(),S2));return K($)}case"genesis-address":{let{default:K}=await Promise.resolve().then(() => (w2(),k2));return K($)}case"inspect-cost":{let{default:K}=await Promise.resolve().then(() => (h2(),f2));return K($)}case"config":{let{default:K}=await Promise.resolve().then(() => (z$(),X$));return K($)}case"cache":{let{default:K}=await Promise.resolve().then(() => (Q$(),Z$));return K($)}case"airdrop":{let{default:K}=await Promise.resolve().then(() => (t2(),a2));return K($,Y)}case"transfer":{let{default:K}=await Promise.resolve().then(() => (r2(),s2));return K($,Y)}case"dust":{let{default:K}=await Promise.resolve().then(() => ($$(),e2));return K($,Y)}case"localnet":{let{default:K}=await Promise.resolve().then(() => (U$(),q$));return K($)}case"status":throw new Error('The "status" command is currently being reworked. Check back soon.');case"serve":{let{default:K}=await Promise.resolve().then(() => (f9(),w9));return K($,Y)}default:throw new Error(`Unknown command: "${Q}"
617
- Run "midnight help" to see available commands.`)}}let q=new Set(["airdrop","transfer","dust","serve"]);G().then(()=>{if(q.has(Q))process.exit(0)}).catch((K)=>{if(Z){X?.();let{exitCode:U,errorCode:W}=U1(K);n$(K,W,U),process.exit(U)}else{process.stderr.write(`
616
+ `);let{default:K}=await Promise.resolve().then(() => (E1(),N1));return K($)}case"info":{let{default:K}=await Promise.resolve().then(() => (x1(),C1));return K($)}case"balance":{let{default:K}=await Promise.resolve().then(() => (b1(),y1));return K($)}case"address":{let{default:K}=await Promise.resolve().then(() => (v1(),S1));return K($)}case"genesis-address":{let{default:K}=await Promise.resolve().then(() => (w1(),k1));return K($)}case"inspect-cost":{let{default:K}=await Promise.resolve().then(() => (h1(),f1));return K($)}case"config":{let{default:K}=await Promise.resolve().then(() => (z$(),X$));return K($)}case"cache":{let{default:K}=await Promise.resolve().then(() => (Q$(),Z$));return K($)}case"airdrop":{let{default:K}=await Promise.resolve().then(() => (t1(),a1));return K($,Y)}case"transfer":{let{default:K}=await Promise.resolve().then(() => (r1(),s1));return K($,Y)}case"dust":{let{default:K}=await Promise.resolve().then(() => ($$(),e1));return K($,Y)}case"localnet":{let{default:K}=await Promise.resolve().then(() => (U$(),q$));return K($)}case"status":throw new Error('The "status" command is currently being reworked. Check back soon.');case"serve":{let{default:K}=await Promise.resolve().then(() => (f9(),w9));return K($,Y)}default:throw new Error(`Unknown command: "${Q}"
617
+ Run "midnight help" to see available commands.`)}}let q=new Set(["airdrop","transfer","dust","serve"]);G().then(()=>{if(q.has(Q))process.exit(0)}).catch((K)=>{if(Z){X?.();let{exitCode:U,errorCode:W}=U2(K);n$(K,W,U),process.exit(U)}else{process.stderr.write(`
618
618
  `+i$(K.message,'Run "midnight help" for usage information.')+`
619
619
 
620
- `);let{exitCode:U}=U1(K);process.exit(U)}})}
620
+ `);let{exitCode:U}=U2(K);process.exit(U)}})}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midnight-wallet-cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "Git-style CLI wallet for the Midnight blockchain",
6
6
  "license": "Apache-2.0",