Skip to content

Add optional useMetaFactory #389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 11, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 37 additions & 15 deletions packages/permissionless/accounts/kernel/toKernelSmartAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ export type ToKernelSmartAccountParameters<
accountLogicAddress?: Address
validatorAddress?: Address
nonceKey?: bigint
useMetaFactory?: boolean
useMetaFactory?: boolean | "optional"
}

export type KernelSmartAccountImplementation<
Expand Down Expand Up @@ -489,7 +489,7 @@ export async function toKernelSmartAccount<
}

// Helper to generate the init code for the smart account
const generateInitCode = async () =>
const generateInitCode = async (_useMetaFactory: boolean) =>
getAccountInitCode({
entryPointVersion: entryPoint.version,
kernelVersion,
Expand All @@ -498,11 +498,9 @@ export async function toKernelSmartAccount<
factoryAddress,
accountLogicAddress,
validatorAddress,
useMetaFactory
useMetaFactory: _useMetaFactory
})

let accountAddress: Address | undefined = address

let chainId: number

const getMemoizedChainId = async () => {
Expand All @@ -513,32 +511,56 @@ export async function toKernelSmartAccount<
return chainId
}

const getFactoryArgs = async () => {
const getFactoryArgsFunc = (_useMetaFactory: boolean) => async () => {
return {
factory:
entryPoint.version === "0.6" || useMetaFactory === false
entryPoint.version === "0.6" || _useMetaFactory === false
? factoryAddress
: metaFactoryAddress,
factoryData: await generateInitCode()
factoryData: await generateInitCode(_useMetaFactory)
}
}

return toSmartAccount({
client,
entryPoint,
getFactoryArgs,
async getAddress() {
if (accountAddress) return accountAddress
const { accountAddress, getFactoryArgs } = await (async () => {
let getFactoryArgs = getFactoryArgsFunc(
useMetaFactory === "optional" ? true : useMetaFactory
)

if (address && useMetaFactory !== "optional") {
return { accountAddress: address, getFactoryArgs }
}

const { factory, factoryData } = await getFactoryArgs()

let accountAddress = await getSenderAddress(client, {
factory,
factoryData,
entryPointAddress: entryPoint.address
})

if (address === accountAddress) {
return { accountAddress, getFactoryArgs }
}

if (useMetaFactory === "optional" && accountAddress === zeroAddress) {
getFactoryArgs = getFactoryArgsFunc(false)
const { factory, factoryData } = await getFactoryArgs()

// Get the sender address based on the init code
accountAddress = await getSenderAddress(client, {
factory,
factoryData,
entryPointAddress: entryPoint.address
})
}

return { accountAddress, getFactoryArgs }
})()

return toSmartAccount({
client,
entryPoint,
getFactoryArgs,
async getAddress() {
return accountAddress
},
async encodeCalls(calls) {
Expand Down
Loading