UNPKG

@thorwallet/xchain-ethereum

Version:
83 lines 3.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getBalance = void 0; const tslib_1 = require("tslib"); const xchain_util_1 = require("@thorwallet/xchain-util"); const ethers_1 = require("ethers"); const p_throttle_1 = tslib_1.__importDefault(require("p-throttle")); const utils_1 = require("./utils"); const ethplorerAPI = tslib_1.__importStar(require("./ethplorer-api")); const etherscanAPI = tslib_1.__importStar(require("./etherscan-api")); const erc20_json_1 = tslib_1.__importDefault(require("./data/erc20.json")); const providers_1 = require("@ethersproject/providers"); const getProvider = (network) => { return providers_1.getDefaultProvider(network); }; const call = (network, contractAddress, abi, func, params) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { if (!contractAddress) { return Promise.reject(new Error('contractAddress must be provided')); } const contract = new ethers_1.ethers.Contract(contractAddress, abi, getProvider(network)); return contract[func](...params); }); const getBalance = ({ address, network, assets, ethplorerUrl, ethplorerApiKey, etherscanApiKey, }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { // get ETH balance directly from provider const ethBalance = yield getProvider(network).getBalance(address); const ethBalanceAmount = xchain_util_1.baseAmount(ethBalance.toString(), utils_1.ETH_DECIMAL); if (network === 'mainnet') { // use ethplorerAPI for mainnet - ignore assets const account = yield ethplorerAPI.getAddress(ethplorerUrl, address, ethplorerApiKey); const balances = [ { asset: xchain_util_1.AssetETH, amount: ethBalanceAmount, }, ]; if (account.tokens) { balances.push(...utils_1.getTokenBalances(account.tokens)); } return balances; } // use etherscan for testnet const newAssets = assets || [xchain_util_1.AssetETH]; // Follow approach is only for testnet // For mainnet, we will use ethplorer api(one request only) // https://github.com/xchainjs/xchainjs-lib/issues/252 // And to avoid etherscan api call limit, it gets balances in a sequence way, not in parallel const throttle = p_throttle_1.default({ limit: 5, interval: 1000, }); const getBalance = throttle((asset) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { const etherscan = new providers_1.EtherscanProvider(network, etherscanApiKey); if (xchain_util_1.assetToString(asset) !== xchain_util_1.assetToString(xchain_util_1.AssetETH)) { // Handle token balances const assetAddress = utils_1.getTokenAddress(asset); if (!assetAddress) { throw new Error(`Invalid asset ${asset}`); } const balance = yield etherscanAPI.getTokenBalance({ baseUrl: etherscan.baseUrl, address, assetAddress, apiKey: etherscan.apiKey, }); const decimals = ethers_1.BigNumber.from(yield call(network, assetAddress, erc20_json_1.default, 'decimals', [])).toNumber() || utils_1.ETH_DECIMAL; if (!Number.isNaN(decimals)) { return { asset, amount: xchain_util_1.baseAmount(balance.toString(), decimals), }; } } return { asset: xchain_util_1.AssetETH, amount: ethBalanceAmount, }; })); const balances = yield Promise.all(newAssets.map((asset) => getBalance(asset))); return balances; }); exports.getBalance = getBalance; //# sourceMappingURL=get-balance.js.map