zoa-wallet 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.mjs +193 -167
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -117,7 +117,7 @@ zoa export --password "..." --type mnemonic
117
117
  | Ethereum | ETH | EVM |
118
118
  | Base | ETH | EVM |
119
119
  | BNB Smart Chain | BNB | EVM |
120
- | Polygon | POL | EVM |
120
+
121
121
  | Arbitrum One | ETH | EVM |
122
122
  | Optimism | ETH | EVM |
123
123
  | Solana | SOL | Non-EVM |
package/dist/index.mjs CHANGED
@@ -8171,7 +8171,7 @@ function fromHex(value, options = {}) {
8171
8171
  let hex = value;
8172
8172
  if (size5) {
8173
8173
  assertSize3(value, size5);
8174
- hex = padRight(value, size5);
8174
+ hex = padRight2(value, size5);
8175
8175
  }
8176
8176
  let hexString = hex.slice(2);
8177
8177
  if (hexString.length % 2)
@@ -8193,11 +8193,11 @@ function fromString(value, options = {}) {
8193
8193
  const bytes = encoder3.encode(value);
8194
8194
  if (typeof size5 === "number") {
8195
8195
  assertSize2(bytes, size5);
8196
- return padRight2(bytes, size5);
8196
+ return padRight3(bytes, size5);
8197
8197
  }
8198
8198
  return bytes;
8199
8199
  }
8200
- function padRight2(value, size5) {
8200
+ function padRight3(value, size5) {
8201
8201
  return pad2(value, { dir: "right", size: size5 });
8202
8202
  }
8203
8203
  function size2(value) {
@@ -8372,7 +8372,7 @@ function fromBytes(value, options = {}) {
8372
8372
  const hex = `0x${string2}`;
8373
8373
  if (typeof options.size === "number") {
8374
8374
  assertSize3(hex, options.size);
8375
- return padRight(hex, options.size);
8375
+ return padRight2(hex, options.size);
8376
8376
  }
8377
8377
  return hex;
8378
8378
  }
@@ -8411,7 +8411,7 @@ function fromString2(value, options = {}) {
8411
8411
  function padLeft(value, size5) {
8412
8412
  return pad3(value, { dir: "left", size: size5 });
8413
8413
  }
8414
- function padRight(value, size5) {
8414
+ function padRight2(value, size5) {
8415
8415
  return pad3(value, { dir: "right", size: size5 });
8416
8416
  }
8417
8417
  function slice3(value, start, end, options = {}) {
@@ -22019,37 +22019,66 @@ import ora from "ora";
22019
22019
 
22020
22020
  // dist/ui/theme.js
22021
22021
  import chalk from "chalk";
22022
+ import gradient from "gradient-string";
22023
+ var zoaGradient = gradient([
22024
+ "#00f5d4",
22025
+ "#00bbf9",
22026
+ "#5e60ce",
22027
+ "#7b2ff7",
22028
+ "#c77dff"
22029
+ ]);
22030
+ var successGradient = gradient(["#10b981", "#34d399", "#6ee7b7"]);
22031
+ var warningGradient = gradient(["#f59e0b", "#fbbf24", "#fcd34d"]);
22032
+ var errorGradient = gradient(["#ef4444", "#f87171", "#fca5a5"]);
22022
22033
  var colors = {
22023
- primary: chalk.cyan,
22024
- secondary: chalk.magenta,
22025
- success: chalk.green,
22026
- warning: chalk.yellow,
22027
- error: chalk.red,
22028
- muted: chalk.gray,
22034
+ // Brand
22035
+ brand: chalk.hex("#00bbf9"),
22036
+ brandBold: chalk.hex("#00bbf9").bold,
22037
+ accent: chalk.hex("#7b2ff7"),
22038
+ accentBold: chalk.hex("#7b2ff7").bold,
22039
+ // Semantic
22040
+ primary: chalk.hex("#00bbf9"),
22041
+ success: chalk.hex("#10b981"),
22042
+ warning: chalk.hex("#f59e0b"),
22043
+ error: chalk.hex("#ef4444"),
22044
+ // Text
22029
22045
  highlight: chalk.white.bold,
22030
- dim: chalk.dim,
22031
- label: chalk.cyan.bold,
22032
22046
  value: chalk.white,
22033
- address: chalk.white,
22034
- amount: chalk.green.bold,
22035
- negative: chalk.red.bold
22047
+ muted: chalk.hex("#6b7280"),
22048
+ dim: chalk.hex("#374151"),
22049
+ subtle: chalk.hex("#4b5563"),
22050
+ // Layout
22051
+ label: chalk.hex("#00bbf9").bold,
22052
+ address: chalk.hex("#e5e7eb"),
22053
+ amount: chalk.hex("#10b981").bold,
22054
+ negative: chalk.hex("#ef4444").bold,
22055
+ // Borders
22056
+ border: chalk.hex("#374151"),
22057
+ borderLight: chalk.hex("#4b5563")
22036
22058
  };
22037
22059
  var symbols = {
22038
- bullet: "\u25CF",
22039
- check: "\u2714",
22040
- cross: "\u2716",
22041
- warning: "\u26A0",
22060
+ // Status
22061
+ check: chalk.hex("#10b981")("\u2714"),
22062
+ cross: chalk.hex("#ef4444")("\u2716"),
22063
+ warning: chalk.hex("#f59e0b")("\u26A0"),
22064
+ info: chalk.hex("#00bbf9")("\u2139"),
22065
+ dot: chalk.hex("#6b7280")("\xB7"),
22066
+ bullet: chalk.hex("#00bbf9")("\u25CF"),
22067
+ // Arrows
22042
22068
  arrow: "\u2192",
22043
22069
  arrowRight: "\u25B8",
22044
- dot: "\xB7",
22045
- line: "\u2500",
22070
+ arrowDown: "\u25BE",
22071
+ pointer: chalk.hex("#00bbf9")("\u276F"),
22072
+ // Box drawing
22046
22073
  cornerTopLeft: "\u256D",
22047
22074
  cornerTopRight: "\u256E",
22048
22075
  cornerBottomLeft: "\u2570",
22049
22076
  cornerBottomRight: "\u256F",
22050
22077
  vertical: "\u2502",
22051
22078
  horizontal: "\u2500",
22052
- star: "\u2605",
22079
+ teeRight: "\u251C",
22080
+ teeLeft: "\u2524",
22081
+ // Domain
22053
22082
  key: "\u{1F511}",
22054
22083
  lock: "\u{1F512}",
22055
22084
  unlock: "\u{1F513}",
@@ -22057,81 +22086,107 @@ var symbols = {
22057
22086
  chain: "\u26D3",
22058
22087
  send: "\u{1F4E4}",
22059
22088
  receive: "\u{1F4E5}",
22060
- info: "\u2139"
22089
+ globe: "\u{1F310}",
22090
+ shield: "\u{1F6E1}",
22091
+ sparkle: "\u2728",
22092
+ diamond: "\u25C6",
22093
+ star: "\u2605"
22061
22094
  };
22062
22095
 
22063
22096
  // dist/ui/components.js
22064
- function infoBox(title, lines, width = 58) {
22097
+ function stripAnsi(s) {
22098
+ return s.replace(/\x1b\[[0-9;]*m/g, "").length;
22099
+ }
22100
+ function padRight(s, width) {
22101
+ const len = stripAnsi(s);
22102
+ const remaining = width - len;
22103
+ return remaining > 0 ? s + " ".repeat(remaining) : s;
22104
+ }
22105
+ function infoBox(title, lines, width = 60) {
22065
22106
  const inner = width - 4;
22066
- const pad4 = (s) => {
22067
- const stripped = s.replace(/\x1b\[[0-9;]*m/g, "");
22068
- const remaining = inner - stripped.length;
22069
- return remaining > 0 ? s + " ".repeat(remaining) : s;
22070
- };
22071
- const top = `${symbols.cornerTopLeft}${symbols.horizontal} ${colors.label(title)} ${symbols.horizontal.repeat(Math.max(0, inner - title.length - 2))}${symbols.cornerTopRight}`;
22072
- const bottom = `${symbols.cornerBottomLeft}${symbols.horizontal.repeat(inner + 2)}${symbols.cornerBottomRight}`;
22073
- const body = lines.map((line) => `${symbols.vertical} ${pad4(line)} ${symbols.vertical}`).join("\n");
22107
+ const borderColor = colors.border;
22108
+ const titleStr = ` ${colors.brandBold(title)} `;
22109
+ const titleLen = title.length + 2;
22110
+ const remaining = Math.max(0, inner - titleLen - 1);
22111
+ const top = borderColor(` ${symbols.cornerTopLeft}${symbols.horizontal}`) + titleStr + borderColor(symbols.horizontal.repeat(remaining) + symbols.cornerTopRight);
22112
+ const bottom = borderColor(` ${symbols.cornerBottomLeft}${symbols.horizontal.repeat(inner + 2)}${symbols.cornerBottomRight}`);
22113
+ const body = lines.map((line) => borderColor(` ${symbols.vertical}`) + ` ${padRight(line, inner)} ` + borderColor(symbols.vertical)).join("\n");
22074
22114
  return `${top}
22075
22115
  ${body}
22076
22116
  ${bottom}`;
22077
22117
  }
22078
- function warningBox(title, lines) {
22079
- const inner = 56;
22080
- const pad4 = (s) => {
22081
- const stripped = s.replace(/\x1b\[[0-9;]*m/g, "");
22082
- const remaining = inner - stripped.length;
22083
- return remaining > 0 ? s + " ".repeat(remaining) : s;
22084
- };
22085
- const top = chalk2.red(`${symbols.cornerTopLeft}${symbols.horizontal} ${title} ${symbols.horizontal.repeat(Math.max(0, inner - title.length - 2))}${symbols.cornerTopRight}`);
22086
- const bottom = chalk2.red(`${symbols.cornerBottomLeft}${symbols.horizontal.repeat(inner + 2)}${symbols.cornerBottomRight}`);
22087
- const body = lines.map((line) => `${chalk2.red(symbols.vertical)} ${pad4(line)} ${chalk2.red(symbols.vertical)}`).join("\n");
22118
+ function successBox(title, lines, width = 60) {
22119
+ const inner = width - 4;
22120
+ const bc = chalk2.hex("#10b981");
22121
+ const titleStr = ` ${chalk2.hex("#10b981").bold(title)} `;
22122
+ const titleLen = title.length + 2;
22123
+ const remaining = Math.max(0, inner - titleLen - 1);
22124
+ const top = bc(` ${symbols.cornerTopLeft}${symbols.horizontal}`) + titleStr + bc(symbols.horizontal.repeat(remaining) + symbols.cornerTopRight);
22125
+ const bottom = bc(` ${symbols.cornerBottomLeft}${symbols.horizontal.repeat(inner + 2)}${symbols.cornerBottomRight}`);
22126
+ const body = lines.map((line) => bc(` ${symbols.vertical}`) + ` ${padRight(line, inner)} ` + bc(symbols.vertical)).join("\n");
22127
+ return `${top}
22128
+ ${body}
22129
+ ${bottom}`;
22130
+ }
22131
+ function warningBox(title, lines, width = 60) {
22132
+ const inner = width - 4;
22133
+ const bc = chalk2.hex("#ef4444");
22134
+ const titleStr = ` ${chalk2.hex("#ef4444").bold(`\u26A0 ${title}`)} `;
22135
+ const titleLen = title.length + 4;
22136
+ const remaining = Math.max(0, inner - titleLen - 1);
22137
+ const top = bc(` ${symbols.cornerTopLeft}${symbols.horizontal}`) + titleStr + bc(symbols.horizontal.repeat(remaining) + symbols.cornerTopRight);
22138
+ const bottom = bc(` ${symbols.cornerBottomLeft}${symbols.horizontal.repeat(inner + 2)}${symbols.cornerBottomRight}`);
22139
+ const body = lines.map((line) => bc(` ${symbols.vertical}`) + ` ${padRight(line, inner)} ` + bc(symbols.vertical)).join("\n");
22088
22140
  return `${top}
22089
22141
  ${body}
22090
22142
  ${bottom}`;
22091
22143
  }
22092
22144
  function successMsg(msg) {
22093
- return `${colors.success(symbols.check)} ${msg}`;
22145
+ return ` ${symbols.check} ${msg}`;
22094
22146
  }
22095
22147
  function errorMsg(msg) {
22096
- return `${colors.error(symbols.cross)} ${msg}`;
22148
+ return ` ${symbols.cross} ${colors.error(msg)}`;
22097
22149
  }
22098
- function kvLine(key, value) {
22099
- return ` ${colors.label(key + ":")} ${colors.value(value)}`;
22150
+ function kvLine(key, value, keyWidth = 16) {
22151
+ const paddedKey = key.padEnd(keyWidth);
22152
+ return ` ${colors.muted(paddedKey)} ${colors.value(value)}`;
22100
22153
  }
22101
22154
  function createTable(heads, colWidths) {
22102
22155
  return new Table({
22103
- head: heads.map((h2) => colors.label(h2)),
22156
+ head: heads.map((h2) => colors.brandBold(h2)),
22104
22157
  colWidths,
22105
- style: { head: [], border: ["gray"] },
22158
+ style: { head: [], border: ["gray"], compact: false },
22106
22159
  chars: {
22107
- top: "\u2500",
22160
+ "top": "\u2500",
22108
22161
  "top-mid": "\u252C",
22109
- "top-left": "\u256D",
22162
+ "top-left": " \u256D",
22110
22163
  "top-right": "\u256E",
22111
- bottom: "\u2500",
22164
+ "bottom": "\u2500",
22112
22165
  "bottom-mid": "\u2534",
22113
- "bottom-left": "\u2570",
22166
+ "bottom-left": " \u2570",
22114
22167
  "bottom-right": "\u256F",
22115
- left: "\u2502",
22116
- "left-mid": "\u251C",
22117
- mid: "\u2500",
22168
+ "left": " \u2502",
22169
+ "left-mid": " \u251C",
22170
+ "mid": "\u2500",
22118
22171
  "mid-mid": "\u253C",
22119
- right: "\u2502",
22172
+ "right": "\u2502",
22120
22173
  "right-mid": "\u2524",
22121
- middle: "\u2502"
22174
+ "middle": "\u2502"
22122
22175
  }
22123
22176
  });
22124
22177
  }
22125
22178
  function createSpinner(text) {
22126
22179
  return ora({
22127
- text: colors.muted(text),
22128
- spinner: "dots",
22129
- color: "cyan"
22180
+ text: ` ${text}`,
22181
+ spinner: "dots12",
22182
+ color: "cyan",
22183
+ prefixText: ""
22130
22184
  });
22131
22185
  }
22132
22186
  function sectionHeader(title) {
22187
+ const gradientTitle = zoaGradient(title);
22133
22188
  return `
22134
- ${colors.label(` ${symbols.arrowRight} ${title}`)}
22189
+ ${symbols.pointer} ${gradientTitle}
22135
22190
  `;
22136
22191
  }
22137
22192
 
@@ -22269,7 +22324,6 @@ var ChainId;
22269
22324
  ChainId2[ChainId2["Ethereum"] = 1] = "Ethereum";
22270
22325
  ChainId2[ChainId2["Base"] = 8453] = "Base";
22271
22326
  ChainId2[ChainId2["BSC"] = 56] = "BSC";
22272
- ChainId2[ChainId2["Polygon"] = 137] = "Polygon";
22273
22327
  ChainId2[ChainId2["Arbitrum"] = 42161] = "Arbitrum";
22274
22328
  ChainId2[ChainId2["Optimism"] = 10] = "Optimism";
22275
22329
  ChainId2[ChainId2["Solana"] = -1] = "Solana";
@@ -27083,7 +27137,7 @@ function encodeBytes2(value, { type: type2 }) {
27083
27137
  if (!parametersize) {
27084
27138
  let value_ = value;
27085
27139
  if (bytesSize % 32 !== 0)
27086
- value_ = padRight(value_, Math.ceil((value.length - 2) / 2 / 32) * 32);
27140
+ value_ = padRight2(value_, Math.ceil((value.length - 2) / 2 / 32) * 32);
27087
27141
  return {
27088
27142
  dynamic: true,
27089
27143
  encoded: concat2(padLeft(fromNumber(bytesSize, { size: 32 })), value_)
@@ -27094,7 +27148,7 @@ function encodeBytes2(value, { type: type2 }) {
27094
27148
  expectedSize: Number.parseInt(parametersize, 10),
27095
27149
  value
27096
27150
  });
27097
- return { dynamic: false, encoded: padRight(value) };
27151
+ return { dynamic: false, encoded: padRight2(value) };
27098
27152
  }
27099
27153
  function encodeBoolean(value) {
27100
27154
  if (typeof value !== "boolean")
@@ -27127,11 +27181,11 @@ function encodeString2(value) {
27127
27181
  const partsLength = Math.ceil(size3(hexValue) / 32);
27128
27182
  const parts = [];
27129
27183
  for (let i = 0; i < partsLength; i++) {
27130
- parts.push(padRight(slice3(hexValue, i * 32, (i + 1) * 32)));
27184
+ parts.push(padRight2(slice3(hexValue, i * 32, (i + 1) * 32)));
27131
27185
  }
27132
27186
  return {
27133
27187
  dynamic: true,
27134
- encoded: concat2(padRight(fromNumber(size3(hexValue), { size: 32 })), ...parts)
27188
+ encoded: concat2(padRight2(fromNumber(size3(hexValue), { size: 32 })), ...parts)
27135
27189
  };
27136
27190
  }
27137
27191
  function encodeTuple2(value, options) {
@@ -27475,7 +27529,7 @@ function encodePacked(types, values2) {
27475
27529
  expectedSize: Number.parseInt(size5, 10),
27476
27530
  value
27477
27531
  });
27478
- return padRight(value, isArray ? 32 : 0);
27532
+ return padRight2(value, isArray ? 32 : 0);
27479
27533
  }
27480
27534
  const arrayMatch = type2.match(arrayRegex);
27481
27535
  if (arrayMatch && Array.isArray(value)) {
@@ -30462,32 +30516,6 @@ var optimism = /* @__PURE__ */ defineChain({
30462
30516
  sourceId: sourceId2
30463
30517
  });
30464
30518
 
30465
- // ../../node_modules/.pnpm/viem@2.46.3_bufferutil@4.1.0_typescript@5.9.3_zod@3.25.76/node_modules/viem/_esm/chains/definitions/polygon.js
30466
- var polygon = /* @__PURE__ */ defineChain({
30467
- id: 137,
30468
- name: "Polygon",
30469
- blockTime: 2e3,
30470
- nativeCurrency: { name: "POL", symbol: "POL", decimals: 18 },
30471
- rpcUrls: {
30472
- default: {
30473
- http: ["https://polygon.drpc.org"]
30474
- }
30475
- },
30476
- blockExplorers: {
30477
- default: {
30478
- name: "PolygonScan",
30479
- url: "https://polygonscan.com",
30480
- apiUrl: "https://api.etherscan.io/v2/api"
30481
- }
30482
- },
30483
- contracts: {
30484
- multicall3: {
30485
- address: "0xca11bde05977b3631167028862be2a173976ca11",
30486
- blockCreated: 25770160
30487
- }
30488
- }
30489
- });
30490
-
30491
30519
  // ../../packages/chain-adapters/dist/evm/chains.js
30492
30520
  var ETHEREUM_CONFIG = {
30493
30521
  chainId: ChainId.Ethereum,
@@ -30516,20 +30544,6 @@ var BSC_CONFIG = {
30516
30544
  blockExplorerUrl: "https://bscscan.com",
30517
30545
  isTestnet: false
30518
30546
  };
30519
- var POLYGON_CONFIG = {
30520
- chainId: ChainId.Polygon,
30521
- name: "Polygon",
30522
- shortName: "MATIC",
30523
- nativeCurrency: {
30524
- name: "POL",
30525
- symbol: "POL",
30526
- decimals: 18,
30527
- coingeckoId: "polygon-ecosystem-token"
30528
- },
30529
- rpcUrls: ["https://polygon-rpc.com"],
30530
- blockExplorerUrl: "https://polygonscan.com",
30531
- isTestnet: false
30532
- };
30533
30547
  var ARBITRUM_CONFIG = {
30534
30548
  chainId: ChainId.Arbitrum,
30535
30549
  name: "Arbitrum One",
@@ -30573,14 +30587,6 @@ var BSCAdapter = class extends BaseEVMAdapter {
30573
30587
  }
30574
30588
  };
30575
30589
 
30576
- // ../../packages/chain-adapters/dist/evm/polygon.js
30577
- var PolygonAdapter = class extends BaseEVMAdapter {
30578
- config = POLYGON_CONFIG;
30579
- getViemChain() {
30580
- return polygon;
30581
- }
30582
- };
30583
-
30584
30590
  // ../../packages/chain-adapters/dist/evm/arbitrum.js
30585
30591
  var ArbitrumAdapter = class extends BaseEVMAdapter {
30586
30592
  config = ARBITRUM_CONFIG;
@@ -44026,7 +44032,6 @@ var ChainAdapterRegistry = class {
44026
44032
  this.register(ChainId.Ethereum, new EthereumAdapter());
44027
44033
  this.register(ChainId.Base, new BaseChainAdapter());
44028
44034
  this.register(ChainId.BSC, new BSCAdapter());
44029
- this.register(ChainId.Polygon, new PolygonAdapter());
44030
44035
  this.register(ChainId.Arbitrum, new ArbitrumAdapter());
44031
44036
  this.register(ChainId.Optimism, new OptimismAdapter());
44032
44037
  this.register(ChainId.Solana, new SolanaAdapter());
@@ -44062,7 +44067,6 @@ var ChainAdapterRegistry = class {
44062
44067
  ChainId.Ethereum,
44063
44068
  ChainId.Base,
44064
44069
  ChainId.BSC,
44065
- ChainId.Polygon,
44066
44070
  ChainId.Arbitrum,
44067
44071
  ChainId.Optimism
44068
44072
  ].filter((id) => this.adapters.has(id)).map((id) => this.adapters.get(id));
@@ -47722,7 +47726,6 @@ var CHAIN_MAP = {
47722
47726
  ethereum: ChainId.Ethereum,
47723
47727
  base: ChainId.Base,
47724
47728
  bsc: ChainId.BSC,
47725
- polygon: ChainId.Polygon,
47726
47729
  arbitrum: ChainId.Arbitrum,
47727
47730
  optimism: ChainId.Optimism,
47728
47731
  solana: ChainId.Solana
@@ -47755,13 +47758,13 @@ function registerBalanceCommand(program2) {
47755
47758
  if (!account)
47756
47759
  throw new Error("No accounts found.");
47757
47760
  if (!isJsonMode())
47758
- spinner.text = "Fetching balances...";
47761
+ spinner.text = " Fetching balances across networks...";
47759
47762
  let chainsToFetch = Object.entries(CHAIN_MAP);
47760
47763
  if (opts.chain) {
47761
47764
  const chainKey = opts.chain.toLowerCase();
47762
47765
  const chainId = CHAIN_MAP[chainKey];
47763
47766
  if (chainId === void 0) {
47764
- throw new Error(`Unknown chain: ${opts.chain}. Use 'zoa chains' to see supported chains.`);
47767
+ throw new Error(`Unknown chain: ${opts.chain}. Run 'zoa chains' to see supported chains.`);
47765
47768
  }
47766
47769
  chainsToFetch = [[chainKey, chainId]];
47767
47770
  }
@@ -47800,11 +47803,15 @@ function registerBalanceCommand(program2) {
47800
47803
  if (!isJsonMode())
47801
47804
  spinner.stop();
47802
47805
  output({ account: { evmAddress: account.evmAddress, solanaAddress: account.solanaAddress }, balances }, () => {
47803
- console.log(sectionHeader(`Balances for ${account.label}`));
47804
- const table = createTable(["Network", "Address", "Balance"], [18, 30, 20]);
47806
+ console.log(sectionHeader(`Balances \u2014 ${account.label}`));
47807
+ console.log(kvLine("EVM", truncateAddress(account.evmAddress)));
47808
+ console.log(kvLine("Solana", truncateAddress(account.solanaAddress)));
47809
+ console.log();
47810
+ const table = createTable(["Network", "Balance", "Symbol"], [22, 20, 10]);
47805
47811
  for (const b of balances) {
47806
- const balColor = b.balance === "Error" ? colors.error(b.balance) : b.balance === "0" ? colors.muted("0 " + b.symbol) : colors.amount(`${formatBalance(b.balance)} ${b.symbol}`);
47807
- table.push([b.chain, truncateAddress(b.address), balColor]);
47812
+ const balDisplay = b.balance === "Error" ? colors.error("error") : b.balance === "0" ? colors.muted("0") : colors.amount(formatBalance(b.balance));
47813
+ const symDisplay = b.balance === "Error" ? colors.muted("\u2014") : colors.muted(b.symbol);
47814
+ table.push([colors.value(b.chain), balDisplay, symDisplay]);
47808
47815
  }
47809
47816
  console.log(table.toString());
47810
47817
  console.log();
@@ -48034,7 +48041,6 @@ function registerHistoryCommand(program2) {
48034
48041
  ethereum: ChainId.Ethereum,
48035
48042
  base: ChainId.Base,
48036
48043
  bsc: ChainId.BSC,
48037
- polygon: ChainId.Polygon,
48038
48044
  arbitrum: ChainId.Arbitrum,
48039
48045
  optimism: ChainId.Optimism,
48040
48046
  solana: ChainId.Solana
@@ -48094,7 +48100,8 @@ function registerInitCommand(program2) {
48094
48100
  password = opts.password;
48095
48101
  } else {
48096
48102
  if (!isJsonMode()) {
48097
- console.log(colors.label("\n Create or Import Wallet\n"));
48103
+ console.log(colors.brandBold(" Create or Import Wallet"));
48104
+ console.log();
48098
48105
  }
48099
48106
  const { action } = await inquirer4.prompt([
48100
48107
  {
@@ -48113,8 +48120,9 @@ function registerInitCommand(program2) {
48113
48120
  const result = createMnemonic(wordCount);
48114
48121
  mnemonic = result.phrase;
48115
48122
  if (!isJsonMode()) {
48116
- console.log(infoBox("Recovery Phrase", [
48117
- colors.warning("Write down these words and store them safely!"),
48123
+ console.log();
48124
+ console.log(warningBox("Recovery Phrase \u2014 Save This!", [
48125
+ colors.warning("Write down these words and store them safely."),
48118
48126
  colors.warning("Anyone with this phrase can access your funds."),
48119
48127
  "",
48120
48128
  colors.highlight(mnemonic),
@@ -48137,7 +48145,7 @@ function registerInitCommand(program2) {
48137
48145
  {
48138
48146
  type: "password",
48139
48147
  name: "pwd",
48140
- message: "Set a secure password for your wallet:",
48148
+ message: "Set a secure password:",
48141
48149
  mask: "*",
48142
48150
  validate: (input) => input.length >= 8 || "Password must be at least 8 characters"
48143
48151
  }
@@ -48146,21 +48154,21 @@ function registerInitCommand(program2) {
48146
48154
  {
48147
48155
  type: "password",
48148
48156
  name: "confirmPwd",
48149
- message: "Confirm your password:",
48157
+ message: "Confirm password:",
48150
48158
  mask: "*",
48151
48159
  validate: (input) => input === pwd || "Passwords do not match"
48152
48160
  }
48153
48161
  ]);
48154
48162
  password = confirmPwd;
48155
48163
  }
48156
- const spinner = createSpinner("Initializing wallet...");
48164
+ const spinner = createSpinner("Deriving keys and encrypting vault...");
48157
48165
  if (!isJsonMode())
48158
48166
  spinner.start();
48159
48167
  const storage = new FileStorage();
48160
48168
  const kr = createKeyring(storage);
48161
48169
  await kr.initialize(mnemonic, password);
48162
48170
  if (!isJsonMode())
48163
- spinner.succeed("Wallet initialized successfully!");
48171
+ spinner.succeed(" Wallet initialized successfully!");
48164
48172
  const accounts = kr.getAccounts();
48165
48173
  const firstAccount = accounts[0];
48166
48174
  if (firstAccount) {
@@ -48176,9 +48184,11 @@ function registerInitCommand(program2) {
48176
48184
  ...isNew ? { mnemonic } : {}
48177
48185
  }, () => {
48178
48186
  console.log();
48179
- console.log(infoBox("Your Wallet", [
48180
- kvLine("EVM Address ", firstAccount.evmAddress),
48181
- kvLine("Solana Address", firstAccount.solanaAddress)
48187
+ console.log(successBox("Wallet Created", [
48188
+ kvLine("EVM Address", firstAccount.evmAddress),
48189
+ kvLine("Solana", firstAccount.solanaAddress),
48190
+ "",
48191
+ colors.muted("Vault encrypted and saved to ~/.zoa/")
48182
48192
  ]));
48183
48193
  console.log();
48184
48194
  });
@@ -48186,9 +48196,8 @@ function registerInitCommand(program2) {
48186
48196
  } catch (error) {
48187
48197
  const msg = error instanceof Error ? error.message : String(error);
48188
48198
  outputError(msg);
48189
- if (!isJsonMode()) {
48199
+ if (!isJsonMode())
48190
48200
  console.log(errorMsg(msg));
48191
- }
48192
48201
  process.exitCode = 1;
48193
48202
  }
48194
48203
  });
@@ -48296,9 +48305,11 @@ function registerReceiveCommand(program2) {
48296
48305
  solanaAddress: showSolana ? account.solanaAddress : void 0
48297
48306
  }, async () => {
48298
48307
  if (showEvm) {
48299
- console.log(sectionHeader("EVM Address (Ethereum, Base, Polygon, etc.)"));
48308
+ console.log(sectionHeader("EVM Address (Ethereum, Base, Arbitrum, etc.)"));
48300
48309
  console.log(infoBox("EVM", [
48301
- kvLine("Address", account.evmAddress)
48310
+ kvLine("Address", account.evmAddress),
48311
+ "",
48312
+ colors.muted("Works on Ethereum, Base, Arbitrum, Optimism, BSC")
48302
48313
  ]));
48303
48314
  console.log();
48304
48315
  await renderQRCode(account.evmAddress);
@@ -48338,7 +48349,8 @@ function registerSendCommand(program2) {
48338
48349
  chain2 = opts.chain || "base";
48339
48350
  } else {
48340
48351
  if (!isJsonMode()) {
48341
- console.log(colors.label("\n Send Tokens\n"));
48352
+ console.log(colors.brandBold(" Send Tokens"));
48353
+ console.log();
48342
48354
  }
48343
48355
  const answers = await inquirer6.prompt([
48344
48356
  {
@@ -48352,7 +48364,7 @@ function registerSendCommand(program2) {
48352
48364
  type: "list",
48353
48365
  name: "chain",
48354
48366
  message: "Select network:",
48355
- choices: ["base", "ethereum", "polygon", "arbitrum", "optimism", "bsc", "solana"],
48367
+ choices: ["base", "ethereum", "arbitrum", "optimism", "bsc", "solana"],
48356
48368
  when: !opts.chain || opts.chain === "base"
48357
48369
  },
48358
48370
  {
@@ -48389,12 +48401,11 @@ function registerSendCommand(program2) {
48389
48401
  if (!account)
48390
48402
  throw new Error("No accounts found.");
48391
48403
  if (!isJsonMode())
48392
- spinner.text = "Estimating gas...";
48404
+ spinner.text = " Estimating gas...";
48393
48405
  const chainMap = {
48394
48406
  ethereum: ChainId.Ethereum,
48395
48407
  base: ChainId.Base,
48396
48408
  bsc: ChainId.BSC,
48397
- polygon: ChainId.Polygon,
48398
48409
  arbitrum: ChainId.Arbitrum,
48399
48410
  optimism: ChainId.Optimism,
48400
48411
  solana: ChainId.Solana
@@ -48408,26 +48419,21 @@ function registerSendCommand(program2) {
48408
48419
  const value = BigInt(Math.floor(Number.parseFloat(amount) * 10 ** decimals));
48409
48420
  let gasEstimate;
48410
48421
  try {
48411
- gasEstimate = await adapter.estimateGas({
48412
- chainId,
48413
- from: from14,
48414
- to,
48415
- value
48416
- });
48422
+ gasEstimate = await adapter.estimateGas({ chainId, from: from14, to, value });
48417
48423
  } catch {
48418
48424
  gasEstimate = null;
48419
48425
  }
48420
48426
  if (!isJsonMode())
48421
48427
  spinner.stop();
48422
48428
  if (!opts.yes && !isJsonMode()) {
48429
+ const gasLine = gasEstimate ? `${formatGas(gasEstimate.estimatedCost, decimals)} ${adapter.config.nativeCurrency.symbol}` : colors.muted("Unable to estimate");
48423
48430
  console.log();
48424
- const gasLine = gasEstimate ? `${formatGas(gasEstimate.estimatedCost, decimals)} ${adapter.config.nativeCurrency.symbol}` : "Unable to estimate";
48425
48431
  console.log(infoBox("Transaction Details", [
48426
- kvLine("From ", from14),
48427
- kvLine("To ", to),
48428
- kvLine("Amount ", `${amount} ${adapter.config.nativeCurrency.symbol}`),
48432
+ kvLine("From", from14),
48433
+ kvLine("To", to),
48434
+ kvLine("Amount", `${amount} ${adapter.config.nativeCurrency.symbol}`),
48429
48435
  kvLine("Network", adapter.config.name),
48430
- kvLine("Gas ", gasLine)
48436
+ kvLine("Est. Gas", gasLine)
48431
48437
  ]));
48432
48438
  console.log();
48433
48439
  const { confirm } = await inquirer6.prompt([
@@ -48439,7 +48445,7 @@ function registerSendCommand(program2) {
48439
48445
  }
48440
48446
  ]);
48441
48447
  if (!confirm) {
48442
- console.log(colors.muted("Transaction cancelled."));
48448
+ console.log(colors.muted(" Transaction cancelled."));
48443
48449
  return;
48444
48450
  }
48445
48451
  }
@@ -48453,14 +48459,14 @@ function registerSendCommand(program2) {
48453
48459
  cost: gasEstimate.formattedCost,
48454
48460
  gasLimit: gasEstimate.gasLimit.toString()
48455
48461
  } : null,
48456
- note: "Transaction signing and broadcast requires full chain integration. Use the SDK for programmatic sending."
48462
+ note: "Transaction signing requires full chain integration. Use the ZOA SDK for programmatic sending."
48457
48463
  }, () => {
48458
48464
  console.log(warningBox("Note", [
48459
48465
  colors.warning("Transaction signing & broadcast requires"),
48460
- colors.warning("full chain integration with RPC nodes."),
48466
+ colors.warning("full RPC integration with chain nodes."),
48461
48467
  "",
48462
48468
  colors.muted("Use the ZOA SDK for programmatic sending:"),
48463
- colors.primary(" import { ZoaClient } from '@zoa/sdk'")
48469
+ colors.brand(" import { ZoaClient } from '@zoa/sdk'")
48464
48470
  ]));
48465
48471
  console.log();
48466
48472
  });
@@ -48477,17 +48483,36 @@ function registerSendCommand(program2) {
48477
48483
  // dist/ui/banner.js
48478
48484
  import chalk3 from "chalk";
48479
48485
  import figlet from "figlet";
48480
- import gradient from "gradient-string";
48481
- var zoaGradient = gradient(["#00d2ff", "#3a7bd5", "#9b59b6"]);
48486
+ import gradient2 from "gradient-string";
48487
+ var zoaGradient2 = gradient2([
48488
+ "#00f5d4",
48489
+ "#00bbf9",
48490
+ "#5e60ce",
48491
+ "#7b2ff7",
48492
+ "#c77dff"
48493
+ ]);
48494
+ var subtleGradient = gradient2(["#6b7280", "#9ca3af", "#6b7280"]);
48495
+ var VERSION = "0.2.0";
48482
48496
  function displayBanner() {
48483
48497
  const banner = figlet.textSync("ZOA", { font: "ANSI Shadow" });
48484
- console.log(zoaGradient.multiline(banner));
48485
- console.log(chalk3.gray(" API-First Crypto Wallet for Developers & AI Agents"));
48486
- console.log(chalk3.gray(` v0.1.0
48487
- `));
48498
+ console.log();
48499
+ console.log(zoaGradient2.multiline(banner));
48500
+ const tagline = " API-First Crypto Wallet for Developers & AI Agents";
48501
+ console.log(subtleGradient(tagline));
48502
+ console.log();
48503
+ const versionBadge = chalk3.bgHex("#5e60ce").white.bold(` v${VERSION} `);
48504
+ const githubLink = chalk3.hex("#6b7280")("github.com/airxtech/zoa-wallet");
48505
+ const npmBadge = chalk3.hex("#cb3837")("npm") + chalk3.hex("#6b7280")(" zoa-wallet");
48506
+ console.log(` ${versionBadge} ${chalk3.hex("#3b3b3b")("\u2502")} ${githubLink} ${chalk3.hex("#3b3b3b")("\u2502")} ${npmBadge}`);
48507
+ console.log();
48508
+ console.log(chalk3.hex("#2d2d2d")(" " + "\u2500".repeat(58)));
48509
+ console.log();
48488
48510
  }
48489
48511
  function displayMiniBanner() {
48490
- console.log(zoaGradient(" \u25C6 ZOA Wallet"));
48512
+ const diamond = zoaGradient2("\u25C6");
48513
+ const name = zoaGradient2.multiline("ZOA");
48514
+ console.log();
48515
+ console.log(` ${diamond} ${chalk3.bold(name)} ${chalk3.hex("#4b5563")(`v${VERSION}`)}`);
48491
48516
  console.log();
48492
48517
  }
48493
48518
 
@@ -48504,7 +48529,7 @@ program.hook("preAction", (_thisCommand, actionCommand) => {
48504
48529
  }
48505
48530
  }
48506
48531
  });
48507
- program.name("zoa").description("ZOA Wallet \u2014 API-First Crypto Wallet for Developers & AI Agents").version("0.1.0");
48532
+ program.name("zoa").description("ZOA Wallet \u2014 API-First Crypto Wallet for Developers & AI Agents").version("0.2.0");
48508
48533
  registerInitCommand(program);
48509
48534
  registerBalanceCommand(program);
48510
48535
  registerSendCommand(program);
@@ -48519,6 +48544,7 @@ program.parse(process.argv);
48519
48544
  if (!process.argv.slice(2).length) {
48520
48545
  displayBanner();
48521
48546
  program.outputHelp();
48547
+ console.log();
48522
48548
  }
48523
48549
  /*! Bundled license information:
48524
48550
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zoa-wallet",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "API-First Crypto Wallet CLI for Developers & AI Agents. Manage multi-chain wallets from your terminal.",
5
5
  "type": "module",
6
6
  "license": "MIT",