zoa-wallet 0.2.9 → 0.3.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 (2) hide show
  1. package/dist/index.mjs +215 -137
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -22211,19 +22211,6 @@ async function saveConfig(config) {
22211
22211
  await ensureConfigDir();
22212
22212
  await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
22213
22213
  }
22214
- async function setConfigValue(key, value) {
22215
- const config = await loadConfig();
22216
- config[key] = value;
22217
- await saveConfig(config);
22218
- }
22219
- async function deleteConfigValue(key) {
22220
- const config = await loadConfig();
22221
- delete config[key];
22222
- await saveConfig(config);
22223
- }
22224
- function getConfigFilePath() {
22225
- return CONFIG_FILE;
22226
- }
22227
22214
  function generateWalletId() {
22228
22215
  const hex = Array.from(crypto.getRandomValues(new Uint8Array(4))).map((b) => b.toString(16).padStart(2, "0")).join("");
22229
22216
  return `w_${hex}`;
@@ -43913,7 +43900,6 @@ var SolanaAdapter = class {
43913
43900
  get connection() {
43914
43901
  if (!this._connection) {
43915
43902
  const url = this.config.rpcUrls[0] || "https://solana-rpc.publicnode.com";
43916
- console.log(`[SolanaAdapter] Initializing connection to ${url}`);
43917
43903
  this._connection = new Connection(url, {
43918
43904
  commitment: "confirmed",
43919
43905
  confirmTransactionInitialTimeout: 6e4
@@ -43926,21 +43912,16 @@ var SolanaAdapter = class {
43926
43912
  if (!address || address === "native") {
43927
43913
  return 0n;
43928
43914
  }
43929
- console.log(`[SolanaAdapter] getBalance for: ${address}`);
43930
43915
  const pubkey = new PublicKey(address);
43931
43916
  const balance = await this.connection.getBalance(pubkey);
43932
- console.log(`[SolanaAdapter] Response for ${address}: ${balance} lamports`);
43933
43917
  return BigInt(balance);
43934
- } catch (error) {
43935
- console.error(`[SolanaAdapter] Error for ${address}:`, error);
43918
+ } catch {
43936
43919
  try {
43937
43920
  const fallbackUrl = this.config.rpcUrls[1] || "https://rpc.ankr.com/solana";
43938
- console.log(`[SolanaAdapter] Attempting fallback RPC: ${fallbackUrl}`);
43939
43921
  const fallbackConn = new Connection(fallbackUrl, "confirmed");
43940
43922
  const balance = await fallbackConn.getBalance(new PublicKey(address));
43941
43923
  return BigInt(balance);
43942
- } catch (fallbackError) {
43943
- console.error(`[SolanaAdapter] Fallback also failed:`, fallbackError);
43924
+ } catch {
43944
43925
  return 0n;
43945
43926
  }
43946
43927
  }
@@ -43979,7 +43960,6 @@ var SolanaAdapter = class {
43979
43960
  });
43980
43961
  return txid;
43981
43962
  } catch (error) {
43982
- console.error(`[SolanaAdapter] sendTransaction error:`, error);
43983
43963
  throw error;
43984
43964
  }
43985
43965
  }
@@ -44001,8 +43981,7 @@ var SolanaAdapter = class {
44001
43981
  maxSupportedTransactionVersion: 0
44002
43982
  });
44003
43983
  parsedTxs.push(parsed);
44004
- } catch (err3) {
44005
- console.warn(`[SolanaAdapter] Failed to fetch details for tx ${info.signature}:`, err3);
43984
+ } catch {
44006
43985
  parsedTxs.push(null);
44007
43986
  }
44008
43987
  }
@@ -44031,8 +44010,7 @@ var SolanaAdapter = class {
44031
44010
  timestamp: info.blockTime ?? void 0
44032
44011
  };
44033
44012
  }).filter((tx) => tx !== null);
44034
- } catch (error) {
44035
- console.error(`[SolanaAdapter] Error fetching history for ${_address}:`, error);
44013
+ } catch {
44036
44014
  return [];
44037
44015
  }
44038
44016
  }
@@ -47423,8 +47401,6 @@ function deriveSolanaKey(seed, index2) {
47423
47401
  }
47424
47402
  const privateKey = child.privateKey;
47425
47403
  const publicKey2 = getPublicKey2(privateKey);
47426
- const solAddress = base58Encode(publicKey2);
47427
- console.log(`[HDWallet] Derived Solana address for index ${index2}: ${solAddress} (path: ${path})`);
47428
47404
  return {
47429
47405
  path,
47430
47406
  privateKey,
@@ -47859,7 +47835,14 @@ function registerBalanceCommand(program2) {
47859
47835
  const spinner = createSpinner("Unlocking wallet...");
47860
47836
  if (!isJsonMode())
47861
47837
  spinner.start();
47862
- const { account } = await loadActiveWallet(password);
47838
+ let account;
47839
+ try {
47840
+ ({ account } = await loadActiveWallet(password));
47841
+ } catch (err3) {
47842
+ if (!isJsonMode())
47843
+ spinner.stop();
47844
+ throw err3;
47845
+ }
47863
47846
  if (!isJsonMode())
47864
47847
  spinner.text = " Fetching balances across networks...";
47865
47848
  let chainsToFetch = Object.entries(CHAIN_MAP);
@@ -47930,28 +47913,34 @@ function registerBalanceCommand(program2) {
47930
47913
  }
47931
47914
 
47932
47915
  // dist/commands/chains.js
47916
+ var HIDDEN_CHAINS = /* @__PURE__ */ new Set([ChainId.Hyperliquid]);
47917
+ var CHAIN_ID_DISPLAY = {
47918
+ [ChainId.Solana]: "mainnet-beta"
47919
+ };
47933
47920
  function registerChainsCommand(program2) {
47934
47921
  program2.command("chains").description("List all supported blockchain networks").action(() => {
47935
47922
  const adapters = chainRegistry.getAll();
47936
47923
  const chains = [];
47937
- for (const [_id, adapter] of adapters) {
47924
+ for (const [id, adapter] of adapters) {
47925
+ if (HIDDEN_CHAINS.has(id))
47926
+ continue;
47938
47927
  const cfg = adapter.config;
47939
47928
  chains.push({
47940
47929
  name: cfg.name,
47941
47930
  shortName: cfg.shortName,
47942
- chainId: cfg.chainId,
47931
+ chainId: CHAIN_ID_DISPLAY[id] ?? String(cfg.chainId),
47943
47932
  symbol: cfg.nativeCurrency.symbol,
47944
47933
  explorer: cfg.blockExplorerUrl
47945
47934
  });
47946
47935
  }
47947
47936
  output({ chains }, () => {
47948
47937
  console.log(sectionHeader("Supported Networks"));
47949
- const table = createTable(["Network", "Symbol", "Chain ID", "Explorer"], [20, 10, 12, 35]);
47938
+ const table = createTable(["Network", "Symbol", "Chain ID", "Explorer"], [20, 10, 16, 35]);
47950
47939
  for (const c of chains) {
47951
47940
  table.push([
47952
47941
  colors.primary(c.name),
47953
47942
  colors.highlight(c.symbol),
47954
- String(c.chainId),
47943
+ c.chainId,
47955
47944
  colors.muted(c.explorer)
47956
47945
  ]);
47957
47946
  }
@@ -47961,65 +47950,6 @@ function registerChainsCommand(program2) {
47961
47950
  });
47962
47951
  }
47963
47952
 
47964
- // dist/commands/config.js
47965
- function registerConfigCommand(program2) {
47966
- const cmd = program2.command("config").description("Manage ZOA configuration (~/.zoa/config.json)");
47967
- cmd.command("show").description("Show current configuration").action(async () => {
47968
- try {
47969
- const config = await loadConfig();
47970
- output({ path: getConfigFilePath(), config }, () => {
47971
- console.log(sectionHeader("Configuration"));
47972
- console.log(colors.muted(` File: ${getConfigFilePath()}
47973
- `));
47974
- const entries2 = Object.entries(config);
47975
- if (entries2.length === 0) {
47976
- console.log(colors.muted(" No configuration set.\n"));
47977
- } else {
47978
- for (const [key, value] of entries2) {
47979
- const displayValue = typeof value === "object" ? JSON.stringify(value) : String(value);
47980
- console.log(kvLine(key, displayValue));
47981
- }
47982
- console.log();
47983
- }
47984
- });
47985
- } catch (error) {
47986
- const msg = error instanceof Error ? error.message : String(error);
47987
- outputError(msg);
47988
- if (!isJsonMode())
47989
- console.log(errorMsg(msg));
47990
- process.exitCode = 1;
47991
- }
47992
- });
47993
- cmd.command("set <key> <value>").description("Set a configuration value").action(async (key, value) => {
47994
- try {
47995
- await setConfigValue(key, value);
47996
- output({ success: true, key, value }, () => {
47997
- console.log(successMsg(`Set ${colors.label(key)} = ${colors.value(value)}`));
47998
- });
47999
- } catch (error) {
48000
- const msg = error instanceof Error ? error.message : String(error);
48001
- outputError(msg);
48002
- if (!isJsonMode())
48003
- console.log(errorMsg(msg));
48004
- process.exitCode = 1;
48005
- }
48006
- });
48007
- cmd.command("delete <key>").description("Delete a configuration value").action(async (key) => {
48008
- try {
48009
- await deleteConfigValue(key);
48010
- output({ success: true, key, deleted: true }, () => {
48011
- console.log(successMsg(`Deleted ${colors.label(key)}`));
48012
- });
48013
- } catch (error) {
48014
- const msg = error instanceof Error ? error.message : String(error);
48015
- outputError(msg);
48016
- if (!isJsonMode())
48017
- console.log(errorMsg(msg));
48018
- process.exitCode = 1;
48019
- }
48020
- });
48021
- }
48022
-
48023
47953
  // dist/commands/export.js
48024
47954
  import inquirer2 from "inquirer";
48025
47955
  function registerExportCommand(program2) {
@@ -48042,7 +47972,14 @@ function registerExportCommand(program2) {
48042
47972
  const spinner = createSpinner("Unlocking wallet...");
48043
47973
  if (!isJsonMode())
48044
47974
  spinner.start();
48045
- const { keyring: kr } = await loadActiveWallet(password);
47975
+ let kr;
47976
+ try {
47977
+ ({ keyring: kr } = await loadActiveWallet(password));
47978
+ } catch (err3) {
47979
+ if (!isJsonMode())
47980
+ spinner.stop();
47981
+ throw err3;
47982
+ }
48046
47983
  if (!isJsonMode())
48047
47984
  spinner.stop();
48048
47985
  let exportType = opts.type;
@@ -48131,7 +48068,14 @@ function registerHistoryCommand(program2) {
48131
48068
  const spinner = createSpinner("Unlocking wallet...");
48132
48069
  if (!isJsonMode())
48133
48070
  spinner.start();
48134
- const { account } = await loadActiveWallet(password);
48071
+ let account;
48072
+ try {
48073
+ ({ account } = await loadActiveWallet(password));
48074
+ } catch (err3) {
48075
+ if (!isJsonMode())
48076
+ spinner.stop();
48077
+ throw err3;
48078
+ }
48135
48079
  const chainMap = {
48136
48080
  ethereum: ChainId.Ethereum,
48137
48081
  base: ChainId.Base,
@@ -48183,21 +48127,65 @@ function registerHistoryCommand(program2) {
48183
48127
  }
48184
48128
 
48185
48129
  // dist/commands/prices.js
48186
- var DEFAULT_TOKENS = ["ethereum", "solana", "bitcoin"];
48130
+ import inquirer4 from "inquirer";
48131
+ var DEFAULT_TOKENS = [
48132
+ "bitcoin",
48133
+ "ethereum",
48134
+ "solana",
48135
+ "binancecoin",
48136
+ "ripple",
48137
+ "cardano",
48138
+ "avalanche-2",
48139
+ "polkadot",
48140
+ "chainlink",
48141
+ "uniswap",
48142
+ "matic-network",
48143
+ "dogecoin"
48144
+ ];
48145
+ var POPULAR_TOKENS = [
48146
+ { name: "Bitcoin (BTC)", id: "bitcoin" },
48147
+ { name: "Ethereum (ETH)", id: "ethereum" },
48148
+ { name: "Solana (SOL)", id: "solana" },
48149
+ { name: "BNB (BNB)", id: "binancecoin" },
48150
+ { name: "XRP (XRP)", id: "ripple" },
48151
+ { name: "Cardano (ADA)", id: "cardano" },
48152
+ { name: "Avalanche (AVAX)", id: "avalanche-2" },
48153
+ { name: "Polkadot (DOT)", id: "polkadot" },
48154
+ { name: "Chainlink (LINK)", id: "chainlink" },
48155
+ { name: "Uniswap (UNI)", id: "uniswap" },
48156
+ { name: "Polygon (MATIC)", id: "matic-network" },
48157
+ { name: "Dogecoin (DOGE)", id: "dogecoin" },
48158
+ { name: "Shiba Inu (SHIB)", id: "shiba-inu" },
48159
+ { name: "Litecoin (LTC)", id: "litecoin" },
48160
+ { name: "Toncoin (TON)", id: "the-open-network" },
48161
+ { name: "Stellar (XLM)", id: "stellar" },
48162
+ { name: "Cosmos (ATOM)", id: "cosmos" },
48163
+ { name: "Near Protocol (NEAR)", id: "near" },
48164
+ { name: "Aptos (APT)", id: "aptos" },
48165
+ { name: "Sui (SUI)", id: "sui" },
48166
+ { name: "Arbitrum (ARB)", id: "arbitrum" },
48167
+ { name: "Optimism (OP)", id: "optimism" },
48168
+ { name: "Render (RNDR)", id: "render-token" },
48169
+ { name: "Pepe (PEPE)", id: "pepe" }
48170
+ ];
48187
48171
  var COINGECKO_API = "https://api.coingecko.com/api/v3";
48172
+ async function fetchPrices(tokenList, apiUrl) {
48173
+ const url = `${apiUrl}/simple/price?ids=${tokenList.join(",")}&vs_currencies=usd&include_24hr_change=true`;
48174
+ const response = await fetch(url);
48175
+ if (!response.ok)
48176
+ throw new Error(`Price API returned ${response.status}`);
48177
+ return response.json();
48178
+ }
48188
48179
  function registerPricesCommand(program2) {
48189
- program2.command("prices").description("View live token prices").option("--tokens <tokens>", "Comma-separated CoinGecko token IDs").action(async (opts) => {
48180
+ const pricesCmd = program2.command("prices").description("View live token prices");
48181
+ pricesCmd.command("list", { isDefault: true }).description("Show default token prices").option("--tokens <tokens>", "Comma-separated CoinGecko token IDs").action(async (opts) => {
48190
48182
  try {
48191
48183
  const spinner = createSpinner("Fetching prices...");
48192
48184
  if (!isJsonMode())
48193
48185
  spinner.start();
48194
48186
  const config = await loadConfig();
48195
48187
  const tokenList = opts.tokens ? opts.tokens.split(",").map((t) => t.trim()) : DEFAULT_TOKENS;
48196
- const url = `${config.apiUrl || COINGECKO_API}/simple/price?ids=${tokenList.join(",")}&vs_currencies=usd&include_24hr_change=true`;
48197
- const response = await fetch(url);
48198
- if (!response.ok)
48199
- throw new Error(`Price API returned ${response.status}`);
48200
- const data = await response.json();
48188
+ const data = await fetchPrices(tokenList, config.apiUrl || COINGECKO_API);
48201
48189
  if (!isJsonMode())
48202
48190
  spinner.stop();
48203
48191
  const prices = tokenList.map((id) => {
@@ -48210,18 +48198,79 @@ function registerPricesCommand(program2) {
48210
48198
  });
48211
48199
  output({ prices }, () => {
48212
48200
  console.log(sectionHeader("Token Prices"));
48213
- const table = createTable(["Token", "Price (USD)", "24h Change"], [20, 18, 18]);
48214
- for (const p of prices) {
48215
- const priceStr = p.usd !== null ? formatUSD(p.usd) : colors.muted("N/A");
48216
- const changeStr = p.change24h !== null ? p.change24h >= 0 ? colors.success(`+${p.change24h.toFixed(2)}%`) : colors.error(`${p.change24h.toFixed(2)}%`) : colors.muted("N/A");
48217
- table.push([
48218
- colors.primary(p.token.charAt(0).toUpperCase() + p.token.slice(1)),
48219
- priceStr,
48220
- changeStr
48221
- ]);
48201
+ printPriceTable(prices);
48202
+ });
48203
+ } catch (error) {
48204
+ const msg = error instanceof Error ? error.message : String(error);
48205
+ outputError(msg);
48206
+ if (!isJsonMode())
48207
+ console.log(errorMsg(msg));
48208
+ process.exitCode = 1;
48209
+ }
48210
+ });
48211
+ pricesCmd.command("search").description("Look up price for a specific token by CoinGecko ID").argument("<token>", "CoinGecko token ID (e.g. bitcoin, ethereum, uniswap)").action(async (token) => {
48212
+ try {
48213
+ const spinner = createSpinner(`Fetching price for ${token}...`);
48214
+ if (!isJsonMode())
48215
+ spinner.start();
48216
+ const config = await loadConfig();
48217
+ const data = await fetchPrices([token], config.apiUrl || COINGECKO_API);
48218
+ if (!isJsonMode())
48219
+ spinner.stop();
48220
+ const info = data[token];
48221
+ const prices = [{
48222
+ token,
48223
+ usd: info?.usd ?? null,
48224
+ change24h: info?.usd_24h_change ?? null
48225
+ }];
48226
+ if (!info) {
48227
+ outputError(`Token "${token}" not found. Make sure you're using the CoinGecko ID.`);
48228
+ if (!isJsonMode())
48229
+ console.log(errorMsg(`Token "${token}" not found. Use the CoinGecko ID (e.g. "bitcoin", not "BTC").`));
48230
+ process.exitCode = 1;
48231
+ return;
48232
+ }
48233
+ output({ prices }, () => {
48234
+ console.log(sectionHeader(`Price \u2014 ${token}`));
48235
+ printPriceTable(prices);
48236
+ });
48237
+ } catch (error) {
48238
+ const msg = error instanceof Error ? error.message : String(error);
48239
+ outputError(msg);
48240
+ if (!isJsonMode())
48241
+ console.log(errorMsg(msg));
48242
+ process.exitCode = 1;
48243
+ }
48244
+ });
48245
+ pricesCmd.command("browse").description("Browse and select tokens to check prices").action(async () => {
48246
+ try {
48247
+ const { selected } = await inquirer4.prompt([
48248
+ {
48249
+ type: "checkbox",
48250
+ name: "selected",
48251
+ message: "Select tokens to check prices:",
48252
+ choices: POPULAR_TOKENS.map((t) => ({ name: t.name, value: t.id })),
48253
+ validate: (input) => input.length > 0 || "Select at least one token"
48222
48254
  }
48223
- console.log(table.toString());
48224
- console.log();
48255
+ ]);
48256
+ const spinner = createSpinner("Fetching prices...");
48257
+ if (!isJsonMode())
48258
+ spinner.start();
48259
+ const config = await loadConfig();
48260
+ const data = await fetchPrices(selected, config.apiUrl || COINGECKO_API);
48261
+ if (!isJsonMode())
48262
+ spinner.stop();
48263
+ const prices = selected.map((id) => {
48264
+ const info = data[id];
48265
+ return {
48266
+ token: id,
48267
+ usd: info?.usd ?? null,
48268
+ change24h: info?.usd_24h_change ?? null
48269
+ };
48270
+ });
48271
+ output({ prices }, () => {
48272
+ console.log(sectionHeader("Token Prices"));
48273
+ printPriceTable(prices);
48225
48274
  });
48226
48275
  } catch (error) {
48227
48276
  const msg = error instanceof Error ? error.message : String(error);
@@ -48232,13 +48281,29 @@ function registerPricesCommand(program2) {
48232
48281
  }
48233
48282
  });
48234
48283
  }
48284
+ function printPriceTable(prices) {
48285
+ const table = createTable(["Token", "Price (USD)", "24h Change"], [24, 18, 18]);
48286
+ for (const p of prices) {
48287
+ const displayName = p.token.charAt(0).toUpperCase() + p.token.slice(1).replace(/-/g, " ");
48288
+ const priceStr = p.usd !== null ? formatUSD(p.usd) : colors.muted("N/A");
48289
+ const changeStr = p.change24h !== null ? p.change24h >= 0 ? colors.success(`+${p.change24h.toFixed(2)}%`) : colors.error(`${p.change24h.toFixed(2)}%`) : colors.muted("N/A");
48290
+ table.push([
48291
+ colors.primary(displayName),
48292
+ priceStr,
48293
+ changeStr
48294
+ ]);
48295
+ }
48296
+ console.log(table.toString());
48297
+ console.log();
48298
+ }
48235
48299
 
48236
48300
  // dist/commands/receive.js
48237
- import inquirer4 from "inquirer";
48301
+ import inquirer5 from "inquirer";
48238
48302
 
48239
48303
  // dist/ui/qrcode.js
48240
48304
  async function renderQRCode(data) {
48241
- const qrcode = await import("qrcode-terminal");
48305
+ const mod3 = await import("qrcode-terminal");
48306
+ const qrcode = mod3.default ?? mod3;
48242
48307
  return new Promise((resolve) => {
48243
48308
  qrcode.generate(data, { small: true }, (code) => {
48244
48309
  console.log(code);
@@ -48255,7 +48320,7 @@ function registerReceiveCommand(program2) {
48255
48320
  if (opts.password) {
48256
48321
  password = opts.password;
48257
48322
  } else {
48258
- const { pwd } = await inquirer4.prompt([
48323
+ const { pwd } = await inquirer5.prompt([
48259
48324
  {
48260
48325
  type: "password",
48261
48326
  name: "pwd",
@@ -48268,7 +48333,14 @@ function registerReceiveCommand(program2) {
48268
48333
  const spinner = createSpinner("Unlocking wallet...");
48269
48334
  if (!isJsonMode())
48270
48335
  spinner.start();
48271
- const { account } = await loadActiveWallet(password);
48336
+ let account;
48337
+ try {
48338
+ ({ account } = await loadActiveWallet(password));
48339
+ } catch (err3) {
48340
+ if (!isJsonMode())
48341
+ spinner.stop();
48342
+ throw err3;
48343
+ }
48272
48344
  if (!isJsonMode())
48273
48345
  spinner.stop();
48274
48346
  const showEvm = !opts.chain || opts.chain === "evm";
@@ -48307,9 +48379,9 @@ function registerReceiveCommand(program2) {
48307
48379
  }
48308
48380
 
48309
48381
  // dist/commands/send.js
48310
- import inquirer5 from "inquirer";
48382
+ import inquirer6 from "inquirer";
48311
48383
  function registerSendCommand(program2) {
48312
- program2.command("send").description("Send tokens to an address").option("--password <password>", "Wallet password (non-interactive)").option("--to <address>", "Recipient address").option("--amount <amount>", "Amount to send").option("--chain <chain>", "Chain to use (base, ethereum, solana, etc.)", "base").option("--yes", "Skip confirmation prompt").action(async (opts) => {
48384
+ program2.command("send").description("Send tokens to an address").option("--password <password>", "Wallet password (non-interactive)").option("--to <address>", "Recipient address").option("--amount <amount>", "Amount to send").option("--chain <chain>", "Chain to use (base, ethereum, solana, etc.)").option("--yes", "Skip confirmation prompt").action(async (opts) => {
48313
48385
  try {
48314
48386
  let password;
48315
48387
  let to;
@@ -48325,7 +48397,7 @@ function registerSendCommand(program2) {
48325
48397
  console.log(colors.brandBold(" Send Tokens"));
48326
48398
  console.log();
48327
48399
  }
48328
- const answers = await inquirer5.prompt([
48400
+ const answers = await inquirer6.prompt([
48329
48401
  {
48330
48402
  type: "password",
48331
48403
  name: "password",
@@ -48338,7 +48410,7 @@ function registerSendCommand(program2) {
48338
48410
  name: "chain",
48339
48411
  message: "Select network:",
48340
48412
  choices: ["base", "ethereum", "arbitrum", "optimism", "bsc", "solana"],
48341
- when: !opts.chain || opts.chain === "base"
48413
+ when: !opts.chain
48342
48414
  },
48343
48415
  {
48344
48416
  type: "input",
@@ -48361,12 +48433,19 @@ function registerSendCommand(program2) {
48361
48433
  password = opts.password || answers.password;
48362
48434
  to = opts.to || answers.to;
48363
48435
  amount = opts.amount || answers.amount;
48364
- chain2 = opts.chain || answers.chain || "base";
48436
+ chain2 = answers.chain || opts.chain || "base";
48365
48437
  }
48366
48438
  const spinner = createSpinner("Unlocking wallet...");
48367
48439
  if (!isJsonMode())
48368
48440
  spinner.start();
48369
- const { account } = await loadActiveWallet(password);
48441
+ let account;
48442
+ try {
48443
+ ({ account } = await loadActiveWallet(password));
48444
+ } catch (err3) {
48445
+ if (!isJsonMode())
48446
+ spinner.stop();
48447
+ throw err3;
48448
+ }
48370
48449
  if (!isJsonMode())
48371
48450
  spinner.text = " Estimating gas...";
48372
48451
  const chainMap = {
@@ -48403,7 +48482,7 @@ function registerSendCommand(program2) {
48403
48482
  kvLine("Est. Gas", gasLine)
48404
48483
  ]));
48405
48484
  console.log();
48406
- const { confirm } = await inquirer5.prompt([
48485
+ const { confirm } = await inquirer6.prompt([
48407
48486
  {
48408
48487
  type: "confirm",
48409
48488
  name: "confirm",
@@ -48449,7 +48528,7 @@ function registerSendCommand(program2) {
48449
48528
 
48450
48529
  // dist/commands/wallet.js
48451
48530
  import chalk3 from "chalk";
48452
- import inquirer6 from "inquirer";
48531
+ import inquirer7 from "inquirer";
48453
48532
  var COLOR_PRESETS = [
48454
48533
  { name: "Cyan", hex: "#00bbf9" },
48455
48534
  { name: "Orange", hex: "#ff6b35" },
@@ -48461,7 +48540,7 @@ var COLOR_PRESETS = [
48461
48540
  { name: "Teal", hex: "#14b8a6" }
48462
48541
  ];
48463
48542
  async function promptLabelColorPassword(opts) {
48464
- const { walletLabel } = await inquirer6.prompt([{
48543
+ const { walletLabel } = await inquirer7.prompt([{
48465
48544
  type: "input",
48466
48545
  name: "walletLabel",
48467
48546
  message: "Wallet name:",
@@ -48477,14 +48556,14 @@ async function promptLabelColorPassword(opts) {
48477
48556
  if (opts.color) {
48478
48557
  color = opts.color;
48479
48558
  } else {
48480
- const { selectedColor } = await inquirer6.prompt([{
48559
+ const { selectedColor } = await inquirer7.prompt([{
48481
48560
  type: "list",
48482
48561
  name: "selectedColor",
48483
48562
  message: "Choose a color:",
48484
48563
  choices: colorChoices
48485
48564
  }]);
48486
48565
  if (selectedColor === "custom") {
48487
- const { customHex } = await inquirer6.prompt([{
48566
+ const { customHex } = await inquirer7.prompt([{
48488
48567
  type: "input",
48489
48568
  name: "customHex",
48490
48569
  message: "Enter hex color (e.g. #ff6b35):",
@@ -48495,14 +48574,14 @@ async function promptLabelColorPassword(opts) {
48495
48574
  color = selectedColor;
48496
48575
  }
48497
48576
  }
48498
- const { pwd } = await inquirer6.prompt([{
48577
+ const { pwd } = await inquirer7.prompt([{
48499
48578
  type: "password",
48500
48579
  name: "pwd",
48501
48580
  message: "Set a secure password:",
48502
48581
  mask: "*",
48503
48582
  validate: (input) => input.length >= 8 || "Password must be at least 8 characters"
48504
48583
  }]);
48505
- await inquirer6.prompt([{
48584
+ await inquirer7.prompt([{
48506
48585
  type: "password",
48507
48586
  name: "confirmPwd",
48508
48587
  message: "Confirm password:",
@@ -48553,7 +48632,7 @@ function registerWalletCommand(program2) {
48553
48632
  if (walletsNeedingAddresses.length > 0) {
48554
48633
  let password = opts.password;
48555
48634
  if (!password && !isJsonMode()) {
48556
- const { pwd } = await inquirer6.prompt([{
48635
+ const { pwd } = await inquirer7.prompt([{
48557
48636
  type: "password",
48558
48637
  name: "pwd",
48559
48638
  message: "Enter wallet password to resolve addresses:",
@@ -48705,7 +48784,7 @@ function registerWalletCommand(program2) {
48705
48784
  if (opts.mnemonic) {
48706
48785
  mnemonic = opts.mnemonic;
48707
48786
  } else {
48708
- const { phrase } = await inquirer6.prompt([{
48787
+ const { phrase } = await inquirer7.prompt([{
48709
48788
  type: "input",
48710
48789
  name: "phrase",
48711
48790
  message: "Enter your recovery phrase:",
@@ -48763,7 +48842,7 @@ function registerWalletCommand(program2) {
48763
48842
  targetId = match.id;
48764
48843
  } else {
48765
48844
  const active = await getActiveWallet();
48766
- const { selected } = await inquirer6.prompt([{
48845
+ const { selected } = await inquirer7.prompt([{
48767
48846
  type: "list",
48768
48847
  name: "selected",
48769
48848
  message: "Select wallet:",
@@ -48842,7 +48921,7 @@ function registerWalletCommand(program2) {
48842
48921
  if (!match)
48843
48922
  throw new Error(`No wallet found matching '${id}'`);
48844
48923
  if (!opts.yes && !isJsonMode()) {
48845
- const { confirm } = await inquirer6.prompt([{
48924
+ const { confirm } = await inquirer7.prompt([{
48846
48925
  type: "confirm",
48847
48926
  name: "confirm",
48848
48927
  message: `Remove wallet '${match.label}' (${match.id})? This will delete the vault file.`,
@@ -48880,7 +48959,7 @@ function registerWalletCommand(program2) {
48880
48959
  if (opts.password) {
48881
48960
  password = opts.password;
48882
48961
  } else {
48883
- const { pwd } = await inquirer6.prompt([{
48962
+ const { pwd } = await inquirer7.prompt([{
48884
48963
  type: "password",
48885
48964
  name: "pwd",
48886
48965
  message: "Enter your wallet password:",
@@ -48949,7 +49028,7 @@ var zoaGradient2 = gradient2([
48949
49028
  "#c77dff"
48950
49029
  ]);
48951
49030
  var subtleGradient = gradient2(["#6b7280", "#9ca3af", "#6b7280"]);
48952
- var VERSION = "0.2.9";
49031
+ var VERSION = "0.3.0";
48953
49032
  async function displayBanner() {
48954
49033
  const banner = figlet.textSync("ZOA-wallet", { font: "ANSI Shadow" });
48955
49034
  console.log();
@@ -48987,7 +49066,7 @@ program.hook("preAction", async (_thisCommand, actionCommand) => {
48987
49066
  }
48988
49067
  }
48989
49068
  });
48990
- program.name("zoa").description("ZOA Wallet \u2014 API-First Crypto Wallet for Power-traders, Developers, & AI Agents").version("0.2.9");
49069
+ program.name("zoa").description("ZOA Wallet \u2014 API-First Crypto Wallet for Power-traders, Developers, & AI Agents").version("0.3.0");
48991
49070
  registerWalletCommand(program);
48992
49071
  registerBalanceCommand(program);
48993
49072
  registerSendCommand(program);
@@ -48996,7 +49075,6 @@ registerHistoryCommand(program);
48996
49075
  registerExportCommand(program);
48997
49076
  registerChainsCommand(program);
48998
49077
  registerPricesCommand(program);
48999
- registerConfigCommand(program);
49000
49078
  registerApiCommand(program);
49001
49079
  if (!process.argv.slice(2).length) {
49002
49080
  await displayBanner();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zoa-wallet",
3
- "version": "0.2.9",
3
+ "version": "0.3.0",
4
4
  "description": "API-First Crypto Wallet CLI for Power-traders, Developers, & AI Agents. Manage multi-chain wallets from your terminal.",
5
5
  "type": "module",
6
6
  "license": "MIT",