UNPKG

chaingate

Version:

Multi-chain cryptocurrency SDK for TypeScript — unified API for Bitcoin, Ethereum, Litecoin, Dogecoin, Bitcoin Cash, Polygon, Arbitrum, and any EVM-compatible chain. Create wallets, query balances, send transactions, and manage tokens and NFTs across UTXO

136 lines (135 loc) 5.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EvmRpcTransaction = void 0; const evmTx_1 = require("../../utils/evmTx"); const evmGasFallback_1 = require("../../utils/evmGasFallback"); const BaseEvmTransaction_1 = require("../EvmConnector/BaseEvmTransaction"); const BroadcastedEvmRpcTransaction_1 = require("./BroadcastedEvmRpcTransaction"); /** * An unsigned EVM transaction prepared by {@link EvmRpcConnector.transfer}. * * @example * ```ts * const network = cg.networks.evmRpc({ rpcUrl: '...', chainId: 56, name: 'BSC', symbol: 'BNB' }); * const conn = cg.connect(network, wallet); * const tx = await conn.transfer(network.amount('0.1'), '0xRecipient...'); * * // Inspect the current fee * const fee = tx.currentFee(); * * // Override with a custom fee and optional gas limit * tx.setFee({ maxFeePerGas: 5_000_000_000n, maxPriorityFeePerGas: 1_000_000_000n, gasLimit: 50_000n }); * * // Sign and broadcast * const broadcasted = await tx.signAndBroadcast(); * ``` */ class EvmRpcTransaction extends BaseEvmTransaction_1.BaseEvmTransaction { /** @internal */ constructor(params) { super({ fromAddress: params.fromAddress, toAddress: params.toAddress, valueWei: params.valueWei, data: params.data, nonce: params.nonce, gasLimit: params.gasLimit, chainId: params.chainId, balanceWei: params.balanceWei, getPrivateKey: params.getPrivateKey, initialFee: { maxFeePerGas: params.feeData.maxFeePerGas ?? params.feeData.gasPrice, maxPriorityFeePerGas: params.feeData.maxPriorityFeePerGas ?? 0n, }, }); this.explorer = params.explorer; this.supportsEip1559 = params.feeData.supportsEip1559; } /** * Returns the current fee parameters that will be used for signing. * * For EIP-1559 chains both `maxFeePerGas` and `maxPriorityFeePerGas` are * meaningful. For legacy chains `maxFeePerGas` represents the gas price and * `maxPriorityFeePerGas` is `0n`. */ currentFee() { return { ...this._currentFee }; } /** * Overrides the fee for this transaction. * * @throws {@link TransactionAlreadySentError} if the transaction has already been sent. */ setFee(fee) { this.applyFee(fee); } signTransaction(privateKey, params) { if (this.supportsEip1559) { return (0, evmTx_1.signEip1559Transaction)(params, privateKey); } return (0, evmTx_1.signLegacyTransaction)({ chainId: params.chainId, nonce: params.nonce, gasPrice: params.maxFeePerGas, gasLimit: params.gasLimit, to: params.to, value: params.value, data: params.data, }, privateKey); } async broadcast(signedRaw) { return this.explorer.sendRawTransaction(signedRaw); } recordNonceUsed() { this.explorer.nonceCache.recordUsed(this.explorer.chainId, this.fromAddress, this.nonce); } buildBroadcasted(transactionId) { return new BroadcastedEvmRpcTransaction_1.BroadcastedEvmRpcTransaction(transactionId, this.explorer); } /** * Fetches all required on-chain data (nonce, gas, fees, balance) and * constructs the transaction. * * @internal — used by {@link EvmRpcConnector.transfer}. */ static async create(params) { const { explorer, fromAddress, toAddress, valueWei, data = '0x', getPrivateKey } = params; // Fetch the nonce first so we can pass it to estimateGas (the nonce can // affect the estimate for contracts whose execution depends on account // state). Take the max with the locally cached nonce so consecutive sends // from the same address don't reuse a nonce when the network hasn't yet // observed the previous broadcast. const networkNonce = await explorer.getNonce(fromAddress); const cachedNonce = explorer.nonceCache.get(explorer.chainId, fromAddress); const nonce = cachedNonce !== undefined && cachedNonce > networkNonce ? cachedNonce : networkNonce; const estimateParams = { from: fromAddress, to: toAddress, value: valueWei, nonce, }; if (data !== '0x') { estimateParams.data = data; } const [gasEstimate, feeData, balance] = await Promise.all([ explorer.estimateGas(estimateParams).catch(() => null), explorer.getFeeData(), explorer.getBalance(fromAddress), ]); const gasLimit = gasEstimate ?? (0, evmGasFallback_1.fallbackGasFromCalldata)(data); return new EvmRpcTransaction({ explorer, fromAddress, toAddress, valueWei, data, nonce, gasLimit, chainId: BigInt(explorer.chainId), balanceWei: balance, feeData, getPrivateKey, }); } } exports.EvmRpcTransaction = EvmRpcTransaction;