Skip to content

Chore/bump viem latest #215

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 5 commits into from
Mar 26, 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
Binary file modified bun.lockb
Binary file not shown.
6 changes: 6 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @zerodev/sdk

## 5.4.28

### Patch Changes

- chore: update viem version

## 5.4.27

### Patch Changes
Expand Down
2 changes: 2 additions & 0 deletions packages/core/accounts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ export { accountMetadata } from "./kernel/utils/common/accountMetadata.js"
export { getActionSelector } from "./kernel/utils/common/getActionSelector.js"
export { getPluginsEnableTypedData } from "./kernel/utils/plugins/ep0_7/getPluginsEnableTypedData.js"
export { getKernelV3Nonce } from "./kernel/utils/account/ep0_7/getKernelV3Nonce.js"
export { getPluginInstallCallData } from "./kernel/utils/plugins/ep0_7/getPluginInstallCallData.js"
export type { CallArgs, DelegateCallArgs } from "./kernel/utils/types.js"
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { encodeFunctionData } from "viem"
import type { SmartAccount, UserOperationCall } from "viem/account-abstraction"
import type { SmartAccount } from "viem/account-abstraction"
import { KernelVersionToAddressesMap } from "../../../../constants.js"
import type { KERNEL_VERSION_TYPE } from "../../../../types/kernel.js"
import { validateKernelVersionWithEntryPoint } from "../../../../utils.js"
import { KernelV3AccountAbi } from "../../abi/kernel_v_3_0_0/KernelAccountAbi.js"
import type { CallArgs } from "../types.js"

export function getUpgradeKernelCall(
account: SmartAccount,
kernelVersion: KERNEL_VERSION_TYPE
): UserOperationCall {
): CallArgs {
validateKernelVersionWithEntryPoint(
account.entryPoint.version,
kernelVersion
Expand Down
4 changes: 2 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zerodev/sdk",
"version": "5.4.27",
"version": "5.4.28",
"author": "ZeroDev",
"main": "./_cjs/index.js",
"module": "./_esm/index.js",
Expand Down Expand Up @@ -100,7 +100,7 @@
}
},
"peerDependencies": {
"viem": "^2.21.40"
"viem": "^2.23.15"
},
"dependencies": {
"semver": "^7.6.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"dependencies": {
"dotenv": "^16.3.1",
"viem": "^2.21.40",
"viem": "^2.23.15",
"@zerodev/sdk": "workspace:*",
"@zerodev/ecdsa-validator": "workspace:*",
"@zerodev/session-key": "workspace:*",
Expand Down
128 changes: 128 additions & 0 deletions packages/test/v0.7/migrationEcdsaKernelAccount.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,134 @@ describe("ECDSA kernel Account", () => {
TEST_TIMEOUT
)

test(
"Client upgrade deployed kernel account with migration account from v3.1 to v3.2 with plugin migration",
async () => {
const privateKey = generatePrivateKey()
const owner = privateKeyToAccount(privateKey)
const kernelAccount = await getEcdsaKernelAccountWithPrivateKey(
privateKey,
[],
sepolia.id,
KERNEL_V3_1,
[],
migrationIndex
)
console.log("kernelAccount", kernelAccount.address)
const zeroDevPaymaster = getZeroDevPaymasterClient()
const kernelClient = await getKernelAccountClient({
account: kernelAccount,
paymaster: zeroDevPaymaster
})
const deployKernelHash = await kernelClient.sendTransaction({
to: zeroAddress,
value: 0n,
data: "0x"
})
console.log(
"deployKernelHash",
`https://sepolia.etherscan.io/tx/${deployKernelHash}`
)

const kernelImplementation = await getKernelImplementationAddress(
publicClient,
{
address: kernelAccount.address
}
)
console.log("kernelImplementation", kernelImplementation)

// 0.0.3 intentExecutorAddress
const executorAddress = "0xD0eb92AE315366A60527906B983A17Ae68aFCAE0"
console.log("executorAddress", executorAddress)
const migrationAccount = await createEcdsaKernelMigrationAccount(
publicClient,
{
entryPoint: getEntryPoint(),
signer: owner,
migrationVersion: {
from: KERNEL_V3_1,
to: KERNEL_V3_2
},
pluginMigrations: [
{
type: 2,
address: executorAddress,
data: concatHex([
zeroAddress,
encodeAbiParameters(
parseAbiParameters(["bytes", "bytes"]),
["0x", "0x"]
)
])
}
],
index: migrationIndex
}
)
console.log("migrationAccount", migrationAccount.address)
expect(migrationAccount.address).toEqual(kernelAccount.address)
const migrationKernelClient = await getKernelAccountClient({
account: migrationAccount,
paymaster: zeroDevPaymaster
})
const migrationDeployKernelHash =
await migrationKernelClient.sendTransaction({
to: zeroAddress,
value: 0n,
data: "0x"
})
console.log(
"migrationDeployKernelHash",
`https://sepolia.etherscan.io/tx/${migrationDeployKernelHash}`
)
const migrationKernelImplementation =
await getKernelImplementationAddress(publicClient, {
address: migrationAccount.address
})

const pluginInstalled = await isPluginInstalled(publicClient, {
address: migrationAccount.address,
plugin: {
type: 2,
address: executorAddress
}
})
console.log("pluginInstalled", pluginInstalled)
console.log(
"migrationKernelImplementation",
migrationKernelImplementation
)
const testHash = await migrationKernelClient.sendTransaction({
to: zeroAddress,
value: 0n,
data: "0x"
})
console.log(
"testHash",
`https://sepolia.etherscan.io/tx/${testHash}`
)
expect(
isAddressEqual(
kernelImplementation,
KernelVersionToAddressesMap[KERNEL_V3_1]
.accountImplementationAddress
)
).toBeTrue()
expect(
isAddressEqual(
migrationKernelImplementation,
KernelVersionToAddressesMap[KERNEL_V3_2]
.accountImplementationAddress
)
).toBeTrue()

// Check if the plugin is installed
expect(pluginInstalled).toBeTrue()
},
TEST_TIMEOUT
)

test(
"Should validate message signatures for undeployed accounts (6492)",
async () => {
Expand Down
6 changes: 6 additions & 0 deletions plugins/ecdsa/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @zerodev/ecdsa-validator

## 5.4.5

### Patch Changes

- chore: update viem version

## 5.4.4

### Patch Changes
Expand Down
78 changes: 74 additions & 4 deletions plugins/ecdsa/account/createEcdsaKernelMigrationAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ import {
validateKernelVersionWithEntryPoint
} from "@zerodev/sdk"
import {
type CallArgs,
type KernelSmartAccountImplementation,
getPluginInstallCallData,
toKernelPluginManager
} from "@zerodev/sdk/accounts"
import {
getAccountNonce,
getKernelImplementationAddress,
getSenderAddress
getSenderAddress,
isPluginInstalled
} from "@zerodev/sdk/actions"
import {
DUMMY_ECDSA_SIG,
Expand All @@ -31,6 +34,7 @@ import type {
GetEntryPointAbi,
GetKernelVersion,
KERNEL_V3_VERSION_TYPE,
PluginMigrationData,
Signer
} from "@zerodev/sdk/types"
import {
Expand Down Expand Up @@ -83,6 +87,7 @@ export type CreateEcdsaKernelMigrationAccountParameters<
from: GetKernelVersion<entryPointVersion>
to: GetKernelVersion<entryPointVersion>
}
pluginMigrations?: PluginMigrationData[]
}

const getKernelInitData = <entryPointVersion extends EntryPointVersion>({
Expand Down Expand Up @@ -164,6 +169,11 @@ const isKernelUpgraded = async (
)
}

type PluginInstallationCache = {
pendingPlugins: PluginMigrationData[]
allInstalled: boolean
}

/**
* Build a kernel smart account from a private key, that use the ECDSA signer behind the scene
* @param client
Expand All @@ -184,7 +194,8 @@ export async function createEcdsaKernelMigrationAccount<
signer,
index = 0n,
address,
migrationVersion
migrationVersion,
pluginMigrations
}: CreateEcdsaKernelMigrationAccountParameters<entryPointVersion>
): Promise<CreateEcdsaKernelMigrationAccountReturnType<entryPointVersion>> {
if (entryPoint.version === "0.6") {
Expand Down Expand Up @@ -263,6 +274,38 @@ export async function createEcdsaKernelMigrationAccount<
migrationVersion.to
)

// Cache for plugin installation status
const pluginCache: PluginInstallationCache = {
pendingPlugins: pluginMigrations || [],
allInstalled: false
}

const checkPluginInstallationStatus = async () => {
// Skip if no plugins or all are installed
if (!pluginCache.pendingPlugins.length || pluginCache.allInstalled) {
pluginCache.allInstalled = true
return
}

// Check all pending plugins in parallel
const installationResults = await Promise.all(
pluginCache.pendingPlugins.map((plugin) =>
isPluginInstalled(client, {
address: accountAddress,
plugin
})
)
)

// Filter out installed plugins
pluginCache.pendingPlugins = pluginCache.pendingPlugins.filter(
(_, index) => !installationResults[index]
)
pluginCache.allInstalled = pluginCache.pendingPlugins.length === 0
}

await checkPluginInstallationStatus()

const _entryPoint = {
address: entryPoint?.address ?? entryPoint07Address,
abi: ((entryPoint?.version ?? "0.7") === "0.6"
Expand All @@ -289,6 +332,9 @@ export async function createEcdsaKernelMigrationAccount<
),
factoryAddress: (await getFactoryArgs()).factory,
generateInitCode,
accountImplementationAddress:
KernelVersionToAddressesMap[migrationVersion.to]
.accountImplementationAddress,
encodeModuleInstallCallData: async () => {
throw new Error("Not implemented")
},
Expand Down Expand Up @@ -317,6 +363,23 @@ export async function createEcdsaKernelMigrationAccount<
throw new Error("Not implemented")
},
async encodeCalls(calls, callType) {
// Check plugin status only if we have pending plugins
await checkPluginInstallationStatus()
const pluginInstallCalls: CallArgs[] = []

// Add plugin installation calls if needed
if (
pluginCache.pendingPlugins.length > 0 &&
entryPoint.version === "0.7"
) {
// convert map into for loop
for (const plugin of pluginCache.pendingPlugins) {
pluginInstallCalls.push(
getPluginInstallCallData(accountAddress, plugin)
)
}
}

kernelUpgraded =
kernelUpgraded ||
(await isKernelUpgraded(
Expand Down Expand Up @@ -361,9 +424,16 @@ export async function createEcdsaKernelMigrationAccount<
}),
value: 0n
}
_calls = [upgradeCall, updateValidatorCall, ...calls]
_calls = [
upgradeCall,
updateValidatorCall,
...pluginInstallCalls,
...calls
]
}
_calls = [upgradeCall, ...calls]
_calls = [upgradeCall, ...pluginInstallCalls, ...calls]
} else {
_calls = [...pluginInstallCalls, ...calls]
}
return encodeCallDataEpV07(_calls, callType)
},
Expand Down
4 changes: 2 additions & 2 deletions plugins/ecdsa/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zerodev/ecdsa-validator",
"version": "5.4.4",
"version": "5.4.5",
"author": "ZeroDev",
"main": "./_cjs/index.js",
"module": "./_esm/index.js",
Expand Down Expand Up @@ -34,7 +34,7 @@
"lint:fix": "bun run lint --apply"
},
"peerDependencies": {
"viem": "^2.21.40",
"viem": "^2.23.15",
"@zerodev/sdk": "^5.4.13"
},
"type": "module"
Expand Down
6 changes: 6 additions & 0 deletions plugins/hooks/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @zerodev/hooks

## 5.3.3

### Patch Changes

- chore: update viem version

## 5.3.2

### Patch Changes
Expand Down
Loading