@zerodev/sdk 4.0.17 → 4.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -0
- package/dist/cjs/kernel-zerodev/abis/RecoveryActionAbi.d.ts +15 -0
- package/dist/cjs/kernel-zerodev/abis/RecoveryActionAbi.js +24 -0
- package/dist/cjs/kernel-zerodev/abis/RecoveryActionAbi.js.map +1 -0
- package/dist/cjs/kernel-zerodev/abis/WeightedValidatorAbi.d.ts +296 -0
- package/dist/cjs/kernel-zerodev/abis/WeightedValidatorAbi.js +389 -0
- package/dist/cjs/kernel-zerodev/abis/WeightedValidatorAbi.js.map +1 -0
- package/dist/cjs/kernel-zerodev/account.d.ts +2 -0
- package/dist/cjs/kernel-zerodev/account.js +30 -0
- package/dist/cjs/kernel-zerodev/account.js.map +1 -1
- package/dist/cjs/kernel-zerodev/api/index.d.ts +2 -0
- package/dist/cjs/kernel-zerodev/api/index.js +28 -1
- package/dist/cjs/kernel-zerodev/api/index.js.map +1 -1
- package/dist/cjs/kernel-zerodev/constants.d.ts +2 -0
- package/dist/cjs/kernel-zerodev/constants.js +3 -1
- package/dist/cjs/kernel-zerodev/constants.js.map +1 -1
- package/dist/cjs/kernel-zerodev/ethers-provider/account-signer.d.ts +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/utils.js +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/utils.js.map +1 -1
- package/dist/cjs/kernel-zerodev/provider.js.map +1 -1
- package/dist/cjs/kernel-zerodev/validator/base.d.ts +2 -0
- package/dist/cjs/kernel-zerodev/validator/base.js +9 -0
- package/dist/cjs/kernel-zerodev/validator/base.js.map +1 -1
- package/dist/cjs/kernel-zerodev/validator/index.d.ts +2 -1
- package/dist/cjs/kernel-zerodev/validator/index.js +4 -1
- package/dist/cjs/kernel-zerodev/validator/index.js.map +1 -1
- package/dist/cjs/kernel-zerodev/validator/recovery-validator.d.ts +52 -0
- package/dist/cjs/kernel-zerodev/validator/recovery-validator.js +302 -0
- package/dist/cjs/kernel-zerodev/validator/recovery-validator.js.map +1 -0
- package/dist/cjs/kernel-zerodev/validator/session-key-validator.js.map +1 -1
- package/dist/cjs/kernel-zerodev/validator/types.d.ts +7 -1
- package/dist/cjs/kernel-zerodev/validator/types.js.map +1 -1
- package/dist/cjs/kernel-zerodev/validator-provider/base.d.ts +2 -2
- package/dist/cjs/kernel-zerodev/validator-provider/base.js +7 -3
- package/dist/cjs/kernel-zerodev/validator-provider/base.js.map +1 -1
- package/dist/cjs/kernel-zerodev/validator-provider/ecdsa-provider.d.ts +1 -1
- package/dist/cjs/kernel-zerodev/validator-provider/erc165-session-key-provider.d.ts +1 -1
- package/dist/cjs/kernel-zerodev/validator-provider/index.d.ts +2 -1
- package/dist/cjs/kernel-zerodev/validator-provider/index.js +4 -1
- package/dist/cjs/kernel-zerodev/validator-provider/index.js.map +1 -1
- package/dist/cjs/kernel-zerodev/validator-provider/kill-switch-provider.d.ts +1 -1
- package/dist/cjs/kernel-zerodev/validator-provider/recovery-provider.d.ts +26 -0
- package/dist/cjs/kernel-zerodev/validator-provider/recovery-provider.js +278 -0
- package/dist/cjs/kernel-zerodev/validator-provider/recovery-provider.js.map +1 -0
- package/dist/cjs/kernel-zerodev/validator-provider/session-key-provider.d.ts +1 -1
- package/dist/cjs/kernel-zerodev/validator-provider/types.d.ts +3 -0
- package/dist/cjs/kernel-zerodev/validator-provider/types.js.map +1 -1
- package/dist/esm/kernel-zerodev/abis/RecoveryActionAbi.d.ts +15 -0
- package/dist/esm/kernel-zerodev/abis/RecoveryActionAbi.js +21 -0
- package/dist/esm/kernel-zerodev/abis/RecoveryActionAbi.js.map +1 -0
- package/dist/esm/kernel-zerodev/abis/WeightedValidatorAbi.d.ts +296 -0
- package/dist/esm/kernel-zerodev/abis/WeightedValidatorAbi.js +386 -0
- package/dist/esm/kernel-zerodev/abis/WeightedValidatorAbi.js.map +1 -0
- package/dist/esm/kernel-zerodev/account.d.ts +2 -0
- package/dist/esm/kernel-zerodev/account.js +30 -0
- package/dist/esm/kernel-zerodev/account.js.map +1 -1
- package/dist/esm/kernel-zerodev/api/index.d.ts +2 -0
- package/dist/esm/kernel-zerodev/api/index.js +25 -0
- package/dist/esm/kernel-zerodev/api/index.js.map +1 -1
- package/dist/esm/kernel-zerodev/constants.d.ts +2 -0
- package/dist/esm/kernel-zerodev/constants.js +2 -0
- package/dist/esm/kernel-zerodev/constants.js.map +1 -1
- package/dist/esm/kernel-zerodev/ethers-provider/account-signer.d.ts +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/utils.js +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/utils.js.map +1 -1
- package/dist/esm/kernel-zerodev/provider.js.map +1 -1
- package/dist/esm/kernel-zerodev/validator/base.d.ts +2 -0
- package/dist/esm/kernel-zerodev/validator/base.js +9 -0
- package/dist/esm/kernel-zerodev/validator/base.js.map +1 -1
- package/dist/esm/kernel-zerodev/validator/index.d.ts +2 -1
- package/dist/esm/kernel-zerodev/validator/index.js +3 -1
- package/dist/esm/kernel-zerodev/validator/index.js.map +1 -1
- package/dist/esm/kernel-zerodev/validator/recovery-validator.d.ts +52 -0
- package/dist/esm/kernel-zerodev/validator/recovery-validator.js +296 -0
- package/dist/esm/kernel-zerodev/validator/recovery-validator.js.map +1 -0
- package/dist/esm/kernel-zerodev/validator/session-key-validator.js.map +1 -1
- package/dist/esm/kernel-zerodev/validator/types.d.ts +7 -1
- package/dist/esm/kernel-zerodev/validator/types.js.map +1 -1
- package/dist/esm/kernel-zerodev/validator-provider/base.d.ts +2 -2
- package/dist/esm/kernel-zerodev/validator-provider/base.js +7 -3
- package/dist/esm/kernel-zerodev/validator-provider/base.js.map +1 -1
- package/dist/esm/kernel-zerodev/validator-provider/ecdsa-provider.d.ts +1 -1
- package/dist/esm/kernel-zerodev/validator-provider/erc165-session-key-provider.d.ts +1 -1
- package/dist/esm/kernel-zerodev/validator-provider/index.d.ts +2 -1
- package/dist/esm/kernel-zerodev/validator-provider/index.js +3 -1
- package/dist/esm/kernel-zerodev/validator-provider/index.js.map +1 -1
- package/dist/esm/kernel-zerodev/validator-provider/kill-switch-provider.d.ts +1 -1
- package/dist/esm/kernel-zerodev/validator-provider/recovery-provider.d.ts +26 -0
- package/dist/esm/kernel-zerodev/validator-provider/recovery-provider.js +271 -0
- package/dist/esm/kernel-zerodev/validator-provider/recovery-provider.js.map +1 -0
- package/dist/esm/kernel-zerodev/validator-provider/session-key-provider.d.ts +1 -1
- package/dist/esm/kernel-zerodev/validator-provider/types.d.ts +3 -0
- package/dist/esm/kernel-zerodev/validator-provider/types.js.map +1 -1
- package/dist/types/kernel-zerodev/abis/RecoveryActionAbi.d.ts +16 -0
- package/dist/types/kernel-zerodev/abis/RecoveryActionAbi.d.ts.map +1 -0
- package/dist/types/kernel-zerodev/abis/WeightedValidatorAbi.d.ts +297 -0
- package/dist/types/kernel-zerodev/abis/WeightedValidatorAbi.d.ts.map +1 -0
- package/dist/types/kernel-zerodev/account.d.ts +2 -0
- package/dist/types/kernel-zerodev/account.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/api/index.d.ts +2 -0
- package/dist/types/kernel-zerodev/api/index.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/constants.d.ts +2 -0
- package/dist/types/kernel-zerodev/constants.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/ethers-provider/account-signer.d.ts +1 -1
- package/dist/types/kernel-zerodev/ethers-provider/account-signer.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator/base.d.ts +2 -0
- package/dist/types/kernel-zerodev/validator/base.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator/index.d.ts +2 -1
- package/dist/types/kernel-zerodev/validator/index.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator/recovery-validator.d.ts +53 -0
- package/dist/types/kernel-zerodev/validator/recovery-validator.d.ts.map +1 -0
- package/dist/types/kernel-zerodev/validator/session-key-validator.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator/types.d.ts +7 -1
- package/dist/types/kernel-zerodev/validator/types.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator-provider/base.d.ts +2 -2
- package/dist/types/kernel-zerodev/validator-provider/base.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator-provider/ecdsa-provider.d.ts +1 -1
- package/dist/types/kernel-zerodev/validator-provider/ecdsa-provider.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator-provider/erc165-session-key-provider.d.ts +1 -1
- package/dist/types/kernel-zerodev/validator-provider/erc165-session-key-provider.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator-provider/index.d.ts +2 -1
- package/dist/types/kernel-zerodev/validator-provider/index.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator-provider/kill-switch-provider.d.ts +1 -1
- package/dist/types/kernel-zerodev/validator-provider/kill-switch-provider.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator-provider/recovery-provider.d.ts +27 -0
- package/dist/types/kernel-zerodev/validator-provider/recovery-provider.d.ts.map +1 -0
- package/dist/types/kernel-zerodev/validator-provider/session-key-provider.d.ts +1 -1
- package/dist/types/kernel-zerodev/validator-provider/session-key-provider.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/validator-provider/types.d.ts +3 -0
- package/dist/types/kernel-zerodev/validator-provider/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/kernel-zerodev/abis/RecoveryActionAbi.ts +20 -0
- package/src/kernel-zerodev/abis/WeightedValidatorAbi.ts +385 -0
- package/src/kernel-zerodev/account.ts +33 -0
- package/src/kernel-zerodev/api/index.ts +32 -0
- package/src/kernel-zerodev/constants.ts +3 -0
- package/src/kernel-zerodev/owner/passkey/utils.ts +2 -2
- package/src/kernel-zerodev/provider.ts +1 -1
- package/src/kernel-zerodev/validator/base.ts +11 -0
- package/src/kernel-zerodev/validator/index.ts +3 -0
- package/src/kernel-zerodev/validator/recovery-validator.ts +370 -0
- package/src/kernel-zerodev/validator/session-key-validator.ts +23 -25
- package/src/kernel-zerodev/validator/types.ts +10 -1
- package/src/kernel-zerodev/validator-provider/base.ts +7 -3
- package/src/kernel-zerodev/validator-provider/index.ts +3 -0
- package/src/kernel-zerodev/validator-provider/recovery-provider.ts +350 -0
- package/src/kernel-zerodev/validator-provider/types.ts +6 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getChain,
|
|
3
|
+
type Address,
|
|
4
|
+
type Hex,
|
|
5
|
+
type SmartAccountSigner,
|
|
6
|
+
type UserOperationRequest,
|
|
7
|
+
type SignTypedDataParams,
|
|
8
|
+
} from "@alchemy/aa-core";
|
|
9
|
+
import {
|
|
10
|
+
KernelBaseValidator,
|
|
11
|
+
ValidatorMode,
|
|
12
|
+
type KernelBaseValidatorParams,
|
|
13
|
+
} from "./base.js";
|
|
14
|
+
import {
|
|
15
|
+
concatHex,
|
|
16
|
+
encodeAbiParameters,
|
|
17
|
+
encodeFunctionData,
|
|
18
|
+
getContract,
|
|
19
|
+
parseAbiParameters,
|
|
20
|
+
type LocalAccount,
|
|
21
|
+
createWalletClient,
|
|
22
|
+
type WalletClient,
|
|
23
|
+
http,
|
|
24
|
+
custom,
|
|
25
|
+
type Transport,
|
|
26
|
+
type Chain,
|
|
27
|
+
type Account,
|
|
28
|
+
publicActions,
|
|
29
|
+
getFunctionSelector,
|
|
30
|
+
} from "viem";
|
|
31
|
+
import { WeightedValidatorAbi } from "../abis/WeightedValidatorAbi.js";
|
|
32
|
+
import { getChainId } from "../api/index.js";
|
|
33
|
+
import {
|
|
34
|
+
CHAIN_ID_TO_NODE,
|
|
35
|
+
DUMMY_ECDSA_SIG,
|
|
36
|
+
RECOVERY_ACTION,
|
|
37
|
+
} from "../constants.js";
|
|
38
|
+
import { KernelAccountAbi } from "../abis/KernelAccountAbi.js";
|
|
39
|
+
import { fixSignedData } from "../utils.js";
|
|
40
|
+
import type { EthereumProvider } from "./types.js";
|
|
41
|
+
import { polygonMumbai } from "viem/chains";
|
|
42
|
+
import { RecoveryActionAbi } from "../abis/RecoveryActionAbi.js";
|
|
43
|
+
|
|
44
|
+
interface WeightedGuardians {
|
|
45
|
+
[guardian: Address]: number;
|
|
46
|
+
}
|
|
47
|
+
export interface RecoveryValidatorParams extends KernelBaseValidatorParams {
|
|
48
|
+
guardians?: WeightedGuardians;
|
|
49
|
+
threshold?: number;
|
|
50
|
+
delaySeconds?: number;
|
|
51
|
+
accountSigner?: SmartAccountSigner;
|
|
52
|
+
guardianAccountOrProvider?: LocalAccount<string> | EthereumProvider;
|
|
53
|
+
walletClient?: WalletClient<Transport, Chain>;
|
|
54
|
+
signatures?: Hex;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type RecoveryConfig = Required<
|
|
58
|
+
Pick<RecoveryValidatorParams, "guardians" | "threshold" | "delaySeconds">
|
|
59
|
+
>;
|
|
60
|
+
|
|
61
|
+
export function isLocalAccount(account: any): account is LocalAccount<string> {
|
|
62
|
+
return account && account.signTransaction !== undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function isEthereumProvider(
|
|
66
|
+
provider: any
|
|
67
|
+
): provider is EthereumProvider {
|
|
68
|
+
return provider && provider.request !== undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
type WalletClientAccountType<T> = T extends LocalAccount<string>
|
|
72
|
+
? Account
|
|
73
|
+
: T extends EthereumProvider
|
|
74
|
+
? undefined
|
|
75
|
+
: never;
|
|
76
|
+
|
|
77
|
+
export const recoverySelector = getFunctionSelector(
|
|
78
|
+
"doRecovery(address, bytes)"
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
export class RecoveryValidator extends KernelBaseValidator {
|
|
82
|
+
protected guardians?: WeightedGuardians;
|
|
83
|
+
protected threshold?: number;
|
|
84
|
+
protected delaySeconds: number;
|
|
85
|
+
protected accountSigner?: SmartAccountSigner;
|
|
86
|
+
protected guardianAccountOrProvider?: LocalAccount<string> | EthereumProvider;
|
|
87
|
+
protected signatures?: Hex;
|
|
88
|
+
walletClient?: WalletClient<
|
|
89
|
+
Transport,
|
|
90
|
+
Chain,
|
|
91
|
+
WalletClientAccountType<typeof this.guardianAccountOrProvider>
|
|
92
|
+
>;
|
|
93
|
+
|
|
94
|
+
constructor(params: RecoveryValidatorParams) {
|
|
95
|
+
super(params);
|
|
96
|
+
this.guardians = params.guardians;
|
|
97
|
+
this.threshold = params.threshold;
|
|
98
|
+
this.delaySeconds = params.delaySeconds ?? 0;
|
|
99
|
+
this.accountSigner = params.accountSigner;
|
|
100
|
+
this.mode = params.mode ?? ValidatorMode.plugin;
|
|
101
|
+
this.guardianAccountOrProvider = params.guardianAccountOrProvider;
|
|
102
|
+
this.signatures = params.signatures;
|
|
103
|
+
this.validAfter = params.validAfter ?? 0;
|
|
104
|
+
this.validUntil = params.validUntil ?? 0;
|
|
105
|
+
this.executor = params.executor ?? RECOVERY_ACTION;
|
|
106
|
+
this.selector = params.selector ?? recoverySelector;
|
|
107
|
+
if (isLocalAccount(params.guardianAccountOrProvider)) {
|
|
108
|
+
this.walletClient = createWalletClient({
|
|
109
|
+
account: params.guardianAccountOrProvider,
|
|
110
|
+
chain: this.chain ?? polygonMumbai,
|
|
111
|
+
transport: http(CHAIN_ID_TO_NODE[this.chain?.id ?? polygonMumbai.id]),
|
|
112
|
+
}).extend(publicActions);
|
|
113
|
+
} else if (isEthereumProvider(params.guardianAccountOrProvider)) {
|
|
114
|
+
this.walletClient = createWalletClient({
|
|
115
|
+
chain: this.chain ?? polygonMumbai,
|
|
116
|
+
transport: custom(params.guardianAccountOrProvider),
|
|
117
|
+
}).extend(publicActions);
|
|
118
|
+
} else if (params.walletClient) {
|
|
119
|
+
this.walletClient = params.walletClient.extend(publicActions);
|
|
120
|
+
} else if (params.guardianAccountOrProvider) {
|
|
121
|
+
throw Error("Incorrect guardianAccountOrProvider type");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public static async init(
|
|
126
|
+
params: RecoveryValidatorParams
|
|
127
|
+
): Promise<RecoveryValidator> {
|
|
128
|
+
const chainId = await getChainId(params.projectId);
|
|
129
|
+
if (!chainId) {
|
|
130
|
+
throw new Error("ChainId not found");
|
|
131
|
+
}
|
|
132
|
+
const chain = getChain(chainId);
|
|
133
|
+
const instance = new RecoveryValidator({ ...params, chain });
|
|
134
|
+
return instance;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
getNonceKey(): bigint {
|
|
138
|
+
return BigInt(this.validatorAddress);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
setRecoverySignatures(signatures: Hex) {
|
|
142
|
+
this.signatures = signatures;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
getRecoverySignatures(): Hex | undefined {
|
|
146
|
+
return this.signatures;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
getRecoveryConfig(): RecoveryConfig {
|
|
150
|
+
if (
|
|
151
|
+
this.guardians === undefined ||
|
|
152
|
+
!this.threshold ||
|
|
153
|
+
Object.values(this.guardians).reduce((a, c) => a + c, 0) !==
|
|
154
|
+
this.threshold
|
|
155
|
+
) {
|
|
156
|
+
throw Error("Recovery config unintialised");
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
guardians: this.guardians,
|
|
160
|
+
threshold: this.threshold,
|
|
161
|
+
delaySeconds: this.delaySeconds,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async signer(): Promise<SmartAccountSigner> {
|
|
166
|
+
if (!this.accountSigner) {
|
|
167
|
+
throw Error("AccountSigner not set");
|
|
168
|
+
}
|
|
169
|
+
return await Promise.resolve(this.accountSigner);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async getEnableData(): Promise<Hex> {
|
|
173
|
+
if (
|
|
174
|
+
this.guardians === undefined ||
|
|
175
|
+
!this.threshold ||
|
|
176
|
+
Object.values(this.guardians).reduce((a, c) => a + c, 0) !==
|
|
177
|
+
this.threshold
|
|
178
|
+
) {
|
|
179
|
+
throw Error("Recovery config unintialised");
|
|
180
|
+
}
|
|
181
|
+
return encodeAbiParameters(
|
|
182
|
+
parseAbiParameters(
|
|
183
|
+
"address[] guardians, uint24[] weights, uint24 threshold, uint48 delay"
|
|
184
|
+
),
|
|
185
|
+
[
|
|
186
|
+
Object.keys(this.guardians) as Address[],
|
|
187
|
+
Object.values(this.guardians),
|
|
188
|
+
this.threshold,
|
|
189
|
+
this.delaySeconds,
|
|
190
|
+
]
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
encodeEnable(recoveryData: Hex): Hex {
|
|
195
|
+
return encodeFunctionData({
|
|
196
|
+
abi: WeightedValidatorAbi,
|
|
197
|
+
functionName: "enable",
|
|
198
|
+
args: [recoveryData],
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
encodeDisable(disableData: Hex = "0x"): Hex {
|
|
203
|
+
return encodeFunctionData({
|
|
204
|
+
abi: WeightedValidatorAbi,
|
|
205
|
+
functionName: "disable",
|
|
206
|
+
args: [disableData],
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
encodeApprove(callDataAndNonceHash: Hex, kernelAccountAddress: Address): Hex {
|
|
211
|
+
return encodeFunctionData({
|
|
212
|
+
abi: WeightedValidatorAbi,
|
|
213
|
+
functionName: "approve",
|
|
214
|
+
args: [callDataAndNonceHash, kernelAccountAddress],
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
encodeApproveWithSig(
|
|
219
|
+
callDataAndNonceHash: Hex,
|
|
220
|
+
kernelAccountAddress: Address,
|
|
221
|
+
sigs: Hex
|
|
222
|
+
): Hex {
|
|
223
|
+
return encodeFunctionData({
|
|
224
|
+
abi: WeightedValidatorAbi,
|
|
225
|
+
functionName: "approveWithSig",
|
|
226
|
+
args: [callDataAndNonceHash, kernelAccountAddress, sigs],
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
encodeVeto(callDataAndNonceHash: Hex): Hex {
|
|
231
|
+
return encodeFunctionData({
|
|
232
|
+
abi: WeightedValidatorAbi,
|
|
233
|
+
functionName: "veto",
|
|
234
|
+
args: [callDataAndNonceHash],
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
encodeRecoveryAction(enableData: Hex, defaultValidatorAddress: Address): Hex {
|
|
239
|
+
return encodeFunctionData({
|
|
240
|
+
abi: RecoveryActionAbi,
|
|
241
|
+
functionName: "doRecovery",
|
|
242
|
+
args: [defaultValidatorAddress, enableData],
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async isPluginEnabled(
|
|
247
|
+
kernelAccountAddress: Address,
|
|
248
|
+
selector: Hex
|
|
249
|
+
): Promise<boolean> {
|
|
250
|
+
if (
|
|
251
|
+
this.guardians === undefined ||
|
|
252
|
+
!this.threshold ||
|
|
253
|
+
Object.values(this.guardians).reduce((a, c) => a + c, 0) !==
|
|
254
|
+
this.threshold
|
|
255
|
+
) {
|
|
256
|
+
throw Error("Recovery config unintialised");
|
|
257
|
+
}
|
|
258
|
+
if (!this.publicClient) {
|
|
259
|
+
throw new Error("Validator uninitialized: PublicClient missing");
|
|
260
|
+
}
|
|
261
|
+
try {
|
|
262
|
+
const kernel = getContract({
|
|
263
|
+
abi: KernelAccountAbi,
|
|
264
|
+
address: kernelAccountAddress,
|
|
265
|
+
publicClient: this.publicClient,
|
|
266
|
+
});
|
|
267
|
+
const execDetail = await kernel.read.getExecution([selector]);
|
|
268
|
+
const enableData = await this.publicClient.readContract({
|
|
269
|
+
abi: WeightedValidatorAbi,
|
|
270
|
+
address: this.validatorAddress,
|
|
271
|
+
functionName: "weightedStorage",
|
|
272
|
+
args: [kernelAccountAddress],
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
return (
|
|
276
|
+
execDetail.validator.toLowerCase() ===
|
|
277
|
+
this.validatorAddress.toLowerCase() &&
|
|
278
|
+
enableData[0] ===
|
|
279
|
+
Object.values(this.guardians).reduce((a, c) => a + c, 0) &&
|
|
280
|
+
enableData[1] === this.threshold &&
|
|
281
|
+
enableData[2] === this.delaySeconds &&
|
|
282
|
+
this.isGuardiansEnabled(kernelAccountAddress)
|
|
283
|
+
);
|
|
284
|
+
} catch (error) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async isGuardiansEnabled(kernelAccountAddress: Address): Promise<boolean> {
|
|
290
|
+
if (
|
|
291
|
+
this.guardians === undefined ||
|
|
292
|
+
!this.threshold ||
|
|
293
|
+
Object.values(this.guardians).reduce((a, c) => a + c, 0) !==
|
|
294
|
+
this.threshold
|
|
295
|
+
) {
|
|
296
|
+
throw Error("Recovery config unintialised");
|
|
297
|
+
}
|
|
298
|
+
const weightedValidator = getContract({
|
|
299
|
+
abi: WeightedValidatorAbi,
|
|
300
|
+
address: this.validatorAddress,
|
|
301
|
+
publicClient: this.publicClient,
|
|
302
|
+
});
|
|
303
|
+
for (const [addr, weight] of Object.entries(this.guardians)) {
|
|
304
|
+
const result = await weightedValidator.read.guardian([
|
|
305
|
+
addr as Address,
|
|
306
|
+
kernelAccountAddress,
|
|
307
|
+
]);
|
|
308
|
+
if (result[0] !== weight) {
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async getDummyUserOpSignature(): Promise<Hex> {
|
|
316
|
+
let dummySignature: Hex = "0x";
|
|
317
|
+
if (this.signatures) {
|
|
318
|
+
const totalSigs = this.signatures.substring(2).length / 130;
|
|
319
|
+
for (let i = 0; i < totalSigs; i++) {
|
|
320
|
+
dummySignature = concatHex([dummySignature, DUMMY_ECDSA_SIG]);
|
|
321
|
+
}
|
|
322
|
+
// Hack - Fix this to not send original signatures
|
|
323
|
+
return this.signatures;
|
|
324
|
+
}
|
|
325
|
+
return DUMMY_ECDSA_SIG;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async signMessage(message: string | Uint8Array): Promise<Hex> {
|
|
329
|
+
if (!this.accountSigner) {
|
|
330
|
+
throw Error("AccountSigner not set");
|
|
331
|
+
}
|
|
332
|
+
return await this.accountSigner.signMessage(message);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
async signTypedData(params: SignTypedDataParams): Promise<Hex> {
|
|
336
|
+
if (!this.accountSigner) {
|
|
337
|
+
throw Error("AccountSigner not set");
|
|
338
|
+
}
|
|
339
|
+
return fixSignedData(await this.accountSigner.signTypedData(params));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async signRecoveryHash(recoveryHash: Hex): Promise<Hex> {
|
|
343
|
+
if (!this.chain) {
|
|
344
|
+
throw new Error("Validator uninitialized");
|
|
345
|
+
}
|
|
346
|
+
const signer = await this.signer();
|
|
347
|
+
return await signer.signTypedData({
|
|
348
|
+
domain: {
|
|
349
|
+
name: "WeightedECDSAValidator",
|
|
350
|
+
version: "1",
|
|
351
|
+
chainId: this.chain.id,
|
|
352
|
+
verifyingContract: this.validatorAddress,
|
|
353
|
+
},
|
|
354
|
+
types: {
|
|
355
|
+
Approve: [{ name: "callDataAndNonceHash", type: "bytes32" }],
|
|
356
|
+
},
|
|
357
|
+
message: {
|
|
358
|
+
callDataAndNonceHash: recoveryHash,
|
|
359
|
+
},
|
|
360
|
+
primaryType: "Approve",
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async signUserOp(_userOp: UserOperationRequest): Promise<Hex> {
|
|
365
|
+
if (!this.chain) {
|
|
366
|
+
throw new Error("Validator uninitialized");
|
|
367
|
+
}
|
|
368
|
+
return this.signatures ?? DUMMY_ECDSA_SIG;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
@@ -40,7 +40,7 @@ import { fixSignedData } from "../utils.js";
|
|
|
40
40
|
// Using this trick: https://github.com/GoogleChromeLabs/jsbi/issues/30#issuecomment-1006086291
|
|
41
41
|
(BigInt.prototype as any).toJSON = function () {
|
|
42
42
|
return this.toString();
|
|
43
|
-
}
|
|
43
|
+
};
|
|
44
44
|
|
|
45
45
|
export interface SessionKeyValidatorParams extends KernelBaseValidatorParams {
|
|
46
46
|
sessionKey: SmartAccountSigner;
|
|
@@ -170,17 +170,15 @@ export class SessionKeyValidator extends KernelBaseValidator {
|
|
|
170
170
|
|
|
171
171
|
if (!valueLimitPermissions.length) return undefined;
|
|
172
172
|
|
|
173
|
-
const sortedPermissions = valueLimitPermissions.sort(
|
|
174
|
-
(a
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return 0
|
|
181
|
-
}
|
|
173
|
+
const sortedPermissions = valueLimitPermissions.sort((a, b) => {
|
|
174
|
+
if (b.valueLimit > a.valueLimit) {
|
|
175
|
+
return 1;
|
|
176
|
+
} else if (b.valueLimit < a.valueLimit) {
|
|
177
|
+
return -1;
|
|
178
|
+
} else {
|
|
179
|
+
return 0;
|
|
182
180
|
}
|
|
183
|
-
);
|
|
181
|
+
});
|
|
184
182
|
|
|
185
183
|
return this.findPermissionByRule(sortedPermissions, args[2]);
|
|
186
184
|
} catch (error) {
|
|
@@ -266,12 +264,12 @@ export class SessionKeyValidator extends KernelBaseValidator {
|
|
|
266
264
|
|
|
267
265
|
return permissionPacked && permissionPacked.length !== 0
|
|
268
266
|
? new MerkleTree(permissionPacked, keccak256, {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
267
|
+
sortPairs: true,
|
|
268
|
+
hashLeaves: true,
|
|
269
|
+
})
|
|
272
270
|
: new MerkleTree([pad("0x00", { size: 32 })], keccak256, {
|
|
273
|
-
|
|
274
|
-
|
|
271
|
+
hashLeaves: false,
|
|
272
|
+
});
|
|
275
273
|
}
|
|
276
274
|
|
|
277
275
|
encodePermissionData(permission: Permission, merkleProof?: string[]): Hex {
|
|
@@ -394,7 +392,7 @@ export class SessionKeyValidator extends KernelBaseValidator {
|
|
|
394
392
|
]);
|
|
395
393
|
return (
|
|
396
394
|
execDetail.validator.toLowerCase() ===
|
|
397
|
-
|
|
395
|
+
this.validatorAddress.toLowerCase() &&
|
|
398
396
|
enableData[4] &&
|
|
399
397
|
enableDataHex.toLowerCase() === (await this.getEnableData()).toLowerCase()
|
|
400
398
|
);
|
|
@@ -409,8 +407,8 @@ export class SessionKeyValidator extends KernelBaseValidator {
|
|
|
409
407
|
}
|
|
410
408
|
const encodedPermissionData =
|
|
411
409
|
this.sessionKeyData.permissions &&
|
|
412
|
-
|
|
413
|
-
|
|
410
|
+
this.sessionKeyData.permissions.length !== 0 &&
|
|
411
|
+
matchingPermission
|
|
414
412
|
? this.encodePermissionData(matchingPermission)
|
|
415
413
|
: "0x";
|
|
416
414
|
const merkleProof = this.merkleTree.getHexProof(
|
|
@@ -418,8 +416,8 @@ export class SessionKeyValidator extends KernelBaseValidator {
|
|
|
418
416
|
);
|
|
419
417
|
const encodedData =
|
|
420
418
|
this.sessionKeyData.permissions &&
|
|
421
|
-
|
|
422
|
-
|
|
419
|
+
this.sessionKeyData.permissions.length !== 0 &&
|
|
420
|
+
matchingPermission
|
|
423
421
|
? this.encodePermissionData(matchingPermission, merkleProof)
|
|
424
422
|
: "0x";
|
|
425
423
|
return concatHex([
|
|
@@ -475,8 +473,8 @@ export class SessionKeyValidator extends KernelBaseValidator {
|
|
|
475
473
|
}
|
|
476
474
|
const encodedPermissionData =
|
|
477
475
|
this.sessionKeyData.permissions &&
|
|
478
|
-
|
|
479
|
-
|
|
476
|
+
this.sessionKeyData.permissions.length !== 0 &&
|
|
477
|
+
matchingPermission
|
|
480
478
|
? this.encodePermissionData(matchingPermission)
|
|
481
479
|
: "0x";
|
|
482
480
|
const merkleProof = this.merkleTree.getHexProof(
|
|
@@ -484,8 +482,8 @@ export class SessionKeyValidator extends KernelBaseValidator {
|
|
|
484
482
|
);
|
|
485
483
|
const encodedData =
|
|
486
484
|
this.sessionKeyData.permissions &&
|
|
487
|
-
|
|
488
|
-
|
|
485
|
+
this.sessionKeyData.permissions.length !== 0 &&
|
|
486
|
+
matchingPermission
|
|
489
487
|
? this.encodePermissionData(matchingPermission, merkleProof)
|
|
490
488
|
: "0x";
|
|
491
489
|
const signature = concat([
|
|
@@ -11,6 +11,10 @@ import type {
|
|
|
11
11
|
KillSwitchValidator,
|
|
12
12
|
KillSwitchValidatorParams,
|
|
13
13
|
} from "./kill-switch-validator.js";
|
|
14
|
+
import type {
|
|
15
|
+
RecoveryValidator,
|
|
16
|
+
RecoveryValidatorParams,
|
|
17
|
+
} from "./recovery-validator.js";
|
|
14
18
|
import type {
|
|
15
19
|
SessionKeyValidator,
|
|
16
20
|
SessionKeyValidatorParams,
|
|
@@ -24,13 +28,15 @@ export type SupportedValidators =
|
|
|
24
28
|
| "ECDSA"
|
|
25
29
|
| "KILL_SWITCH"
|
|
26
30
|
| "ERC165_SESSION_KEY"
|
|
27
|
-
| "SESSION_KEY"
|
|
31
|
+
| "SESSION_KEY"
|
|
32
|
+
| "RECOVERY";
|
|
28
33
|
|
|
29
34
|
export type ValidatorTypeMap = {
|
|
30
35
|
ECDSA: ECDSAValidator;
|
|
31
36
|
KILL_SWITCH: KillSwitchValidator;
|
|
32
37
|
ERC165_SESSION_KEY: ERC165SessionKeyValidator;
|
|
33
38
|
SESSION_KEY: SessionKeyValidator;
|
|
39
|
+
RECOVERY: RecoveryValidator;
|
|
34
40
|
};
|
|
35
41
|
|
|
36
42
|
export type ValidatorParamsMap = {
|
|
@@ -38,6 +44,7 @@ export type ValidatorParamsMap = {
|
|
|
38
44
|
KILL_SWITCH: KillSwitchValidatorParams;
|
|
39
45
|
ERC165_SESSION_KEY: ERC165SessionKeyValidatorParams;
|
|
40
46
|
SESSION_KEY: SessionKeyValidatorParams;
|
|
47
|
+
RECOVERY: RecoveryValidatorParams;
|
|
41
48
|
};
|
|
42
49
|
|
|
43
50
|
export type ValidatorMap = {
|
|
@@ -46,4 +53,6 @@ export type ValidatorMap = {
|
|
|
46
53
|
) => ValidatorTypeMap[V];
|
|
47
54
|
};
|
|
48
55
|
|
|
56
|
+
export type EthereumProvider = { request(...args: any): Promise<any> };
|
|
57
|
+
|
|
49
58
|
export type { ParamRules, Permission, SessionKeyData, SessionKeyParams };
|
|
@@ -74,6 +74,7 @@ export abstract class ValidatorProvider<
|
|
|
74
74
|
projectId: params.projectId,
|
|
75
75
|
bundlerProvider,
|
|
76
76
|
});
|
|
77
|
+
this.defaultProvider = params.defaultProvider;
|
|
77
78
|
this.connect(
|
|
78
79
|
() =>
|
|
79
80
|
new KernelSmartContractAccount({
|
|
@@ -117,7 +118,7 @@ export abstract class ValidatorProvider<
|
|
|
117
118
|
return await this.account.validator.encodeEnable(enableData);
|
|
118
119
|
};
|
|
119
120
|
|
|
120
|
-
getEncodedDisableData = async (disableData: Hex): Promise<Hex> => {
|
|
121
|
+
getEncodedDisableData = async (disableData: Hex = "0x"): Promise<Hex> => {
|
|
121
122
|
if (!isKernelAccount(this.account) || !this.account.validator) {
|
|
122
123
|
throw new Error(
|
|
123
124
|
"ValidatorProvider: account with validator is not set, did you call all connects first?"
|
|
@@ -143,7 +144,7 @@ export abstract class ValidatorProvider<
|
|
|
143
144
|
};
|
|
144
145
|
|
|
145
146
|
sendDisableUserOperation = async (
|
|
146
|
-
disableData: Hex
|
|
147
|
+
disableData: Hex = "0x"
|
|
147
148
|
): Promise<SendUserOperationResult> => {
|
|
148
149
|
const encodedDisableData = await this.getEncodedDisableData(disableData);
|
|
149
150
|
if (!isKernelAccount(this.account) || !this.account.validator) {
|
|
@@ -151,8 +152,11 @@ export abstract class ValidatorProvider<
|
|
|
151
152
|
"ValidatorProvider: account with validator is not set, did you call all connects first?"
|
|
152
153
|
);
|
|
153
154
|
}
|
|
155
|
+
if (!this.defaultProvider) {
|
|
156
|
+
throw Error("Default Validator provider unintialized");
|
|
157
|
+
}
|
|
154
158
|
|
|
155
|
-
return await this.sendUserOperation({
|
|
159
|
+
return await this.defaultProvider.sendUserOperation({
|
|
156
160
|
target: this.account.validator.validatorAddress,
|
|
157
161
|
data: encodedDisableData,
|
|
158
162
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ECDSAProvider } from "./ecdsa-provider.js";
|
|
2
2
|
import { ERC165SessionKeyProvider } from "./erc165-session-key-provider.js";
|
|
3
3
|
import { KillSwitchProvider } from "./kill-switch-provider.js";
|
|
4
|
+
import { RecoveryProvider } from "./recovery-provider.js";
|
|
4
5
|
import { SessionKeyProvider } from "./session-key-provider.js";
|
|
5
6
|
import type { ValidatorProviderMap } from "./types.js";
|
|
6
7
|
|
|
@@ -9,6 +10,7 @@ export const ValidatorProviders: ValidatorProviderMap = {
|
|
|
9
10
|
KILL_SWITCH: KillSwitchProvider,
|
|
10
11
|
ERC165_SESSION_KEY: ERC165SessionKeyProvider,
|
|
11
12
|
SESSION_KEY: SessionKeyProvider,
|
|
13
|
+
RECOVERY: RecoveryProvider,
|
|
12
14
|
};
|
|
13
15
|
|
|
14
16
|
export {
|
|
@@ -16,4 +18,5 @@ export {
|
|
|
16
18
|
KillSwitchProvider,
|
|
17
19
|
ERC165SessionKeyProvider,
|
|
18
20
|
SessionKeyProvider,
|
|
21
|
+
RecoveryProvider,
|
|
19
22
|
};
|