UNPKG

@kiroboio/fct-core

Version:

Kirobo.io FCT Core library

148 lines 6.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.decodeOutputData = exports.decodeFromData = exports.getEncodedMethodParams = exports.getMethodInterface = void 0; const fct_plugins_1 = require("@kiroboio/fct-plugins"); const ethers_1 = require("ethers"); const utils_1 = require("ethers/lib/utils"); const constants_1 = require("../../../../constants"); const helpers_1 = require("../../../../helpers"); const params_1 = require("./params"); function manage(val) { // If the value is not an array if (!Array.isArray(val)) { return (0, params_1.manageValue)(val); } // If the value is an array return val.map(manage); } const buildInputsFromParams = (params) => { return params.map((param) => { if (helpers_1.InstanceOf.Param(param.value)) { return { type: "tuple", name: param.name, components: buildInputsFromParams(param.value) }; } else if (helpers_1.InstanceOf.ParamArray(param.value)) { return { type: "tuple[]", name: param.name, components: buildInputsFromParams(param.value[0]) }; } return { type: param.type, name: param.name }; }); }; // From method and params create tuple // This version creates a ABI and gets the interface from it in ethers and then encodes the function bytes4 const getMethodInterface = (call) => { if (!call.method) return ""; const ABI = [ { name: call.method, type: "function", constant: false, payable: false, inputs: buildInputsFromParams(call.params || []), outputs: [], }, ]; return new ethers_1.utils.Interface(ABI).getFunction(call.method).format(); }; exports.getMethodInterface = getMethodInterface; const getEncodedMethodParams = (call) => { if (!call.method || !call.params) return "0x"; return utils_1.defaultAbiCoder.encode(call.params.map(_getTypeForEncodedMethodParams), call.params.map(_getValuesForEncodedMethodParams)); }; exports.getEncodedMethodParams = getEncodedMethodParams; const decodeFromData = (call, data) => { if (!call.method) return undefined; const ABI = [ { name: call.method, type: "function", constant: false, payable: false, inputs: buildInputsFromParams(call.params || []), outputs: [], }, ]; const decodedData = new ethers_1.utils.Interface(ABI).decodeFunctionData(call.method, data); return decodedData.slice(0, data.length).map(manage); }; exports.decodeFromData = decodeFromData; const decodeOutputData = (plugin, data) => { if (!plugin) return null; if (plugin instanceof fct_plugins_1.Multicall) { // If the plugin method is multiCall, we handle it differently if (plugin.method === "multiCall") { // the returned types from plugin.getOutputParamsTypes() is a bit different so we have to // handle it differently. plugin.getOutputParamsTypes() returns string[][][] return []; } const outputTypes = plugin.getOutputParamsTypes(); const outputParams = utils_1.defaultAbiCoder.decode(outputTypes, data).map(manage); return outputParams; } const outputTypes = plugin.output.paramsList.map(({ param }) => param.fctType); return utils_1.defaultAbiCoder.decode(outputTypes, data).map(manage); }; exports.decodeOutputData = decodeOutputData; function _handleTypeConversion(param) { // If messageType is the same as type, no need for conversion console.log({ param }); if (param.messageType === param.type || (0, constants_1.isVariable)(param.value) || helpers_1.InstanceOf.Variable(param.value)) return param.value; const conversion = typeConversions[`${param.messageType}_${param.type}`]; if (conversion) return conversion(param.value); console.error(`wrong param`, { param }); throw new Error(`Param ${JSON.stringify(param)}, value ${param.value}, ${param.name} - Conversion from ${param.messageType} to ${param.type} is not supported`); } // This function is used to convert the value to the correct type // `${messageType}_${type}`: (value: string) => any const typeConversions = { ["string_bytes32"]: (value) => ethers_1.utils.keccak256(ethers_1.utils.toUtf8Bytes(value)), ["string_bytes"]: (value) => ethers_1.utils.toUtf8Bytes(value), }; const _getTypeForEncodedMethodParams = (param) => { if (param.customType || param.type.includes("tuple")) { let value; let isArray = false; if (param.type.lastIndexOf("[") > 0) { isArray = true; value = param.value[0]; } else { value = param.value; } return `(${value.map(_getTypeForEncodedMethodParams).join(",")})${isArray ? "[]" : ""}`; } // If param.value is a Variable, the type needs to be uint256 if (param.value && (0, constants_1.isVariable)(param.value)) { return "uint256"; } return param.type; }; const _getValuesForEncodedMethodParams = (param) => { if (param.value === undefined || param.value === null) { throw new Error("Param value is required"); } if (param.customType || param.type.includes("tuple")) { let value; if (param.type.lastIndexOf("[") > 0) { value = param.value; return value.reduce((acc, val) => { return [...acc, val.map(_getValuesForEncodedMethodParams)]; }, []); } else { value = param.value; return value.map(_getValuesForEncodedMethodParams); } } if (param.messageType) { // TODO: Here we need to add the logic for type conversion // If message type is defined, we need to convert value. Value is always a `messageType` return _handleTypeConversion(param); } return param.value; }; //# sourceMappingURL=callParams.js.map