UNPKG

@kiroboio/fct-core

Version:

Kirobo.io FCT Core library

158 lines 6.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.manageValidationAndComputed = exports.executedCallsFromRawLogs = exports.executedCallsFromLogs = exports.txTraceMapLog = exports.verifyMessageHashRaw = exports.verifyMessageHash = void 0; exports.getCallsFromTrace = getCallsFromTrace; exports.getTraceData = getTraceData; const tslib_1 = require("tslib"); const ethers_1 = require("ethers"); const SmartWallet_min_abi_json_1 = tslib_1.__importDefault(require("../../../../abi/SmartWallet.min.abi.json")); const Interfaces_1 = require("../../../../helpers/Interfaces"); const getVersion_1 = require("../../../versions/getVersion"); // const batchMultiSigInterface = Interfaces.FCT_BatchMultiSigCall; const controllerInterface = Interfaces_1.Interfaces.FCT_Controller; const SmartWalletMinInterface = new ethers_1.ethers.utils.Interface(SmartWallet_min_abi_json_1.default); const getBatchMultiSigCallInterface = () => { const Version = (0, getVersion_1.getVersionFromVersion)(`0x020201`); return Version.Utils.getBatchMultiSigCallABI(); }; function getCallsFromTrace(trace) { return trace.filter((call) => { const regularCall = call.traceAddress.length === 7 && call.traceAddress[0] === 0 && call.traceAddress[1] === 0 && call.traceAddress[3] === 0 && call.traceAddress[4] === 0 && call.traceAddress[5] === 2 && call.traceAddress[6] === 2; const secureStorageCall = call.traceAddress.length === 3 && call.traceAddress[0] === 0 && call.traceAddress[1] === 0 && call.traceAddress[2] === 2; return regularCall || secureStorageCall; }); } function getTraceData({ FCT_BatchMultiSigAddress, calls, callsFromTenderlyTrace, executedCalls, computedVariables, }) { FCT_BatchMultiSigAddress = FCT_BatchMultiSigAddress.toLowerCase(); return executedCalls.reduce((acc, executedCall, index) => { const fctCall = calls[Number(executedCall.callIndex) - 1]; const callResult = callsFromTenderlyTrace[index]; const input = callResult.input; const output = callResult.output; // If the from address is the FCT_BatchMultiSigAddress, then we // need to do a different decoding const callerIsBatchMultiSig = callResult.from.toLowerCase() === FCT_BatchMultiSigAddress; let resData; if (callerIsBatchMultiSig) { // Different way decoding, because this is // 1. Need to decode the input, because the input is fctCall function const decodedInput = SmartWalletMinInterface.parseTransaction({ data: input }); // 2. We need to take the calldata from the arguments. It is stored in args.callData.data const calldata = decodedInput.args.callData.data; // 3. Decode the calldata const decodedCallData = fctCall.decodeData({ inputData: calldata, }); resData = decodedCallData; } else { resData = fctCall.decodeData({ inputData: input, outputData: output, }); } acc.calls = [ ...acc.calls, { method: fctCall.call.method ?? "", value: callResult.value ? parseInt(callResult.value, 16).toString() : "0", inputData: resData?.inputData ?? [], outputData: resData?.outputData ?? [], error: callResult.error || callResult.errorString || null, isSuccess: executedCall.isSuccess, id: fctCall.nodeId, }, ]; (0, exports.manageValidationAndComputed)(acc, fctCall, computedVariables); return acc; }, { calls: [], validations: [], computed: [], }); } const verifyMessageHash = (logs, messageHas) => { const rawLogs = logs.map((log) => log.raw); return (0, exports.verifyMessageHashRaw)(rawLogs, messageHas); }; exports.verifyMessageHash = verifyMessageHash; const verifyMessageHashRaw = (logs, messageHashFromFCT) => { const messageHash = logs.find((log) => { try { return controllerInterface.parseLog(log).name === "FCTE_Registered"; } catch (e) { return false; } })?.topics[2]; if (messageHash.toLowerCase() !== messageHashFromFCT.toLowerCase()) { throw new Error("Message hash mismatch"); } return true; }; exports.verifyMessageHashRaw = verifyMessageHashRaw; const txTraceMapLog = (log) => { const parsedLog = getBatchMultiSigCallInterface().parseLog(log); return { id: parsedLog.args.id, caller: parsedLog.args.caller, callIndex: parsedLog.args.callIndex.toString(), isSuccess: parsedLog.name === "FCTE_CallSucceed", }; }; exports.txTraceMapLog = txTraceMapLog; const executedCallsFromLogs = (logs, messageHash) => { const rawLogs = logs.map((log) => log.raw); return (0, exports.executedCallsFromRawLogs)(rawLogs, messageHash); }; exports.executedCallsFromLogs = executedCallsFromLogs; const executedCallsFromRawLogs = (rawLogs, messageHash) => { (0, exports.verifyMessageHashRaw)(rawLogs, messageHash); return rawLogs .filter((log) => { try { return (getBatchMultiSigCallInterface().parseLog(log).name === "FCTE_CallSucceed" || getBatchMultiSigCallInterface().parseLog(log).name === "FCTE_CallFailed"); } catch (e) { return false; } }) .map(exports.txTraceMapLog); }; exports.executedCallsFromRawLogs = executedCallsFromRawLogs; const manageValidationAndComputed = (acc, call, computed) => { if (call.options.validation && call.options.validation !== "0") { acc.validations = [ ...acc.validations, { id: call.options.validation, }, ]; } const usedComputed = computed.filter((computed, index) => { return call.isComputedUsed(computed.id, index); }); usedComputed.forEach((computed) => { // Check if the computed was already added. If yes, skip if (acc.computed.find((accComputed) => accComputed.id === computed.id)) return; acc.computed = [ ...acc.computed, { id: computed.id, }, ]; }); }; exports.manageValidationAndComputed = manageValidationAndComputed; //# sourceMappingURL=transactionTrace.js.map