Skip to content
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

Use actual kernel version for deployed contracts #328

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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/olive-boats-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"permissionless": patch
---

Now supports using deployed Kernel accounts with a different version
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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
}

Expand All @@ -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
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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<KernelVersion<"0.6" | "0.7">> {
try {
const contract = getContract({
address,
abi: [
Copy link

@hapetherw hapetherw Dec 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather define abi as a constant variable for reusability.

const EIP712_DOMAIN_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", }, ];

{
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
}
}
Loading