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.
- package/dist/index.mjs +215 -137
- 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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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 [
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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")
|
|
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
|
|
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
|
-
|
|
48214
|
-
|
|
48215
|
-
|
|
48216
|
-
|
|
48217
|
-
|
|
48218
|
-
|
|
48219
|
-
|
|
48220
|
-
|
|
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
|
-
|
|
48224
|
-
|
|
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
|
|
48301
|
+
import inquirer5 from "inquirer";
|
|
48238
48302
|
|
|
48239
48303
|
// dist/ui/qrcode.js
|
|
48240
48304
|
async function renderQRCode(data) {
|
|
48241
|
-
const
|
|
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
|
|
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
|
-
|
|
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
|
|
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.)"
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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