UNPKG

@kiroboio/fct-core

Version:

Kirobo.io FCT Core library

133 lines 4.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transactionValidator = void 0; const ethers_1 = require("ethers"); const getVersion_1 = require("../batchMultiSigCall/versions/getVersion"); const Interfaces_1 = require("../helpers/Interfaces"); const ErrorFunctionSignature = "0x08c379a0"; // keccak256("Error(string)") // const ErrorInterface = new ethers.utils.Interface(["error Error(string message)"]); const transactionValidator = async (txVal) => { const { callData, actuatorContractAddress, activator, rpcUrl, activateForFree, version } = txVal; let { gasPrice } = txVal; const Version = (0, getVersion_1.getVersionFromVersion)(`0x${version}`); const decodedFCTCalldata = Version.Utils.getBatchMultiSigCallABI().decodeFunctionData("batchMultiSigCall", callData); const parsedSessionId = Version.SessionId.parse(decodedFCTCalldata[1].sessionId.toHexString()); const { maxGasPrice, dryRun } = parsedSessionId; gasPrice = manageGasPrice({ gasPrice, maxGasPrice, dryRun }); try { const gas = await estimateGas({ rpcUrl, actuatorContractAddress, activateForFree, callData, activator, gasPrice, }); if (gas.lt(40000)) { throw new Error("Unknown error - FCT execution finalized too quickly. Is there enough power for user?"); } // Add 20% to gasUsed value, calculate with BigInt const gasUsed = Math.round(gas.toNumber() + gas.toNumber() * 0.2); return { isValid: true, txData: { gas: gasUsed, ...gasPrice, type: 2 }, prices: { gas: gasUsed, gasPrice: gasPrice.maxFeePerGas }, error: null, }; } catch (err) { return handleTxValidatorError({ err, dryRun, gasPrice, errorIsValid: txVal.errorIsValid, }); } }; exports.transactionValidator = transactionValidator; function manageGasPrice({ dryRun, gasPrice, maxGasPrice, }) { if (dryRun) { return { maxFeePerGas: "0", maxPriorityFeePerGas: "0" }; } if (BigInt(maxGasPrice) < BigInt(gasPrice.maxFeePerGas)) { return { maxFeePerGas: maxGasPrice.toString(), maxPriorityFeePerGas: "0" }; } return gasPrice; } async function estimateGas({ rpcUrl, actuatorContractAddress, activateForFree, callData, activator, gasPrice, }) { const provider = new ethers_1.ethers.providers.JsonRpcProvider(rpcUrl); const data = Interfaces_1.Interfaces.FCT_Actuator.encodeFunctionData(activateForFree ? "activateForFree" : "activate", [ callData, activator, ]); console.log("uiasudgpuasgdpu", { to: actuatorContractAddress, data, ...gasPrice, from: activator, }); return await provider.estimateGas({ to: actuatorContractAddress, data, ...gasPrice, from: activator, }); } function handleTxValidatorError({ err, dryRun, gasPrice, errorIsValid, }) { if (dryRun && err.reason.includes("dry run success")) { return { isValid: true, txData: { gas: 0, ...gasPrice, type: 2 }, prices: { gas: 0, gasPrice: gasPrice.maxFeePerGas, }, error: null, }; } if (err.code === "SERVER_ERROR") { return { isValid: false, txData: { gas: 0, ...gasPrice, type: 2 }, prices: { gas: 0, gasPrice: gasPrice.maxFeePerGas, }, error: err.error.message || err.error, }; } if (errorIsValid) { return { isValid: true, txData: { gas: 1_000_000, ...gasPrice, type: 2 }, prices: { gas: 1_000_000, // 900k is the default gas limit gasPrice: gasPrice.maxFeePerGas, }, error: null, }; } let error = err.reason; // If error.data starts with the Error(string) sig, decode it if (!error && err.data.startsWith(ErrorFunctionSignature)) { // Need to decode the error message from the data // 1. Remove the Error(string) signature // 2. Decode the message const message = err.data.slice(10); const decoded = ethers_1.ethers.utils.defaultAbiCoder.decode(["string"], message); error = decoded; } else if (!error) { error = err.message; } return { isValid: false, txData: { gas: 0, ...gasPrice, type: 2 }, prices: { gas: 0, gasPrice: gasPrice.maxFeePerGas, }, error: err.reason ? err.reason : err.message, }; } //# sourceMappingURL=transactionValidator.js.map