@owlprotocol/contracts-account-abstraction
Version:
ERC4337 Account Abstraction support for deploying relevant smart contracts and interacting with UserOps.
233 lines (232 loc) • 9.92 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 setupERC4337Contracts_exports = {};
__export(setupERC4337Contracts_exports, {
erc4337Contracts: () => erc4337Contracts,
getERC4337Contracts: () => getERC4337Contracts,
getVerifyingPaymaster: () => getVerifyingPaymaster,
prepareERC4337Contracts: () => prepareERC4337Contracts,
setupERC4337Contracts: () => setupERC4337Contracts,
setupVerifyingPaymaster: () => setupVerifyingPaymaster,
topupPaymaster: () => topupPaymaster
});
module.exports = __toCommonJS(setupERC4337Contracts_exports);
var import_viem_utils = require("@owlprotocol/viem-utils");
var import_viem = require("viem");
var import_account_abstraction = require("viem/account-abstraction");
var import_actions = require("viem/actions");
var import_utils = require("viem/utils");
var import_constants = require("./constants.js");
var import_EntryPoint = require("./artifacts/EntryPoint.js");
var import_SimpleAccountFactory = require("./artifacts/SimpleAccountFactory.js");
var import_VerifyingPaymaster = require("./artifacts/VerifyingPaymaster.js");
var import_EntryPointSimulations = require("./artifacts/EntryPointSimulations.js");
var import_PimlicoEntryPointSimulations = require("./artifacts/PimlicoEntryPointSimulations.js");
function getERC4337Contracts() {
const deterministicDeployer = import_viem_utils.DETERMINISTIC_DEPLOYER_ADDRESS;
const entrypoint = (0, import_viem_utils.getDeployDeterministicAddress)({ salt: import_constants.ENTRYPOINT_SALT_V07, bytecode: import_EntryPoint.EntryPoint.bytecode });
const simpleAccountFactory = (0, import_viem_utils.getDeployDeterministicAddress)({
salt: import_viem.zeroHash,
bytecode: (0, import_viem.encodeDeployData)({
abi: import_SimpleAccountFactory.SimpleAccountFactory.abi,
bytecode: import_SimpleAccountFactory.SimpleAccountFactory.bytecode,
args: [entrypoint]
})
});
const entrypointSimulations = (0, import_viem_utils.getDeployDeterministicAddress)({
salt: import_viem.zeroHash,
bytecode: (0, import_viem.encodeDeployData)({
abi: import_EntryPointSimulations.EntryPointSimulations.abi,
bytecode: import_EntryPointSimulations.EntryPointSimulations.bytecode,
args: []
})
});
const pimlicoEntrypointSimulations = (0, import_viem_utils.getDeployDeterministicAddress)({
salt: import_viem.zeroHash,
bytecode: (0, import_viem.encodeDeployData)({
abi: import_PimlicoEntryPointSimulations.PimlicoEntryPointSimulations.abi,
bytecode: import_PimlicoEntryPointSimulations.PimlicoEntryPointSimulations.bytecode,
args: [entrypointSimulations]
})
});
return {
deterministicDeployer,
entrypoint,
simpleAccountFactory,
entrypointSimulations,
pimlicoEntrypointSimulations
};
}
const erc4337Contracts = getERC4337Contracts();
async function prepareERC4337Contracts(client) {
const requests = [];
const [entrypoint, simpleAccountFactory, entrypointSimulations, pimlicoEntrypointSimulations] = await Promise.all([
(0, import_viem_utils.getOrPrepareDeterministicContract)(
client,
//Extracted salt (first 32 bytes) from original tx
//https://etherscan.io/tx/0x5c81ea86f6c54481d3e21c78675b4f1d985c1fa62b678dcdfdf7934ddd6e127e
{
salt: import_constants.ENTRYPOINT_SALT_V07,
bytecode: import_EntryPoint.EntryPoint.bytecode
}
),
(0, import_viem_utils.getOrPrepareDeterministicContract)(client, {
salt: import_viem.zeroHash,
bytecode: (0, import_viem.encodeDeployData)({
abi: import_SimpleAccountFactory.SimpleAccountFactory.abi,
bytecode: import_SimpleAccountFactory.SimpleAccountFactory.bytecode,
args: [erc4337Contracts.entrypoint]
})
}),
(0, import_viem_utils.getOrPrepareDeterministicContract)(client, {
salt: import_viem.zeroHash,
bytecode: (0, import_viem.encodeDeployData)({
abi: import_EntryPointSimulations.EntryPointSimulations.abi,
bytecode: import_EntryPointSimulations.EntryPointSimulations.bytecode,
args: []
})
}),
(0, import_viem_utils.getOrPrepareDeterministicContract)(client, {
salt: import_viem.zeroHash,
bytecode: (0, import_viem.encodeDeployData)({
abi: import_PimlicoEntryPointSimulations.PimlicoEntryPointSimulations.abi,
bytecode: import_PimlicoEntryPointSimulations.PimlicoEntryPointSimulations.bytecode,
args: [erc4337Contracts.entrypointSimulations]
})
})
]);
if (entrypoint.address != import_account_abstraction.entryPoint07Address) {
throw new Error(
`Entrypoint v0.7 deployed address ${import_account_abstraction.entryPoint07Address} (expected) != ${entrypoint.address} (actual)`
);
}
if (entrypoint.request)
requests.push(entrypoint.request);
if (simpleAccountFactory.request)
requests.push(simpleAccountFactory.request);
if (entrypointSimulations.request)
requests.push(entrypointSimulations.request);
if (pimlicoEntrypointSimulations.request)
requests.push(pimlicoEntrypointSimulations.request);
return {
requests,
entrypoint,
simpleAccountFactory,
entrypointSimulations,
pimlicoEntrypointSimulations
};
}
async function setupERC4337Contracts(client) {
if (!client.account.nonceManager) {
throw new Error("client.account.nonceManager undefined");
}
const erc4337Contracts2 = await prepareERC4337Contracts(client);
const transactions = await Promise.all(
erc4337Contracts2.requests.map(
(request) => (0, import_utils.getAction)(client, import_actions.sendTransaction, "sendTransaction")(request)
)
);
const receipts = await Promise.all(
transactions.map((hash) => (0, import_utils.getAction)(client, import_actions.waitForTransactionReceipt, "waitForTransactionReceipt")({ hash }))
);
return {
...erc4337Contracts2,
transactions,
receipts
};
}
function getVerifyingPaymaster(params) {
const { verifyingSignerAddress } = params;
return (0, import_viem_utils.getDeployDeterministicAddress)({
salt: import_viem.zeroHash,
bytecode: (0, import_viem.encodeDeployData)({
abi: import_VerifyingPaymaster.VerifyingPaymaster.abi,
bytecode: import_VerifyingPaymaster.VerifyingPaymaster.bytecode,
args: [import_account_abstraction.entryPoint07Address, verifyingSignerAddress]
})
});
}
async function setupVerifyingPaymaster(client, parameters) {
const { verifyingSignerAddress } = parameters;
const entrypointBytecode = await (0, import_utils.getAction)(client, import_actions.getCode, "getCode")({ address: import_account_abstraction.entryPoint07Address });
if (!entrypointBytecode) {
throw new Error(
`EntryPoint v0.7 ${import_account_abstraction.entryPoint07Address} not deployed. Consider deploying with setupERC4337Contracts()`
);
}
const verifyingPaymaster = await (0, import_viem_utils.getOrDeployDeterministicContract)(client, {
salt: import_viem.zeroHash,
bytecode: (0, import_viem.encodeDeployData)({
abi: import_VerifyingPaymaster.VerifyingPaymaster.abi,
bytecode: import_VerifyingPaymaster.VerifyingPaymaster.bytecode,
args: [import_account_abstraction.entryPoint07Address, verifyingSignerAddress]
})
});
if (verifyingPaymaster.hash) {
await (0, import_utils.getAction)(
client,
import_actions.waitForTransactionReceipt,
"waitForTransactionReceipt"
)({ hash: verifyingPaymaster.hash });
}
return verifyingPaymaster;
}
async function topupPaymaster(client, parameters) {
const { paymaster, minBalance } = parameters;
if (minBalance == 0n && parameters.targetBalance === void 0) {
throw new Error(`topupAddressL2: minBalance 0, targetBalance MUST be defined`);
}
const targetBalance = parameters.targetBalance ?? minBalance;
if (minBalance > targetBalance) {
throw new Error(
`topupPaymaster: minBalance (${(0, import_viem.formatEther)(minBalance)}) > targetBalance (${(0, import_viem.formatEther)(targetBalance)})`
);
}
if (0n >= targetBalance) {
throw new Error(`topupPaymaster: 0 >= targetBalance (${(0, import_viem.formatEther)(targetBalance)})`);
}
const balance = await (0, import_utils.getAction)(
client,
import_actions.readContract,
"readContract"
)({
address: import_account_abstraction.entryPoint07Address,
abi: import_EntryPoint.EntryPoint.abi,
functionName: "balanceOf",
args: [paymaster]
});
const targetDeficit = targetBalance - balance;
if (targetDeficit > 0n && (balance < minBalance || minBalance == 0n)) {
const paymasterDeposit = await (0, import_utils.getAction)(
client,
import_actions.simulateContract,
"simulateContract"
)({
account: client.account,
chain: client.chain,
address: paymaster,
abi: import_VerifyingPaymaster.VerifyingPaymaster.abi,
functionName: "deposit",
value: targetDeficit,
args: []
});
const paymasterDepositHash = await (0, import_utils.getAction)(client, import_actions.writeContract, "writeContract")(paymasterDeposit.request);
return { balance, hash: paymasterDepositHash };
}
return { balance };
}