chaingate
Version:
A complete TypeScript library for connecting to and making transactions on different blockchains
106 lines • 6.84 kB
JavaScript
"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