UNPKG

@codegame.dev/wallet-cli

Version:

A CLI tool for managing wallets across multiple blockchains, supporting operations like wallet creation, balance checking, transfers, and fee estimation.

279 lines (278 loc) 11.7 kB
import { getCoin } from "./address.js"; import Chains from "../chains/index.js"; export default (program, trustCore) => { const { HDWallet, CoinType, Curve, Derivation, AnyAddress } = trustCore; program.command('get-balance') .description('check wallet balance of coin or token') .option('--coin <coin>', 'set coin name based on trustwallet core') .option('--coingecko-platform <platform>', 'set platform name based on coingecko api') .option('--address <address>', 'receiver wallet address') .option('--token-address <token-address>', 'contract address of the token. set empty for the coin.') .option('--json-rpc-provider <json-rpc-provider>', 'url of the json rpc provider') .option('--http-provider <http-provider>', 'url of the http provider') .option('--json', 'output will be in json format') .option('--testnet', 'the default provider will be in testnet') .option('--delay <delay>', 'delay between each request in milliseconds to avoid rate limiting') .action(async (values) => { const [coin, error] = getCoin(trustCore, values.coin, values.coingeckoPlatform, true); if (error || !coin) { program.error(JSON.stringify({ ...error, json: values.json })); } const chain = Chains.find(v => v.id == coin); if (!chain) { program.error(JSON.stringify({ success: false, code: 'not-supported', message: "This chain not supported", json: values.json })); } const address = values.address; const tokenAddress = values.tokenAddress; const delay = Number(values.delay) || 0; let jsonRpcProvider = values.jsonRpcProvider?.trim?.(); if (!jsonRpcProvider) { jsonRpcProvider = values.testnet ? chain.json_rpc_test_provider : chain.json_rpc_provider; } try { if (!chain.api?.getBalance) { program.error(JSON.stringify({ success: false, code: 'not-supported', message: "This chain not supported", json: values.json })); } const r = await chain.api.getBalance({ coin, address, jsonRpcProvider, tokenAddress, chainDecimals: chain.decimals, testnet: values.testnet, delay }); if (!r.success) { program.error(JSON.stringify({ ...r, json: values.json })); } if (values.json) { console.log(JSON.stringify(r)); } else { if (r.coin_balance !== undefined) { console.log("Coin Balance:", r.coin_balance); } if (r.token_balance !== undefined) { console.log("Token Balance:", r.token_balance); } } } catch (e) { program.error(JSON.stringify({ success: false, code: 'error-get-balance', message: e?.shortMessage || e?.message || "Error in fetching balance", json: values.json })); } }); program.command('transfer') .description('transfer coin or token to another wallet') .option('--mnemonic <mnemonic>', 'set an existing mnemonic') .option('--coin <coin>', 'set coin name based on trustwallet core') .option('--coingecko-platform <platform>', 'set platform name based on coingecko api') .option('--address <address>', 'receiver wallet address') .option('--amount <amount>', 'the amount to transfer') .option('--token-address <token-address>', 'contract address of the token. set empty for the coin.') .option('--json-rpc-provider <json-rpc-provider>', 'url of the json rpc provider') .option('--json', 'output will be in json format') .option('--testnet', 'the default provider will be in testnet') .option('--delay <delay>', 'delay between each request in milliseconds to avoid rate limiting') .action(async (values) => { const [coin, error] = getCoin(trustCore, values.coin, values.coingeckoPlatform, true); if (error || !coin) { program.error(JSON.stringify({ ...error, json: values.json })); } const chain = Chains.find(v => v.id == coin); if (!chain) { program.error(JSON.stringify({ success: false, code: 'not-supported', message: "This chain not supported", json: values.json })); } const mnemonic = values.mnemonic || ''; let amount = values.amount; const tokenAddress = values.tokenAddress; const toAddress = values.address; const delay = Number(values.delay) || 0; let jsonRpcProvider = values.jsonRpcProvider?.trim?.(); if (!jsonRpcProvider) { jsonRpcProvider = values.testnet ? chain.json_rpc_test_provider : chain.json_rpc_provider; } if (!mnemonic) { program.error(JSON.stringify({ success: false, code: 'empty-mnemonic', message: "Set the mnemonic", json: values.json })); } if (!amount) { program.error(JSON.stringify({ success: false, code: 'empty-amount', message: "Set the amount you want to transfer", json: values.json })); } if (!toAddress) { program.error(JSON.stringify({ success: false, code: 'empty-address', message: "Set the wallet address you want to transfer to it", json: values.json })); } const wallet = HDWallet.createWithMnemonic(mnemonic, ""); const secretKey = wallet.getKeyForCoin(CoinType[coin]).data(); const fromAddress = wallet.getAddressForCoin(CoinType[coin]); try { if (!chain.api?.transfer) { program.error(JSON.stringify({ success: false, code: 'not-supported', message: "This chain not supported", json: values.json })); } const r = await chain.api.transfer({ coin, mnemonic, secretKey, fromAddress, toAddress, amount, jsonRpcProvider, tokenAddress, chainDecimals: chain.decimals, testnet: values.testnet, delay }); if (!r.success) { program.error(JSON.stringify({ ...r, json: values.json })); } if (values.json) { console.log(JSON.stringify(r)); } else { console.log("Hash:", r.hash); console.log("Fee:", r.fee); } } catch (e) { program.error(JSON.stringify({ success: false, code: 'error-transfer', message: e?.shortMessage || e?.message || "Error in transfering", json: values.json })); } }); program.command('estimate-fee') .description('estimate fee for a coin or token transfer') .option('--mnemonic <mnemonic>', 'set an existing mnemonic') .option('--coin <coin>', 'set coin name based on trustwallet core') .option('--coingecko-platform <platform>', 'set platform name based on coingecko api') .option('--address <address>', 'receiver wallet address') .option('--amount <amount>', 'the amount to transfer') .option('--token-address <token-address>', 'contract address of the token. set empty for the coin.') .option('--json-rpc-provider <json-rpc-provider>', 'url of the json rpc provider') .option('--json', 'output will be in json format') .option('--testnet', 'the default provider will be in testnet') .option('--delay <delay>', 'delay between each request in milliseconds to avoid rate limiting') .action(async (values) => { const [coin, error] = getCoin(trustCore, values.coin, values.coingeckoPlatform, true); if (error || !coin) { program.error(JSON.stringify({ ...error, json: values.json })); } const chain = Chains.find(v => v.id == coin); if (!chain) { program.error(JSON.stringify({ success: false, code: 'not-supported', message: "This chain not supported", json: values.json })); } const mnemonic = values.mnemonic || ''; const amount = values.amount; const tokenAddress = values.tokenAddress; const toAddress = values.address; const delay = Number(values.delay) || 0; let jsonRpcProvider = values.jsonRpcProvider?.trim?.(); if (!jsonRpcProvider) { jsonRpcProvider = values.testnet ? chain.json_rpc_test_provider : chain.json_rpc_provider; } if (!mnemonic) { program.error(JSON.stringify({ success: false, code: 'empty-mnemonic', message: "Set the mnemonic", json: values.json })); } if (!amount) { program.error(JSON.stringify({ success: false, code: 'empty-amount', message: "Set the amount you want to transfer", json: values.json })); } if (!toAddress) { program.error(JSON.stringify({ success: false, code: 'empty-address', message: "Set the wallet address you want to transfer to it", json: values.json })); } const wallet = HDWallet.createWithMnemonic(mnemonic, ""); const secretKey = wallet.getKeyForCoin(CoinType[coin]).data(); const fromAddress = wallet.getAddressForCoin(CoinType[coin]); try { if (!chain.api?.estimateFee) { program.error(JSON.stringify({ success: false, code: 'not-supported', message: "This chain not supported", json: values.json })); } const r = await chain.api.estimateFee({ coin, mnemonic, secretKey, fromAddress, toAddress, amount, jsonRpcProvider, tokenAddress, chainDecimals: chain.decimals, testnet: values.testnet, delay }); if (!r.success) { program.error(JSON.stringify({ ...r, json: values.json })); } if (values.json) { console.log(JSON.stringify(r)); } else { console.log("Fee:", r.fee); } } catch (e) { program.error(JSON.stringify({ success: false, code: 'error-gas-limit', message: e?.shortMessage || e?.message || "Error in estimating gas limit", json: values.json })); } }); };