UNPKG

@biconomy/abstractjs

Version:

SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.

275 lines 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.prepareRawComposableParams = exports.prepareComposableInputCalldataParams = exports.isComposableCallRequired = exports.runtimeEncodeAbiParameters = exports.runtimeERC20BalanceOf = exports.runtimeNativeBalanceOf = exports.runtimeERC20AllowanceOf = exports.runtimeParamViaCustomStaticCall = exports.runtimeNonceOf = exports.validateAndProcessConstraints = exports.orConstraint = exports.lessThanOrEqualToSigned = exports.greaterThanOrEqualToSigned = exports.equalTo = exports.lessThanOrEqualTo = exports.greaterThanOrEqualTo = exports.prepareConstraint = exports.prepareOutputParam = exports.prepareInputParam = exports.isRuntimeComposableValue = exports.CONSTRAINT_TUPLE_ABI = exports.ConstraintType = exports.OutputParamFetcherType = exports.InputParamFetcherType = exports.InputParamType = void 0; const viem_1 = require("viem"); const account_1 = require("../../account/index.js"); const constants_1 = require("../../constants/index.js"); const runtimeAbiEncoding_1 = require("./runtimeAbiEncoding.js"); exports.InputParamType = { TARGET: 0, VALUE: 1, CALL_DATA: 2 }; exports.InputParamFetcherType = { RAW_BYTES: 0, STATIC_CALL: 1, BALANCE: 2 }; exports.OutputParamFetcherType = { EXEC_RESULT: 0, STATIC_CALL: 1 }; exports.ConstraintType = { EQ: 0, GTE: 1, LTE: 2, IN: 3, GTE_SIGNED: 4, LTE_SIGNED: 5, OR: 6 }; exports.CONSTRAINT_TUPLE_ABI = { type: "tuple[]", components: [ { name: "constraintType", type: "uint8" }, { name: "referenceData", type: "bytes" } ] }; const isRuntimeComposableValue = (value) => { if (value && typeof value === "object" && !Array.isArray(value) && value.isRuntime) { return true; } return false; }; exports.isRuntimeComposableValue = isRuntimeComposableValue; const prepareInputParam = (fetcherType, paramData, constraints = []) => { return { fetcherType, paramData, constraints }; }; exports.prepareInputParam = prepareInputParam; const prepareOutputParam = (fetcherType, paramData) => { return { fetcherType, paramData }; }; exports.prepareOutputParam = prepareOutputParam; const prepareConstraint = (constraintType, referenceData) => { return { constraintType, referenceData }; }; exports.prepareConstraint = prepareConstraint; const greaterThanOrEqualTo = (value) => { return { type: exports.ConstraintType.GTE, value }; }; exports.greaterThanOrEqualTo = greaterThanOrEqualTo; const lessThanOrEqualTo = (value) => { return { type: exports.ConstraintType.LTE, value }; }; exports.lessThanOrEqualTo = lessThanOrEqualTo; const equalTo = (value) => { return { type: exports.ConstraintType.EQ, value }; }; exports.equalTo = equalTo; const greaterThanOrEqualToSigned = (value) => { return { type: exports.ConstraintType.GTE_SIGNED, value }; }; exports.greaterThanOrEqualToSigned = greaterThanOrEqualToSigned; const lessThanOrEqualToSigned = (value) => { return { type: exports.ConstraintType.LTE_SIGNED, value }; }; exports.lessThanOrEqualToSigned = lessThanOrEqualToSigned; const orConstraint = (subConstraints) => { return { type: exports.ConstraintType.OR, value: subConstraints }; }; exports.orConstraint = orConstraint; const CHILD_CONSTRAINT_TYPES = new Set([ exports.ConstraintType.EQ, exports.ConstraintType.GTE, exports.ConstraintType.LTE, exports.ConstraintType.GTE_SIGNED, exports.ConstraintType.LTE_SIGNED ]); const SIGNED_CONSTRAINT_TYPES = new Set([ exports.ConstraintType.GTE_SIGNED, exports.ConstraintType.LTE_SIGNED ]); const validateAndProcessChildConstraint = (constraint) => { if (constraint.type === exports.ConstraintType.OR) throw new Error("Nested OR constraints are not supported"); if (!CHILD_CONSTRAINT_TYPES.has(constraint.type)) throw new Error("Invalid constraint type"); if (SIGNED_CONSTRAINT_TYPES.has(constraint.type)) { if (typeof constraint.value !== "bigint") throw new Error("Invalid constraint value: signed constraints require bigint"); const valueHex = (0, viem_1.encodeAbiParameters)([{ type: "int256" }], [constraint.value]); const referenceData = (0, viem_1.encodeAbiParameters)([{ type: "bytes32" }], [valueHex]); return { constraintType: constraint.type, referenceData }; } if (typeof constraint.value !== "bigint" && typeof constraint.value !== "boolean" && !(0, viem_1.isHex)(constraint.value) && !(0, viem_1.isAddress)(constraint.value)) { throw new Error("Invalid constraint value"); } if (typeof constraint.value === "bigint" && constraint.value < BigInt(0)) { throw new Error("Invalid constraint value"); } const valueHex = (0, account_1.toBytes32)(constraint.value); const referenceData = (0, viem_1.encodeAbiParameters)([{ type: "bytes32" }], [valueHex]); return (0, exports.prepareConstraint)(constraint.type, referenceData); }; const validateAndProcessConstraints = (constraints) => { const result = []; for (const constraint of constraints) { if (constraint.type === exports.ConstraintType.OR) { if (!Array.isArray(constraint.value) || constraint.value.length === 0) throw new Error("OR constraint must have at least one sub-constraint"); const processedSubs = constraint.value.map(validateAndProcessChildConstraint); const referenceData = (0, viem_1.encodeAbiParameters)([exports.CONSTRAINT_TUPLE_ABI], [ processedSubs.map((c) => ({ constraintType: c.constraintType, referenceData: c.referenceData })) ]); result.push({ constraintType: exports.ConstraintType.OR, referenceData }); } else { result.push(validateAndProcessChildConstraint(constraint)); } } return result; }; exports.validateAndProcessConstraints = validateAndProcessConstraints; const runtimeNonceOf = ({ smartAccountAddress, nonceKey, constraints = [] }) => { const defaultFunctionSig = "getNonce"; const entryPointNonceAbi = (0, viem_1.parseAbi)([ "function getNonce(address sender, uint192 key) public view returns (uint256)" ]); const encodedParam = (0, viem_1.encodeAbiParameters)([{ type: "address" }, { type: "bytes" }], [ constants_1.ENTRY_POINT_ADDRESS, (0, viem_1.encodeFunctionData)({ abi: entryPointNonceAbi, functionName: defaultFunctionSig, args: [smartAccountAddress, nonceKey] }) ]); const constraintsToAdd = (0, exports.validateAndProcessConstraints)(constraints); return { isRuntime: true, inputParams: [ (0, exports.prepareInputParam)(exports.InputParamFetcherType.STATIC_CALL, encodedParam, constraintsToAdd) ], outputParams: [] }; }; exports.runtimeNonceOf = runtimeNonceOf; const runtimeParamViaCustomStaticCall = ({ targetContractAddress, functionAbi, functionName, args, constraints = [] }) => { const encodedParam = (0, viem_1.encodeAbiParameters)([{ type: "address" }, { type: "bytes" }], [ targetContractAddress, (0, viem_1.encodeFunctionData)({ abi: functionAbi, functionName: functionName, args }) ]); const constraintsToAdd = (0, exports.validateAndProcessConstraints)(constraints); return { isRuntime: true, inputParams: [ (0, exports.prepareInputParam)(exports.InputParamFetcherType.STATIC_CALL, encodedParam, constraintsToAdd) ], outputParams: [] }; }; exports.runtimeParamViaCustomStaticCall = runtimeParamViaCustomStaticCall; const runtimeERC20AllowanceOf = ({ owner, spender, tokenAddress, constraints = [] }) => { const encodedParam = (0, viem_1.encodeAbiParameters)([{ type: "address" }, { type: "bytes" }], [ tokenAddress, (0, viem_1.encodeFunctionData)({ abi: viem_1.erc20Abi, functionName: "allowance", args: [owner, spender] }) ]); const constraintsToAdd = (0, exports.validateAndProcessConstraints)(constraints); return { isRuntime: true, inputParams: [ (0, exports.prepareInputParam)(exports.InputParamFetcherType.STATIC_CALL, encodedParam, constraintsToAdd) ], outputParams: [] }; }; exports.runtimeERC20AllowanceOf = runtimeERC20AllowanceOf; const runtimeNativeBalanceOf = ({ targetAddress, constraints = [] }) => { return getBalanceOf({ targetAddress, tokenAddress: viem_1.zeroAddress, constraints }); }; exports.runtimeNativeBalanceOf = runtimeNativeBalanceOf; const runtimeERC20BalanceOf = ({ targetAddress, tokenAddress, constraints = [] }) => { return getBalanceOf({ targetAddress, tokenAddress, constraints }); }; exports.runtimeERC20BalanceOf = runtimeERC20BalanceOf; const getBalanceOf = ({ targetAddress, tokenAddress, constraints = [] }) => { const constraintsToAdd = (0, exports.validateAndProcessConstraints)(constraints); const encodedInputParamData = (0, viem_1.encodePacked)(["address", "address"], [tokenAddress, targetAddress]); return { isRuntime: true, inputParams: [ (0, exports.prepareInputParam)(exports.InputParamFetcherType.BALANCE, encodedInputParamData, constraintsToAdd) ], outputParams: [] }; }; const runtimeEncodeAbiParameters = (inputs, args) => { const inputParams = (0, exports.prepareComposableInputCalldataParams)(inputs, args); return { isRuntime: true, inputParams: inputParams, outputParams: [] }; }; exports.runtimeEncodeAbiParameters = runtimeEncodeAbiParameters; const isComposableCallRequired = (functionContext, args) => { if (!functionContext.inputs || functionContext.inputs.length <= 0) return false; const isComposableCall = functionContext.inputs.some((input, inputIndex) => { if (input.type === "tuple") { const isComposableCallDetected = Object.values(args[inputIndex]).some((internalArg) => (0, exports.isRuntimeComposableValue)(internalArg)); return isComposableCallDetected; } if (input.type.match(/^(.*)\[(\d+)?\]$/)) { const isComposableCallDetected = args[inputIndex].some((internalArg) => (0, exports.isRuntimeComposableValue)(internalArg)); return isComposableCallDetected; } return (0, exports.isRuntimeComposableValue)(args[inputIndex]); }); return isComposableCall; }; exports.isComposableCallRequired = isComposableCallRequired; const prepareComposableInputCalldataParams = (inputs, args) => { const composableParams = (0, runtimeAbiEncoding_1.encodeRuntimeFunctionData)(inputs, args).map((calldata) => { if ((0, exports.isRuntimeComposableValue)(calldata)) { return calldata?.inputParams; } return [ (0, exports.prepareInputParam)(exports.InputParamFetcherType.RAW_BYTES, calldata) ]; }); return composableParams.flat(); }; exports.prepareComposableInputCalldataParams = prepareComposableInputCalldataParams; const prepareRawComposableParams = (calldata) => { const composableParams = [ (0, exports.prepareInputParam)(exports.InputParamFetcherType.RAW_BYTES, calldata) ]; return composableParams.flat(); }; exports.prepareRawComposableParams = prepareRawComposableParams; //# sourceMappingURL=composabilityCalls.js.map