UNPKG

chaingate

Version:

A complete TypeScript library for connecting to and making transactions on different blockchains

106 lines 6.84 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EvmPreparedTransaction = void 0; const ethers_1 = require("ethers"); const decimal_js_1 = __importDefault(require("decimal.js")); const CGDriver_1 = require("../../../../../CGDriver"); const CurrencyPreparedTransaction_1 = require("../../CurrencyPreparedTransaction"); const EvmFee_1 = require("./EvmFee"); const CurrencyAmount_1 = require("../../CurrencyAmount"); const EvmConfirmedTransaction_1 = require("./EvmConfirmedTransaction"); const errors_1 = require("../../errors"); class EvmPreparedTransaction extends CurrencyPreparedTransaction_1.CurrencyPreparedTransaction { privateKeyProvider; data; constructor(api, currencyProviders, currencyInfo, fromAddress, toAddress, amount, data, privateKeyProvider) { super(api, currencyProviders, currencyInfo, fromAddress, toAddress, amount); this.data = data; this.privateKeyProvider = privateKeyProvider; } async broadcast(fee) { if (typeof fee === 'string') fee = (this._suggestedFees ?? await this.buildSuggestedFees())[fee]; // Param passed is fee level if (!fee.enoughFunds || !fee.feeAmount) throw new errors_1.NotEnoughFundsError(); const signer = new ethers_1.ethers.Wallet(new ethers_1.SigningKey((await this.privateKeyProvider()).raw)); const nonce = new decimal_js_1.default(await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.addressTransactionCount, this.fromAddress)); let gasLimit; try { gasLimit = new decimal_js_1.default(await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.estimateGas, this.fromAddress, this.toAddress, nonce.toString(), this.amount.baseAmount.toString(), this.data ? this.data.toString() : '0x')); } catch (ex) { if (ex.response?.data == 'Insufficient amount') throw new errors_1.NotEnoughFundsError(); throw ex; } const tx = { from: this.fromAddress, to: this.toAddress, maxFeePerGas: ethers_1.ethers.toBigInt(fee.maxFeePerGas.minimalUnitAmount.toString()), maxPriorityFeePerGas: ethers_1.ethers.toBigInt(fee.maxPriorityFeePerGas.minimalUnitAmount.toString()), value: ethers_1.ethers.toBigInt(this.amount.minimalUnitAmount.toString()), data: this.data ? this.data.toString() : '0x', nonce: nonce.toNumber(), gasLimit: ethers_1.ethers.toBigInt(gasLimit.toString()), chainId: this.currencyInfo.chainId }; const txSigned = await signer.signTransaction(tx); const broadcastedTx = await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.broadcastTransaction, { 'transactionRaw': txSigned }); return new EvmConfirmedTransaction_1.EvmConfirmedTransaction(this.api, broadcastedTx.txId); } async buildSuggestedFees() { const addressBalance = new decimal_js_1.default((await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.addressBalance, this.fromAddress)).confirmed); const fees = {}; if (addressBalance.gte(this.amount.baseAmount)) { const nonce = new decimal_js_1.default(await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.addressTransactionCount, this.fromAddress)); const estimatedGas = new CurrencyAmount_1.CurrencyAmount(this.currencyInfo, new decimal_js_1.default(await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.estimateGas, this.fromAddress, this.toAddress, nonce.toString(), this.amount.baseAmount.toString(), this.data?.toString() ?? '0x'))); const feeRateResponse = await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.feeRate); this.processFeeLevels(feeRateResponse, estimatedGas, addressBalance, fees); } else { const feeRateResponse = await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.feeRate); this.processFeeLevels(feeRateResponse, null, addressBalance, fees); } return fees; } processFeeLevels(feeRateResponse, estimatedGas, addressBalance, fees) { const levels = ['low', 'normal', 'high', 'maximum']; for (const level of levels) { const { maxFeePerGas, maxPriorityFeePerGas, confirmationTimeSecs } = feeRateResponse[level]; const maxFee = new CurrencyAmount_1.CurrencyAmount(this.currencyInfo, new decimal_js_1.default(maxFeePerGas)); const maxPriorityFee = new CurrencyAmount_1.CurrencyAmount(this.currencyInfo, new decimal_js_1.default(maxPriorityFeePerGas)); let amountFee = null; let isBalanceSufficient = false; if (estimatedGas) { amountFee = estimatedGas.mul(maxFee); isBalanceSufficient = addressBalance.gte(amountFee.plus(this.amount).baseAmount); } fees[level] = new EvmFee_1.EvmFee(maxFee, maxPriorityFee, true, isBalanceSufficient, confirmationTimeSecs, amountFee); } } async fee(maxFeePerGas, maxPriorityFeePerGas) { const addressBalance = new decimal_js_1.default((await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.addressBalance, this.fromAddress)).confirmed); if (typeof maxFeePerGas == 'string') maxFeePerGas = new CurrencyAmount_1.CurrencyAmount(this.currencyInfo, new decimal_js_1.default(maxFeePerGas)); if (typeof maxPriorityFeePerGas == 'string') maxPriorityFeePerGas = new CurrencyAmount_1.CurrencyAmount(this.currencyInfo, new decimal_js_1.default(maxPriorityFeePerGas)); const nonce = new decimal_js_1.default(await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.addressTransactionCount, this.fromAddress)); let estimatedGas; try { estimatedGas = new CurrencyAmount_1.CurrencyAmount(this.currencyInfo, new decimal_js_1.default(await (0, CGDriver_1.ConsumeFunction)(this.api, this.api.estimateGas, this.fromAddress, this.toAddress, nonce.toString(), this.amount.baseAmount.toString(), this.data ? this.data.toString() : '0x'))); const totalGasFee = maxFeePerGas.mul(estimatedGas); return new EvmFee_1.EvmFee(maxFeePerGas, maxPriorityFeePerGas, true, addressBalance.gte(totalGasFee.plus(this.amount).baseAmount), null, totalGasFee); } catch (ex) { if (ex.response?.data == 'Insufficient amount') { return new EvmFee_1.EvmFee(maxFeePerGas, maxPriorityFeePerGas, true, false, null, null); } throw ex; } } } exports.EvmPreparedTransaction = EvmPreparedTransaction; //# sourceMappingURL=EvmPreparedTransaction.js.map