Skip to content

Commit e3013d8

Browse files
Merge pull request #460 from pimlicolabs/kernerl-webauthn-fix
auto patch old validator
2 parents 53643dc + 5eaeaa2 commit e3013d8

File tree

4 files changed

+171
-3
lines changed

4 files changed

+171
-3
lines changed

packages/permissionless/accounts/kernel/toKernelSmartAccount.ts

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
type LocalAccount,
1616
type TypedDataDefinition,
1717
concatHex,
18+
decodeFunctionData,
1819
encodeAbiParameters,
1920
encodeFunctionData,
2021
keccak256,
@@ -32,10 +33,13 @@ import {
3233
getUserOperationHash,
3334
toSmartAccount
3435
} from "viem/account-abstraction"
35-
import { getChainId } from "viem/actions"
36+
import { getChainId, readContract } from "viem/actions"
3637
import { getAction } from "viem/utils"
3738
import { getAccountNonce } from "../../actions/public/getAccountNonce.js"
3839
import { getSenderAddress } from "../../actions/public/getSenderAddress.js"
40+
import { encode7579Calls } from "../../utils/encode7579Calls.js"
41+
import { encodeInstallModule } from "../../utils/encodeInstallModule.js"
42+
import { encodeUninstallModule } from "../../utils/encodeUninstallModule.js"
3943
import { type EthereumProvider, toOwner } from "../../utils/toOwner.js"
4044
import { KernelInitAbi } from "./abi/KernelAccountAbi.js"
4145
import {
@@ -59,6 +63,29 @@ import { signTypedData } from "./utils/signTypedData.js"
5963

6064
type EntryPointVersion = "0.6" | "0.7"
6165

66+
const migrationHelperAbi = [
67+
{
68+
type: "function",
69+
name: "migrateWithCall",
70+
inputs: [
71+
{
72+
name: "validators",
73+
type: "address[]",
74+
internalType: "contract IValidator[]"
75+
},
76+
{
77+
name: "permissionIds",
78+
type: "bytes4[]",
79+
internalType: "bytes4[]"
80+
},
81+
{ name: "execMode", type: "bytes32", internalType: "ExecMode" },
82+
{ name: "execData", type: "bytes", internalType: "bytes" }
83+
],
84+
outputs: [],
85+
stateMutability: "nonpayable"
86+
}
87+
]
88+
6289
/**
6390
* The account creation ABI for a kernel smart account (from the KernelFactory)
6491
*/
@@ -99,6 +126,9 @@ export type KernelVersion<entryPointVersion extends EntryPointVersion> =
99126
? "0.2.1" | "0.2.2" | "0.2.3" | "0.2.4"
100127
: "0.3.0-beta" | "0.3.1" | "0.3.2" | "0.3.3"
101128

129+
export const MIGRATION_HELPER_ADDRESS =
130+
"0x03EB97959433D55748839D27C93330Cb85F31A93"
131+
102132
/**
103133
* Default addresses map for different kernel smart account versions
104134
*/
@@ -660,6 +690,41 @@ export async function toKernelSmartAccount<
660690
return { accountAddress, getFactoryArgs }
661691
})()
662692

693+
const getKernelAccountPatchedStatus = async () => {
694+
const rootValidator = await getAction(
695+
client,
696+
readContract,
697+
"readContract"
698+
)({
699+
address: accountAddress,
700+
abi: [
701+
{
702+
type: "function",
703+
name: "rootValidator",
704+
inputs: [],
705+
outputs: [
706+
{
707+
name: "",
708+
type: "bytes21",
709+
internalType: "ValidationId"
710+
}
711+
],
712+
stateMutability: "view"
713+
}
714+
],
715+
functionName: "rootValidator",
716+
args: []
717+
})
718+
719+
const patchedRootValidator =
720+
"0x017ab16ff354acb328452f1d445b3ddee9a91e9e69"
721+
722+
return rootValidator.toLowerCase() === patchedRootValidator
723+
}
724+
725+
let isKernelAccountPatched =
726+
validatorAddress !== "0xbA45a2BFb8De3D24cA9D7F1B551E14dFF5d690Fd"
727+
663728
return toSmartAccount({
664729
client,
665730
entryPoint,
@@ -679,6 +744,102 @@ export async function toKernelSmartAccount<
679744
return accountAddress
680745
},
681746
async encodeCalls(calls) {
747+
if (!isKernelAccountPatched) {
748+
const isDeployed =
749+
"isDeployed" in this && (await (this as any).isDeployed())
750+
isKernelAccountPatched =
751+
isDeployed && (await getKernelAccountPatchedStatus())
752+
}
753+
if (!isKernelAccountPatched) {
754+
const [installFallbackCall] = encodeInstallModule({
755+
account: this as any,
756+
modules: [
757+
{
758+
type: "fallback",
759+
address: MIGRATION_HELPER_ADDRESS,
760+
context:
761+
"0x36f541c10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001FF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000"
762+
}
763+
]
764+
})
765+
766+
const [uninstallFallbackCall] = encodeUninstallModule({
767+
account: this as any,
768+
modules: [
769+
{
770+
type: "fallback",
771+
address: MIGRATION_HELPER_ADDRESS,
772+
context: "0x36f541c1"
773+
}
774+
]
775+
})
776+
777+
const executeCallData = encodeCallData({
778+
calls,
779+
kernelVersion
780+
})
781+
782+
const { args } = decodeFunctionData({
783+
abi: [
784+
{
785+
type: "function",
786+
name: "execute",
787+
inputs: [
788+
{
789+
name: "execMode",
790+
type: "bytes32",
791+
internalType: "ExecMode"
792+
},
793+
{
794+
name: "executionCalldata",
795+
type: "bytes",
796+
internalType: "bytes"
797+
}
798+
],
799+
outputs: [],
800+
stateMutability: "payable"
801+
}
802+
],
803+
data: executeCallData
804+
})
805+
806+
const migrationCallData = encodeFunctionData({
807+
abi: migrationHelperAbi,
808+
functionName: "migrateWithCall",
809+
args: [[], [], ...args] as readonly any[]
810+
})
811+
812+
if (kernelVersion !== "0.3.0-beta") {
813+
return encode7579Calls({
814+
mode: {
815+
type: "delegatecall",
816+
revertOnError: false,
817+
selector: "0x",
818+
context: "0x"
819+
},
820+
callData: [
821+
{
822+
to: MIGRATION_HELPER_ADDRESS,
823+
data: migrationCallData,
824+
value: 0n
825+
}
826+
]
827+
})
828+
}
829+
830+
return encodeCallData({
831+
calls: [
832+
installFallbackCall,
833+
{
834+
to: accountAddress,
835+
data: migrationCallData,
836+
value: 0n
837+
},
838+
uninstallFallbackCall
839+
],
840+
kernelVersion
841+
})
842+
}
682843
return encodeCallData({ calls, kernelVersion })
683844
},
684845
async decodeCalls(callData) {

packages/permissionless/actions/erc7579/supportsExecutionMode.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export type SupportsExecutionModeParameters<
3333
callType extends CallType = CallType
3434
> = GetSmartAccountParameter<TSmartAccount> & ExecutionMode<callType>
3535

36-
function parseCallType(callType: CallType) {
36+
export function getCallType(callType: CallType) {
3737
switch (callType) {
3838
case "call":
3939
return "0x00"
@@ -53,7 +53,7 @@ export function encodeExecutionMode<callType extends CallType>({
5353
return encodePacked(
5454
["bytes1", "bytes1", "bytes4", "bytes4", "bytes22"],
5555
[
56-
toHex(toBytes(parseCallType(type), { size: 1 })),
56+
toHex(toBytes(getCallType(type), { size: 1 })),
5757
toHex(toBytes(revertOnError ? "0x01" : "0x00", { size: 1 })),
5858
toHex(toBytes("0x0", { size: 4 })),
5959
toHex(toBytes(selector ?? "0x", { size: 4 })),

packages/permissionless/utils/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ import {
1414
type EncodeInstallModuleParameters,
1515
encodeInstallModule
1616
} from "./encodeInstallModule.js"
17+
import {
18+
type EncodeUninstallModuleParameters,
19+
encodeUninstallModule
20+
} from "./encodeUninstallModule.js"
1721
import { getPackedUserOperation } from "./getPackedUserOperation.js"
1822

1923
import {
@@ -48,6 +52,8 @@ export {
4852
decodeNonce,
4953
type EncodeInstallModuleParameters,
5054
encodeInstallModule,
55+
type EncodeUninstallModuleParameters,
56+
encodeUninstallModule,
5157
type EncodeCallDataParams,
5258
encode7579Calls,
5359
decode7579Calls,

packages/wagmi-demo/src/PasskeysDemo.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ function KernelSmartAccountDemo() {
103103
client: publicClient,
104104
version: "0.3.1",
105105
owners: [toWebAuthnAccount({ credential })],
106+
index: 17n,
106107
entryPoint: {
107108
address: entryPoint07Address,
108109
version: "0.7"

0 commit comments

Comments
 (0)