diff --git a/.changeset/olive-boats-rest.md b/.changeset/olive-boats-rest.md new file mode 100644 index 00000000..a0363d8d --- /dev/null +++ b/.changeset/olive-boats-rest.md @@ -0,0 +1,5 @@ +--- +"permissionless": patch +--- + +Now supports using deployed Kernel accounts with a different version diff --git a/packages/permissionless/accounts/kernel/toEcdsaKernelSmartAccount.ts b/packages/permissionless/accounts/kernel/toEcdsaKernelSmartAccount.ts index 4b70f596..ee0ff0c9 100644 --- a/packages/permissionless/accounts/kernel/toEcdsaKernelSmartAccount.ts +++ b/packages/permissionless/accounts/kernel/toEcdsaKernelSmartAccount.ts @@ -27,7 +27,7 @@ import { getUserOperationHash, toSmartAccount } from "viem/account-abstraction" -import { signMessage as _signMessage, getChainId } from "viem/actions" +import { getChainId } from "viem/actions" import { getAction } from "viem/utils" import { getAccountNonce } from "../../actions/public/getAccountNonce.js" import { getSenderAddress } from "../../actions/public/getSenderAddress.js" @@ -44,6 +44,7 @@ import { VALIDATOR_TYPE } from "./constants.js" import { encodeCallData } from "./utils/encodeCallData.js" +import { getActualKernelVersion } from "./utils/getActualKernelVersion.js" import { getNonceKeyWithEncoding } from "./utils/getNonceKey.js" import { isKernelV2 } from "./utils/isKernelV2.js" import { signMessage } from "./utils/signMessage.js" @@ -479,15 +480,22 @@ export async function toEcdsaKernelSmartAccount< return this.signMessage({ message: hash }) }, async signMessage({ message }) { + const accountAddress = await this.getAddress() + const actualKernelVersion = await getActualKernelVersion( + client, + accountAddress, + kernelVersion + ) + const signature = await signMessage({ owner: localOwner, message, accountAddress: await this.getAddress(), - kernelVersion, + kernelVersion: actualKernelVersion, chainId: await getMemoizedChainId() }) - if (isKernelV2(kernelVersion)) { + if (isKernelV2(actualKernelVersion)) { return signature } @@ -497,15 +505,22 @@ export async function toEcdsaKernelSmartAccount< ]) }, async signTypedData(typedData) { + const accountAddress = await this.getAddress() + const actualKernelVersion = await getActualKernelVersion( + client, + accountAddress, + kernelVersion + ) + const signature = await signTypedData({ owner: localOwner, chainId: await getMemoizedChainId(), ...(typedData as TypedDataDefinition), accountAddress: await this.getAddress(), - kernelVersion + kernelVersion: actualKernelVersion }) - if (isKernelV2(kernelVersion)) { + if (isKernelV2(actualKernelVersion)) { return signature } diff --git a/packages/permissionless/accounts/kernel/utils/getActualKernelVersion.ts b/packages/permissionless/accounts/kernel/utils/getActualKernelVersion.ts new file mode 100644 index 00000000..5998d594 --- /dev/null +++ b/packages/permissionless/accounts/kernel/utils/getActualKernelVersion.ts @@ -0,0 +1,67 @@ +import { type Address, type Client, getContract } from "viem" +import type { KernelVersion } from "../toEcdsaKernelSmartAccount.js" + +// If the kernel contract is already deployed, we can get the actual version from the contract +export async function getActualKernelVersion( + client: Client, + address: Address, + version: KernelVersion<"0.6" | "0.7"> +): Promise> { + try { + const contract = getContract({ + address, + abi: [ + { + type: "function", + name: "eip712Domain", + inputs: [], + outputs: [ + { + name: "fields", + type: "bytes1", + internalType: "bytes1" + }, + { + name: "name", + type: "string", + internalType: "string" + }, + { + name: "version", + type: "string", + internalType: "string" + }, + { + name: "chainId", + type: "uint256", + internalType: "uint256" + }, + { + name: "verifyingContract", + type: "address", + internalType: "address" + }, + { + name: "salt", + type: "bytes32", + internalType: "bytes32" + }, + { + name: "extensions", + type: "uint256[]", + internalType: "uint256[]" + } + ], + stateMutability: "view" + } + ], + client + }) + + const [, , version] = await contract.read.eip712Domain() + + return version as KernelVersion<"0.6" | "0.7"> + } catch { + return version + } +}