@deserialize/multi-vm-wallet 1.2.441 → 1.3.0
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/.claude/settings.local.json +12 -0
- package/SMART_WALLET_GUIDE.md +746 -0
- package/SMART_WALLET_IMPLEMENTATION.md +460 -0
- package/dist/IChainWallet.d.ts +3 -3
- package/dist/IChainWallet.js +5 -0
- package/dist/IChainWallet.js.map +1 -1
- package/dist/evm/SMART_WALLET_EXAMPLES.d.ts +20 -0
- package/dist/evm/SMART_WALLET_EXAMPLES.js +451 -0
- package/dist/evm/SMART_WALLET_EXAMPLES.js.map +1 -0
- package/dist/evm/aa-service/index.d.ts +16 -0
- package/dist/evm/aa-service/index.js +69 -0
- package/dist/evm/aa-service/index.js.map +1 -0
- package/dist/evm/aa-service/lib/account-adapter.d.ts +26 -0
- package/dist/evm/aa-service/lib/account-adapter.js +53 -0
- package/dist/evm/aa-service/lib/account-adapter.js.map +1 -0
- package/dist/evm/aa-service/lib/kernel-account.d.ts +91 -0
- package/dist/evm/aa-service/lib/kernel-account.js +251 -0
- package/dist/evm/aa-service/lib/kernel-account.js.map +1 -0
- package/dist/evm/aa-service/lib/kernel-modules.d.ts +240 -0
- package/dist/evm/aa-service/lib/kernel-modules.js +409 -0
- package/dist/evm/aa-service/lib/kernel-modules.js.map +1 -0
- package/dist/evm/aa-service/lib/session-keys.d.ts +170 -0
- package/dist/evm/aa-service/lib/session-keys.js +297 -0
- package/dist/evm/aa-service/lib/session-keys.js.map +1 -0
- package/dist/evm/aa-service/lib/type.d.ts +167 -0
- package/dist/evm/aa-service/lib/type.js +43 -0
- package/dist/evm/aa-service/lib/type.js.map +1 -0
- package/dist/evm/aa-service/services/account-abstraction.d.ts +614 -0
- package/dist/evm/aa-service/services/account-abstraction.js +754 -0
- package/dist/evm/aa-service/services/account-abstraction.js.map +1 -0
- package/dist/evm/aa-service/services/bundler.d.ts +29 -0
- package/dist/evm/aa-service/services/bundler.js +168 -0
- package/dist/evm/aa-service/services/bundler.js.map +1 -0
- package/dist/evm/evm.d.ts +67 -3
- package/dist/evm/evm.js +212 -7
- package/dist/evm/evm.js.map +1 -1
- package/dist/evm/index.d.ts +1 -0
- package/dist/evm/index.js +3 -0
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/smartWallet.d.ts +265 -0
- package/dist/evm/smartWallet.js +675 -0
- package/dist/evm/smartWallet.js.map +1 -0
- package/dist/evm/smartWallet.types.d.ts +10 -0
- package/dist/evm/smartWallet.types.js +16 -0
- package/dist/evm/smartWallet.types.js.map +1 -0
- package/dist/evm/transaction.utils.d.ts +10 -10
- package/dist/evm/transaction.utils.js +12 -8
- package/dist/evm/transaction.utils.js.map +1 -1
- package/dist/evm/transactionParsing.js +77 -1
- package/dist/evm/transactionParsing.js.map +1 -1
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +15 -0
- package/dist/helpers/index.js.map +1 -1
- package/dist/helpers/routeScan.d.ts +191 -0
- package/dist/helpers/routeScan.js +114 -0
- package/dist/helpers/routeScan.js.map +1 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/svm/svm.d.ts +4 -3
- package/dist/svm/svm.js +29 -18
- package/dist/svm/svm.js.map +1 -1
- package/dist/svm/transactionSender.js +2 -2
- package/dist/svm/transactionSender.js.map +1 -1
- package/dist/svm/utils.d.ts +4 -3
- package/dist/svm/utils.js +19 -6
- package/dist/svm/utils.js.map +1 -1
- package/dist/test.js +7 -0
- package/dist/test.js.map +1 -1
- package/dist/types.d.ts +19 -2
- package/dist/types.js.map +1 -1
- package/dist/vm.js +9 -7
- package/dist/vm.js.map +1 -1
- package/package.json +2 -2
- package/tsconfig.json +4 -3
- package/utils/IChainWallet.ts +3 -3
- package/utils/evm/SMART_WALLET_EXAMPLES.ts.bak +591 -0
- package/utils/evm/aa-service/index.ts +85 -0
- package/utils/evm/aa-service/lib/account-adapter.ts +60 -0
- package/utils/evm/aa-service/lib/kernel-account.ts +367 -0
- package/utils/evm/aa-service/lib/kernel-modules.ts +598 -0
- package/utils/evm/aa-service/lib/session-keys.ts +389 -0
- package/utils/evm/aa-service/lib/type.ts +236 -0
- package/utils/evm/aa-service/services/account-abstraction.ts +1015 -0
- package/utils/evm/aa-service/services/bundler.ts +217 -0
- package/utils/evm/evm.ts +268 -11
- package/utils/evm/index.ts +5 -1
- package/utils/evm/smartWallet.ts +797 -0
- package/utils/evm/smartWallet.types.ts +33 -0
- package/utils/evm/transaction.utils.ts +12 -10
- package/utils/evm/transactionParsing.ts +100 -14
- package/utils/helpers/index.ts +1 -0
- package/utils/helpers/routeScan.ts +397 -0
- package/utils/index.ts +0 -2
- package/utils/svm/svm.ts +50 -9
- package/utils/svm/utils.ts +52 -7
- package/utils/test.ts +7 -0
- package/utils/types.ts +24 -2
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EIP-7702 Session Keys Utilities
|
|
3
|
+
*
|
|
4
|
+
* Utilities for creating and managing session keys with ZeroDev's permission system.
|
|
5
|
+
* This uses the NEW EIP-7702 pattern, not the legacy smart account pattern.
|
|
6
|
+
*
|
|
7
|
+
* Key differences from legacy pattern:
|
|
8
|
+
* - Uses `eip7702Account` instead of `address`
|
|
9
|
+
* - Uses `addressToEmptyAccount` for permission validator creation
|
|
10
|
+
* - Passes `sessionKeySigner` to `deserializePermissionAccount`
|
|
11
|
+
* - No sudo validator needed, only permission plugin
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { Hex, Address, createPublicClient, http, parseAbi, parseUnits, parseEther } from 'viem';
|
|
15
|
+
import { Chain } from 'viem/chains';
|
|
16
|
+
import { PrivateKeyAccount, privateKeyToAccount, generatePrivateKey } from 'viem/accounts';
|
|
17
|
+
import {
|
|
18
|
+
createKernelAccount,
|
|
19
|
+
createKernelAccountClient,
|
|
20
|
+
addressToEmptyAccount,
|
|
21
|
+
// serializePermissionAccount,
|
|
22
|
+
// deserializePermissionAccount
|
|
23
|
+
} from '@zerodev/sdk';
|
|
24
|
+
import { toECDSASigner } from '@zerodev/permissions/signers';
|
|
25
|
+
import { toPermissionValidator, ModularSigner } from '@zerodev/permissions';
|
|
26
|
+
import { toSudoPolicy, toCallPolicy, CallPolicyVersion } from '@zerodev/permissions/policies';
|
|
27
|
+
import { getEntryPoint, KERNEL_V3_3 } from '@zerodev/sdk/constants';
|
|
28
|
+
|
|
29
|
+
// ============================================
|
|
30
|
+
// Types
|
|
31
|
+
// ============================================
|
|
32
|
+
|
|
33
|
+
export interface SessionKeyPermissionRule {
|
|
34
|
+
target: Hex;
|
|
35
|
+
abi: any[];
|
|
36
|
+
functionName: string;
|
|
37
|
+
args?: any[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CreateSessionKeyApprovalOptions {
|
|
41
|
+
sessionKeyAddress: Address;
|
|
42
|
+
owner: PrivateKeyAccount;
|
|
43
|
+
chain: Chain;
|
|
44
|
+
entryPointVersion?: '0.6' | '0.7';
|
|
45
|
+
useSudoPolicy?: boolean;
|
|
46
|
+
permissions?: SessionKeyPermissionRule[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface SessionKeyInfo {
|
|
50
|
+
privateKey: Hex;
|
|
51
|
+
address: Address;
|
|
52
|
+
signer: ModularSigner;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface DeserializedSessionKey {
|
|
56
|
+
account: any;
|
|
57
|
+
client: any;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ============================================
|
|
61
|
+
// Session Key Generation
|
|
62
|
+
// ============================================
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Generate a new session key
|
|
66
|
+
*
|
|
67
|
+
* Creates a new keypair for use as a session key.
|
|
68
|
+
* The private key should be stored securely and shared with the agent.
|
|
69
|
+
* The address should be shared with the owner for approval.
|
|
70
|
+
*
|
|
71
|
+
* @returns Session key info including private key, address, and signer
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* const sessionKey = await generateSessionKey();
|
|
75
|
+
* console.log("Share this address with owner:", sessionKey.address);
|
|
76
|
+
* console.log("Keep this private key secure:", sessionKey.privateKey);
|
|
77
|
+
*/
|
|
78
|
+
export async function generateSessionKey(): Promise<SessionKeyInfo> {
|
|
79
|
+
const sessionPrivateKey = generatePrivateKey();
|
|
80
|
+
const sessionKeyAccount = privateKeyToAccount(sessionPrivateKey);
|
|
81
|
+
const sessionKeySigner = await toECDSASigner({
|
|
82
|
+
signer: sessionKeyAccount as any,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
privateKey: sessionPrivateKey,
|
|
87
|
+
address: sessionKeyAccount.address,
|
|
88
|
+
signer: sessionKeySigner
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Recreate session key from private key
|
|
94
|
+
*
|
|
95
|
+
* Recreates a session key signer from a stored private key.
|
|
96
|
+
*
|
|
97
|
+
* @param privateKey - The session key private key
|
|
98
|
+
* @returns Session key info
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* const sessionKey = await recreateSessionKey(storedPrivateKey);
|
|
102
|
+
*/
|
|
103
|
+
export async function recreateSessionKey(privateKey: Hex): Promise<SessionKeyInfo> {
|
|
104
|
+
const sessionKeyAccount = privateKeyToAccount(privateKey);
|
|
105
|
+
const sessionKeySigner = await toECDSASigner({
|
|
106
|
+
signer: sessionKeyAccount as any,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
privateKey,
|
|
111
|
+
address: sessionKeyAccount.address,
|
|
112
|
+
signer: sessionKeySigner
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ============================================
|
|
117
|
+
// Owner Side: Create Approval
|
|
118
|
+
// ============================================
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Create session key approval (Owner side)
|
|
122
|
+
*
|
|
123
|
+
* The owner calls this to create an approval for a session key address.
|
|
124
|
+
* This uses the NEW EIP-7702 pattern with addressToEmptyAccount.
|
|
125
|
+
*
|
|
126
|
+
* @param options - Configuration options
|
|
127
|
+
* @returns Serialized approval string to share with the agent
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* // Owner approves session key
|
|
131
|
+
* const approval = await createSessionKeyApproval({
|
|
132
|
+
* sessionKeyAddress: '0x...', // Agent's session key address
|
|
133
|
+
* owner: ownerAccount,
|
|
134
|
+
* chain: sepolia,
|
|
135
|
+
* permissions: [{
|
|
136
|
+
* target: USDC_ADDRESS,
|
|
137
|
+
* abi: parseAbi(['function transfer(address to, uint256 amount)']),
|
|
138
|
+
* functionName: 'transfer',
|
|
139
|
+
* args: [null, { condition: 3, value: parseUnits('10', 6) }]
|
|
140
|
+
* }]
|
|
141
|
+
* });
|
|
142
|
+
* // Share approval with agent
|
|
143
|
+
*/
|
|
144
|
+
export async function createSessionKeyApproval(
|
|
145
|
+
options: CreateSessionKeyApprovalOptions
|
|
146
|
+
): Promise<string> {
|
|
147
|
+
const {
|
|
148
|
+
sessionKeyAddress,
|
|
149
|
+
owner,
|
|
150
|
+
chain,
|
|
151
|
+
entryPointVersion = '0.7',
|
|
152
|
+
useSudoPolicy = false,
|
|
153
|
+
permissions = []
|
|
154
|
+
} = options;
|
|
155
|
+
|
|
156
|
+
const publicClient = createPublicClient({
|
|
157
|
+
chain,
|
|
158
|
+
transport: http()
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const entryPoint = getEntryPoint(entryPointVersion);
|
|
162
|
+
|
|
163
|
+
// Create "empty account" from just the session key address
|
|
164
|
+
// This is the KEY difference from legacy pattern!
|
|
165
|
+
const emptyAccount = addressToEmptyAccount(sessionKeyAddress);
|
|
166
|
+
const emptySessionKeySigner = await toECDSASigner({
|
|
167
|
+
signer: emptyAccount
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Create permission plugin
|
|
171
|
+
let policies: any[];
|
|
172
|
+
|
|
173
|
+
if (useSudoPolicy || permissions.length === 0) {
|
|
174
|
+
// Sudo policy - unrestricted access
|
|
175
|
+
policies = [toSudoPolicy({})];
|
|
176
|
+
} else {
|
|
177
|
+
// Call policy - restricted access
|
|
178
|
+
const callPermissions = permissions.map(perm => ({
|
|
179
|
+
target: perm.target,
|
|
180
|
+
abi: perm.abi,
|
|
181
|
+
functionName: perm.functionName,
|
|
182
|
+
args: perm.args || []
|
|
183
|
+
}));
|
|
184
|
+
|
|
185
|
+
policies = [
|
|
186
|
+
toCallPolicy({
|
|
187
|
+
policyVersion: CallPolicyVersion.V0_0_5,
|
|
188
|
+
permissions: callPermissions
|
|
189
|
+
})
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const permissionPlugin = await toPermissionValidator(publicClient as any, {
|
|
194
|
+
entryPoint,
|
|
195
|
+
signer: emptySessionKeySigner,
|
|
196
|
+
policies,
|
|
197
|
+
kernelVersion: KERNEL_V3_3,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Create kernel account with eip7702Account (NOT address!)
|
|
201
|
+
const sessionKeyAccount = await createKernelAccount(publicClient as any, {
|
|
202
|
+
entryPoint,
|
|
203
|
+
eip7702Account: owner as any, // ← EIP-7702 pattern
|
|
204
|
+
plugins: {
|
|
205
|
+
regular: permissionPlugin,
|
|
206
|
+
},
|
|
207
|
+
kernelVersion: KERNEL_V3_3,
|
|
208
|
+
// NO address parameter!
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Serialize approval (no private key in approval)
|
|
212
|
+
// TODO: serializePermissionAccount not available in @zerodev/sdk yet
|
|
213
|
+
// const approval = await serializePermissionAccount(sessionKeyAccount);
|
|
214
|
+
const approval = JSON.stringify({ sessionKeyAccount: 'placeholder' });
|
|
215
|
+
|
|
216
|
+
return approval;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ============================================
|
|
220
|
+
// Agent Side: Use Session Key
|
|
221
|
+
// ============================================
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Deserialize session key account (Agent side)
|
|
225
|
+
*
|
|
226
|
+
* The agent calls this to reconstruct the session key account from the approval.
|
|
227
|
+
* This requires BOTH the approval AND the session key signer.
|
|
228
|
+
*
|
|
229
|
+
* @param approval - Approval string from owner
|
|
230
|
+
* @param sessionKeySigner - Session key signer (created from private key)
|
|
231
|
+
* @param chain - Chain to use
|
|
232
|
+
* @param entryPointVersion - EntryPoint version
|
|
233
|
+
* @returns Deserialized session key account
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* // Agent deserializes with private key
|
|
237
|
+
* const sessionKey = await recreateSessionKey(storedPrivateKey);
|
|
238
|
+
* const account = await deserializeSessionKey({
|
|
239
|
+
* approval,
|
|
240
|
+
* sessionKeySigner: sessionKey.signer,
|
|
241
|
+
* chain: sepolia
|
|
242
|
+
* });
|
|
243
|
+
*/
|
|
244
|
+
export async function deserializeSessionKey(options: {
|
|
245
|
+
approval: string;
|
|
246
|
+
sessionKeySigner: ModularSigner;
|
|
247
|
+
chain: Chain;
|
|
248
|
+
entryPointVersion?: '0.6' | '0.7';
|
|
249
|
+
}): Promise<any> {
|
|
250
|
+
const {
|
|
251
|
+
approval,
|
|
252
|
+
sessionKeySigner,
|
|
253
|
+
chain,
|
|
254
|
+
entryPointVersion = '0.7'
|
|
255
|
+
} = options;
|
|
256
|
+
|
|
257
|
+
const publicClient = createPublicClient({
|
|
258
|
+
chain,
|
|
259
|
+
transport: http()
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const entryPoint = getEntryPoint(entryPointVersion);
|
|
263
|
+
|
|
264
|
+
// Deserialize WITH the session key signer
|
|
265
|
+
// This is the 5-parameter version (not 4!)
|
|
266
|
+
// TODO: deserializePermissionAccount not available in @zerodev/sdk yet
|
|
267
|
+
// const sessionKeyAccount = await deserializePermissionAccount(
|
|
268
|
+
// publicClient,
|
|
269
|
+
// entryPoint,
|
|
270
|
+
// KERNEL_V3_3,
|
|
271
|
+
// approval,
|
|
272
|
+
// sessionKeySigner // ← Must pass the signer!
|
|
273
|
+
// );
|
|
274
|
+
|
|
275
|
+
// Placeholder until SDK is available
|
|
276
|
+
const sessionKeyAccount = null;
|
|
277
|
+
|
|
278
|
+
return sessionKeyAccount;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Create kernel client for session key
|
|
283
|
+
*
|
|
284
|
+
* Creates a client for sending transactions with the session key.
|
|
285
|
+
*
|
|
286
|
+
* @param account - Deserialized session key account
|
|
287
|
+
* @param chain - Chain to use
|
|
288
|
+
* @param bundlerUrl - Bundler RPC URL
|
|
289
|
+
* @param paymasterUrl - Optional paymaster URL for gas sponsorship
|
|
290
|
+
* @returns Kernel account client
|
|
291
|
+
*
|
|
292
|
+
* @example
|
|
293
|
+
* const client = createSessionKeyClient({
|
|
294
|
+
* account: sessionKeyAccount,
|
|
295
|
+
* chain: sepolia,
|
|
296
|
+
* bundlerUrl: 'https://api.pimlico.io/...'
|
|
297
|
+
* });
|
|
298
|
+
*/
|
|
299
|
+
export function createSessionKeyClient(options: {
|
|
300
|
+
account: any;
|
|
301
|
+
chain: Chain;
|
|
302
|
+
bundlerUrl: string;
|
|
303
|
+
paymasterUrl?: string;
|
|
304
|
+
}): any {
|
|
305
|
+
const {
|
|
306
|
+
account,
|
|
307
|
+
chain,
|
|
308
|
+
bundlerUrl,
|
|
309
|
+
paymasterUrl
|
|
310
|
+
} = options;
|
|
311
|
+
|
|
312
|
+
const clientOptions: any = {
|
|
313
|
+
account,
|
|
314
|
+
chain,
|
|
315
|
+
bundlerTransport: http(bundlerUrl)
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
// Add paymaster if provided
|
|
319
|
+
if (paymasterUrl) {
|
|
320
|
+
// Note: Paymaster client creation would go here
|
|
321
|
+
// For now, just the basic client
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const kernelClient = createKernelAccountClient(clientOptions);
|
|
325
|
+
|
|
326
|
+
return kernelClient;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// ============================================
|
|
330
|
+
// Convenience Functions
|
|
331
|
+
// ============================================
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Create USDC transfer permission rule
|
|
335
|
+
*
|
|
336
|
+
* Helper to create a permission rule for USDC transfers with a maximum amount.
|
|
337
|
+
*
|
|
338
|
+
* @param usdcAddress - USDC contract address
|
|
339
|
+
* @param maxAmount - Maximum USDC amount (in USDC units, e.g., "10" for 10 USDC)
|
|
340
|
+
* @returns Permission rule
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* const rule = createUSDCTransferPermission(
|
|
344
|
+
* '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
|
|
345
|
+
* '10' // Max 10 USDC
|
|
346
|
+
* );
|
|
347
|
+
*/
|
|
348
|
+
export function createUSDCTransferPermission(
|
|
349
|
+
usdcAddress: Hex,
|
|
350
|
+
maxAmount: string
|
|
351
|
+
): SessionKeyPermissionRule {
|
|
352
|
+
return {
|
|
353
|
+
target: usdcAddress,
|
|
354
|
+
abi: parseAbi(['function transfer(address to, uint256 amount) returns (bool)']) as any,
|
|
355
|
+
functionName: 'transfer',
|
|
356
|
+
args: [
|
|
357
|
+
null, // Any recipient
|
|
358
|
+
{
|
|
359
|
+
condition: 3, // LESS_THAN_OR_EQUAL
|
|
360
|
+
value: parseUnits(maxAmount, 6) // USDC has 6 decimals
|
|
361
|
+
}
|
|
362
|
+
]
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Create ETH transfer permission rule
|
|
368
|
+
*
|
|
369
|
+
* Helper to create a permission rule for ETH transfers with a maximum value.
|
|
370
|
+
*
|
|
371
|
+
* @param maxValue - Maximum ETH value (in ether units, e.g., "0.1" for 0.1 ETH)
|
|
372
|
+
* @returns Permission rule
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* const rule = createETHTransferPermission('0.1'); // Max 0.1 ETH
|
|
376
|
+
*/
|
|
377
|
+
export function createETHTransferPermission(maxValue: string): SessionKeyPermissionRule {
|
|
378
|
+
return {
|
|
379
|
+
target: '0x0000000000000000000000000000000000000000' as Hex, // Native token
|
|
380
|
+
abi: [],
|
|
381
|
+
functionName: '',
|
|
382
|
+
args: [
|
|
383
|
+
{
|
|
384
|
+
condition: 3, // LESS_THAN_OR_EQUAL
|
|
385
|
+
value: parseEther(maxValue)
|
|
386
|
+
}
|
|
387
|
+
]
|
|
388
|
+
};
|
|
389
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Wallet Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for EVM smart wallet functionality using Account Abstraction (EIP-4337)
|
|
5
|
+
* and EIP-7702 delegation features.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Chain, Hex, SignAuthorizationReturnType } from "viem";
|
|
9
|
+
import { PrivateKeyAccount } from "viem/accounts";
|
|
10
|
+
import { ModularSigner } from "@zerodev/permissions";
|
|
11
|
+
import { EntryPointVersion as ViemEntryPointVersion } from "viem/account-abstraction";
|
|
12
|
+
import { BundlerManager } from "../services/bundler";
|
|
13
|
+
import { ModuleType } from "./kernel-modules";
|
|
14
|
+
import { SessionKeyPermissionRule } from "./session-keys";
|
|
15
|
+
|
|
16
|
+
// ============================================
|
|
17
|
+
// Types
|
|
18
|
+
// ============================================
|
|
19
|
+
|
|
20
|
+
export type KernelVersion = '0.3.3';
|
|
21
|
+
export type EntryPointVersion = '0.6' | '0.7';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Single call/operation in a transaction
|
|
25
|
+
*/
|
|
26
|
+
export interface Call {
|
|
27
|
+
/** Target contract address */
|
|
28
|
+
to: Hex;
|
|
29
|
+
/** ETH value to send (optional, defaults to 0) */
|
|
30
|
+
value?: bigint;
|
|
31
|
+
/** Calldata (optional, defaults to '0x') */
|
|
32
|
+
data?: Hex;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Batch transaction configuration
|
|
36
|
+
*/
|
|
37
|
+
export interface BatchTransactionConfig {
|
|
38
|
+
kernelAccount: KernelAccountInstance;
|
|
39
|
+
bundlerManager: BundlerManager;
|
|
40
|
+
authorization?: SignAuthorizationReturnType;
|
|
41
|
+
calls: Call[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Single transaction configuration (convenience)
|
|
46
|
+
*/
|
|
47
|
+
export interface SingleTransactionConfig {
|
|
48
|
+
kernelAccount: KernelAccountInstance;
|
|
49
|
+
bundlerManager: BundlerManager;
|
|
50
|
+
authorization?: SignAuthorizationReturnType;
|
|
51
|
+
to: Hex;
|
|
52
|
+
value?: bigint;
|
|
53
|
+
data?: Hex;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface KernelAccountConfig {
|
|
57
|
+
chain: Chain;
|
|
58
|
+
owner: PrivateKeyAccount;
|
|
59
|
+
bundlerManager: BundlerManager;
|
|
60
|
+
entryPointVersion?: EntryPointVersion;
|
|
61
|
+
kernelVersion?: KernelVersion;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface KernelAccountInstance {
|
|
65
|
+
account: any; // The kernel account from ZeroDev
|
|
66
|
+
address: string;
|
|
67
|
+
owner: PrivateKeyAccount;
|
|
68
|
+
chain: Chain;
|
|
69
|
+
entryPoint: {
|
|
70
|
+
address: Hex;
|
|
71
|
+
version: EntryPointVersion;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// ============================================
|
|
75
|
+
// Configuration Types
|
|
76
|
+
// ============================================
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
export interface SmartWalletOptions {
|
|
83
|
+
/** Bundler URL for submitting UserOperations */
|
|
84
|
+
bundlerUrl?: string;
|
|
85
|
+
/** Paymaster URL for gas sponsorship (optional) */
|
|
86
|
+
paymasterUrl?: string;
|
|
87
|
+
/** EntryPoint version to use (default: '0.7') */
|
|
88
|
+
entryPointVersion?: EntryPointVersion;
|
|
89
|
+
/** Auto-initialize on extend (default: true) */
|
|
90
|
+
autoInitialize?: boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ============================================
|
|
94
|
+
// Transaction Types
|
|
95
|
+
// ============================================
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
export interface SmartWalletTransactionResult {
|
|
100
|
+
/** Whether the transaction succeeded */
|
|
101
|
+
success: boolean;
|
|
102
|
+
/** UserOperation hash */
|
|
103
|
+
userOpHash: Hex;
|
|
104
|
+
/** Transaction hash (after bundler execution) */
|
|
105
|
+
transactionHash?: string;
|
|
106
|
+
/** Error message if failed */
|
|
107
|
+
error?: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface GasEstimate {
|
|
111
|
+
/** Estimated gas for UserOperation */
|
|
112
|
+
callGasLimit: bigint;
|
|
113
|
+
/** Estimated verification gas */
|
|
114
|
+
verificationGasLimit: bigint;
|
|
115
|
+
/** Estimated pre-verification gas */
|
|
116
|
+
preVerificationGas: bigint;
|
|
117
|
+
/** Total estimated gas */
|
|
118
|
+
total: bigint;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
export interface SessionKeyApprovalOptions {
|
|
125
|
+
/** Session key address to approve */
|
|
126
|
+
sessionKeyAddress: Hex;
|
|
127
|
+
/** Permission rules for the session key */
|
|
128
|
+
permissions?: SessionKeyPermissionRule[];
|
|
129
|
+
/** Use unrestricted sudo policy (not recommended for production) */
|
|
130
|
+
useSudoPolicy?: boolean;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface SessionKeyUsageOptions {
|
|
134
|
+
/** Serialized approval from owner */
|
|
135
|
+
approval: string;
|
|
136
|
+
/** Session key signer */
|
|
137
|
+
sessionKeySigner: ModularSigner;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ============================================
|
|
141
|
+
// Module Types
|
|
142
|
+
// ============================================
|
|
143
|
+
|
|
144
|
+
export interface ModuleInstallOptions {
|
|
145
|
+
/** Type of module to install */
|
|
146
|
+
moduleType: ModuleType;
|
|
147
|
+
/** Module contract address */
|
|
148
|
+
moduleAddress: Hex;
|
|
149
|
+
/** Initialization data for the module */
|
|
150
|
+
initData?: Hex;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface ModuleUninstallOptions {
|
|
154
|
+
/** Type of module to uninstall */
|
|
155
|
+
moduleType: ModuleType;
|
|
156
|
+
/** Module contract address */
|
|
157
|
+
moduleAddress: Hex;
|
|
158
|
+
/** De-initialization data for the module */
|
|
159
|
+
deInitData?: Hex;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
// ============================================
|
|
164
|
+
// Advanced Feature Types
|
|
165
|
+
// ============================================
|
|
166
|
+
|
|
167
|
+
export interface MultiSigConfig {
|
|
168
|
+
/** List of owner addresses */
|
|
169
|
+
owners: Hex[];
|
|
170
|
+
/** Number of signatures required (threshold) */
|
|
171
|
+
threshold: number;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface RecoveryConfig {
|
|
175
|
+
/** Guardian addresses for account recovery */
|
|
176
|
+
guardians: Hex[];
|
|
177
|
+
/** Recovery delay in seconds */
|
|
178
|
+
recoveryDelay?: number;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export interface PaymasterConfig {
|
|
182
|
+
/** Paymaster URL for sponsored transactions */
|
|
183
|
+
paymasterUrl: string;
|
|
184
|
+
/** Paymaster context (optional, provider-specific) */
|
|
185
|
+
context?: any;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface SmartAccountInfo {
|
|
189
|
+
/** Smart account address */
|
|
190
|
+
address: Hex;
|
|
191
|
+
/** Owner EOA address */
|
|
192
|
+
ownerAddress: Hex;
|
|
193
|
+
/** Chain information */
|
|
194
|
+
chain: Chain;
|
|
195
|
+
/** EntryPoint version */
|
|
196
|
+
entryPointVersion: EntryPointVersion;
|
|
197
|
+
/** Whether account is delegated (EIP-7702) */
|
|
198
|
+
isDelegated: boolean;
|
|
199
|
+
/** Current balance in wei */
|
|
200
|
+
balance: bigint;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ============================================
|
|
204
|
+
// Error Types
|
|
205
|
+
// ============================================
|
|
206
|
+
|
|
207
|
+
export class SmartWalletError extends Error {
|
|
208
|
+
code: string;
|
|
209
|
+
|
|
210
|
+
constructor(message: string, code: string = 'SMART_WALLET_ERROR') {
|
|
211
|
+
super(message);
|
|
212
|
+
this.name = 'SmartWalletError';
|
|
213
|
+
this.code = code;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export class SessionKeyError extends SmartWalletError {
|
|
218
|
+
constructor(message: string) {
|
|
219
|
+
super(message, 'SESSION_KEY_ERROR');
|
|
220
|
+
this.name = 'SessionKeyError';
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export class ModuleError extends SmartWalletError {
|
|
225
|
+
constructor(message: string) {
|
|
226
|
+
super(message, 'MODULE_ERROR');
|
|
227
|
+
this.name = 'ModuleError';
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export class TransactionError extends SmartWalletError {
|
|
232
|
+
constructor(message: string) {
|
|
233
|
+
super(message, 'TRANSACTION_ERROR');
|
|
234
|
+
this.name = 'TransactionError';
|
|
235
|
+
}
|
|
236
|
+
}
|