midnight-wallet-cli 0.1.3 → 0.1.5

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.
Files changed (3) hide show
  1. package/README.md +14 -15
  2. package/dist/wallet.js +105 -61
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?logo=typescript)](https://www.typescriptlang.org/)
7
7
  [![CI](https://github.com/nel349/midnight-wallet-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/nel349/midnight-wallet-cli/actions/workflows/ci.yml)
8
8
 
9
- A standalone CLI wallet for the Midnight blockchain. Manage wallets, check balances, transfer NIGHT tokens, and run a local devnet — all from the terminal.
9
+ A standalone CLI wallet for the Midnight blockchain. Manage wallets, check balances, transfer NIGHT tokens, and run a local network — all from the terminal.
10
10
 
11
11
  ## Install
12
12
 
@@ -14,7 +14,7 @@ A standalone CLI wallet for the Midnight blockchain. Manage wallets, check balan
14
14
  npm install -g midnight-wallet-cli
15
15
  ```
16
16
 
17
- This installs three commands: `midnight` (or `mn` for short) and `midnight-wallet-mcp`.
17
+ This installs two commands: `midnight` (or `mn` for short) and `midnight-wallet-mcp`.
18
18
 
19
19
  ## Commands
20
20
 
@@ -24,7 +24,7 @@ This installs three commands: `midnight` (or `mn` for short) and `midnight-walle
24
24
  | `midnight info` | Display wallet address, network, creation date |
25
25
  | `midnight balance [address]` | Check unshielded NIGHT balance |
26
26
  | `midnight transfer <to> <amount>` | Send NIGHT tokens to another address |
27
- | `midnight airdrop <amount>` | Fund wallet from genesis (local devnet only) |
27
+ | `midnight airdrop <amount>` | Fund wallet from genesis (undeployed network only) |
28
28
  | `midnight dust register` | Register NIGHT UTXOs for dust (fee token) generation |
29
29
  | `midnight dust status` | Check dust registration status and balance |
30
30
  | `midnight address --seed <hex>` | Derive an address from a seed |
@@ -37,29 +37,28 @@ This installs three commands: `midnight` (or `mn` for short) and `midnight-walle
37
37
  ## Quick Start
38
38
 
39
39
  ```bash
40
+ # Start local network
41
+ midnight localnet up
42
+
40
43
  # Generate a wallet
41
- midnight generate --network preprod
44
+ midnight generate --network undeployed
45
+
46
+ # Airdrop tokens and register dust
47
+ midnight airdrop 1000
48
+ midnight dust register
42
49
 
43
50
  # Check balance
44
51
  midnight balance
45
52
 
46
53
  # Transfer NIGHT
47
- midnight transfer mn_addr_preprod1... 100
48
-
49
- # Local devnet: start network, airdrop, register dust
50
- midnight localnet up
51
- midnight generate --network undeployed
52
- midnight airdrop 1000
53
- midnight dust register
54
+ midnight transfer mn_addr_undeployed1... 100
54
55
  ```
55
56
 
56
57
  ## Supported Networks
57
58
 
58
59
  | Network | Description |
59
60
  |---------|-------------|
60
- | `preprod` | Midnight pre-production testnet |
61
- | `preview` | Midnight preview testnet |
62
- | `undeployed` | Local devnet via Docker (`midnight localnet up`) |
61
+ | `undeployed` | Local network via Docker (`midnight localnet up`) |
63
62
 
64
63
  ## JSON Output for Automation
65
64
 
@@ -190,4 +189,4 @@ Once connected, your AI agent gets access to 17 tools:
190
189
 
191
190
  - Node.js >= 20
192
191
  - Docker (for `midnight localnet` commands)
193
- - A running proof server on `localhost:6300` (for transactions on local devnet)
192
+ - A running proof server on `localhost:6300` (for transactions on undeployed network)
package/dist/wallet.js CHANGED
@@ -102,10 +102,13 @@ function green(text) {
102
102
  function yellow(text) {
103
103
  return fg(text, YELLOW_CODE);
104
104
  }
105
+ function white(text) {
106
+ return fg(text, WHITE_CODE);
107
+ }
105
108
  function gray(text) {
106
109
  return fg(text, DIM_GRAY);
107
110
  }
108
- var ESC = "\x1B[", RESET = "\x1B[0m", TEAL = 38, DIM_GRAY = 245, RED_CODE = 196, GREEN_CODE = 40, YELLOW_CODE = 226;
111
+ var ESC = "\x1B[", RESET = "\x1B[0m", TEAL = 38, WHITE_CODE = 15, DIM_GRAY = 245, RED_CODE = 196, GREEN_CODE = 40, YELLOW_CODE = 226;
109
112
 
110
113
  // src/ui/format.ts
111
114
  function header(title, width = DEFAULT_WIDTH) {
@@ -2810,6 +2813,26 @@ var init_mcp_server = __esm(() => {
2810
2813
  });
2811
2814
 
2812
2815
  // src/ui/art.ts
2816
+ function getWordmarkTypingFrame(progress) {
2817
+ const clamped = Math.max(0, Math.min(1, progress));
2818
+ const width = WORDMARK_BIG[0].length;
2819
+ const visibleCols = Math.floor(clamped * width);
2820
+ return WORDMARK_BIG.map((line) => line.slice(0, visibleCols).padEnd(width));
2821
+ }
2822
+ function getWordmarkMaterializeFrame(progress) {
2823
+ const clamped = Math.max(0, Math.min(1, progress));
2824
+ const seed = Math.floor(progress * 100);
2825
+ if (clamped >= 1)
2826
+ return WORDMARK_BIG;
2827
+ return WORDMARK_BIG.map((line, row) => Array.from(line).map((ch, col) => {
2828
+ if (ch === " ")
2829
+ return " ";
2830
+ if (clamped <= 0)
2831
+ return noiseChar(row + 20, col, 0);
2832
+ const threshold = ((row + 20) * 131 + col * 997) % 100 / 100;
2833
+ return clamped >= threshold ? ch : noiseChar(row + 20, col, seed);
2834
+ }).join(""));
2835
+ }
2813
2836
  function noiseChar(row, col, seed) {
2814
2837
  const hash = (row * 131 + col * 997 + seed * 7919) % 65537 / 65537;
2815
2838
  return NOISE_CHARS[Math.floor(hash * NOISE_CHARS.length)];
@@ -2833,26 +2856,30 @@ function getMaterializeFrame(progress) {
2833
2856
  }).join("")).join(`
2834
2857
  `);
2835
2858
  }
2836
- function getWordmarkFrame(progress) {
2837
- const clamped = Math.max(0, Math.min(1, progress));
2838
- const visibleChars = Math.floor(clamped * WORDMARK.length);
2839
- return WORDMARK.slice(0, visibleChars);
2840
- }
2841
- var MIDNIGHT_LOGO, WORDMARK = "m i d n i g h t", COMMAND_BRIEFS, NOISE_CHARS;
2859
+ var MIDNIGHT_LOGO, WORDMARK_BIG, COMMAND_BRIEFS, NOISE_CHARS;
2842
2860
  var init_art = __esm(() => {
2843
2861
  MIDNIGHT_LOGO = [
2844
- " ██████████████ ",
2845
- " ██ ██ ",
2846
- " ██ ██████ ██ ",
2847
- " ██ ██████ ██ ",
2848
- " ██ ██ ",
2849
- " ██ ██████ ██ ",
2850
- " ██ ██████ ██ ",
2851
- " ██ ██ ",
2852
- " ██ ██ ",
2853
- " ██████████████ "
2862
+ " ████████████ ",
2863
+ " ███ ███ ",
2864
+ " ███ ██ ███ ",
2865
+ " ██ ██ ",
2866
+ " ██ ██ ██ ",
2867
+ " ██ ██ ",
2868
+ " ██ ██ ██ ",
2869
+ " ██ ██ ",
2870
+ " ██ ██ ",
2871
+ " ██ ██ ",
2872
+ " ██ ██ ",
2873
+ " ███ ███ ",
2874
+ " ███ ███ ",
2875
+ " ████████████ "
2854
2876
  ].join(`
2855
2877
  `);
2878
+ WORDMARK_BIG = [
2879
+ "█▄ ▄█ █ █▀▄ █▄ █ █ █▀▀ █ █ ▀█▀",
2880
+ "█ █ █ █ █ █ █ ██ █ █ █ █▀█ █ ",
2881
+ "▀ ▀ ▀ ▀▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ "
2882
+ ];
2856
2883
  COMMAND_BRIEFS = [
2857
2884
  ["generate", "Generate or restore a wallet"],
2858
2885
  ["info", "Display wallet metadata"],
@@ -2884,34 +2911,38 @@ function sleep(ms, signal) {
2884
2911
  }, { once: true });
2885
2912
  });
2886
2913
  }
2887
- function writeLine(text) {
2888
- process.stderr.write(`\r${text}\x1B[K`);
2889
- }
2890
2914
  async function animateMaterialize(signal, sideContent) {
2891
2915
  const totalFrames = 20;
2892
2916
  const logoLines = MIDNIGHT_LOGO.split(`
2893
2917
  `);
2894
2918
  const logoLineCount = logoLines.length;
2919
+ const rightCol = 36;
2920
+ const totalHeight = Math.max(logoLineCount, sideContent?.length ?? 0);
2921
+ const wordmarkLineCount = 3;
2895
2922
  if (!isColorEnabled()) {
2896
- for (let j = 0;j < logoLineCount; j++) {
2897
- const left = logoLines[j].padEnd(30);
2923
+ for (let j = 0;j < totalHeight; j++) {
2924
+ const left = (j < logoLineCount ? logoLines[j] : "").padEnd(rightCol - 1);
2898
2925
  const right = sideContent?.[j] ?? "";
2899
- process.stderr.write((sideContent ? left + " " + right : left) + `
2926
+ process.stderr.write(left + right + `
2900
2927
  `);
2901
2928
  }
2902
- const wordmarkLine = ` ${WORDMARK}`;
2903
- const footerSide2 = sideContent?.[logoLineCount] ?? "";
2904
- process.stderr.write((footerSide2 ? wordmarkLine.padEnd(34) + footerSide2 : wordmarkLine) + `
2929
+ return;
2930
+ }
2931
+ function renderFrame(frameLogoLines, rightLines) {
2932
+ for (let j = 0;j < totalHeight; j++) {
2933
+ const left = j < frameLogoLines.length ? white(frameLogoLines[j]) : "";
2934
+ const right = rightLines[j] ?? "";
2935
+ if (right) {
2936
+ process.stderr.write(left + `\x1B[${rightCol}G` + right + `\x1B[K
2905
2937
  `);
2906
- if (sideContent) {
2907
- for (let j = logoLineCount + 1;j < sideContent.length; j++) {
2908
- if (sideContent[j]) {
2909
- process.stderr.write(" ".repeat(34) + sideContent[j] + `
2938
+ } else {
2939
+ process.stderr.write(left + `\x1B[K
2910
2940
  `);
2911
- }
2912
2941
  }
2913
2942
  }
2914
- return;
2943
+ }
2944
+ function moveUp() {
2945
+ process.stderr.write(`\x1B[${totalHeight}A`);
2915
2946
  }
2916
2947
  for (let i = 0;i <= totalFrames; i++) {
2917
2948
  if (signal?.aborted)
@@ -2920,42 +2951,51 @@ async function animateMaterialize(signal, sideContent) {
2920
2951
  const frame = getMaterializeFrame(progress);
2921
2952
  const frameLines = frame.split(`
2922
2953
  `);
2923
- if (i > 0) {
2924
- process.stderr.write(`\x1B[${logoLineCount}A`);
2925
- }
2926
- for (let j = 0;j < logoLineCount; j++) {
2927
- const left = teal(frameLines[j]);
2928
- const right = sideContent?.[j] ?? "";
2929
- const line = sideContent ? left + `\x1B[35G` + right : left;
2930
- process.stderr.write(line + `\x1B[K
2931
- `);
2932
- }
2954
+ if (i > 0)
2955
+ moveUp();
2956
+ renderFrame(frameLines, []);
2933
2957
  await sleep(FRAME_MS, signal);
2934
2958
  }
2935
- const wordmarkFrames = 15;
2936
- const footerSide = sideContent?.[logoLineCount] ?? "";
2937
- for (let i = 0;i <= wordmarkFrames; i++) {
2959
+ const typingFrames = 20;
2960
+ for (let i = 0;i <= typingFrames; i++) {
2938
2961
  if (signal?.aborted)
2939
2962
  break;
2940
- const progress = i / wordmarkFrames;
2941
- const partial = getWordmarkFrame(progress);
2942
- if (footerSide) {
2943
- writeLine(` ${bold(teal(partial))}\x1B[35G${footerSide}`);
2944
- } else {
2945
- writeLine(` ${bold(teal(partial))}`);
2946
- }
2963
+ const progress = i / typingFrames;
2964
+ const typedLines = getWordmarkTypingFrame(progress);
2965
+ moveUp();
2966
+ const rightLines = new Array(totalHeight).fill(null);
2967
+ for (let j = 0;j < typedLines.length; j++) {
2968
+ rightLines[j] = bold(white(typedLines[j]));
2969
+ }
2970
+ renderFrame(logoLines, rightLines);
2947
2971
  await sleep(FRAME_MS, signal);
2948
2972
  }
2949
- process.stderr.write(`
2950
- `);
2973
+ const flashFrames = 12;
2974
+ for (let i = 0;i <= flashFrames; i++) {
2975
+ if (signal?.aborted)
2976
+ break;
2977
+ const progress = i / flashFrames;
2978
+ const flashedLines = getWordmarkMaterializeFrame(progress);
2979
+ moveUp();
2980
+ const rightLines = new Array(totalHeight).fill(null);
2981
+ for (let j = 0;j < flashedLines.length; j++) {
2982
+ rightLines[j] = bold(white(flashedLines[j]));
2983
+ }
2984
+ renderFrame(logoLines, rightLines);
2985
+ await sleep(FRAME_MS, signal);
2986
+ }
2987
+ moveUp();
2988
+ const fullRight = new Array(totalHeight).fill(null);
2951
2989
  if (sideContent) {
2952
- for (let j = logoLineCount + 1;j < sideContent.length; j++) {
2953
- if (sideContent[j]) {
2954
- process.stderr.write(`\x1B[35G${sideContent[j]}\x1B[K
2955
- `);
2990
+ for (let j = 0;j < sideContent.length; j++) {
2991
+ if (j < wordmarkLineCount) {
2992
+ fullRight[j] = bold(white(sideContent[j]));
2993
+ } else {
2994
+ fullRight[j] = sideContent[j];
2956
2995
  }
2957
2996
  }
2958
2997
  }
2998
+ renderFrame(logoLines, fullRight);
2959
2999
  }
2960
3000
  var FRAME_MS = 80;
2961
3001
  var init_animate = __esm(() => {
@@ -2969,8 +3009,12 @@ __export(exports_help, {
2969
3009
  COMMAND_SPECS: () => COMMAND_SPECS
2970
3010
  });
2971
3011
  import { createRequire as createRequire2 } from "node:module";
2972
- function buildSideContent() {
3012
+ function buildRightColumn() {
2973
3013
  const lines = [];
3014
+ for (const wl of WORDMARK_BIG) {
3015
+ lines.push(wl);
3016
+ }
3017
+ lines.push("");
2974
3018
  lines.push(bold("Commands"));
2975
3019
  for (const [name, brief] of COMMAND_BRIEFS) {
2976
3020
  lines.push(`${teal(name.padEnd(18))}${brief}`);
@@ -3199,8 +3243,8 @@ async function helpCommand(args) {
3199
3243
  printPlainHelp();
3200
3244
  return;
3201
3245
  }
3202
- const sideContent = buildSideContent();
3203
- await animateMaterialize(undefined, sideContent);
3246
+ const rightColumn = buildRightColumn();
3247
+ await animateMaterialize(undefined, rightColumn);
3204
3248
  }
3205
3249
  var COMMAND_SPECS;
3206
3250
  var init_help = __esm(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midnight-wallet-cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "description": "Git-style CLI wallet for the Midnight blockchain",
6
6
  "license": "Apache-2.0",