UNPKG

hector-rubic-sdk

Version:
760 lines 39.3 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Web3Public = void 0; var cache_decorator_1 = require("../../../common/decorators/cache.decorator"); var healthcheck_error_1 = require("../../../common/errors/blockchain/healthcheck.error"); var timeout_error_1 = require("../../../common/errors/utils/timeout.error"); var p_timeout_1 = __importDefault(require("../../../common/utils/p-timeout")); var erc_20_abi_1 = require("../constants/erc-20-abi"); var healthcheck_1 = require("../constants/healthcheck"); var native_tokens_1 = require("../constants/native-tokens"); var multicall_abi_1 = require("./constants/multicall-abi"); var multicall_addresses_1 = require("./constants/multicall-addresses"); var web3_pure_1 = require("../web3-pure/web3-pure"); var bignumber_js_1 = __importDefault(require("bignumber.js")); var insufficient_funds_error_1 = require("../../../common/errors/swap/insufficient-funds.error"); var default_http_client_1 = require("../../../common/http/default-http-client"); /** * Class containing methods for calling contracts in order to obtain information from the blockchain. * To send transaction or execute contract method use {@link Web3Private}. */ var Web3Public = /** @class */ (function () { /** * @param web3 web3 instance initialized with ethereum provider, e.g. rpc link * @param blockchainName blockchain in which you need to execute requests * @param [httpClient=axios] http client that implements {@link HttpClient} interface */ function Web3Public(web3, blockchainName, httpClient) { this.web3 = web3; this.blockchainName = blockchainName; this.httpClient = httpClient; this.multicallAddresses = multicall_addresses_1.MULTICALL_ADDRESSES; this.clearController = { clear: false }; } /** * HealthCheck current rpc node * @param timeoutMs acceptable node response timeout * @return null if healthcheck is not defined for current blockchain, else is node works status */ Web3Public.prototype.healthCheck = function (timeoutMs) { if (timeoutMs === void 0) { timeoutMs = 4000; } return __awaiter(this, void 0, void 0, function () { var healthcheckData, contract, result, e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(0, healthcheck_1.isBlockchainHealthcheckAvailable)(this.blockchainName)) { return [2 /*return*/, true]; } healthcheckData = healthcheck_1.HEALTHCHECK[this.blockchainName]; contract = new this.web3.eth.Contract(healthcheckData.contractAbi, healthcheckData.contractAddress); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, (0, p_timeout_1.default)(contract.methods[healthcheckData.method]().call(), timeoutMs)]; case 2: result = _a.sent(); if (result !== healthcheckData.expected) { throw new healthcheck_error_1.HealthcheckError(); } return [2 /*return*/, true]; case 3: e_1 = _a.sent(); if (e_1 instanceof timeout_error_1.TimeoutError) { console.debug("".concat(this.blockchainName, " node healthcheck timeout (").concat(timeoutMs, "ms) has occurred.")); } else { console.debug("".concat(this.blockchainName, " node healthcheck fail: ").concat(e_1)); } return [2 /*return*/, false]; case 4: return [2 /*return*/]; } }); }); }; /** * @description set new provider to web3 instance * @param provider new web3 provider, e.g. rpc link */ Web3Public.prototype.setProvider = function (provider) { this.web3.setProvider(provider); }; /** * @description gets block by blockId * @param [blockId] block id: hash, number ... Default is 'latest'. * @returns {BlockTransactionString} block by blockId parameter. */ Web3Public.prototype.getBlock = function (blockId) { if (blockId === void 0) { blockId = 'latest'; } return this.web3.eth.getBlock(blockId); }; /** * @description gets account eth or token balance as integer (multiplied to 10 ** decimals) * @param address wallet address whose balance you want to find out * @param [tokenAddress] address of the smart-contract corresponding to the token, or {@link NATIVE_TOKEN_ADDRESS}. * If not passed the balance in the native currency will be returned. * @returns address eth or token balance as integer (multiplied to 10 ** decimals) */ Web3Public.prototype.getBalance = function (address, tokenAddress) { return __awaiter(this, void 0, void 0, function () { var balance; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(tokenAddress && !web3_pure_1.Web3Pure.isNativeAddress(tokenAddress))) return [3 /*break*/, 2]; return [4 /*yield*/, this.getTokenBalance(address, tokenAddress)]; case 1: balance = _a.sent(); return [3 /*break*/, 4]; case 2: return [4 /*yield*/, this.web3.eth.getBalance(address)]; case 3: balance = _a.sent(); _a.label = 4; case 4: return [2 /*return*/, new bignumber_js_1.default(balance)]; } }); }); }; /** * @description gets ERC-20 tokens balance as integer (multiplied to 10 ** decimals) * @param tokenAddress address of the smart-contract corresponding to the token * @param address wallet address whose balance you want to find out * @returns address tokens balance as integer (multiplied to 10 ** decimals) */ Web3Public.prototype.getTokenBalance = function (address, tokenAddress) { return __awaiter(this, void 0, void 0, function () { var contract, balance; return __generator(this, function (_a) { switch (_a.label) { case 0: contract = new this.web3.eth.Contract(erc_20_abi_1.ERC20_TOKEN_ABI, tokenAddress); return [4 /*yield*/, contract.methods.balanceOf(address).call()]; case 1: balance = _a.sent(); return [2 /*return*/, new bignumber_js_1.default(balance)]; } }); }); }; /** * @description predicts the volume of gas required to execute the contract method * @param contractAbi abi of smart-contract * @param contractAddress address of smart-contract * @param methodName method whose execution gas number is to be calculated * @param methodArguments arguments of the executed contract method * @param fromAddress the address for which the gas calculation will be called * @param [value] The value transferred for the call “transaction” in wei. * @return The gas amount estimated */ Web3Public.prototype.getEstimatedGas = function (contractAbi, contractAddress, methodName, methodArguments, fromAddress, value) { return __awaiter(this, void 0, void 0, function () { var contract, gasLimit, err_1; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: contract = new this.web3.eth.Contract(contractAbi, contractAddress); _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, (_a = contract.methods)[methodName].apply(_a, methodArguments).estimateGas(__assign({ from: fromAddress, gas: 10000000 }, (value && { value: value })))]; case 2: gasLimit = _b.sent(); return [2 /*return*/, new bignumber_js_1.default(gasLimit)]; case 3: err_1 = _b.sent(); console.debug(err_1); return [2 /*return*/, null]; case 4: return [2 /*return*/]; } }); }); }; /** * @description calculates the average price per unit of gas according to web3 * @return average gas price in Wei */ Web3Public.prototype.getGasPrice = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.web3.eth.getGasPrice()]; }); }); }; /** * @description calculates the average price per unit of gas according to web3 * @return average gas price in ETH */ Web3Public.prototype.getGasPriceInETH = function () { return __awaiter(this, void 0, void 0, function () { var gasPrice; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.web3.eth.getGasPrice()]; case 1: gasPrice = _a.sent(); return [2 /*return*/, new bignumber_js_1.default(gasPrice).div(Math.pow(10, 18))]; } }); }); }; /** * @description calculates the gas fee using average price per unit of gas according to web3 and Eth price according to coingecko * @param gasLimit gas limit * @param etherPrice price of Eth unit * @return gas fee in usd$ */ Web3Public.prototype.getGasFee = function (gasLimit, etherPrice) { return __awaiter(this, void 0, void 0, function () { var gasPrice; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getGasPriceInETH()]; case 1: gasPrice = _a.sent(); return [2 /*return*/, gasPrice.multipliedBy(gasLimit).multipliedBy(etherPrice)]; } }); }); }; /** * @description executes allowance method in ERC-20 token contract * @param tokenAddress address of the smart-contract corresponding to the token * @param spenderAddress wallet or contract address, allowed to spend * @param ownerAddress wallet address to spend from * @return tokens amount, allowed to be spent */ Web3Public.prototype.getAllowance = function (tokenAddress, ownerAddress, spenderAddress) { return __awaiter(this, void 0, void 0, function () { var contract, allowance; return __generator(this, function (_a) { switch (_a.label) { case 0: contract = new this.web3.eth.Contract(erc_20_abi_1.ERC20_TOKEN_ABI, tokenAddress); return [4 /*yield*/, contract.methods .allowance(ownerAddress, spenderAddress) .call({ from: ownerAddress })]; case 1: allowance = _a.sent(); return [2 /*return*/, new bignumber_js_1.default(allowance)]; } }); }); }; /** * @description gets mined transaction gas fee in Ether * @param hash transaction hash * @return transaction gas fee in Wei or null if transaction is not mined */ Web3Public.prototype.getTransactionGasFee = function (hash) { return __awaiter(this, void 0, void 0, function () { var transaction, receipt, gasPrice, gasLimit; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getTransactionByHash(hash)]; case 1: transaction = _a.sent(); return [4 /*yield*/, this.web3.eth.getTransactionReceipt(hash)]; case 2: receipt = _a.sent(); if (!transaction || !receipt) { return [2 /*return*/, null]; } gasPrice = new bignumber_js_1.default(transaction.gasPrice); gasLimit = new bignumber_js_1.default(receipt.gasUsed); return [2 /*return*/, gasPrice.multipliedBy(gasLimit)]; } }); }); }; /** * @description get a transaction by hash in several attempts * @param hash hash of the target transaction * @param attempt current attempt number * @param attemptsLimit maximum allowed number of attempts * @param delay ms delay before next attempt */ Web3Public.prototype.getTransactionByHash = function (hash, attempt, attemptsLimit, delay) { return __awaiter(this, void 0, void 0, function () { var limit, timeoutMs, transaction; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: attempt = attempt || 0; limit = attemptsLimit || 10; timeoutMs = delay || 500; if (attempt >= limit) { return [2 /*return*/, null]; } return [4 /*yield*/, this.web3.eth.getTransaction(hash)]; case 1: transaction = _a.sent(); if (transaction === null) { return [2 /*return*/, new Promise(function (resolve) { return setTimeout(function () { return resolve(_this.getTransactionByHash(hash, attempt + 1)); }, timeoutMs); })]; } return [2 /*return*/, transaction]; } }); }); }; /** * @description call smart-contract pure method of smart-contract and returns its output value * @param contractAddress address of smart-contract which method is to be executed * @param contractAbi abi of smart-contract which method is to be executed * @param methodName calling method name * @param [options] additional options * @param [options.from] the address the call “transaction” should be made from * @param [options.methodArguments] executing method arguments * @return smart-contract pure method returned value */ Web3Public.prototype.callContractMethod = function (contractAddress, contractAbi, methodName, options) { if (options === void 0) { options = { methodArguments: [] }; } return __awaiter(this, void 0, void 0, function () { var contract; var _a; return __generator(this, function (_b) { contract = new this.web3.eth.Contract(contractAbi, contractAddress); return [2 /*return*/, (_a = contract.methods)[methodName].apply(_a, options.methodArguments).call(__assign(__assign({}, (options.from && { from: options.from })), (options.value && { value: options.value })))]; }); }); }; /** * @description get balance of multiple tokens via multicall * @param address wallet address * @param tokensAddresses tokens addresses */ Web3Public.prototype.getTokensBalances = function (address, tokensAddresses) { return __awaiter(this, void 0, void 0, function () { var contract, indexOfNativeCoin, promises, calls, results, tokensBalances; return __generator(this, function (_a) { switch (_a.label) { case 0: contract = new this.web3.eth.Contract(erc_20_abi_1.ERC20_TOKEN_ABI, tokensAddresses[0]); indexOfNativeCoin = tokensAddresses.findIndex(web3_pure_1.Web3Pure.isNativeAddress); promises = []; if (indexOfNativeCoin !== -1) { tokensAddresses.splice(indexOfNativeCoin, 1); promises[1] = this.getBalance(address); } calls = tokensAddresses.map(function (tokenAddress) { return ({ target: tokenAddress, callData: contract.methods.balanceOf(address).encodeABI() }); }); promises[0] = this.multicall(calls); return [4 /*yield*/, Promise.all(promises)]; case 1: results = _a.sent(); tokensBalances = results[0].map(function (_a) { var success = _a.success, returnData = _a.returnData; return success ? new bignumber_js_1.default(returnData) : new bignumber_js_1.default(0); }); if (indexOfNativeCoin !== -1) { tokensBalances.splice(indexOfNativeCoin, 0, results[1]); } return [2 /*return*/, tokensBalances]; } }); }); }; /** * Uses multicall to make several calls of one method in one contract. * @param contractAddress Target contract address. * @param contractAbi Target contract abi. * @param methodName target method name * @param methodCallsArguments list method calls parameters arrays */ Web3Public.prototype.multicallContractMethod = function (contractAddress, contractAbi, methodName, methodCallsArguments) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.multicallContractMethods(contractAddress, contractAbi, methodCallsArguments.map(function (methodArguments) { return ({ methodName: methodName, methodArguments: methodArguments }); }))]; }); }); }; /** * Uses multicall to make several methods calls in one contract. * @param contractAddress Target contract address. * @param contractAbi Target contract abi. * @param methodsData Methods data, containing methods' names and arguments. */ Web3Public.prototype.multicallContractMethods = function (contractAddress, contractAbi, methodsData) { return __awaiter(this, void 0, void 0, function () { var results; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.multicallContractsMethods(contractAbi, [ { contractAddress: contractAddress, methodsData: methodsData } ])]; case 1: results = _a.sent(); if (!(results === null || results === void 0 ? void 0 : results[0])) { throw new Error('[RUBIC SDK] Cant perform multicall or request data is empty.'); } return [2 /*return*/, results[0]]; } }); }); }; /** * Uses multicall to make many methods calls in several contracts. * @param contractAbi Target contract abi. * @param contractsData Contract addresses and methods data, containing methods' names and arguments. */ Web3Public.prototype.multicallContractsMethods = function (contractAbi, contractsData) { return __awaiter(this, void 0, void 0, function () { var calls, outputs, outputIndex; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: calls = contractsData.map(function (_a) { var contractAddress = _a.contractAddress, methodsData = _a.methodsData; var contract = new _this.web3.eth.Contract(contractAbi, contractAddress); return methodsData.map(function (_a) { var _b; var methodName = _a.methodName, methodArguments = _a.methodArguments; return ({ callData: (_b = contract.methods)[methodName].apply(_b, methodArguments).encodeABI(), target: contractAddress }); }); }); return [4 /*yield*/, this.multicall(calls.flat())]; case 1: outputs = _a.sent(); outputIndex = 0; return [2 /*return*/, contractsData.map(function (contractData) { return contractData.methodsData.map(function (methodData) { var methodOutputAbi = contractAbi.find(function (funcSignature) { return funcSignature.name === methodData.methodName; }).outputs; var output = outputs[outputIndex]; if (!output) { throw new Error('[RUBIC SDK] Output has to be defined'); } outputIndex++; return { success: output.success, output: output.success ? _this.web3.eth.abi.decodeParameters(methodOutputAbi, output.returnData) : null }; }); })]; } }); }); }; /** * @description Checks if the specified address contains the required amount of these tokens. * Throws an InsufficientFundsError if the balance is insufficient * @param token token balance for which you need to check * @param amount required balance * @param userAddress the address where the required balance should be */ Web3Public.prototype.checkBalance = function (token, amount, userAddress) { return __awaiter(this, void 0, void 0, function () { var balance, amountAbsolute; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!web3_pure_1.Web3Pure.isNativeAddress(token.address)) return [3 /*break*/, 2]; return [4 /*yield*/, this.getBalance(userAddress)]; case 1: balance = _a.sent(); return [3 /*break*/, 4]; case 2: return [4 /*yield*/, this.getTokenBalance(userAddress, token.address)]; case 3: balance = _a.sent(); _a.label = 4; case 4: amountAbsolute = web3_pure_1.Web3Pure.toWei(amount, token.decimals); if (balance.lt(amountAbsolute)) { throw new insufficient_funds_error_1.InsufficientFundsError(amount.toFixed(0)); } return [2 /*return*/]; } }); }); }; /** * Gets ERC-20 token info by address. * @param tokenAddress Address of token. * @param tokenFields Token's fields to get. */ Web3Public.prototype.callForTokenInfo = function (tokenAddress, tokenFields) { if (tokenFields === void 0) { tokenFields = ['decimals', 'symbol', 'name']; } return __awaiter(this, void 0, void 0, function () { var nativeToken, tokenFieldsPromises, tokenFieldsResults; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: if (web3_pure_1.Web3Pure.isNativeAddress(tokenAddress)) { nativeToken = native_tokens_1.nativeTokensList[this.blockchainName]; return [2 /*return*/, __assign(__assign({}, nativeToken), { decimals: nativeToken.decimals.toString() })]; } tokenFieldsPromises = tokenFields.map(function (method) { return _this.callContractMethod(tokenAddress, erc_20_abi_1.ERC20_TOKEN_ABI, method); }); return [4 /*yield*/, Promise.all(tokenFieldsPromises)]; case 1: tokenFieldsResults = _a.sent(); return [2 /*return*/, tokenFieldsResults.reduce(function (acc, field, index) { var _a; var fieldName = tokenFields[index]; if (!fieldName) { throw new Error('[RUBIC SDK] Field name has to be defined.'); } return __assign(__assign({}, acc), (_a = {}, _a[fieldName] = field, _a)); }, {})]; } }); }); }; /** * Gets ERC-20 tokens info by addresses. * @param tokenAddresses Addresses of tokens. */ Web3Public.prototype.callForTokensInfo = function (tokenAddresses) { return __awaiter(this, void 0, void 0, function () { var tokenFields, contractsData, results, notSave, tokensInfo, conditionalReturns; return __generator(this, function (_a) { switch (_a.label) { case 0: tokenFields = ['decimals', 'symbol', 'name']; contractsData = tokenAddresses.map(function (contractAddress) { return ({ contractAddress: contractAddress, methodsData: tokenFields.map(function (methodName) { return ({ methodName: methodName, methodArguments: [] }); }) }); }); return [4 /*yield*/, this.multicallContractsMethods(erc_20_abi_1.ERC20_TOKEN_ABI, contractsData)]; case 1: results = _a.sent(); notSave = false; tokensInfo = results.map(function (contractCallResult) { var token = {}; contractCallResult.forEach(function (field, index) { var _a; token[tokenFields[index]] = field.success ? (_a = field.output) === null || _a === void 0 ? void 0 : _a[0] : undefined; if (!field.success) { notSave = true; } }); return token; }); conditionalReturns = { notSave: notSave, value: tokensInfo }; // see https://github.com/microsoft/TypeScript/issues/4881 // @ts-ignore return [2 /*return*/, conditionalReturns]; } }); }); }; /** * @description get estimated gas of several contract method execution via rpc batch request * @param abi contract ABI * @param contractAddress contract address * @param fromAddress sender address * @param callsData transactions parameters * @returns list of contract execution estimated gases. * if the execution of the method in the real blockchain would not be reverted, * then the list item would be equal to the predicted gas limit. * Else (if you have not enough balance, allowance ...) then the list item would be equal to null */ Web3Public.prototype.batchEstimatedGas = function (abi, contractAddress, fromAddress, callsData) { return __awaiter(this, void 0, void 0, function () { var contract_1, dataList, rpcCallsData, result, e_2; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); contract_1 = new this.web3.eth.Contract(abi, contractAddress); dataList = callsData.map(function (callData) { var _a; return (_a = contract_1.methods)[callData.contractMethod].apply(_a, callData.params).encodeABI(); }); rpcCallsData = dataList.map(function (data, index) { var _a, _b; return ({ rpcMethod: 'eth_estimateGas', params: __assign({ from: fromAddress, to: contractAddress, data: data }, (((_a = callsData === null || callsData === void 0 ? void 0 : callsData[index]) === null || _a === void 0 ? void 0 : _a.value) && { value: "0x".concat(parseInt((_b = callsData === null || callsData === void 0 ? void 0 : callsData[index]) === null || _b === void 0 ? void 0 : _b.value).toString(16)) })) }); }); return [4 /*yield*/, this.rpcBatchRequest(rpcCallsData)]; case 1: result = _a.sent(); return [2 /*return*/, result.map(function (value) { return (value ? new bignumber_js_1.default(value) : null); })]; case 2: e_2 = _a.sent(); console.error(e_2); return [2 /*return*/, callsData.map(function () { return null; })]; case 3: return [2 /*return*/]; } }); }); }; /** * @description send batch request via web3 * @see {@link https://web3js.readthedocs.io/en/v1.3.0/web3-eth.html#batchrequest|Web3BatchRequest} * @param calls Web3 method calls * @param callsParams ethereum method transaction parameters * @returns batch request call result sorted in order of input parameters */ Web3Public.prototype.web3BatchRequest = function (calls, callsParams) { var batch = new this.web3.BatchRequest(); var promises = calls.map(function (call, index) { return new Promise(function (resolve, reject) { return batch.add(call.request(__assign({}, callsParams[index]), function (error, result) { return error ? reject(error) : resolve(result); })); }); }); batch.execute(); return Promise.all(promises); }; /** * @description send batch request to rpc provider directly * @see {@link https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/ethereum/eth1.0-apis/assembled-spec/openrpc.json&uiSchema%5BappBar%5D%5Bui:splitView%5D=false&uiSchema%5BappBar%5D%5Bui:input%5D=false&uiSchema%5BappBar%5D%5Bui:examplesDropdown%5D=false|EthereumJSON-RPC} * @param rpcCallsData rpc methods and parameters list * @returns rpc batch request call result sorted in order of input 1parameters */ Web3Public.prototype.rpcBatchRequest = function (rpcCallsData) { return __awaiter(this, void 0, void 0, function () { var seed, batch, httpClient, response; return __generator(this, function (_a) { switch (_a.label) { case 0: seed = Date.now(); batch = rpcCallsData.map(function (callData, index) { return ({ id: seed + index, jsonrpc: '2.0', method: callData.rpcMethod, params: [__assign({}, callData.params)] }); }); return [4 /*yield*/, this.getHttpClient()]; case 1: httpClient = _a.sent(); return [4 /*yield*/, httpClient.post(this.web3.currentProvider.host, batch)]; case 2: response = _a.sent(); return [2 /*return*/, response.sort(function (a, b) { return a.id - b.id; }).map(function (item) { return (item.error ? null : item.result); })]; } }); }); }; /** * @description execute multiplie calls in the single contract call * @param calls multicall calls data list * @return result of calls execution */ Web3Public.prototype.multicall = function (calls) { return __awaiter(this, void 0, void 0, function () { var contract; return __generator(this, function (_a) { contract = new this.web3.eth.Contract(multicall_abi_1.MULTICALL_ABI, this.multicallAddresses[this.blockchainName]); return [2 /*return*/, contract.methods.tryAggregate(false, calls).call()]; }); }); }; /** * @description returns httpClient if it exists or imports the axios client */ Web3Public.prototype.getHttpClient = function () { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!!this.httpClient) return [3 /*break*/, 2]; _a = this; return [4 /*yield*/, default_http_client_1.DefaultHttpClient.getInstance()]; case 1: _a.httpClient = _b.sent(); _b.label = 2; case 2: return [2 /*return*/, this.httpClient]; } }); }); }; __decorate([ cache_decorator_1.Cache ], Web3Public.prototype, "callForTokenInfo", null); __decorate([ (0, cache_decorator_1.Cache)({ conditionalCache: true }) ], Web3Public.prototype, "callForTokensInfo", null); return Web3Public; }()); exports.Web3Public = Web3Public; //# sourceMappingURL=web3-public.js.map