UNPKG

@moonsong-labs/moonwall-util

Version:

Testing framework for the Moon family of projects

222 lines (220 loc) 8.13 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/functions/eth-tester.ts var eth_tester_exports = {}; __export(eth_tester_exports, { EthTester: () => EthTester }); module.exports = __toCommonJS(eth_tester_exports); var EthTester = class { /** * @name defaultType: Default type of Ethereum transaction */ defaultType; /** * @name defaultType: Default account to sign Ethereum transactions (usually sudo account) */ defaultAccount; /** * @name logger: Logger to use */ logger; /** * @name web3: Web3 instance */ web3; /** * @name constructor * @param web3: Web3 instance * @param privateKey: Private key of the default account * @param logger: Logger to use * @param type: Default type of Ethereum transaction * @returns Web3Tester instance * @description Creates a new Web3Tester instance * @example * const web3 = new Web3("http://localhost:9944"); * const web3Tester = new Web3Tester(web3, alith.privateKey, logger, "EIP1559"); * const rawTransaction = await web3Tester.genSignedTransfer({ * to: baltathar.address, * value: web3.utils.toWei("1", "ether"), * }); */ constructor(web3, privateKey, logger, type = "Legacy") { this.web3 = web3; this.logger = logger; this.defaultType = type; this.defaultAccount = web3.eth.accounts.privateKeyToAccount(privateKey); } /** * @name genSignedTransaction * @param options: Transaction options * @param txType: Type of Ethereum transaction * @returns Signed transaction * @description Generates a signed Ethereum transaction * @example * const rawTransaction = await web3Tester.genSignedTransaction({ * to: baltathar.address, * to: authorMapping.address, * data: authorMapping.encodeFunctionData("setKeys", [keys]), * }); */ genSignedTransaction = async (options, txType) => { const type = txType || this.defaultType; const isLegacy = type === "Legacy"; const isEip2930 = type === "EIP2930"; const isEip1559 = type === "EIP1559"; if (options.gasPrice && options.maxFeePerGas) { throw new Error(`txn has both gasPrice and maxFeePerGas!`); } if (options.gasPrice && options.maxPriorityFeePerGas) { throw new Error(`txn has both gasPrice and maxPriorityFeePerGas!`); } if (typeof options.gasPrice === "bigint") { options.gasPrice = "0x" + options.gasPrice.toString(16); } if (typeof options.maxFeePerGas === "bigint") { options.maxFeePerGas = "0x" + options.maxFeePerGas.toString(16); } if (typeof options.maxPriorityFeePerGas === "bigint") { options.maxPriorityFeePerGas = "0x" + options.maxPriorityFeePerGas.toString(16); } let maxFeePerGas; let maxPriorityFeePerGas; if (options.gasPrice) { maxFeePerGas = options.gasPrice; maxPriorityFeePerGas = options.gasPrice; } else { maxFeePerGas = options.maxFeePerGas || BigInt(await this.web3.eth.getGasPrice()); maxPriorityFeePerGas = options.maxPriorityFeePerGas || 0; } const gasPrice = options.gasPrice !== void 0 ? options.gasPrice : "0x" + BigInt(await this.web3.eth.getGasPrice()).toString(16); const value = options.value !== void 0 ? options.value : "0x00"; const from = options.from || this.defaultAccount.address; const privateKey = options.privateKey !== void 0 ? options.privateKey : this.defaultAccount.privateKey; let error; const estimatedGas = await this.web3.eth.estimateGas({ from, to: options.to, data: options.data }).catch((e) => { error = e; return 0; }); const gas = options.gas || estimatedGas; const accessList = options.accessList || []; const nonce = options.nonce != null ? options.nonce : await this.web3.eth.getTransactionCount(from, "pending"); let data; let rawTransaction; if (isLegacy) { data = { from, to: options.to, value: value && value.toString(), gasPrice, gas, nonce, data: options.data }; const tx = await this.web3.eth.accounts.signTransaction(data, privateKey); rawTransaction = tx.rawTransaction; } else { const chainId = await this.web3.eth.getChainId(); if (isEip2930) { data = { from, to: options.to, value: value && value.toString(), gasPrice, gasLimit: gas, nonce, data: options.data, accessList, chainId, type: 1 }; } else if (isEip1559) { data = { from, to: options.to, value: value && value.toString(), maxFeePerGas, maxPriorityFeePerGas, gasLimit: gas, nonce, data: options.data, accessList, chainId, type: 2 }; } const tx = await this.web3.eth.accounts.signTransaction(data, privateKey); rawTransaction = tx.rawTransaction; } this.logger( `Tx [${/:([0-9]+)$/.exec(this.web3.currentProvider.host)?.[1]}] from: ${data.from.substr(0, 5) + "..." + data.from.substr(data.from.length - 3)}, ` + (data.to ? `to: ${data.to.substr(0, 5) + "..." + data.to.substr(data.to.length - 3)}, ` : "") + (data.value ? `value: ${data.value.toString()}, ` : "") + (data.gasPrice ? `gasPrice: ${data.gasPrice.toString()}, ` : "") + (data.maxFeePerGas ? `maxFeePerGas: ${data.maxFeePerGas.toString()}, ` : "") + (data.maxPriorityFeePerGas ? `maxPriorityFeePerGas: ${data.maxPriorityFeePerGas.toString()}, ` : "") + (data.accessList ? `accessList: ${data.accessList.toString()}, ` : "") + (data.gas ? `gas: ${data.gas.toString()}, ` : "") + (data.nonce ? `nonce: ${data.nonce.toString()}, ` : "") + (!data.data ? "" : `data: ${data.data.length < 50 ? data.data : data.data.substr(0, 5) + "..." + data.data.substr(data.data.length - 3)}, `) + (error ? `ERROR: ${error.toString()}, ` : "") ); return rawTransaction; }; /** * @name genSignedTransfer * @param to Address of the recipient * @param value Amount of Wei to send * @param options Transaction options * @description Generates a signed Ethereum transactiosn * @returns Signed transaction */ genSignedTransfer = async (to, value, options) => { return await this.genSignedTransaction({ ...options, value: value.toString(), to }); }; /** * @name sendSignedTransaction * @description Sends a signed transaction, without waiting for it to be produced. * @param rawTransaction Signed transaction * @returns Transaction JSON RPC response */ sendSignedTransaction = async (rawTransaction) => { return new Promise(async (resolve, reject) => { if (typeof this.web3.currentProvider == "string") { reject("Web3 provider is not a valid provider"); return; } this.web3.currentProvider.send( { jsonrpc: "2.0", id: 1, method: "eth_sendRawTransaction", params: [await rawTransaction] }, (error, result) => { if (error) { reject(`Failed to send signed transaction: ${error.message || error.toString()}`); } resolve(result); } ); }); }; }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { EthTester });