Skip to content

Add support for kernel + 7702 #414

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 6 commits into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
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
5 changes: 5 additions & 0 deletions .changeset/silly-eyes-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"permissionless": patch
---

Added to7702KernelSmartAccount
196 changes: 177 additions & 19 deletions bun.lock

Large diffs are not rendered by default.

Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@changesets/cli": "^2.26.2",
"@permissionless/wagmi": "workspace:packages/wagmi",
"@pimlico/mock-paymaster": "workspace:packages/mock-paymaster",
"@pimlico/alto": "^0.0.18",
"@pimlico/alto": "0.0.0-main.20250527T165035",
"@size-limit/esbuild-why": "^9.0.0",
"@size-limit/preset-small-lib": "^9.0.0",
"@tanstack/react-query": "5.45.1",
Expand Down
33 changes: 29 additions & 4 deletions packages/mock-paymaster/helpers/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,27 @@ export const hexDataSchema = z
.regex(hexDataPattern, { message: "not valid hex data" })
.transform((val) => val.toLowerCase() as Hex)

const signedAuthorizationSchema = z.union([
z.object({
contractAddress: addressSchema,
chainId: hexNumberSchema.transform((val) => Number(val)),
nonce: hexNumberSchema.transform((val) => Number(val)),
r: hexDataSchema.transform((val) => val as Hex),
s: hexDataSchema.transform((val) => val as Hex),
v: hexNumberSchema.optional(),
yParity: hexNumberSchema.transform((val) => Number(val))
}),
z.object({
address: addressSchema,
chainId: hexNumberSchema.transform((val) => Number(val)),
nonce: hexNumberSchema.transform((val) => Number(val)),
r: hexDataSchema.transform((val) => val as Hex),
s: hexDataSchema.transform((val) => val as Hex),
v: hexNumberSchema.optional(),
yParity: hexNumberSchema.transform((val) => Number(val))
})
])

const userOperationSchemaPaymasterV6 = z
.object({
sender: addressSchema,
Expand All @@ -80,7 +101,8 @@ const userOperationSchemaPaymasterV6 = z
return "0x"
}
return val
})
}),
eip7702Auth: signedAuthorizationSchema.optional().nullable()
})
.strict()
.transform((val) => {
Expand Down Expand Up @@ -122,7 +144,8 @@ const userOperationSchemaPaymasterV7 = z
return "0x"
}
return val
})
}),
eip7702Auth: signedAuthorizationSchema.optional().nullable()
})
.strict()
.transform((val) => {
Expand Down Expand Up @@ -173,7 +196,8 @@ const eip7677UserOperationSchemaV6 = z
.optional()
.transform((_) => {
return "0x" as Hex
})
}),
eip7702Auth: signedAuthorizationSchema.optional().nullable()
})
.strict()
.transform((val) => {
Expand Down Expand Up @@ -219,7 +243,8 @@ const eip7677UserOperationSchemaV7 = z
return "0x"
}
return val
})
}),
eip7702Auth: signedAuthorizationSchema.optional().nullable()
})
.strict()
.transform((val) => {
Expand Down

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions packages/permissionless-test/mock-aa-infra/alto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,13 @@ export const setupContracts = async (rpc: string) => {
data: "0x6e7dbabb000000000000000000000000E30c76Dc9eCF1c19F6Fec070674E1b4eFfE069FA0000000000000000000000000000000000000000000000000000000000000001"
})

// register 0x2577507b78c2008Ff367261CB6285d44ba5eF2E9
await sendTransaction(walletClient, {
account: kernelFactoryOwner,
to: "0xd703aaE79538628d27099B8c4f621bE4CCd142d5" /* kernel factory v0.7 */,
data: "0x6e7dbabb0000000000000000000000002577507b78c2008Ff367261CB6285d44ba5eF2E90000000000000000000000000000000000000000000000000000000000000001"
})

await sendTransaction(walletClient, {
account: kernelFactoryOwner,
to: "0xd703aaE79538628d27099B8c4f621bE4CCd142d5" /* kernel factory v0.7 */,
Expand Down Expand Up @@ -707,8 +714,8 @@ export const setupContracts = async (rpc: string) => {
"0xbA45a2BFb8De3D24cA9D7F1B551E14dFF5d690Fd", // Kernel v0.3.1 WebAuthn Validator
"0xD830D15D3dc0C269F3dBAa0F3e8626d33CFdaBe1", // Kernel v0.3.2 Account Logic
"0x7a1dBAB750f12a90EB1B60D2Ae3aD17D4D81EfFe", // Kernel v0.3.2 Factory
"0xE264dCCc54e4b6906c0D1Fee11D4326c06D33c80", // Kernel v0.3.3 Account Logic
"0xE30c76Dc9eCF1c19F6Fec070674E1b4eFfE069FA", // Kernel v0.3.3 Factory
"0xd6CEDDe84be40893d153Be9d467CD6aD37875b28", // Kernel v0.3.3 Account Logic
"0x2577507b78c2008Ff367261CB6285d44ba5eF2E9", // Kernel v0.3.3 Factory
"0x00004EC70002a32400f8ae005A26081065620D20", // LightAccountFactory v1.1.0
"0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba", // LightAccount v1.1.0 implementation
"0x0000000000400CdFef5E2714E63d8040b700BC24", // LightAccountFactory v2.0.0
Expand Down
6 changes: 4 additions & 2 deletions packages/permissionless-test/src/testWithRpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ export const getInstances = async ({
? anvil({
chainId: foundry.id,
port: anvilPort,
hardfork: "Prague",
forkUrl
})
: anvil({
chainId: foundry.id,
hardfork: "Prague",
port: anvilPort
})

Expand All @@ -49,10 +51,10 @@ export const getInstances = async ({
utilityPrivateKey: anvilPrivateKey
})

// instance.on("stderr", (data) => {
// altoInstance.on("stderr", (data) => {
// console.error(data.toString())
// })
// instance.on("stdout", (data) => {
// altoInstance.on("stdout", (data) => {
// console.log(data.toString())
// })

Expand Down
43 changes: 41 additions & 2 deletions packages/permissionless-test/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import { foundry } from "viem/chains"
import {
type KernelVersion,
to7702KernelSmartAccount,
toKernelSmartAccount,
toThirdwebSmartAccount
} from "../../permissionless/accounts"
Expand Down Expand Up @@ -328,10 +329,12 @@ export const getKernelEcdsaClient = async <
anvilRpc,
version,
privateKey,
useMetaFactory
useMetaFactory,
eip7702 = false
}: AAParamType<entryPointVersion> & {
version?: KernelVersion<entryPointVersion>
useMetaFactory?: boolean
eip7702?: boolean
}) => {
const publicClient = getPublicClient(anvilRpc)

Expand All @@ -342,6 +345,13 @@ export const getKernelEcdsaClient = async <
throw new Error("Kernel ERC7579 is not supported for V06")
}

if (eip7702) {
return to7702KernelSmartAccount({
client: publicClient,
owner: privateKeyToAccount(privateKey ?? generatePrivateKey())
})
}

return toKernelSmartAccount({
client: publicClient,
entryPoint: {
Expand Down Expand Up @@ -449,6 +459,7 @@ export const getCoreSmartAccounts = (): Array<{
supportsEntryPointV06: boolean
supportsEntryPointV07: boolean
supportsEntryPointV08: boolean
isEip7702Compliant?: boolean
isEip1271Compliant: boolean
getSmartAccountClient: (
conf: AAParamType<EntryPointVersion>
Expand Down Expand Up @@ -727,9 +738,37 @@ export const getCoreSmartAccounts = (): Array<{
}),
supportsEntryPointV06: false,
supportsEntryPointV07: true,
supportsEntryPointV08: false,
supportsEntryPointV08: true,
isEip1271Compliant: true
},
{
name: "Kernel 7579 0.3.3 + EIP-7702",
getSmartAccountClient: async (conf: AAParamType<EntryPointVersion>) =>
getBundlerClient({
account: await getKernelEcdsaClient({
...(conf as AAParamType<"0.6" | "0.7">),
version: "0.3.3" as KernelVersion<"0.6" | "0.7">,
eip7702: true
}),
...conf
}),
getErc7579SmartAccountClient: async (
conf: AAParamType<EntryPointVersion>
) =>
getSmartAccountClient({
account: await getKernelEcdsaClient({
...(conf as AAParamType<"0.6" | "0.7">),
version: "0.3.3" as KernelVersion<"0.6" | "0.7">,
eip7702: true
}),
...conf
}),
supportsEntryPointV06: false,
supportsEntryPointV07: true,
supportsEntryPointV08: false,
isEip7702Compliant: true,
isEip1271Compliant: false
},
{
name: "Biconomy",
getSmartAccountClient: async (conf: AAParamType<EntryPointVersion>) =>
Expand Down
13 changes: 12 additions & 1 deletion packages/permissionless/accounts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ import {
toEcdsaKernelSmartAccount
} from "./kernel/toEcdsaKernelSmartAccount.js"

import {
type To7702KernelSmartAccountImplementation,
type To7702KernelSmartAccountParameters,
type To7702KernelSmartAccountReturnType,
to7702KernelSmartAccount
} from "./kernel/to7702KernelSmartAccount.js"

import {
type KernelSmartAccountImplementation,
type KernelVersion,
Expand Down Expand Up @@ -114,5 +121,9 @@ export {
type ToEtherspotSmartAccountParameters,
type EtherspotSmartAccountImplementation,
type ToEtherspotSmartAccountReturnType,
toEtherspotSmartAccount
toEtherspotSmartAccount,
type To7702KernelSmartAccountParameters,
type To7702KernelSmartAccountImplementation,
type To7702KernelSmartAccountReturnType,
to7702KernelSmartAccount
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type {
Account,
Chain,
LocalAccount,
OneOf,
Prettify,
Transport,
WalletClient
} from "viem"
import type { EthereumProvider } from "../../utils/toOwner.js"
import {
type KernelSmartAccountImplementation,
type KernelVersion,
type ToKernelSmartAccountParameters,
type ToKernelSmartAccountReturnType,
toKernelSmartAccount
} from "./toKernelSmartAccount.js"

export type To7702KernelSmartAccountParameters<
entryPointVersion extends "0.7",
kernelVersion extends KernelVersion<entryPointVersion>,
owner extends OneOf<
| EthereumProvider
| WalletClient<Transport, Chain | undefined, Account>
| LocalAccount
>
> = ToKernelSmartAccountParameters<
entryPointVersion,
kernelVersion,
owner,
true
>

export type To7702KernelSmartAccountImplementation<
entryPointVersion extends "0.7" = "0.7"
> = KernelSmartAccountImplementation<entryPointVersion, true>

export type To7702KernelSmartAccountReturnType<
entryPointVersion extends "0.7" = "0.7"
> = ToKernelSmartAccountReturnType<entryPointVersion, true>

export async function to7702KernelSmartAccount<
entryPointVersion extends "0.7",
kernelVersion extends KernelVersion<entryPointVersion>,
owner extends OneOf<
| EthereumProvider
| WalletClient<Transport, Chain | undefined, Account>
| LocalAccount
>
>(
parameters: Prettify<
To7702KernelSmartAccountParameters<
entryPointVersion,
kernelVersion,
owner
>
>
): Promise<To7702KernelSmartAccountReturnType<entryPointVersion>> {
return toKernelSmartAccount({
...parameters,
eip7702: true
})
}
Loading
Loading