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.

315 lines (274 loc) 12.6 kB
import { Command } from "commander"; import type { WalletCore } from '@trustwallet/wallet-core' import { getCoin } from "./address"; import Chains from "../chains/index"; export default (program: Command, trustCore: WalletCore) => { 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: any) { 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: any) { 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: any) { program.error(JSON.stringify({ success: false, code: 'error-gas-limit', message: e?.shortMessage || e?.message || "Error in estimating gas limit", json: values.json })) } }) }