Skip to content

Commit

Permalink
feat: added validator plugin type support to pluginMigrations
Browse files Browse the repository at this point in the history
  • Loading branch information
SahilVasava committed Jan 27, 2025
1 parent a61e31a commit 8a82418
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 6 deletions.
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.18

### Patch Changes

- feat: added validator plugin type support to pluginMigrations

## 5.4.17

### Patch Changes
Expand Down
30 changes: 26 additions & 4 deletions packages/core/accounts/kernel/createKernelAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ import {
} from "../../actions/public/index.js"
import {
KernelVersionToAddressesMap,
MAGIC_VALUE_SIG_REPLAYABLE
MAGIC_VALUE_SIG_REPLAYABLE,
PLUGIN_TYPE
} from "../../constants.js"
import type {
CallType,
Expand Down Expand Up @@ -75,6 +76,9 @@ import { encodeDeployCallData as encodeDeployCallDataV07 } from "./utils/account
import { accountMetadata } from "./utils/common/accountMetadata.js"
import { eip712WrapHash } from "./utils/common/eip712WrapHash.js"
import { getPluginInstallCallData } from "./utils/plugins/ep0_7/getPluginInstallCallData.js"
import type { CallArgs } from "./utils/types.js"
import { getValidatorPluginInstallCallData } from "./utils/plugins/ep0_7/getValidatorPluginInstallCallData.js"
import { getKernelV3Nonce } from "./utils/account/ep0_7/getKernelV3Nonce.js"

type SignMessageParameters = {
message: SignableMessage
Expand Down Expand Up @@ -595,9 +599,27 @@ export async function createKernelAccount<
entryPoint.version === "0.7" &&
kernelPluginManager.activeValidatorMode === "sudo"
) {
const pluginInstallCalls = pluginCache.pendingPlugins.map(
(plugin) => getPluginInstallCallData(accountAddress, plugin)
)
// convert map into for loop
const pluginInstallCalls: CallArgs[] = []
for (const plugin of pluginCache.pendingPlugins) {
if (plugin.type === PLUGIN_TYPE.VALIDATOR) {
const nonce = await getKernelV3Nonce(
client,
accountAddress
)
pluginInstallCalls.push(
getValidatorPluginInstallCallData(
accountAddress,
plugin,
nonce
)
)
} else {
pluginInstallCalls.push(
getPluginInstallCallData(accountAddress, plugin)
)
}
}
return encodeCallDataEpV07(
[...calls, ...pluginInstallCalls],
callType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const getKernelV3Nonce = async (
const nonce = await getAction(
client,
readContract,
"sendTransaction"
"readContract"
)({
abi: KernelV3AccountAbi,
address: accountAddress,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
type Address,
concatHex,
encodeFunctionData,
type Hex,
zeroAddress
} from "viem"
import type { PluginMigrationData } from "../../../../../types/kernel.js"
import type { CallArgs } from "../../types.js"
import { KernelV3_1AccountAbi } from "../../../abi/kernel_v_3_1/KernelAccountAbi.js"
import { VALIDATOR_TYPE } from "../../../../../constants.js"

export const getValidatorPluginInstallCallData = (
accountAddress: Address,
plugin: PluginMigrationData,
nonce: number
): CallArgs => {
const vIds = [concatHex([VALIDATOR_TYPE.SECONDARY, plugin.address])]
const configs = [{ nonce, hook: zeroAddress }]
const validationData = [plugin.data]
const hookData: Hex[] = ["0x"]
const data = encodeFunctionData({
abi: KernelV3_1AccountAbi,
functionName: "installValidations",
args: [vIds, configs, validationData, hookData]
})
return {
to: accountAddress,
data
}
}
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zerodev/sdk",
"version": "5.4.17",
"version": "5.4.18",
"author": "ZeroDev",
"main": "./_cjs/index.js",
"module": "./_esm/index.js",
Expand Down
101 changes: 101 additions & 0 deletions packages/test/v0.7/ecdsaKernelAccount.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,107 @@ describe("ECDSA kernel Account", () => {
TEST_TIMEOUT
)

test(
"Client install Kernel validator plugins automatically",
async () => {
const pluginToInstall: PluginMigrationData = {
type: PLUGIN_TYPE.VALIDATOR,
address: "0x43C757131417c5a245a99c4D5B7722ec20Cb0b31",
data: "0xb33f"
}
const privateKey = generatePrivateKey()
const kernelAccountWithoutPlugins =
await getEcdsaKernelAccountWithPrivateKey(
privateKey,
undefined,
undefined,
"0.3.0",
undefined,
BigInt(0)
)
console.log(
"kernelAccountWithoutPlugins",
kernelAccountWithoutPlugins.address
)
const kernelAccountWithPlugins =
await getEcdsaKernelAccountWithPrivateKey(
privateKey,
undefined,
undefined,
"0.3.0",
[pluginToInstall],
BigInt(0)
)
console.log(
"kernelAccountWithPlugins",
kernelAccountWithPlugins.address
)
expect(
isAddressEqual(
kernelAccountWithoutPlugins.address,
kernelAccountWithPlugins.address
)
).toBeTrue()
const zeroDevPaymaster = getZeroDevPaymasterClient()
let kernelClient = await getKernelAccountClient({
account: kernelAccountWithoutPlugins,
paymaster: zeroDevPaymaster
})
const deployKernelHash = await kernelClient.sendTransaction({
to: zeroAddress,
value: 0n,
data: "0x"
})
console.log(
"deployKernelReceipt",
`https://sepolia.etherscan.io/tx/${deployKernelHash}`
)

kernelClient = await getKernelAccountClient({
account: kernelAccountWithPlugins,
paymaster: zeroDevPaymaster
})

const pluginInstalledBefore = await isPluginInstalled(
publicClient,
{
address: kernelAccountWithPlugins.address,
plugin: pluginToInstall
}
)
console.log("pluginInstalledBefore", pluginInstalledBefore)

const userOpHash = await kernelClient.sendUserOperation({
calls: [{ to: zeroAddress, value: 0n, data: "0x" }]
// callData: await kernelClient.account.encodeCalls([
// { to: zeroAddress, value: 0n, data: "0x" }
// ])
})
console.log("userOpHash", userOpHash)
const userOpReceipt =
await kernelClient.waitForUserOperationReceipt({
hash: userOpHash
})
console.log("userOpReceipt", userOpReceipt.receipt.transactionHash)

const pluginInstalledAfter = await isPluginInstalled(publicClient, {
address: kernelAccountWithPlugins.address,
plugin: pluginToInstall
})
console.log("pluginInstalledAfter", pluginInstalledAfter)

expect(pluginInstalledBefore).toBeFalse()
expect(pluginInstalledAfter).toBeTrue()
const transactionHash2 = await kernelClient.sendTransaction({
to: zeroAddress,
value: 0n,
data: "0x"
})
console.log("transactionHash2", transactionHash2)
},
TEST_TIMEOUT
)

// [TODO] - erc20 paymaster integration with EP v0.7
// test(
// "Client send transaction with ERC20 paymaster",
Expand Down

0 comments on commit 8a82418

Please sign in to comment.