@owlprotocol/contracts-account-abstraction
Version:
ERC4337 Account Abstraction support for deploying relevant smart contracts and interacting with UserOps.
133 lines (132 loc) • 6.3 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var estimateUserOperationGas_exports = {};
__export(estimateUserOperationGas_exports, {
entryPointDepositSlot: () => entryPointDepositSlot,
estimateUserOperationGas: () => estimateUserOperationGas,
getPaymasterSlot: () => getPaymasterSlot
});
module.exports = __toCommonJS(estimateUserOperationGas_exports);
var import_viem = require("viem");
var import_actions = require("viem/actions");
var import_utils = require("viem/utils");
var import_chains = require("viem/chains");
var import_simulateHandleOp = require("./simulateHandleOp.js");
var import_calcPreVerificationGas = require("./calcPreVerificationGas.js");
var import_getSupportedEntryPoints = require("./getSupportedEntryPoints.js");
var import_calcVerificationGasAndCallGasLimit = require("../../gasestimation/calcVerificationGasAndCallGasLimit.js");
var import_UserOperation = require("../../models/UserOperation.js");
var import_PackedUserOperation = require("../../models/PackedUserOperation.js");
var import_constants = require("../../constants.js");
const entryPointDepositSlot = 0;
const getPaymasterSlot = (paymaster) => (0, import_viem.keccak256)((0, import_viem.encodeAbiParameters)([{ type: "address" }, { type: "uint8" }], [paymaster, entryPointDepositSlot]));
async function estimateUserOperationGas(client, parameters) {
const { factory, factoryData, paymaster } = parameters;
const { entryPointSimulationsAddress } = client;
const supportedEntryPoints = await (0, import_utils.getAction)(client, import_getSupportedEntryPoints.getSupportedEntryPoints, "getSupportedEntryPoints")({});
const entryPointAddress = supportedEntryPoints[0];
const chainId = client.chain?.id ?? await (0, import_utils.getAction)(client, import_actions.getChainId, "getChainId")({});
const userOperation = {
...parameters,
factory: factory ?? import_viem.zeroAddress,
factoryData: factoryData ?? "0x",
signature: import_UserOperation.dummySignature,
// initial dummy gas values
// populated first, based on byte-size of the user op, this is the gas cost of encoding the user op data before any contract execution
preVerificationGas: 0n,
// gas cost of verifying the user op (eg. smart account signature check)
verificationGasLimit: 10000000n,
// gas cost of executing the user op
callGasLimit: 10000000n,
maxFeePerGas: parameters.maxFeePerGas,
maxPriorityFeePerGas: parameters.maxFeePerGas
};
if (userOperation.paymaster) {
userOperation.paymasterVerificationGasLimit = 5000000n;
userOperation.paymasterPostOpGasLimit = 2000000n;
}
let stateOverride;
if (paymaster) {
const paymasterSlot = getPaymasterSlot(paymaster);
stateOverride = {
address: import_constants.ENTRYPOINT_ADDRESS_V07,
stateDiff: [
{
slot: paymasterSlot,
value: (0, import_viem.toHex)((0, import_viem.parseEther)("1000000"), { size: 32 })
}
]
};
} else {
stateOverride = {
// Either the paymaster or the smart account would pay. Override accordingly
address: paymaster ?? userOperation.sender,
balance: (0, import_viem.parseEther)("1000000")
};
}
const executionResult = await (0, import_simulateHandleOp.getExecutionResult)(client, {
packedUserOperation: (0, import_PackedUserOperation.toPackedUserOperation)((0, import_UserOperation.encodeUserOp)(userOperation)),
entryPoint: entryPointAddress,
entryPointSimulationsAddress,
stateOverride
});
let { verificationGasLimit, callGasLimit } = (0, import_calcVerificationGasAndCallGasLimit.calcVerificationGasAndCallGasLimit)(
userOperation,
executionResult.data.executionResult,
chainId,
executionResult.data.callDataResult
);
verificationGasLimit = verificationGasLimit * 120n / 100n;
if (chainId === import_chains.base.id || chainId === import_chains.baseSepolia.id) {
callGasLimit += 10000n;
}
if (chainId === import_chains.base.id || chainId === import_chains.optimism.id || chainId === import_chains.baseSepolia.id || chainId === import_chains.optimismSepolia.id) {
const currCallGasLimit = callGasLimit;
callGasLimit = currCallGasLimit > 120000n ? currCallGasLimit : 120000n;
}
if (chainId === import_chains.celoAlfajores.id || chainId === import_chains.celo.id || chainId === import_chains.sei.id || chainId === import_chains.seiDevnet.id || chainId === import_chains.seiTestnet.id) {
verificationGasLimit = 1000000n;
callGasLimit = 1000000n;
}
if (userOperation.callData === "0x") {
callGasLimit = 0n;
}
callGasLimit = callGasLimit * 110n / 100n;
if (userOperation.paymaster != null) {
userOperation.paymasterVerificationGasLimit = 100000n;
userOperation.paymasterPostOpGasLimit = 100000n;
}
let preVerificationGas = await (0, import_calcPreVerificationGas.calcPreVerificationGas)(client, {
packedUserOperation: (0, import_PackedUserOperation.toPackedUserOperation)((0, import_UserOperation.encodeUserOp)(userOperation)),
//TODO: Rename to entryPointAddress
entryPoint: entryPointAddress
});
preVerificationGas = preVerificationGas * 110n / 100n;
const userOpGas = {
preVerificationGas,
verificationGasLimit,
callGasLimit
};
if (userOperation.paymasterVerificationGasLimit) {
userOpGas.paymasterVerificationGasLimit = userOperation.paymasterVerificationGasLimit;
}
if (userOperation.paymasterPostOpGasLimit) {
userOpGas.paymasterPostOpGasLimit = userOperation.paymasterPostOpGasLimit;
}
return userOpGas;
}