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.

212 lines (211 loc) 7.77 kB
import { ethers, formatUnits } from "ethers"; import { TronWeb } from 'tronweb'; import { sleep } from "../utils/index.js"; const trc20Abi = [ { "constant": true, "inputs": [{ "name": "owner", "type": "address" }], "name": "balanceOf", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "to", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "transfer", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [{ "name": "", "type": "uint8" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [{ "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "name", "outputs": [{ "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" } ]; export const getBalance = async (params) => { const tronWeb = new TronWeb({ fullHost: params.jsonRpcProvider, }); tronWeb.setAddress(params.address); if (params.tokenAddress) { const tokenContract = tronWeb.contract(trc20Abi, params.tokenAddress); const decimals = await tokenContract.decimals().call(); await sleep(params.delay); const tokenBalance = formatUnits(await tokenContract.balanceOf(params.address).call(), decimals); return { success: true, token_balance: tokenBalance, }; } else { const coinBalance = formatUnits(await tronWeb.trx.getBalance(params.address), params.chainDecimals); return { success: true, coin_balance: coinBalance, }; } }; export const transfer = async (params) => { const tronWeb = new TronWeb({ fullHost: params.jsonRpcProvider, }); tronWeb.setPrivateKey(Buffer.from(params.secretKey).toString('hex')); tronWeb.setAddress(params.fromAddress); if (params.tokenAddress) { const tokenContract = tronWeb.contract(trc20Abi, params.tokenAddress); const decimals = Number(await tokenContract.decimals().call()); await sleep(params.delay); const amount = Number(params.amount).toFixed(decimals); const amountInSun = ethers.parseUnits(amount, decimals); const transaction = await tokenContract.transfer(params.toAddress, amountInSun).send(); const hash = transaction; const fee = "0"; return { success: true, hash, fee, }; } else { const amount = Number(params.amount).toFixed(params.chainDecimals); const amountInSun = Number(ethers.parseUnits(amount, params.chainDecimals)); const transaction = await tronWeb.trx.sendTransaction(params.toAddress, amountInSun); const hash = transaction.txid; const fee = "0"; return { success: true, hash, fee, }; } }; export const estimateFee = async (params) => { const tronWeb = new TronWeb({ fullHost: params.jsonRpcProvider, }); tronWeb.setAddress(params.fromAddress); if (params.tokenAddress) { const tokenContract = tronWeb.contract(trc20Abi, params.tokenAddress); const decimals = await tokenContract.decimals().call(); await sleep(params.delay); const amountInSun = ethers.parseUnits("0", decimals); const result = await tronWeb.transactionBuilder.triggerConstantContract(params.tokenAddress, 'transfer(address,uint256)', {}, [ { type: 'address', value: params.toAddress }, { type: 'uint256', value: amountInSun } ], params.fromAddress); await sleep(params.delay); const energyLimit = (result.energy_used || result.energy_required || 0) + (result.energy_penalty || 0); const currentTimestamp = Date.now(); const energyPrices = (await tronWeb.trx.getEnergyPrices()).split(",").map(part => part.split(':').map(v => Number(v))); energyPrices.reverse(); await sleep(params.delay); const energyPrice = (energyPrices.find(part => currentTimestamp <= part[0]) || energyPrices[0])[1]; if (!energyPrice) { return { success: false, code: 'empty-gas-price', message: "Error in fetching energy price", }; } const energyCostInSum = energyLimit * energyPrice; const energyCost = formatUnits(energyCostInSum, params.chainDecimals); const bandwidthLimit = 400; const bandwidthPrices = (await tronWeb.trx.getBandwidthPrices()).split(",").map(part => part.split(':').map(v => Number(v))); bandwidthPrices.reverse(); const bandwidthPrice = (bandwidthPrices.find(part => currentTimestamp <= part[0]) || bandwidthPrices[0])[1]; if (!bandwidthPrice) { return { success: false, code: 'empty-gas-price', message: "Error in fetching bandwidth price", }; } const bandwidthCostInSum = bandwidthLimit * bandwidthPrice; const bandwidthCost = formatUnits(bandwidthCostInSum, params.chainDecimals); const gasCost = Number(bandwidthCost) + Number(energyCost); return { success: true, fee: String(gasCost || 0), }; } else { const bandwidthLimit = 400; const bandwidthPrices = (await tronWeb.trx.getBandwidthPrices()).split(",").map(part => part.split(':').map(v => Number(v))); bandwidthPrices.reverse(); const currentTimestamp = Date.now(); const bandwidthPrice = (bandwidthPrices.find(part => currentTimestamp <= part[0]) || bandwidthPrices[0])[1]; if (!bandwidthPrice) { return { success: false, code: 'empty-gas-price', message: "Error in fetching bandwidth price" }; } const bandwidthCostInSum = bandwidthLimit * bandwidthPrice; const bandwidthCost = formatUnits(bandwidthCostInSum, params.chainDecimals); const gasCost = bandwidthCost; return { success: true, fee: gasCost, }; } }; export default { getBalance, transfer, estimateFee };