@kiroboio/fct-core
Version:
Kirobo.io FCT Core library
133 lines • 4.82 kB
JavaScript
;
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