midnight-wallet-cli 0.2.1 → 0.2.3
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 +30 -14
- package/dist/mcp-server.js +95 -95
- package/dist/wallet.js +65 -65
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`;if(I1)I1(Z);else process.stdout.write(Z)}var I1=null;function _($,Z){let Q=$.flags[Z];if(Q===void 0||Q===!0)return;return Q}function I($,Z){return Z in $.flags}function
|
|
4
|
-
`,{mode:G0})}function
|
|
5
|
-
Valid keys: ${
|
|
2
|
+
var U$=Object.defineProperty;var f=($,Z)=>{for(var Q in Z)U$($,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:(X)=>Z[Q]=()=>X})};var E=($,Z)=>()=>($&&(Z=$($=0)),Z);function M1($){I1=$}function M($){let Z=JSON.stringify($)+`
|
|
3
|
+
`;if(I1)I1(Z);else process.stdout.write(Z)}var I1=null;function _($,Z){let Q=$.flags[Z];if(Q===void 0||Q===!0)return;return Q}function I($,Z){return Z in $.flags}function L0($){return I($,"verbose")}function V2($,Z,Q){let X=_($,Z);if(X===void 0)throw new Error(`Missing required flag: --${Z} <${Q}>`);return X}function K0($){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 c0="0000000000000000000000000000000000000000000000000000000000000001",H2="0000000000000000000000000000000000000000000000000000000000000000",_1=6,T1=1e6,W2=300000000000000n,L2=5,x0=800000000000000n,P2=300000,g0=30000,F2=120000,O2=1e4,R1=120000,I2=300000,x1=60000,A1=10,M2=3,_2=600000,E1=15000,T2=115,g=".midnight",d0="wallet.json",R2="config.json",e=448,G0=384,x2="localnet",D1=1,C1="cache",l0="wallets",N1="default",i0="https://midnight-comp-tracker.vercel.app";var D2={};f(D2,{unsetConfigValue:()=>k1,setConfigValue:()=>v1,saveCliConfig:()=>E0,loadCliConfig:()=>l,getValidConfigKeys:()=>n0,getConfigValue:()=>b1});import*as $0 from"fs";import*as y1 from"path";import{homedir as B$}from"os";function V$($){return/^(https?|wss?):\/\/\S+/.test($)}function A2($){return $??y1.join(B$(),g)}function E2($){return y1.join(A2($),R2)}function H$($){let Z=A2($);if(!$0.existsSync(Z))$0.mkdirSync(Z,{recursive:!0,mode:e})}function l($){let Z=E2($);if(!$0.existsSync(Z))return{...A0};let Q;try{Q=$0.readFileSync(Z,"utf-8")}catch{return{...A0}}let X;try{X=JSON.parse(Q)}catch{return{...A0}}let z={network:X.network&&Z0(X.network)?X.network:A0.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 E0($,Z){H$(Z);let Q=E2(Z);$0.writeFileSync(Q,JSON.stringify($,null,2)+`
|
|
4
|
+
`,{mode:G0})}function b1($,Z){let Q=l(Z);if($==="network")return Q.network;if($==="wallet")return Q.wallet??"(not set)";if(S1.has($)){let X=Q[$];return typeof X==="string"?X:"(not set)"}throw new Error(`Unknown config key: "${$}"
|
|
5
|
+
Valid keys: ${o0.join(", ")}`)}function v1($,Z,Q){let X=l(Q);if($==="network"){if(!Z0(Z))throw new Error(`Invalid network: "${Z}"
|
|
6
6
|
Valid networks: preprod, preview, undeployed`);X.network=Z}else if($==="wallet"){if(!K0(Z))throw new Error(`Invalid wallet name: "${Z}"
|
|
7
|
-
Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);X.wallet=Z}else if(
|
|
7
|
+
Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);X.wallet=Z}else if(S1.has($)){if(!V$(Z))throw new Error(`Invalid URL for "${$}": "${Z}"
|
|
8
8
|
Must start with http://, https://, ws://, or wss://`);X[$]=Z}else throw new Error(`Unknown config key: "${$}"
|
|
9
|
-
Valid keys: ${
|
|
10
|
-
Valid keys: ${
|
|
11
|
-
`)){if(!Q)continue;let[X,z]=Q.split("|"),q=(Y)=>{let G=new RegExp(`0\\.0\\.0\\.0:(\\d+)->${Y}/tcp`),K=z?.match(G);return K?parseInt(K[1],10):void 0};if(X.includes("indexer-standalone")||X.includes("indexer")){let Y=q(8088);if(Y)Z.indexerPort=Y}if(X.includes("midnight-node")){let Y=q(9944);if(Y)Z.nodePort=Y}if(X.includes("proof-server")){let Y=q(6300);if(Y)Z.proofServerPort=Y}}return Z}catch{return{}}}function N2($){let Z=w1($);if($==="undeployed"){let Q=
|
|
12
|
-
Valid networks: ${
|
|
13
|
-
Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Z=p.join(
|
|
14
|
-
Run "midnight wallet list" to see available wallets.`);let Q=l();Q.wallet=$,
|
|
15
|
-
Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Z=
|
|
16
|
-
Run "midnight wallet list" to see available wallets.`);let X=
|
|
17
|
-
Switch to another wallet first: midnight wallet use <other-wallet>`);if(
|
|
18
|
-
`+"Create another wallet first: midnight wallet generate <name>");
|
|
19
|
-
Generate a wallet first: midnight wallet generate <name> --network <name>`);let Q;try{Q=
|
|
20
|
-
${q.message}`)}let X;try{X=JSON.parse(Q)}catch{throw new Error(`Invalid JSON in wallet file: ${Z}`)}if(!X.seed||!X.createdAt){let q=["seed","createdAt"];if(!X.addresses)q.push("address");let Y=q.filter((G)=>!X[G]);if(Y.length>0)throw new Error(`Wallet file is missing required fields (${Y.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 q=Buffer.from(X.seed,"hex"),Y=U0(q),G={seed:X.seed,addresses:Y,createdAt:X.createdAt};if(X.mnemonic)G.mnemonic=X.mnemonic;let K={...X,addresses:Y};return
|
|
21
|
-
`,{mode:G0}),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
|
|
22
|
-
`,{mode:G0}),Q}var X0=E(()=>{
|
|
23
|
-
`)}var k2=60,v2=15;var c=()=>{};var u2={};f(u2,{default:()=>p2});import*as f2 from"fs";import*as
|
|
24
|
-
Use --force to overwrite, or --output <file> to save to a different path.`);let Y,G;if(X!==void 0){let U=X.replace(/^0x/,"");if(U.length!==64||!/^[0-9a-fA-F]+$/.test(U))throw new Error("Seed must be a 64-character hex string (32 bytes)");Y=Buffer.from(U,"hex")}else if(z!==void 0){if(!
|
|
9
|
+
Valid keys: ${o0.join(", ")}`);E0(X,Q)}function k1($,Z){let Q=l(Z);if($==="network")Q.network=A0.network;else if($==="wallet")delete Q.wallet;else if(S1.has($))delete Q[$];else throw new Error(`Unknown config key: "${$}"
|
|
10
|
+
Valid keys: ${o0.join(", ")}`);E0(Q,Z)}function n0(){return o0}var A0,o0,S1;var P0=E(()=>{Q0();A0={network:"undeployed"},o0=["network","proof-server","node","indexer-ws","wallet"],S1=new Set(["proof-server","node","indexer-ws"])});import{execSync as W$}from"child_process";function Z0($){return C2.includes($)}function w1($){return{...L$[$]}}function t0(){return C2}function P$(){try{let $=W$('docker ps --format "{{.Image}}|{{.Ports}}"',{encoding:"utf-8",timeout:5000}),Z={};for(let Q of $.trim().split(`
|
|
11
|
+
`)){if(!Q)continue;let[X,z]=Q.split("|"),q=(Y)=>{let G=new RegExp(`0\\.0\\.0\\.0:(\\d+)->${Y}/tcp`),K=z?.match(G);return K?parseInt(K[1],10):void 0};if(X.includes("indexer-standalone")||X.includes("indexer")){let Y=q(8088);if(Y)Z.indexerPort=Y}if(X.includes("midnight-node")){let Y=q(9944);if(Y)Z.nodePort=Y}if(X.includes("proof-server")){let Y=q(6300);if(Y)Z.proofServerPort=Y}}return Z}catch{return{}}}function N2($){let Z=w1($);if($==="undeployed"){let Q=P$();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 z0($,Z,Q){let X=l(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 L$,C2;var Q0=E(()=>{P0();L$={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"}},C2=["preprod","preview","undeployed"]});import{HDWallet as F$,Roles as O$}from"@midnight-ntwrk/wallet-sdk-hd";import{createKeystore as I$,PublicKey as M$}from"@midnight-ntwrk/wallet-sdk-unshielded-wallet";import{NetworkId as h1}from"@midnight-ntwrk/wallet-sdk-abstractions";function J0($,Z,Q=0){let X=_$[Z],z=F$.fromSeed($);if(z.type!=="seedOk")throw new Error("Invalid seed for HD wallet");let q=z.hdWallet.selectAccount(0).selectRole(O$.NightExternal).deriveKeyAt(Q);if(q.type==="keyOutOfBounds")throw new Error(`Key index ${Q} out of bounds`);let Y=I$(q.key,X);return M$.fromKeyStore(Y).address}function U0($,Z=0){let Q={};for(let X of t0())Q[X]=J0($,X,Z);return Q}var _$;var j0=E(()=>{Q0();_$={preprod:h1.NetworkId.PreProd,preview:h1.NetworkId.Preview,undeployed:h1.NetworkId.Undeployed}});function d($){let Z=_($.args,"network");if(Z!==void 0){if(!Z0(Z))throw new Error(`Invalid network: "${Z}"
|
|
12
|
+
Valid networks: ${t0().join(", ")}`);return Z}let Q=l($.configDir);if(Q.network&&Z0(Q.network))return Q.network;return"undeployed"}function t($){let Z=d($),Q=N2(Z);return{name:Z,config:Q}}var o=E(()=>{Q0();P0()});import*as S from"fs";import*as p from"path";import{homedir as T$}from"os";function f1(){return p.join(T$(),g)}function D0(){return p.join(f1(),l0)}function y2(){return p.join(f1(),d0)}function R$(){let $=f1();if(!S.existsSync($))S.mkdirSync($,{recursive:!0,mode:e})}function x$($){return $.includes("/")||$.includes("\\")||$.endsWith(".json")}function u($){if($!==void 0){if(x$($))return p.resolve($);return p.join(D0(),`${$}.json`)}let Q=l().wallet??N1;return p.join(D0(),`${Q}.json`)}function C0(){return l().wallet??N1}function p1($){if(!K0($))throw new Error(`Invalid wallet name: "${$}"
|
|
13
|
+
Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Z=p.join(D0(),`${$}.json`);if(!S.existsSync(Z))throw new Error(`Wallet "${$}" not found.
|
|
14
|
+
Run "midnight wallet list" to see available wallets.`);let Q=l();Q.wallet=$,E0(Q)}function S2(){let $=D0();if(!S.existsSync($))return[];let Z=C0();return S.readdirSync($).filter((X)=>X.endsWith(".json")).sort().map((X)=>{let z=X.replace(/\.json$/,""),q=p.join($,X);try{let Y=JSON.parse(S.readFileSync(q,"utf-8")),G;if(Y.addresses)G=Y.addresses;else if(Y.address&&Y.seed)try{let K=Buffer.from(Y.seed,"hex");G=U0(K)}catch{G={undeployed:Y.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 b2($){if(!K0($))throw new Error(`Invalid wallet name: "${$}"
|
|
15
|
+
Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Z=D0(),Q=p.join(Z,`${$}.json`);if(!S.existsSync(Q))throw new Error(`Wallet "${$}" not found.
|
|
16
|
+
Run "midnight wallet list" to see available wallets.`);let X=C0();if($===X)throw new Error(`Cannot remove the active wallet "${$}".
|
|
17
|
+
Switch to another wallet first: midnight wallet use <other-wallet>`);if(S.readdirSync(Z).filter((q)=>q.endsWith(".json")).length<=1)throw new Error(`Cannot remove "${$}" — it is the only wallet.
|
|
18
|
+
`+"Create another wallet first: midnight wallet generate <name>");S.unlinkSync(Q)}function m($){let Z=$?p.resolve($):y2();if(!S.existsSync(Z))throw new Error(`Wallet file not found: ${Z}
|
|
19
|
+
Generate a wallet first: midnight wallet generate <name> --network <name>`);let Q;try{Q=S.readFileSync(Z,"utf-8")}catch(q){throw new Error(`Failed to read wallet file: ${Z}
|
|
20
|
+
${q.message}`)}let X;try{X=JSON.parse(Q)}catch{throw new Error(`Invalid JSON in wallet file: ${Z}`)}if(!X.seed||!X.createdAt){let q=["seed","createdAt"];if(!X.addresses)q.push("address");let Y=q.filter((G)=>!X[G]);if(Y.length>0)throw new Error(`Wallet file is missing required fields (${Y.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 q=Buffer.from(X.seed,"hex"),Y=U0(q),G={seed:X.seed,addresses:Y,createdAt:X.createdAt};if(X.mnemonic)G.mnemonic=X.mnemonic;let K={...X,addresses:Y};return S.writeFileSync(Z,JSON.stringify(K,null,2)+`
|
|
21
|
+
`,{mode:G0}),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 r0($,Z){let Q=Z?p.resolve(Z):y2();if(!Z)R$();else{let X=p.dirname(Q);if(!S.existsSync(X))S.mkdirSync(X,{recursive:!0,mode:e})}return S.writeFileSync(Q,JSON.stringify($,null,2)+`
|
|
22
|
+
`,{mode:G0}),Q}var X0=E(()=>{P0();j0()});function F0(){return!("NO_COLOR"in process.env)}function N0($,Z){if(!F0())return $;return`\x1B[38;5;${Z}m${$}\x1B[0m`}function R($){if(!F0())return $;return`\x1B[1m${$}\x1B[0m`}function H($){if(!F0())return $;return`\x1B[2m${$}\x1B[0m`}function r($){return N0($,38)}function a($){return N0($,196)}function b($){return N0($,40)}function q0($){return N0($,226)}function y0($){return N0($,245)}function D($,Z=k2){let Q=` ${$} `,X=Z-Q.length;if(X<=0)return R(Q);let z=Math.floor(X/2),q=X-z;return R("═".repeat(z)+Q+"═".repeat(q))}function C($=k2){return H("─".repeat($))}function L($,Z,Q=16){let X=($+":").padEnd(Q);return` ${y0(X)}${Z}`}function S0($){let Z=$<0n,Q=Z?-$:$,X=BigInt(10**_1),z=Q/X,Y=(Q%X).toString().padStart(_1,"0");return`${Z?"-":""}${z}.${Y}`}function a0($){return`${S0($)} NIGHT`}function s0($){let Z=$<0n,Q=Z?-$:$,X=10n**BigInt(v2),z=Q/X,G=(Q%X).toString().padStart(v2,"0").replace(/0+$/,"").padEnd(6,"0");return`${Z?"-":""}${z}.${G}`}function e0($){return`${s0($)} DUST`}function v($,Z=!1){let Q=Z&&$.length>20?$.slice(0,10)+"…"+$.slice(-8):$;return r(Q)}function B0($,Z){let X=[`${b("✓")} ${$}`];if(Z)X.push(L("Transaction",r(Z)));return X.join(`
|
|
23
|
+
`)}var k2=60,v2=15;var c=()=>{};var u2={};f(u2,{default:()=>p2});import*as f2 from"fs";import*as $1 from"path";import{homedir as A$}from"os";import{generateMnemonic as E$,mnemonicToSeedSync as w2,validateMnemonic as D$}from"@scure/bip39";import{wordlist as h2}from"@scure/bip39/wordlists/english.js";async function p2($){let Z=d({args:$}),Q=_($,"output"),X=_($,"seed"),z=_($,"mnemonic");if(X!==void 0&&z!==void 0)throw new Error("Cannot specify both --seed and --mnemonic. Use one or the other.");let q=Q?$1.resolve(Q):$1.join(A$(),g,d0);if(f2.existsSync(q)&&!I($,"force"))throw new Error(`Wallet file already exists: ${q}
|
|
24
|
+
Use --force to overwrite, or --output <file> to save to a different path.`);let Y,G;if(X!==void 0){let U=X.replace(/^0x/,"");if(U.length!==64||!/^[0-9a-fA-F]+$/.test(U))throw new Error("Seed must be a 64-character hex string (32 bytes)");Y=Buffer.from(U,"hex")}else if(z!==void 0){if(!D$(z,h2))throw new Error("Invalid BIP-39 mnemonic. Expected 12 or 24 words from the English wordlist.");G=z,Y=Buffer.from(w2(G).slice(0,32))}else G=E$(h2,256),Y=Buffer.from(w2(G).slice(0,32));let K=U0(Y),J=K[Z],B={seed:Y.toString("hex"),addresses:K,createdAt:new Date().toISOString()};if(G)B.mnemonic=G;let j=r0(B,Q);if(I($,"json")){let U={addresses:K,activeAddress:J,activeNetwork:Z,seed:Y.toString("hex"),file:j,createdAt:B.createdAt};if(G)U.mnemonic=G;M(U);return}if(process.stdout.write(J+`
|
|
25
25
|
`),process.stderr.write(`
|
|
26
26
|
`+D("Wallet Generated")+`
|
|
27
27
|
|
|
@@ -38,7 +38,7 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
|
|
|
38
38
|
`),process.stderr.write(C()+`
|
|
39
39
|
`),process.stderr.write(H(" Next: midnight info | midnight balance")+`
|
|
40
40
|
|
|
41
|
-
`),process.stderr.write(
|
|
41
|
+
`),process.stderr.write(b("✓")+` Wallet saved
|
|
42
42
|
`)}var m2=E(()=>{j0();o();X0();c()});var g2={};f(g2,{default:()=>c2});async function c2($){let Z=u(_($,"wallet")),Q=m(Z),X=d({args:$}),z=Q.addresses[X];if(I($,"json")){M({addresses:Q.addresses,activeNetwork:X,activeAddress:z,createdAt:Q.createdAt,file:Z});return}process.stdout.write(z+`
|
|
43
43
|
`),process.stderr.write(`
|
|
44
44
|
`+D("Wallet Info")+`
|
|
@@ -52,7 +52,7 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
|
|
|
52
52
|
`),process.stderr.write(`
|
|
53
53
|
`+C()+`
|
|
54
54
|
|
|
55
|
-
`)}var d2=E(()=>{X0();o();c();c()});import
|
|
55
|
+
`)}var d2=E(()=>{X0();o();c();c()});import C$ from"ws";function l2($,Z,Q){return new Promise((X,z)=>{let q=new C$(Z,["graphql-transport-ws"]),Y=new Map,G=0,K=0,J=0,B=!1,j=!1,U,W=()=>{let x=new Map,F=0;for(let O of Y.values())if(!O.spent){F++;let A=x.get(O.tokenType)??0n;x.set(O.tokenType,A+O.value)}return{balances:x,utxoCount:F,txCount:G,highestTxId:K}},V=()=>{clearTimeout(U)},P=()=>{if(!j&&B&&(K===0||J>=K))j=!0,V(),q.send(JSON.stringify({id:"1",type:"complete"})),q.close(),X(W())};q.on("open",()=>{q.send(JSON.stringify({type:"connection_init"}))}),q.on("message",(x)=>{let F=JSON.parse(x.toString());switch(F.type){case"connection_ack":q.send(JSON.stringify({id:"1",type:"subscribe",payload:{query:N$,variables:{address:$}}}));break;case"next":{if(F.payload?.errors){let A=F.payload.errors[0]?.message||"Unknown GraphQL error";if(!j)j=!0,V(),q.close(),z(new Error(`GraphQL error: ${A}`));return}let O=F.payload?.data?.unshieldedTransactions;if(!O)return;if(O.__typename==="UnshieldedTransaction"){G++;let A=O;J=Math.max(J,A.transaction.id);for(let k of A.createdUtxos){let h=`${k.intentHash}:${k.outputIndex}`;Y.set(h,{value:BigInt(k.value),tokenType:k.tokenType,spent:!1})}for(let k of A.spentUtxos){let h=`${k.intentHash}:${k.outputIndex}`,R0=Y.get(h);if(R0)R0.spent=!0}if(Q)Q(J,K);P()}else if(O.__typename==="UnshieldedTransactionsProgress")K=O.highestTransactionId,B=!0,P();break}case"error":if(!j)j=!0,V(),q.close(),z(new Error(`GraphQL subscription error: ${JSON.stringify(F.payload)}`));break;case"complete":break}}),q.on("error",(x)=>{if(!j)j=!0,V(),z(new Error(`WebSocket connection failed: ${x.message}`))}),q.on("close",()=>{if(!j)j=!0,V(),z(new Error(`Indexer closed the connection before balance sync completed. Indexer: ${Z}`))}),U=setTimeout(()=>{if(!j)j=!0,q.close(),z(new Error(`Balance check timed out after ${x1/1000}s. Indexer: ${Z}`))},x1)})}function b0($){return $===H2}var N$=`
|
|
56
56
|
subscription UnshieldedTransactions($address: UnshieldedAddress!) {
|
|
57
57
|
unshieldedTransactions(address: $address) {
|
|
58
58
|
__typename
|
|
@@ -66,12 +66,12 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
-
`;var i2=()=>{};function n2($){return $.replace(/\x1b\[[0-9;]*m/g,"")}function w($){let Z=!1;if(!
|
|
69
|
+
`;var i2=()=>{};function n2($){return $.replace(/\x1b\[[0-9;]*m/g,"")}function w($){let Z=!1;if(!F0()){let G=$;process.stderr.write(`⠋ ${G}`);let K={update(J){G=J,process.stderr.write(`\r⠋ ${G}\x1B[K`)},stop(J){if(Z)return;Z=!0,Z1=null,process.stderr.write(`\r✓ ${J??G}\x1B[K
|
|
70
70
|
`)},log(J){process.stderr.write(`\r\x1B[K${J}
|
|
71
|
-
`),process.stderr.write(`⠋ ${G}`)}};return
|
|
71
|
+
`),process.stderr.write(`⠋ ${G}`)}};return Z1=K,K}let Q=0,X=$,z=()=>{let G=r(o2[Q]),J=(process.stderr.columns||80)-4,B=X;if(n2(B).length>J)B=n2(B).slice(0,J);process.stderr.write(`\r${G} ${B}\x1B[K`),Q=(Q+1)%o2.length};z();let q=setInterval(z,y$),Y={update(G){X=G},stop(G){if(Z)return;Z=!0,clearInterval(q),Z1=null;let K=G??X;process.stderr.write(`\r\x1B[32m✓\x1B[0m ${K}\x1B[K
|
|
72
72
|
`)},log(G){process.stderr.write(`\r\x1B[K${G}
|
|
73
|
-
`),z()}};return
|
|
74
|
-
`);else for(let[Y,G]of q.balances)if(
|
|
73
|
+
`),z()}};return Z1=Y,Y}var o2,y$=80,Z1=null;var V0=E(()=>{o2=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"]});var r2={};f(r2,{default:()=>t2});async function t2($){let{name:Z,config:Q}=t({args:$}),X;if($.subcommand)X=$.subcommand;else X=m(u(_($,"wallet"))).addresses[Z];if(!X)throw new Error("No address provided and no wallet file found.");z0(Q,{proofServer:_($,"proof-server"),node:_($,"node"),indexerWS:_($,"indexer-ws")});let z=w(`Checking balance on ${Z}...`);try{let q=await l2(X,Q.indexerWS,(Y,G)=>{if(G>0){let K=Math.round(Y/G*100);z.update(`Syncing transactions... ${K}%`)}});if(z.stop(`Synced ${q.txCount} transactions`),I($,"json")){let Y={};for(let[G,K]of q.balances){let J=b0(G)?"NIGHT":G;Y[J]=b0(G)?S0(K):K.toString()}M({address:X,network:Z,balances:Y,utxoCount:q.utxoCount,txCount:q.txCount});return}if(q.balances.size===0)process.stdout.write(`0
|
|
74
|
+
`);else for(let[Y,G]of q.balances)if(b0(Y))process.stdout.write(`NIGHT=${G}
|
|
75
75
|
`);else process.stdout.write(`${Y}=${G}
|
|
76
76
|
`);if(process.stderr.write(`
|
|
77
77
|
`+D("Balance")+`
|
|
@@ -82,12 +82,12 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
|
|
|
82
82
|
`),process.stderr.write(L("Transactions",q.txCount.toString())+`
|
|
83
83
|
`),process.stderr.write(`
|
|
84
84
|
`),q.balances.size===0)process.stderr.write(` ${H("No balance found")}
|
|
85
|
-
`);else for(let[Y,G]of q.balances)if(
|
|
85
|
+
`);else for(let[Y,G]of q.balances)if(b0(Y))process.stderr.write(L("NIGHT",R(a0(G)))+`
|
|
86
86
|
`);else{let K=Y.slice(0,8)+"…"+Y.slice(-8);process.stderr.write(L(`Token ${K}`,R(G.toString()))+`
|
|
87
87
|
`)}process.stderr.write(`
|
|
88
88
|
`+C()+`
|
|
89
89
|
|
|
90
|
-
`)}catch(q){throw z.stop("Failed"),q}}var a2=E(()=>{X0();o();Q0();i2();c();
|
|
90
|
+
`)}catch(q){throw z.stop("Failed"),q}}var a2=E(()=>{X0();o();Q0();i2();c();V0()});var e2={};f(e2,{default:()=>s2});async function s2($){let Z=V2($,"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=_($,"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"),q=d({args:$}),Y=J0(z,q,X),G=`m/44'/2400'/0'/NightExternal/${X}`;if(I($,"json")){M({address:Y,network:q,index:X,path:G});return}process.stdout.write(Y+`
|
|
91
91
|
`),process.stderr.write(`
|
|
92
92
|
`),process.stderr.write(L("Network",q)+`
|
|
93
93
|
`),process.stderr.write(L("Index",X.toString())+`
|
|
@@ -95,39 +95,39 @@ Use --force to overwrite, or --output <file> to save to a different path.`);let
|
|
|
95
95
|
`),process.stderr.write(L("Path",H(G))+`
|
|
96
96
|
`),process.stderr.write(C()+`
|
|
97
97
|
|
|
98
|
-
`)}var
|
|
98
|
+
`)}var $3=E(()=>{j0();o();c()});var Q3={};f(Q3,{default:()=>Z3});async function Z3($){let Z=d({args:$}),Q=Buffer.from(c0,"hex"),X=J0(Q,Z);if(I($,"json")){M({address:X,network:Z});return}process.stdout.write(X+`
|
|
99
99
|
`),process.stderr.write(`
|
|
100
100
|
`),process.stderr.write(L("Network",Z)+`
|
|
101
101
|
`),process.stderr.write(L("Address",v(X))+`
|
|
102
102
|
`),process.stderr.write(L("Seed",H("0x01 (genesis)"))+`
|
|
103
103
|
`),process.stderr.write(C()+`
|
|
104
104
|
|
|
105
|
-
`)}var
|
|
105
|
+
`)}var X3=E(()=>{j0();o();c()});var Y3={};f(Y3,{default:()=>q3});import*as z3 from"@midnight-ntwrk/ledger-v7";function v0($,Z,Q){let X={readTime:0n,computeTime:0n,blockUsage:0n,bytesWritten:0n,bytesChurned:0n};X[Z]=Q;let q=$.normalizeFullness(X)[Z];return Math.round(Number(Q)/q)}function S$($){return{readTime:v0($,"readTime",1000000000n),computeTime:v0($,"computeTime",1000000000n),blockUsage:v0($,"blockUsage",10000n),bytesWritten:v0($,"bytesWritten",10000n),bytesChurned:v0($,"bytesChurned",1000000n)}}async function q3($){let Z=z3.LedgerParameters.initialParameters(),Q=S$(Z);if(I($,"json")){M(Q);return}for(let[X,z]of Object.entries(Q))process.stdout.write(`${X}=${z}
|
|
106
106
|
`);process.stderr.write(`
|
|
107
107
|
`+D("Block Limits")+`
|
|
108
108
|
|
|
109
109
|
`),process.stderr.write(H(" Derived from LedgerParameters.initialParameters()")+`
|
|
110
110
|
|
|
111
|
-
`);for(let[X,z]of Object.entries(Q)){let q=
|
|
111
|
+
`);for(let[X,z]of Object.entries(Q)){let q=b$[X]??"";process.stderr.write(L(X,`${R(z.toLocaleString())} ${H(q)}`)+`
|
|
112
112
|
`)}process.stderr.write(`
|
|
113
113
|
`+C()+`
|
|
114
114
|
`),process.stderr.write(H(" bytesWritten is typically the tightest constraint")+`
|
|
115
115
|
`),process.stderr.write(H(" for large contract deployments.")+`
|
|
116
116
|
|
|
117
|
-
`)}var
|
|
118
|
-
`)}var
|
|
119
|
-
`),W=await j()}}else T("facade","No cache, building fresh"),W=await j();return{facade:W,keystore:J,zswapSecretKeys:G,dustSecretKey:K,restoredFromCache:U}}function
|
|
120
|
-
Expected a bech32m address for network "${Z.networkId}"`)}}function
|
|
121
|
-
Available: ${G1(
|
|
117
|
+
`)}var b$;var G3=E(()=>{c();b$={readTime:"picoseconds",computeTime:"picoseconds",blockUsage:"bytes",bytesWritten:"bytes",bytesChurned:"bytes"}});function O0(){K3=!0}function T($,Z){if(!K3)return;let Q=new Date().toISOString().slice(11,23);process.stderr.write(H(` [${Q}] ${$}: ${Z}`)+`
|
|
118
|
+
`)}var K3=!1;var I0=()=>{};import{HDWallet as v$,Roles as u1}from"@midnight-ntwrk/wallet-sdk-hd";function m1($,Z){let Q=v$.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 J3($){return m1($,u1.Zswap)}function U3($){return m1($,u1.NightExternal)}function j3($){return m1($,u1.Dust)}var B3=()=>{};import{ShieldedWallet as V3}from"@midnight-ntwrk/wallet-sdk-shielded";import{UnshieldedWallet as H3,createKeystore as k$,PublicKey as w$,InMemoryTransactionHistoryStorage as h$}from"@midnight-ntwrk/wallet-sdk-unshielded-wallet";import{DustWallet as W3}from"@midnight-ntwrk/wallet-sdk-dust-wallet";import{WalletFacade as L3}from"@midnight-ntwrk/wallet-sdk-facade";import*as M0 from"@midnight-ntwrk/ledger-v7";import{NetworkId as c1}from"@midnight-ntwrk/wallet-sdk-abstractions";import*as s from"rxjs";async function k0($,Z,Q){let X=f$[Z.networkId];if(X===void 0)throw new Error(`Unknown networkId: ${Z.networkId}`);T("facade",`Building facade for network ${Z.networkId}`),T("facade",`Node: ${Z.node}`),T("facade",`Indexer: ${Z.indexerWS}`),T("facade",`Proof server: ${Z.proofServer}`);let z=J3($),q=U3($),Y=j3($),G=M0.ZswapSecretKeys.fromSeed(z),K=M0.DustSecretKey.fromSeed(Y),J=k$(q,X),B={networkId:X,indexerClientConnection:{indexerHttpUrl:Z.indexer,indexerWsUrl:Z.indexerWS},costParameters:{additionalFeeOverhead:W2,feeBlocksMargin:L2},txHistoryStorage:new h$,provingServerUrl:new URL(Z.proofServer),relayURL:new URL(Z.node)},j=()=>L3.init({configuration:B,shielded:(V)=>V3(V).startWithSecretKeys(G),unshielded:(V)=>H3(V).startWithPublicKey(w$.fromKeyStore(J)),dust:(V)=>W3(V).startWithSecretKey(K,M0.LedgerParameters.initialParameters().dust)}),U=!1,W;if(Q){T("facade","Restoring from cache...");try{W=await L3.init({configuration:B,shielded:(V)=>V3(V).restore(Q.shielded),unshielded:(V)=>H3(V).restore(Q.unshielded),dust:(V)=>W3(V).restore(Q.dust)}),U=!0,T("facade","Cache restore successful")}catch(V){T("facade",`Cache restore failed: ${V.message}`),process.stderr.write(` Cache restore failed, building from scratch: ${V.message}
|
|
119
|
+
`),W=await j()}}else T("facade","No cache, building fresh"),W=await j();return{facade:W,keystore:J,zswapSecretKeys:G,dustSecretKey:K,restoredFromCache:U}}function P3($,Z="full"){let Q=$.unshielded?.progress?.isStrictlyComplete()??!1,X=$.dust?.state?.progress?.isStrictlyComplete()??!1;if(!X)try{let q=$.dust?.state?.progress;if(q&&q.highestRelevantWalletIndex>0&&q.appliedIndex>=q.highestRelevantWalletIndex)X=!0}catch{}if(Z==="lite")return Q&&X;return($.shielded?.state?.progress?.isStrictlyComplete()??!1)&&Q&&X}function p$($){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 w0($,Z={}){let{onProgress:Q,onSyncDetail:X,timeoutMs:z,syncMode:q="full"}=Z,{facade:Y,zswapSecretKeys:G,dustSecretKey:K}=$;T("sync","Starting facade (connecting to node and indexer)..."),await Y.start(G,K),T("sync","Facade started, subscribing to state...");let J=z??P2;return T("sync",`Sync timeout: ${J/1000}s, mode: ${q}`),new Promise((B,j)=>{let U=!1,W=0,V="",P=null,x=setTimeout(()=>{if(!U){if(T("sync",`Sync timed out after ${J/1000}s (${W} emissions)`),P)try{let F=P.unshielded?.progress;T("sync",` unshielded: applied=${F?.appliedId} highest=${F?.highestTransactionId} complete=${F?.isStrictlyComplete()}`);let O=P.dust?.state?.progress;if(T("sync",` dust: applied=${O?.appliedIndex} highest=${O?.highestRelevantWalletIndex} complete=${O?.isStrictlyComplete?.()} connected=${O?.isConnected}`),q==="full"){let A=P.shielded?.state?.progress;T("sync",` shielded: complete=${A?.isStrictlyComplete()}`)}}catch{}j(new Error("Wallet sync timed out"))}},J);$.keepAlive=Y.state().subscribe({next:(F)=>{if(U)return;if(W++,P=F,Q){let A=F.unshielded.progress;if(A){let k=Number(A.appliedId),h=Number(A.highestTransactionId);Q(Math.min(k,h),h)}}let O=[];try{if(q==="full"&&!F.shielded?.state?.progress?.isStrictlyComplete())O.push("shielded");if(p$(F))O.push("dust");if(!F.unshielded?.progress?.isStrictlyComplete())O.push("unshielded")}catch{}if(O.length>0){X?.(O.join(", "));let A=O.join(",");if(W===1||A!==V||W%100===0)T("sync",`Waiting on: ${O.join(", ")} (emission #${W})`),V=A}if(P3(F,q))U=!0,clearTimeout(x),T("sync",`Sync complete after ${W} emissions`),B(F)},error:(F)=>{if(!U)T("sync",`Sync error: ${F.message}`),clearTimeout(x),j(F)}})})}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 s.firstValueFrom($.facade.state().pipe(s.filter(Z),s.timeout(15000)))}catch{return await s.firstValueFrom($.facade.state())}}async function d1($,Z="full"){return s.firstValueFrom($.facade.state().pipe(s.filter((Q)=>P3(Q,Z)),s.timeout(O2)))}async function h0($){$.keepAlive?.unsubscribe(),await Promise.race([$.facade.stop(),new Promise((Z)=>setTimeout(Z,5000))])}function Q1($){let Z=(X)=>{let z=X?._tag;if(typeof z==="string"&&z.startsWith("Wallet.")){let q=X?.message??"transient error";$?.(z,q);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 f$;var l1=E(()=>{B3();I0();f$={PreProd:c1.NetworkId.PreProd,Preview:c1.NetworkId.Preview,Undeployed:c1.NetworkId.Undeployed}});import{existsSync as z1,mkdirSync as u$,writeFileSync as m$,readFileSync as c$,unlinkSync as X1,readdirSync as i1,renameSync as g$}from"node:fs";import{join as H0,dirname as d$}from"node:path";import{homedir as F3}from"node:os";import{randomBytes as l$}from"node:crypto";function o1($,Z,Q){let X=Q??H0(F3(),g,C1),z=$.slice(0,20);return H0(X,Z,`${z}.json`)}function f0($,Z,Q){let X=o1($,Z,Q);if(!z1(X))return null;try{let z=c$(X,"utf-8"),q=JSON.parse(z);if(q.version!==D1)return null;if(q.network!==Z)return null;if(q.address!==$)return null;if(!q.wallets||typeof q.wallets.shielded!=="string"||typeof q.wallets.unshielded!=="string"||typeof q.wallets.dust!=="string")return null;return q.wallets}catch{return null}}async function _0($,Z,Q,X){let[z,q,Y]=await Promise.all([Q.shielded.serializeState(),Q.unshielded.serializeState(),Q.dust.serializeState()]),G={version:D1,network:Z,address:$,timestamp:new Date().toISOString(),wallets:{shielded:z,unshielded:q,dust:Y}},K=o1($,Z,X),J=d$(K);if(!z1(J))u$(J,{recursive:!0,mode:e});let B=K+`.tmp.${l$(4).toString("hex")}`;try{m$(B,JSON.stringify(G),{mode:G0}),g$(B,K)}catch(j){try{X1(B)}catch{}throw j}}function q1($,Z,Q){let X=Q??H0(F3(),g,C1);if($&&Z){let z=o1($,Z,Q);try{X1(z)}catch{}return}if(Z){let z=H0(X,Z);if(!z1(z))return;try{for(let q of i1(z))if(q.endsWith(".json"))X1(H0(z,q))}catch{}return}if(!z1(X))return;try{for(let z of i1(X)){let q=H0(X,z);try{for(let Y of i1(q))if(Y.endsWith(".json"))X1(H0(q,Y))}catch{}}}catch{}}var Y1=()=>{};import*as r1 from"@midnight-ntwrk/ledger-v7";import{MidnightBech32m as i$,UnshieldedAddress as o$}from"@midnight-ntwrk/wallet-sdk-address-format";import{NetworkId as n1}from"@midnight-ntwrk/wallet-sdk-abstractions";function t$($){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"),q=BigInt(z);if(q<=0n)throw new Error("Amount too small — minimum is 0.000001 NIGHT");return q}function K1($){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 r$($,Z){let Q=n$[Z.networkId];if(Q===void 0)throw new Error(`Unknown networkId: ${Z.networkId}`);try{return i$.parse($).decode(o$,Q)}catch(X){throw new Error(`Invalid recipient address: ${X.message}
|
|
120
|
+
Expected a bech32m address for network "${Z.networkId}"`)}}function a$($){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 O3($){let Z=$?.message?.toLowerCase()??"";return Z.includes("not enough dust")||Z.includes("dust generated")||Z.includes("insufficient funds")||Z.includes("no dust tokens")||a$($)}function G1($){let Z=$<0n?-$:$,Q=Z/1000000000000000n,X=Z%1000000000000000n;return`${$<0n?"-":""}${Q}.${X.toString().padStart(15,"0").slice(0,6)}`}function t1($){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 a1(){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 s$($,Z,Q){let X=new Date(Date.now()+A1*60*1000);await Promise.race([$.facade.dust.waitForSyncedState(),new Promise((J,B)=>setTimeout(()=>B(new Error("Insufficient funds: dust wallet sync timed out")),g0))]);let z=await $.facade.dust.createDustGenerationTransaction(new Date,X,Z,$.keystore.getPublicKey(),Q),q=z.intents?.get(1);if(!q)throw new Error("Dust generation intent not found on transaction");let Y=$.keystore.signData(q.signatureData(1)),G=await $.facade.dust.addDustGenerationSignature(z,Y),K=await $.facade.finalizeTransaction(G);return await $.facade.submitTransaction(K)}async function e$($,Z,Q,X){let z=Date.now(),q=z+_2,Y,G=!1,K=setInterval(()=>{if(G&&X){let J=t1(Date.now()-z);X(`Waiting for dust generation capacity (${J} elapsed, ~5 min on fresh wallets)...`)}},1000);try{while(Date.now()<q)try{return await s$($,Z,Q)}catch(J){if(Y=J,O3(J)&&Date.now()+E1<q){G=!0;let B=t1(Date.now()-z);X?.(`Waiting for dust generation capacity (${B} elapsed, ~5 min on fresh wallets)...`),await new Promise((j)=>setTimeout(j,E1));continue}throw J}throw Y??new Error("Dust registration timed out")}finally{clearInterval(K)}}async function J1($,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),q;if(z.length>0){Z?.(`Registering ${z.length} UTXO(s) for dust generation...`);let G=z.map((K)=>({...K.utxo,ctime:new Date(K.meta.ctime)}));q=await e$($,G,X.dust.address,Z)}else Z?.("UTXOs already registered, waiting for dust generation...");Z?.("Waiting for dust tokens...");let Y=Date.now();while(Date.now()-Y<R1){try{if((await Promise.race([$.facade.waitForSyncedState(),new Promise((K,J)=>setTimeout(()=>J(new Error("Poll sync timed out")),g0))])).dust.balance(new Date)>0n)return Z?.("Dust available"),{alreadyAvailable:!1,txHash:q}}catch{}await new Promise((G)=>setTimeout(G,5000))}throw new Error("Timed out waiting for dust tokens. Try running: midnight dust register")}async function $7($,Z,Q,X,z,q){let Y=Date.now(),G=Y+R1,K,J=0;while(!0)try{if(K)await d1($,"lite");let B=new Date(Date.now()+A1*60*1000);T("transfer","Building transfer transaction...");let j=await $.facade.transferTransaction([{type:"unshielded",outputs:[{amount:Q,receiverAddress:Z,type:r1.unshieldedToken().raw}]}],{shieldedSecretKeys:$.zswapSecretKeys,dustSecretKey:$.dustSecretKey},{ttl:B,payFees:!0});T("transfer","Signing recipe...");let U=await $.facade.signRecipe(j,(P)=>$.keystore.signData(P));T("transfer","Generating ZK proof..."),X?.();let W=await Promise.race([$.facade.finalizeRecipe(U),new Promise((P,x)=>{setTimeout(()=>x(new Error("ZK proof generation timed out")),I2)})]);T("transfer","Submitting transaction to node..."),z?.();let V=await $.facade.submitTransaction(W);return T("transfer",`Transaction submitted: ${V}`),V}catch(B){if(K=B,(B?.code===T2||B?.message?.includes("115")||B?.message?.toLowerCase().includes("stale"))&&++J<M2)continue;if(O3(B)&&Date.now()<G){let U=t1(Date.now()-Y);q?.(`Dust insufficient, re-ensuring (${U} elapsed)...`);try{let W=await d1($,"lite"),V=W.dust.balance(new Date);if(V>0n&&V<x0)throw new Error(`Insufficient dust for transaction fees.
|
|
121
|
+
Available: ${G1(V)} DUST, need ≥${G1(x0)} DUST.
|
|
122
122
|
Dust regenerates over time from registered NIGHT UTXOs.
|
|
123
|
-
Check status: midnight dust status`);await J1($,q,W)}catch(W){if(String(W?.message).startsWith("Insufficient dust"))throw W;await new Promise((
|
|
124
|
-
Available: ${G1(O1)} DUST, need ≥${G1(
|
|
123
|
+
Check status: midnight dust status`);await J1($,q,W)}catch(W){if(String(W?.message).startsWith("Insufficient dust"))throw W;await new Promise((V)=>setTimeout(V,5000))}continue}throw B}}async function U1($){let{seedBuffer:Z,networkConfig:Q,recipientAddress:X,amountNight:z,signal:q,onSync:Y,onSyncDetail:G,onDust:K,onProving:J,onSubmitting:B,onSyncWarning:j,noCache:U,walletAddress:W,networkName:V}=$,P=t$(z),x=r$(X,Q),F=Q1(j),O=a1(),A=!U&&W&&V,k=A?f0(W,V):null;T("transfer","Building facade...");let h=await k0(Z,Q,k),R0=!1,Y2=async()=>{if(!R0){R0=!0;try{await h0(h)}catch{}}},G2=()=>{Y2()};q?.addEventListener("abort",G2,{once:!0});try{let K2=Q.networkId!=="Undeployed",J2=K2?F2:g0,m7=3,u0;T("transfer",`Sync timeout: ${J2/1000}s (${K2?"remote":"local"} network)`);for(let W0=1;W0<=3;W0++)try{u0=await w0(h,{onProgress:Y,onSyncDetail:G,timeoutMs:J2,syncMode:"lite"});break}catch(U2){if(q?.aborted)throw new Error("Operation cancelled");if(W0<3&&String(U2?.message).includes("timed out")){if(A)try{T("transfer","Saving partial sync progress to cache..."),await _0(W,V,h.facade)}catch{}K?.(`Sync timed out, retrying (attempt ${W0+1}/3)...`),await h0(h).catch(()=>{});let J$=A?f0(W,V):null;h=await k0(Z,Q,J$);continue}throw U2}if(q?.aborted)throw new Error("Operation cancelled");T("transfer","Sync complete, checking balance...");let F1=u0.unshielded.balances[r1.unshieldedToken().raw]??0n;if(T("transfer",`Balance: ${Number(F1)/T1} NIGHT`),F1<P){let W0=Number(F1)/T1;throw new Error(`Insufficient balance: ${W0.toFixed(6)} NIGHT available, ${z} NIGHT requested`)}if(q?.aborted)throw new Error("Operation cancelled");T("transfer","Ensuring dust availability..."),await J1(h,K,u0),T("transfer","Dust available");let O1=u0.dust.balance(new Date);if(O1>0n&&O1<x0)throw new Error(`Insufficient dust for transaction fees.
|
|
124
|
+
Available: ${G1(O1)} DUST, need ≥${G1(x0)} DUST.
|
|
125
125
|
Dust regenerates over time from registered NIGHT UTXOs.
|
|
126
|
-
Check status: midnight dust status`);if(q?.aborted)throw new Error("Operation cancelled");T("transfer","Building and submitting transaction...");let
|
|
126
|
+
Check status: midnight dust status`);if(q?.aborted)throw new Error("Operation cancelled");T("transfer","Building and submitting transaction...");let K$=await $7(h,x,P,J,B,K);if(A)try{await _0(W,V,h.facade)}catch{}return{txHash:K$,amountMicroNight:P}}finally{q?.removeEventListener("abort",G2),O(),F(),await Y2()}}var n$;var j1=E(()=>{l1();Y1();I0();n$={PreProd:n1.NetworkId.PreProd,Preview:n1.NetworkId.Preview,Undeployed:n1.NetworkId.Undeployed}});var M3={};f(M3,{default:()=>I3});async function I3($,Z){let Q=$.subcommand;if(!Q)throw new Error(`Missing amount.
|
|
127
127
|
Usage: midnight airdrop <amount>
|
|
128
128
|
Example: midnight airdrop 1000`);let X=K1(Q),z=m(u(_($,"wallet"))),{name:q,config:Y}=t({args:$});if(z0(Y,{proofServer:_($,"proof-server"),node:_($,"node"),indexerWS:_($,"indexer-ws")}),q!=="undeployed")throw new Error(`Airdrop is only available on the "undeployed" network (local devnet).
|
|
129
129
|
Current network: "${q}"
|
|
130
|
-
On preprod/preview, use a faucet or transfer from another wallet.`);let G=I($,"no-cache")
|
|
130
|
+
On preprod/preview, use a faucet or transfer from another wallet.`);let G=I($,"no-cache");if(L0($))O0();let K=z.addresses[q],J=Buffer.from(c0,"hex"),B=J0(J,q);process.stderr.write(`
|
|
131
131
|
`+D("Airdrop")+`
|
|
132
132
|
|
|
133
133
|
`),process.stderr.write(L("Network",q)+`
|
|
@@ -135,9 +135,9 @@ On preprod/preview, use a faucet or transfer from another wallet.`);let G=I($,"n
|
|
|
135
135
|
`),process.stderr.write(L("To",v(K,!0))+`
|
|
136
136
|
`),process.stderr.write(L("Amount",R(X+" NIGHT"))+`
|
|
137
137
|
`),process.stderr.write(`
|
|
138
|
-
`);let j=w("Starting genesis wallet...");try{let U=await U1({seedBuffer:J,networkConfig:Y,recipientAddress:K,amountNight:X,signal:Z,noCache:G,walletAddress:
|
|
138
|
+
`);let j=w("Starting genesis wallet...");try{let U=await U1({seedBuffer:J,networkConfig:Y,recipientAddress:K,amountNight:X,signal:Z,noCache:G,walletAddress:B,networkName:q,onSync(W,V){if(V>0){let P=Math.round(W/V*100);j.update(`Syncing genesis wallet... ${P}%`)}},onDust(W){j.update(`Dust: ${W}`)},onProving(){j.update("Generating ZK proof (this may take a few minutes)...")},onSubmitting(){j.update("Submitting transaction...")},onSyncWarning(W,V){j.update(`Syncing genesis wallet... (${V}, retrying)`)}});if(j.stop("Transaction submitted"),I($,"json")){M({txHash:U.txHash,amount:X,recipient:K,network:q});return}process.stdout.write(U.txHash+`
|
|
139
139
|
`),process.stderr.write(`
|
|
140
|
-
`+
|
|
140
|
+
`+B0(`Airdropped ${X} NIGHT to your wallet`,U.txHash)+`
|
|
141
141
|
`),process.stderr.write(`
|
|
142
142
|
`+C()+`
|
|
143
143
|
`),process.stderr.write(H(" Verify: midnight balance")+`
|
|
@@ -148,69 +148,69 @@ On preprod/preview, use a faucet or transfer from another wallet.`);let G=I($,"n
|
|
|
148
148
|
`)}catch(U){if(j.stop("Failed"),U instanceof Error&&U.message.toLowerCase().includes("dust"))throw new Error(`${U.message}
|
|
149
149
|
|
|
150
150
|
On a fresh localnet, the minimum airdrop is ~1 NIGHT.
|
|
151
|
-
Try: midnight airdrop 1`);throw U}}var
|
|
151
|
+
Try: midnight airdrop 1`);throw U}}var _3=E(()=>{I0();X0();o();Q0();j0();j1();c();V0()});var R3={};f(R3,{default:()=>T3});async function T3($,Z){let Q=$.subcommand,X=$.positionals[0];if(!Q)throw new Error(`Missing recipient address.
|
|
152
152
|
Usage: midnight transfer <to> <amount>
|
|
153
153
|
Example: midnight transfer mn_addr_undeployed1... 100`);if(!X)throw new Error(`Missing amount.
|
|
154
154
|
Usage: midnight transfer <to> <amount>
|
|
155
|
-
Example: midnight transfer mn_addr_undeployed1... 100`);let z=K1(X),q=u(_($,"wallet")),Y=m(q),G=Buffer.from(Y.seed,"hex"),{name:K,config:J}=t({args:$}),
|
|
155
|
+
Example: midnight transfer mn_addr_undeployed1... 100`);let z=K1(X),q=u(_($,"wallet")),Y=m(q),G=Buffer.from(Y.seed,"hex"),{name:K,config:J}=t({args:$}),B=Y.addresses[K];z0(J,{proofServer:_($,"proof-server"),node:_($,"node"),indexerWS:_($,"indexer-ws")}),process.stderr.write(`
|
|
156
156
|
`+D("Transfer")+`
|
|
157
157
|
|
|
158
158
|
`),process.stderr.write(L("Network",K)+`
|
|
159
|
-
`),process.stderr.write(L("From",v(
|
|
159
|
+
`),process.stderr.write(L("From",v(B,!0))+`
|
|
160
160
|
`),process.stderr.write(L("To",v(Q,!0))+`
|
|
161
161
|
`),process.stderr.write(L("Amount",R(z+" NIGHT"))+`
|
|
162
162
|
`),process.stderr.write(`
|
|
163
|
-
`);let j=I($,"no-cache");if(
|
|
163
|
+
`);let j=I($,"no-cache");if(L0($))O0();let U=w("Starting wallet...");try{let W=await U1({seedBuffer:G,networkConfig:J,recipientAddress:Q,amountNight:z,signal:Z,noCache:j,walletAddress:B,networkName:K,onSync(V,P){if(P>0){let x=Math.min(Math.round(V/P*100),100);U.update(x>=100?"Syncing wallet...":`Syncing wallet... ${x}%`)}},onSyncDetail(V){U.update(`Syncing wallet... (waiting on: ${V})`)},onDust(V){U.update(`Dust: ${V}`)},onProving(){U.update("Generating ZK proof (this may take a few minutes)...")},onSubmitting(){U.update("Submitting transaction...")},onSyncWarning(V,P){U.update(`Syncing wallet... (${P}, retrying)`)}});if(U.stop("Transaction submitted"),I($,"json")){M({txHash:W.txHash,amount:z,recipient:Q,network:K});return}process.stdout.write(W.txHash+`
|
|
164
164
|
`),process.stderr.write(`
|
|
165
|
-
`+
|
|
165
|
+
`+B0(`Transferred ${z} NIGHT`,W.txHash)+`
|
|
166
166
|
`),process.stderr.write(`
|
|
167
167
|
`+C()+`
|
|
168
168
|
`),process.stderr.write(H(" Verify: midnight balance")+`
|
|
169
169
|
|
|
170
|
-
`)}catch(W){throw U.stop("Failed"),W}}var
|
|
170
|
+
`)}catch(W){throw U.stop("Failed"),W}}var x3=E(()=>{I0();X0();o();Q0();j1();c();V0()});var D3={};f(D3,{default:()=>E3});import*as A3 from"@midnight-ntwrk/ledger-v7";async function E3($,Z){let Q=$.subcommand;if(!Q||Q!=="register"&&Q!=="status")throw new Error(`Missing or invalid subcommand.
|
|
171
171
|
Usage:
|
|
172
172
|
midnight dust register Register NIGHT UTXOs for dust generation
|
|
173
|
-
midnight dust status Check dust registration status`);let X=u(_($,"wallet")),z=m(X),q=Buffer.from(z.seed,"hex"),{name:Y,config:G}=t({args:$}),K=z.addresses[Y];z0(G,{proofServer:_($,"proof-server"),node:_($,"node"),indexerWS:_($,"indexer-ws")});let J=I($,"no-cache");if(
|
|
173
|
+
midnight dust status Check dust registration status`);let X=u(_($,"wallet")),z=m(X),q=Buffer.from(z.seed,"hex"),{name:Y,config:G}=t({args:$}),K=z.addresses[Y];z0(G,{proofServer:_($,"proof-server"),node:_($,"node"),indexerWS:_($,"indexer-ws")});let J=I($,"no-cache");if(L0($))O0();let B=J?null:f0(K,Y),j=await k0(q,G,B),U=async()=>{try{await h0(j)}catch{}},W=()=>{U()};Z?.addEventListener("abort",W,{once:!0});let V={},P=Q1((O,A)=>{V.current?.(O,A)}),x=a1(),F=I($,"json");try{if(Q==="register")await Z7(j,Y,K,J,F,Z,V);else await Q7(j,Y,K,J,F,Z,V)}finally{Z?.removeEventListener("abort",W),x(),P(),await U()}}async function Z7($,Z,Q,X,z,q,Y){process.stderr.write(`
|
|
174
174
|
`+D("Dust Register")+`
|
|
175
175
|
|
|
176
176
|
`),process.stderr.write(L("Network",Z)+`
|
|
177
177
|
|
|
178
|
-
`);let G=w($.restoredFromCache?"Restoring from cache...":"Syncing wallet...");if(Y)Y.current=(K,J)=>G.update(`Syncing wallet... (${J}, retrying)`);try{let K=await
|
|
178
|
+
`);let G=w($.restoredFromCache?"Restoring from cache...":"Syncing wallet...");if(Y)Y.current=(K,J)=>G.update(`Syncing wallet... (${J}, retrying)`);try{let K=await w0($,{syncMode:"lite",onProgress:(U,W)=>{if(W>0){let V=Math.min(Math.round(U/W*100),100);G.update(V>=100?"Syncing wallet...":`Syncing wallet... ${V}%`)}},onSyncDetail:(U)=>{G.update(`Syncing wallet... (waiting on: ${U})`)}});if(q?.aborted)throw new Error("Operation cancelled");G.update("Checking dust status...");let J=await J1($,(U)=>{G.update(U)},K);if(q?.aborted)throw new Error("Operation cancelled");let j=(await g1($)).dust.balance(new Date);if(!X)try{await _0(Q,Z,$.facade)}catch{}if(J.alreadyAvailable)G.stop("Dust already available");else G.stop("Dust registration complete");if(z){let U={subcommand:"register",dustBalance:s0(j)};if(J.txHash)U.txHash=J.txHash;M(U);return}if(process.stdout.write(j.toString()+`
|
|
179
179
|
`),J.alreadyAvailable)process.stderr.write(`
|
|
180
|
-
`+
|
|
180
|
+
`+B0(`Dust tokens already available: ${e0(j)}`)+`
|
|
181
181
|
|
|
182
182
|
`);else process.stderr.write(`
|
|
183
|
-
`+
|
|
183
|
+
`+B0(`Dust tokens available: ${e0(j)}`)+`
|
|
184
184
|
|
|
185
185
|
`)}catch(K){throw G.stop("Failed"),K}}async function Q7($,Z,Q,X,z,q,Y){process.stderr.write(`
|
|
186
186
|
`+D("Dust Status")+`
|
|
187
187
|
|
|
188
188
|
`),process.stderr.write(L("Network",Z)+`
|
|
189
189
|
|
|
190
|
-
`);let G=w($.restoredFromCache?"Restoring from cache...":"Syncing wallet...");if(Y)Y.current=(K,J)=>G.update(`Syncing wallet... (${J}, retrying)`);try{if(await
|
|
190
|
+
`);let G=w($.restoredFromCache?"Restoring from cache...":"Syncing wallet...");if(Y)Y.current=(K,J)=>G.update(`Syncing wallet... (${J}, retrying)`);try{if(await w0($,{syncMode:"lite",onProgress:(P,x)=>{if(x>0){let F=Math.min(Math.round(P/x*100),100);G.update(F>=100?"Syncing wallet...":`Syncing wallet... ${F}%`)}},onSyncDetail:(P)=>{G.update(`Syncing wallet... (waiting on: ${P})`)}}),q?.aborted)throw new Error("Operation cancelled");G.update("Checking dust status...");let K=await g1($);if(!X)try{await _0(Q,Z,$.facade)}catch{}let J=K.dust.balance(new Date),B=K.dust.availableCoins.length>0,j=K.unshielded.availableCoins,U=j.filter((P)=>P.meta?.registeredForDustGeneration!==!0),W=j.length-U.length,V=K.unshielded.balances[A3.unshieldedToken().raw]??0n;if(G.stop("Done"),z){M({subcommand:"status",dustBalance:s0(J),registered:W,unregistered:U.length,nightBalance:S0(V),dustAvailable:B});return}process.stdout.write(`dust=${J}
|
|
191
191
|
`),process.stdout.write(`registered=${W}
|
|
192
192
|
`),process.stdout.write(`unregistered=${U.length}
|
|
193
|
-
`),process.stderr.write(L("NIGHT Balance",R(
|
|
194
|
-
`),process.stderr.write(L("Dust Balance",R(
|
|
195
|
-
`),process.stderr.write(L("Dust Available",
|
|
193
|
+
`),process.stderr.write(L("NIGHT Balance",R(a0(V)))+`
|
|
194
|
+
`),process.stderr.write(L("Dust Balance",R(e0(J)))+`
|
|
195
|
+
`),process.stderr.write(L("Dust Available",B?"yes":"no")+`
|
|
196
196
|
`),process.stderr.write(L("Registered",W.toString()+" UTXO(s)")+`
|
|
197
197
|
`),process.stderr.write(L("Unregistered",U.length.toString()+" UTXO(s)")+`
|
|
198
198
|
`),process.stderr.write(`
|
|
199
199
|
`+C()+`
|
|
200
200
|
|
|
201
|
-
`)}catch(K){throw G.stop("Failed"),K}}var
|
|
202
|
-
`)}else if(X){if(q1(void 0,X),z){M({action:"clear",scope:"network",network:X});return}process.stderr.write(
|
|
203
|
-
`)}else{if(q1(),z){M({action:"clear",scope:"all"});return}process.stderr.write(
|
|
204
|
-
`)}}var
|
|
205
|
-
Valid keys: ${
|
|
206
|
-
Valid keys: ${
|
|
207
|
-
`)}else if(Z==="unset"){k1(Q);let X=Q==="network"?"(default)":"(removed)";if(I($,"json")){M({action:"unset",key:Q,value:X});return}process.stderr.write(
|
|
201
|
+
`)}catch(K){throw G.stop("Failed"),K}}var C3=E(()=>{I0();X0();o();Q0();l1();Y1();j1();c();V0()});var y3={};f(y3,{default:()=>N3});async function N3($){if($.subcommand!=="clear")throw new Error("Usage: midnight cache clear [--network <name>] [--wallet <name|file>]");let Q=_($,"wallet"),X=_($,"network"),z=I($,"json");if(Q){let q=u(Q),Y=m(q),{name:G}=t({args:$}),K=Y.addresses[G];if(q1(K,G),z){M({action:"clear",scope:"wallet",wallet:Q,network:G});return}process.stderr.write(b("✓")+` Cache cleared for wallet "${Q}" on ${G}
|
|
202
|
+
`)}else if(X){if(q1(void 0,X),z){M({action:"clear",scope:"network",network:X});return}process.stderr.write(b("✓")+` Cache cleared for network "${X}"
|
|
203
|
+
`)}else{if(q1(),z){M({action:"clear",scope:"all"});return}process.stderr.write(b("✓")+` Cache cleared
|
|
204
|
+
`)}}var S3=E(()=>{Y1();X0();o()});var v3={};f(v3,{default:()=>b3});async function b3($){let Z=$.subcommand;if(!Z||!["get","set","unset"].includes(Z))throw new Error(`Usage: midnight config <get|set|unset> <key> [value]
|
|
205
|
+
Valid keys: ${n0().join(", ")}`);let Q=$.positionals[0];if(!Q)throw new Error(`Missing config key.
|
|
206
|
+
Valid keys: ${n0().join(", ")}`);if(Z==="get"){let X=b1(Q);if(I($,"json")){M({action:"get",key:Q,value:X});return}process.stdout.write(X+`
|
|
207
|
+
`)}else if(Z==="unset"){k1(Q);let X=Q==="network"?"(default)":"(removed)";if(I($,"json")){M({action:"unset",key:Q,value:X});return}process.stderr.write(b("✓")+` ${Q} ${X}
|
|
208
208
|
`)}else{let X=$.positionals[1];if(X===void 0)throw new Error(`Missing value for config set.
|
|
209
|
-
Usage: midnight config set ${Q} <value>`);if(v1(Q,X),I($,"json")){M({action:"set",key:Q,value:X});return}process.stderr.write(
|
|
210
|
-
`)}}var
|
|
209
|
+
Usage: midnight config set ${Q} <value>`);if(v1(Q,X),I($,"json")){M({action:"set",key:Q,value:X});return}process.stderr.write(b("✓")+` ${Q} = ${X}
|
|
210
|
+
`)}}var k3=E(()=>{P0()});import{execSync as p0}from"child_process";import{existsSync as w3,mkdirSync as X7,readFileSync as z7,writeFileSync as h3}from"fs";import{homedir as q7}from"os";import{join as e1}from"path";function p3(){try{return p0("docker compose version",{...V1,timeout:1e4}).trim()}catch{try{throw p0("docker --version",{...V1,timeout:5000}),new Error(`Docker Compose v2 is required.
|
|
211
211
|
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.
|
|
212
|
-
Install Docker from https://docs.docker.com/get-docker/`)}}}function
|
|
213
|
-
`),Q=[];for(let X of Z){if(!X.trim())continue;try{let z=JSON.parse(X),q=z.Service??"unknown";Q.push({name:q,state:z.State??"unknown",health:z.Health??"",port:G7[q]??"",image:z.Image??""})}catch{}}return Q}catch{return[]}}function
|
|
212
|
+
Install Docker from https://docs.docker.com/get-docker/`)}}}function u3(){if(w3(s1)&&w3(B1)&&z7(s1,"utf-8").trim()===f3)return!1;return X7($2,{recursive:!0,mode:e}),h3(B1,Y7,"utf-8"),h3(s1,f3,"utf-8"),!0}function T0($){return p0(`docker compose -f "${B1}" ${$}`,V1)}function H1(){try{let $=T0("ps --format json");if(!$.trim())return[];let Z=$.trim().split(`
|
|
213
|
+
`),Q=[];for(let X of Z){if(!X.trim())continue;try{let z=JSON.parse(X),q=z.Service??"unknown";Q.push({name:q,state:z.State??"unknown",health:z.Health??"",port:G7[q]??"",image:z.Image??""})}catch{}}return Q}catch{return[]}}function m3($=120000,Z=3000){let Q=Date.now()+$;while(Date.now()<Q){let X=H1();if(X.length===3&&X.every((q)=>q.state==="running")){if(X.every((Y)=>Y.health==="healthy"||Y.health===""))return!0}p0(`sleep ${Z/1000}`,{timeout:Z+1000})}return!1}function Z2(){return B1}function c3(){let $=[];for(let Z of K7)try{p0(`docker rm -f "${Z}"`,{...V1,timeout:1e4}),$.push(Z)}catch{}return $}var f3="2.0.0",$2,B1,s1,Y7=`services:
|
|
214
214
|
proof-server:
|
|
215
215
|
image: 'midnightntwrk/proof-server:8.0.0-rc.5'
|
|
216
216
|
container_name: "proof-server"
|
|
@@ -252,20 +252,20 @@ Install Docker from https://docs.docker.com/get-docker/`)}}}function u$(){if(w$(
|
|
|
252
252
|
start_period: 5s
|
|
253
253
|
environment:
|
|
254
254
|
CFG_PRESET: "dev"
|
|
255
|
-
`,
|
|
256
|
-
`)}async function j7($){if(
|
|
257
|
-
`);let Q=w("Starting local network...");try{if(
|
|
255
|
+
`,V1,G7,K7;var g3=E(()=>{$2=e1(q7(),g,x2),B1=e1($2,"compose.yml"),s1=e1($2,".version"),V1={encoding:"utf-8",timeout:30000};G7={node:"9944",indexer:"8088","proof-server":"6300"};K7=["node","indexer","proof-server"]});var o3={};f(o3,{default:()=>i3});import{spawn as J7}from"child_process";function U7($){return d3.includes($)}function l3($){let Z=[];for(let Q of $){let X=Q.state==="running"?b:a,z=Q.health?` (${Q.health})`:"",q=Q.port?`:${Q.port}`:"",Y=Q.image?` ${H(Q.image)}`:"";if(Z.push(` ${Q.name.padEnd(16)}${X(Q.state)}${H(z)}${H(q)}`),Y)Z.push(Y)}return Z.join(`
|
|
256
|
+
`)}async function j7($){if(u3())process.stderr.write(H(` Wrote compose.yml to ${Z2()}`)+`
|
|
257
|
+
`);let Q=w("Starting local network...");try{if(T0("up -d"),Q.update("Waiting for services to be healthy..."),!m3(120000))Q.stop(q0("Services started but not all healthy yet")),process.stderr.write(`
|
|
258
258
|
`+H(" Tip: run ")+R("midnight localnet logs")+H(" to check for errors")+`
|
|
259
259
|
`);else Q.stop("Local network is running")}catch(z){if(Q.stop(a("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
|
|
260
260
|
`+`(likely from a previous midnight-local-network setup).
|
|
261
261
|
|
|
262
262
|
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.
|
|
263
263
|
`+"Check ports 9944, 8088, and 6300, then try again.")}throw z}let X=H1();if($){M({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(`
|
|
264
|
-
`+
|
|
264
|
+
`+l3(X)+`
|
|
265
265
|
`);for(let z of X)process.stdout.write(`${z.name}=${z.state}:${z.port}
|
|
266
266
|
`);process.stderr.write(`
|
|
267
267
|
`+H(" Next: ")+R("midnight wallet generate dev --network undeployed")+`
|
|
268
|
-
`)}async function
|
|
268
|
+
`)}async function B7($){let Z=w("Stopping local network...");try{if(T0("stop"),Z.stop("Local network stopped (containers preserved)"),$){M({subcommand:"stop",status:"stopped"});return}}catch(Q){throw Z.stop(a("Failed to stop local network")),Q}}async function V7($){let Z=w("Tearing down local network...");try{if(T0("down --volumes"),Z.stop("Local network removed (containers, networks, volumes)"),$){M({subcommand:"down",status:"removed"});return}}catch(Q){throw Z.stop(a("Failed to tear down local network")),Q}}async function H7($){let Z=H1();if($){M({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(`
|
|
269
269
|
`+D("Localnet Status")+`
|
|
270
270
|
|
|
271
271
|
`),process.stderr.write(H(" No services running.")+`
|
|
@@ -274,12 +274,12 @@ Run "midnight localnet clean" to remove them, then try again.`);if(z.message.inc
|
|
|
274
274
|
`);return}process.stderr.write(`
|
|
275
275
|
`+D("Localnet Status")+`
|
|
276
276
|
|
|
277
|
-
`),process.stderr.write(
|
|
277
|
+
`),process.stderr.write(l3(Z)+`
|
|
278
278
|
`),process.stderr.write(`
|
|
279
279
|
`+C()+`
|
|
280
280
|
|
|
281
281
|
`);for(let Q of Z)process.stdout.write(`${Q.name}=${Q.state}:${Q.port}
|
|
282
|
-
`)}async function W7($){let Z=w("Removing conflicting containers...");try{try{
|
|
282
|
+
`)}async function W7($){let Z=w("Removing conflicting containers...");try{try{T0("down")}catch{}let Q=c3();if(Q.length>0)Z.stop(`Removed ${Q.length} container${Q.length>1?"s":""}: ${Q.join(", ")}`);else Z.stop("No conflicting containers found");if($){M({subcommand:"clean",status:"cleaned",removed:Q});return}}catch(Q){throw Z.stop(a("Failed to clean up")),Q}}async function L7(){let $=Z2(),Z=J7("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 i3($){let Z=$.subcommand;if(!Z||!U7(Z))throw new Error(`Usage: midnight localnet <${d3.join("|")}>
|
|
283
283
|
|
|
284
284
|
Subcommands:
|
|
285
285
|
up Start the local network
|
|
@@ -289,21 +289,21 @@ Subcommands:
|
|
|
289
289
|
logs Stream service logs
|
|
290
290
|
clean Remove conflicting containers
|
|
291
291
|
|
|
292
|
-
Example: midnight localnet up`);
|
|
292
|
+
Example: midnight localnet up`);p3();let Q=I($,"json");switch(process.stderr.write(`
|
|
293
293
|
`+D("Localnet")+`
|
|
294
294
|
|
|
295
|
-
`),Z){case"up":return j7(Q);case"stop":return
|
|
295
|
+
`),Z){case"up":return j7(Q);case"stop":return B7(Q);case"down":return V7(Q);case"status":return H7(Q);case"logs":return L7();case"clean":return W7(Q)}}var d3;var n3=E(()=>{g3();c();V0();d3=["up","stop","down","status","logs","clean"]});var e3={};f(e3,{default:()=>s3});import*as a3 from"fs";import*as Q2 from"path";import{homedir as P7}from"os";import{generateMnemonic as F7,mnemonicToSeedSync as t3,validateMnemonic as O7}from"@scure/bip39";import{wordlist as r3}from"@scure/bip39/wordlists/english.js";async function s3($){let Z=$.subcommand;switch(Z){case"generate":return I7($);case"list":case"ls":return M7($);case"use":return _7($);case"info":return T7($);case"remove":case"rm":return R7($);default:throw new Error(`Unknown wallet subcommand: "${Z??"(none)"}"
|
|
296
296
|
Available: generate, list, use, info, remove
|
|
297
297
|
Run "midnight help wallet" for usage.`)}}async function I7($){let Z=$.positionals[0];if(!Z)throw new Error(`Missing wallet name.
|
|
298
298
|
Usage: midnight wallet generate <name> [--network <name>]`);if(!K0(Z))throw new Error(`Invalid wallet name: "${Z}"
|
|
299
|
-
Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Q=d({args:$}),X=_($,"seed"),z=_($,"mnemonic");if(X!==void 0&&z!==void 0)throw new Error("Cannot specify both --seed and --mnemonic. Use one or the other.");let q=Q2.join(P7(),g,
|
|
300
|
-
Use --force to overwrite.`);let G,K;if(X!==void 0){let W=X.replace(/^0x/,"");if(W.length!==64||!/^[0-9a-fA-F]+$/.test(W))throw new Error("Seed must be a 64-character hex string (32 bytes)");G=Buffer.from(W,"hex")}else if(z!==void 0){if(!O7(z,
|
|
299
|
+
Wallet name must be a simple name (no path separators, .json suffix, or special characters).`);let Q=d({args:$}),X=_($,"seed"),z=_($,"mnemonic");if(X!==void 0&&z!==void 0)throw new Error("Cannot specify both --seed and --mnemonic. Use one or the other.");let q=Q2.join(P7(),g,l0),Y=Q2.join(q,`${Z}.json`);if(a3.existsSync(Y)&&!I($,"force"))throw new Error(`Wallet "${Z}" already exists: ${Y}
|
|
300
|
+
Use --force to overwrite.`);let G,K;if(X!==void 0){let W=X.replace(/^0x/,"");if(W.length!==64||!/^[0-9a-fA-F]+$/.test(W))throw new Error("Seed must be a 64-character hex string (32 bytes)");G=Buffer.from(W,"hex")}else if(z!==void 0){if(!O7(z,r3))throw new Error("Invalid BIP-39 mnemonic. Expected 12 or 24 words from the English wordlist.");K=z,G=Buffer.from(t3(K).slice(0,32))}else K=F7(r3,256),G=Buffer.from(t3(K).slice(0,32));let J=U0(G),B=J[Q],j={seed:G.toString("hex"),addresses:J,createdAt:new Date().toISOString()};if(K)j.mnemonic=K;let U=r0(j,Y);if(p1(Z),I($,"json")){let W={name:Z,addresses:J,activeAddress:B,activeNetwork:Q,seed:G.toString("hex"),file:U,createdAt:j.createdAt,active:!0};if(K)W.mnemonic=K;M(W);return}if(process.stdout.write(B+`
|
|
301
301
|
`),process.stderr.write(`
|
|
302
302
|
`+D("Wallet Generated")+`
|
|
303
303
|
|
|
304
304
|
`),process.stderr.write(L("Name",Z)+`
|
|
305
305
|
`),process.stderr.write(L("Network",Q)+`
|
|
306
|
-
`),process.stderr.write(L("Address",v(
|
|
306
|
+
`),process.stderr.write(L("Address",v(B))+`
|
|
307
307
|
`),process.stderr.write(L("File",U)+`
|
|
308
308
|
`),process.stderr.write(L("Active","yes")+`
|
|
309
309
|
`),process.stderr.write(`
|
|
@@ -316,27 +316,27 @@ Use --force to overwrite.`);let G,K;if(X!==void 0){let W=X.replace(/^0x/,"");if(
|
|
|
316
316
|
`),process.stderr.write(C()+`
|
|
317
317
|
`),process.stderr.write(H(" Next: midnight wallet list | midnight balance")+`
|
|
318
318
|
|
|
319
|
-
`),process.stderr.write(
|
|
320
|
-
`)}async function M7($){let Z=
|
|
319
|
+
`),process.stderr.write(b("✓")+` Wallet saved
|
|
320
|
+
`)}async function M7($){let Z=S2();if(I($,"json")){M({wallets:Z});return}if(Z.length===0){process.stderr.write(`
|
|
321
321
|
No wallets found.
|
|
322
322
|
`),process.stderr.write(H(" Create one: midnight wallet generate <name> --network <name>")+`
|
|
323
323
|
|
|
324
324
|
`);return}let Q=d({args:$});process.stderr.write(`
|
|
325
325
|
`+D("Wallets")+`
|
|
326
326
|
|
|
327
|
-
`);for(let X of Z){let z=X.isActive?
|
|
327
|
+
`);for(let X of Z){let z=X.isActive?b(" ●"):" ",q=X.name.padEnd(16),Y=X.isActive?R(r(q)):r(q),G=X.addresses[Q]??"(unknown)",K=G.length>30?G.slice(0,20)+"..."+G.slice(-8):G;process.stderr.write(`${z} ${Y} ${K.padEnd(35)} ${H(Q)}
|
|
328
328
|
`)}process.stderr.write(`
|
|
329
329
|
`+C()+`
|
|
330
330
|
`),process.stderr.write(H(" ● = active wallet")+`
|
|
331
331
|
|
|
332
332
|
`)}async function _7($){let Z=$.positionals[0];if(!Z)throw new Error(`Missing wallet name.
|
|
333
|
-
Usage: midnight wallet use <name>`);if(p1(Z),I($,"json")){M({wallet:Z,active:!0});return}process.stderr.write(
|
|
334
|
-
`)}async function T7($){let Z=$.positionals[0]??
|
|
333
|
+
Usage: midnight wallet use <name>`);if(p1(Z),I($,"json")){M({wallet:Z,active:!0});return}process.stderr.write(b("✓")+` Active wallet set to "${Z}"
|
|
334
|
+
`)}async function T7($){let Z=$.positionals[0]??C0(),Q=u(Z),X=m(Q),z=Z===C0(),q=d({args:$}),Y=X.addresses[q];if(I($,"json")){M({name:Z,addresses:X.addresses,activeAddress:Y,activeNetwork:q,createdAt:X.createdAt,file:Q,active:z});return}process.stdout.write(Y+`
|
|
335
335
|
`),process.stderr.write(`
|
|
336
336
|
`+D("Wallet Info")+`
|
|
337
337
|
|
|
338
338
|
`),process.stderr.write(L("Name",Z)+`
|
|
339
|
-
`);for(let[G,K]of Object.entries(X.addresses)){let J=G===q,
|
|
339
|
+
`);for(let[G,K]of Object.entries(X.addresses)){let J=G===q,B=J?R(G):G,j=J?" *":"";process.stderr.write(L(B+j,v(K))+`
|
|
340
340
|
`)}process.stderr.write(L("Created",X.createdAt)+`
|
|
341
341
|
`),process.stderr.write(L("File",Q)+`
|
|
342
342
|
`),process.stderr.write(L("Active",z?"yes":"no")+`
|
|
@@ -345,28 +345,28 @@ Usage: midnight wallet use <name>`);if(p1(Z),I($,"json")){M({wallet:Z,active:!0}
|
|
|
345
345
|
`+C()+`
|
|
346
346
|
|
|
347
347
|
`)}async function R7($){let Z=$.positionals[0];if(!Z)throw new Error(`Missing wallet name.
|
|
348
|
-
Usage: midnight wallet remove <name>`);if(
|
|
349
|
-
`)}var
|
|
348
|
+
Usage: midnight wallet remove <name>`);if(b2(Z),I($,"json")){M({wallet:Z,removed:!0});return}process.stderr.write(b("✓")+` Wallet "${Z}" removed
|
|
349
|
+
`)}var $$=E(()=>{j0();o();X0();c()});var q$={};f(q$,{default:()=>z$});function z2($){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 X2($){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 W1($){let Z=`${i0}${$}`,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 D7($){let Z=_($,"network");if(Z)return Z;try{let{loadCliConfig:Q}=await Promise.resolve().then(() => (P0(),D2)),X=Q();if(X.network&&Z0(X.network))return X.network}catch{}return}async function P1($,Z={}){let Q=new AbortController,X=setTimeout(()=>Q.abort(),E7),z=Date.now();try{return{response:await fetch($,{...Z,signal:Q.signal}),latencyMs:Date.now()-z}}finally{clearTimeout(X)}}async function C7($){let Z=new Date().toISOString();try{let{response:Q,latencyMs:X}=await P1($,{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 q=z.data?.block?.height;return{status:X>L1?"degraded":"up",latencyMs:X,lastChecked:Z,...q!==void 0?{blockHeight:q}:{},...X>L1?{notes:`Slow (${X}ms)`}:{}}}catch(Q){return{status:"down",latencyMs:0,lastChecked:Z,notes:Q.message}}}async function N7($){let Z=new Date().toISOString(),Q=$.replace(/^wss:/,"https:").replace(/^ws:/,"http:");try{let{response:X,latencyMs:z}=await P1(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 Y=(await X.json())?.result;if(!Y)return{status:"down",latencyMs:z,lastChecked:Z,notes:"No result in response"};let G=Y.peers??0,K=Y.isSyncing??!1,J="up",B;if(K)J="degraded",B="Node is syncing";else if(G===0)J="degraded",B="No peers";return{status:J,latencyMs:z,lastChecked:Z,peers:G,isSyncing:K,...B?{notes:B}:{}}}catch(X){return{status:"down",latencyMs:0,lastChecked:Z,notes:X.message}}}async function y7($){let Z=new Date().toISOString();if(!$)return{status:"unknown",latencyMs:0,lastChecked:Z,notes:"No faucet URL"};try{let{response:Q,latencyMs:X}=await P1($);if(!Q.ok)return{status:"down",latencyMs:X,lastChecked:Z,notes:`HTTP ${Q.status}`};return{status:X>Q$?"degraded":"up",latencyMs:X,lastChecked:Z,...X>Q$?{notes:`Slow (${X}ms)`}:{}}}catch(Q){return{status:"down",latencyMs:0,lastChecked:Z,notes:Q.message}}}async function S7($){let Z=new Date().toISOString();if(!$)return{status:"unknown",latencyMs:0,lastChecked:Z,notes:"URL not configured"};try{let{response:Q,latencyMs:X}=await P1($);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>L1?"degraded":"up",latencyMs:X,lastChecked:Z,...X>L1?{notes:`Slow (${X}ms)`}:{}}}catch(Q){return{status:"down",latencyMs:0,lastChecked:Z,notes:Q.message}}}async function X$($){if(!Z0($))return{};let Z=w1($),Q=x7[$];if(!Q)return{};let[X,z,q,Y]=await Promise.all([C7(Z.indexer),N7(Z.node),y7(Q.faucet),S7(Q.explorer)]);return{indexer:X,rpc:z,faucet:q,explorer:Y}}function b7($,Z,Q){process.stderr.write(`
|
|
350
350
|
`+R($)+`
|
|
351
351
|
`),process.stderr.write(H(" "+"─".repeat(62))+`
|
|
352
|
-
`);let X=new Set([...Object.keys(Q),...Z?Object.keys(Z):[]]);for(let z of X){let q=Q[z],Y=Z?.[z],G=(A7[z]??z).padEnd(18);if(q){let K=
|
|
353
|
-
`)}else if(Y){let K=
|
|
352
|
+
`);let X=new Set([...Object.keys(Q),...Z?Object.keys(Z):[]]);for(let z of X){let q=Q[z],Y=Z?.[z],G=(A7[z]??z).padEnd(18);if(q){let K=Z$[q.status]??H("—"),J=q.latencyMs>0?H(` ${q.latencyMs}ms`):"",B=q.notes?H(` — ${q.notes}`):"",j="";if(Y&&Y.status!==q.status&&Y.status!=="unknown")j=H(` (canary: ${Y.status}${Y.lastChecked?" "+z2(Y.lastChecked):""})`);process.stderr.write(` ${y0(G)}${K}${J}${B}${j}
|
|
353
|
+
`)}else if(Y){let K=Z$[Y.status]??H("—"),J=Y.latencyMs>0?H(` ${Y.latencyMs}ms`):"",B=Y.lastChecked?H(` (${z2(Y.lastChecked)})`):"",j=Y.notes?H(` — ${Y.notes}`):"";process.stderr.write(` ${y0(G)}${K}${J}${B}${j}
|
|
354
354
|
`)}}}function v7($,Z){let Q=Z?$.filter((X)=>X.affects.toLowerCase().includes(Z.toLowerCase())):$;if(Q.length===0)return;process.stderr.write(`
|
|
355
355
|
`+D("Known Issues")+`
|
|
356
356
|
|
|
357
357
|
`);for(let X of Q)process.stderr.write(` ${a(X.id.padEnd(28))}${X.summary}
|
|
358
358
|
`),process.stderr.write(` ${" ".repeat(28)}${H(X.status)}
|
|
359
|
-
`)}async function
|
|
359
|
+
`)}async function z$($){let Z=I($,"json"),Q=I($,"all"),X=I($,"watch"),z=await D7($)??"preprod",q=w("Checking network status..."),Y=null,G=null,K,J;if(Q)J=["preprod","preview"];else J=[z];let[B,...j]=await Promise.all([Promise.all([W1("/api/status"),W1("/api/issues")]).catch((P)=>{return K=P.message,null}),...J.map((P)=>X$(P))]);if(B)[Y,G]=B;q.stop("Done");let U={};for(let P=0;P<J.length;P++)U[J[P]]=j[P];if(Z){let P={lastUpdated:Y?.lastUpdated??null,dashboard:i0,canaryAvailable:Y!==null,networks:{}};for(let F of J){let O=U[F]??{},A=Y?.networks[F],k={...A,...O};P.networks[F]={overall:X2(k),live:O,canary:A??null}}if(G){let F=Q?void 0:J[0];P.issues=F?G.issues.filter((O)=>O.affects.toLowerCase().includes(F.toLowerCase())):G.issues}if(K)P.canaryError=K;M(P);let x=J.reduce((F,O)=>{let A={...Y?.networks[O]??{},...U[O]??{}},k=X2(A);if(k==="down")return"down";if(k==="degraded"&&F!=="down")return"degraded";return F},"up");if(x==="down")process.exitCode=2;else if(x==="degraded")process.exitCode=1;return}let W=()=>{if(process.stderr.write(`
|
|
360
360
|
`+D("Midnight Network Status")+`
|
|
361
361
|
`),Y?.lastUpdated)process.stderr.write(H(` Canary: ${z2(Y.lastUpdated)}`)+" ");if(process.stderr.write(H("Live: just now")+`
|
|
362
362
|
`),K)process.stderr.write(H(` (Dashboard unreachable: ${K})`)+`
|
|
363
363
|
`);if(J.length===0){process.stderr.write(`
|
|
364
364
|
`+H("No network data available.")+`
|
|
365
365
|
|
|
366
|
-
`);return}for(let P of J)
|
|
366
|
+
`);return}for(let P of J)b7(P,Y?.networks[P],U[P]??{});if(G){let P=Q?void 0:J[0];v7(G.issues,P)}process.stderr.write(`
|
|
367
367
|
`+C()+`
|
|
368
|
-
`),process.stderr.write(H(" Dashboard: ")+r(
|
|
368
|
+
`),process.stderr.write(H(" Dashboard: ")+r(i0)+`
|
|
369
369
|
|
|
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)=>
|
|
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.1",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}
|
|
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)=>X$(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 V=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(V==="down")process.exitCode=2;else if(V==="degraded")process.exitCode=1}var x7,A7,Z$,E7=15000,L1=5000,Q$=1e4;var Y$=E(()=>{Q0();c();V0();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"},Z$={up:b("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 m0={name:"midnight-wallet-cli",version:"0.2.3",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=m0.name,B2=m0.version,r7=m0.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(() => ($3(),e2)),"genesis-address":()=>Promise.resolve().then(() => (X3(),Q3)),"inspect-cost":()=>Promise.resolve().then(() => (G3(),Y3)),airdrop:()=>Promise.resolve().then(() => (_3(),M3)),transfer:()=>Promise.resolve().then(() => (x3(),R3)),dust:()=>Promise.resolve().then(() => (C3(),D3)),cache:()=>Promise.resolve().then(() => (S3(),y3)),config:()=>Promise.resolve().then(() => (k3(),v3)),localnet:()=>Promise.resolve().then(() => (n3(),o3)),wallet:()=>Promise.resolve().then(() => ($$(),e3)),status:()=>Promise.resolve().then(() => (Y$(),q$))};async function y($){let Z=p7[$];if(!Z)throw new Error(`Unknown command handler: ${$}`);return(await Z()).default}var G$=[{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:B2},{capabilities:{tools:{}}});q2.setRequestHandler(h7,async()=>{return{tools:G$.map(($)=>({name:$.name,description:$.description,inputSchema:$.inputSchema}))}});q2.setRequestHandler(f7,async($)=>{let{name:Z,arguments:Q}=$.params,X=G$.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)});
|