@deserialize/multi-vm-wallet 1.3.2 → 1.3.3
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 +2 -1
- package/dist/constant.js +60 -16
- package/dist/constant.js.map +1 -1
- package/dist/evm/aa-service/index.d.ts +1 -1
- package/dist/evm/aa-service/index.js +1 -2
- package/dist/evm/aa-service/index.js.map +1 -1
- package/dist/evm/aa-service/lib/kernel-account.d.ts +1 -1
- package/dist/evm/aa-service/lib/kernel-account.js +22 -6
- package/dist/evm/aa-service/lib/kernel-account.js.map +1 -1
- package/dist/evm/aa-service/lib/session-keys.d.ts +14 -17
- package/dist/evm/aa-service/lib/session-keys.js +40 -58
- package/dist/evm/aa-service/lib/session-keys.js.map +1 -1
- package/dist/evm/aa-service/lib/type.d.ts +2 -1
- package/dist/evm/aa-service/lib/type.js.map +1 -1
- package/dist/evm/aa-service/services/account-abstraction.d.ts +3 -29
- package/dist/evm/aa-service/services/account-abstraction.js +3 -67
- package/dist/evm/aa-service/services/account-abstraction.js.map +1 -1
- package/dist/evm/aa-service/services/bundler.js +2 -1
- package/dist/evm/aa-service/services/bundler.js.map +1 -1
- package/dist/evm/evm.d.ts +161 -1
- package/dist/evm/evm.js +247 -0
- package/dist/evm/evm.js.map +1 -1
- package/dist/evm/smartWallet.d.ts +11 -43
- package/dist/evm/smartWallet.js +136 -116
- package/dist/evm/smartWallet.js.map +1 -1
- package/dist/evm/utils.js +0 -1
- package/dist/evm/utils.js.map +1 -1
- package/dist/privacy/artifact-manager.d.ts +117 -0
- package/dist/privacy/artifact-manager.js +251 -0
- package/dist/privacy/artifact-manager.js.map +1 -0
- package/dist/privacy/broadcaster-client.d.ts +166 -0
- package/dist/privacy/broadcaster-client.js +261 -0
- package/dist/privacy/broadcaster-client.js.map +1 -0
- package/dist/privacy/index.d.ts +34 -0
- package/dist/privacy/index.js +56 -0
- package/dist/privacy/index.js.map +1 -0
- package/dist/privacy/network-config.d.ts +57 -0
- package/dist/privacy/network-config.js +118 -0
- package/dist/privacy/network-config.js.map +1 -0
- package/dist/privacy/poi-helper.d.ts +161 -0
- package/dist/privacy/poi-helper.js +249 -0
- package/dist/privacy/poi-helper.js.map +1 -0
- package/dist/privacy/railgun-engine.d.ts +135 -0
- package/dist/privacy/railgun-engine.js +205 -0
- package/dist/privacy/railgun-engine.js.map +1 -0
- package/dist/privacy/railgun-privacy-wallet.d.ts +288 -0
- package/dist/privacy/railgun-privacy-wallet.js +539 -0
- package/dist/privacy/railgun-privacy-wallet.js.map +1 -0
- package/dist/privacy/types.d.ts +229 -0
- package/dist/privacy/types.js +26 -0
- package/dist/privacy/types.js.map +1 -0
- package/dist/savings/savings-manager.d.ts +126 -0
- package/dist/savings/savings-manager.js +234 -0
- package/dist/savings/savings-manager.js.map +1 -0
- package/dist/savings/smart-savings.d.ts +74 -0
- package/dist/savings/smart-savings.js +152 -0
- package/dist/savings/smart-savings.js.map +1 -0
- package/dist/savings/types.d.ts +125 -0
- package/dist/savings/types.js +9 -0
- package/dist/savings/types.js.map +1 -0
- package/dist/svm/svm.d.ts +16 -0
- package/dist/svm/svm.js +23 -0
- package/dist/svm/svm.js.map +1 -1
- package/dist/test.js +53 -15
- package/dist/test.js.map +1 -1
- package/dist/vm.d.ts +14 -0
- package/dist/vm.js.map +1 -1
- package/package.json +2 -1
- package/utils/constant.ts +63 -16
- package/utils/evm/aa-service/index.ts +0 -1
- package/utils/evm/aa-service/lib/kernel-account.ts +23 -8
- package/utils/evm/aa-service/lib/session-keys.ts +58 -60
- package/utils/evm/aa-service/lib/type.ts +2 -1
- package/utils/evm/aa-service/services/account-abstraction.ts +10 -76
- package/utils/evm/aa-service/services/bundler.ts +2 -1
- package/utils/evm/evm.ts +300 -0
- package/utils/evm/smartWallet.ts +118 -128
- package/utils/evm/utils.ts +1 -1
- package/utils/savings/savings-manager.ts +271 -0
- package/utils/savings/smart-savings.ts +184 -0
- package/utils/savings/types.ts +135 -0
- package/utils/svm/svm.ts +27 -0
- package/utils/test.ts +82 -18
- package/utils/vm.ts +10 -0
package/utils/constant.ts
CHANGED
|
@@ -32,7 +32,7 @@ export const DefaultChains: ChainWalletConfig[] = [{
|
|
|
32
32
|
}, {
|
|
33
33
|
chainId: 123456789,
|
|
34
34
|
name: "Solana",
|
|
35
|
-
rpcUrl: "https://solana-mainnet.g.alchemy.com/v2/
|
|
35
|
+
rpcUrl: "https://solana-mainnet.g.alchemy.com/v2/TFdA4BilCnKIwaqtypk0d",
|
|
36
36
|
explorerUrl: "https://explorer.solana.com",
|
|
37
37
|
nativeToken: {
|
|
38
38
|
name: "Solana",
|
|
@@ -46,7 +46,7 @@ export const DefaultChains: ChainWalletConfig[] = [{
|
|
|
46
46
|
, {
|
|
47
47
|
chainId: 1,
|
|
48
48
|
name: "Ethereum",
|
|
49
|
-
rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/
|
|
49
|
+
rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/TFdA4BilCnKIwaqtypk0d",
|
|
50
50
|
explorerUrl: "https://etherscan.io",
|
|
51
51
|
nativeToken: {
|
|
52
52
|
name: "Ether",
|
|
@@ -69,25 +69,27 @@ export const DefaultChains: ChainWalletConfig[] = [{
|
|
|
69
69
|
testnet: false,
|
|
70
70
|
logoUrl: "https://bscscan.com/assets/bsc/images/svg/logos/token-light.svg?v=25.10.5.0",
|
|
71
71
|
vmType: "EVM"
|
|
72
|
-
}, {
|
|
73
|
-
chainId: 123456791,
|
|
74
|
-
name: "Eclipse",
|
|
75
|
-
rpcUrl: "https://mainnetbeta-rpc.eclipse.xyz",
|
|
76
|
-
explorerUrl: "https://explorer.eclipse.xyz/",
|
|
77
|
-
nativeToken: {
|
|
78
|
-
name: "Eclipse",
|
|
79
|
-
symbol: "ETH",
|
|
80
|
-
decimals: 9,
|
|
81
|
-
},
|
|
82
|
-
testnet: false,
|
|
83
|
-
logoUrl: "https://raw.githubusercontent.com/hyperlane-xyz/hyperlane-registry/a86c3b432b6f9ad7272ae09859f20eb3ade3bd6e/deployments/warp_routes/ES/logo.svg",
|
|
84
|
-
vmType: "SVM"
|
|
85
72
|
},
|
|
86
73
|
|
|
74
|
+
// {
|
|
75
|
+
// chainId: 123456791,
|
|
76
|
+
// name: "Eclipse",
|
|
77
|
+
// rpcUrl: "https://mainnetbeta-rpc.eclipse.xyz",
|
|
78
|
+
// explorerUrl: "https://explorer.eclipse.xyz/",
|
|
79
|
+
// nativeToken: {
|
|
80
|
+
// name: "Eclipse",
|
|
81
|
+
// symbol: "ETH",
|
|
82
|
+
// decimals: 9,
|
|
83
|
+
// },
|
|
84
|
+
// testnet: false,
|
|
85
|
+
// logoUrl: "https://raw.githubusercontent.com/hyperlane-xyz/hyperlane-registry/a86c3b432b6f9ad7272ae09859f20eb3ade3bd6e/deployments/warp_routes/ES/logo.svg",
|
|
86
|
+
// vmType: "SVM"
|
|
87
|
+
// },
|
|
88
|
+
|
|
87
89
|
{
|
|
88
90
|
chainId: base.id,
|
|
89
91
|
name: base.name,
|
|
90
|
-
rpcUrl: base.
|
|
92
|
+
rpcUrl: "https://base-mainnet.g.alchemy.com/v2/TFdA4BilCnKIwaqtypk0d",
|
|
91
93
|
explorerUrl: base.blockExplorers?.default.url || "",
|
|
92
94
|
nativeToken: {
|
|
93
95
|
name: base.nativeCurrency.name,
|
|
@@ -97,6 +99,51 @@ export const DefaultChains: ChainWalletConfig[] = [{
|
|
|
97
99
|
testnet: base.testnet,
|
|
98
100
|
logoUrl: "https://avatars.githubusercontent.com/u/108554348?s=200&v=4",
|
|
99
101
|
vmType: "EVM"
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
chainId: 42161,
|
|
106
|
+
name: "Arbitrum One",
|
|
107
|
+
rpcUrl: "https://arbitrum-mainnet.g.alchemy.com/v2/TFdA4BilCnKIwaqtypk0d",
|
|
108
|
+
explorerUrl: "https://arbiscan.io",
|
|
109
|
+
nativeToken: {
|
|
110
|
+
name: "Ether",
|
|
111
|
+
symbol: "ETH",
|
|
112
|
+
decimals: 18,
|
|
113
|
+
},
|
|
114
|
+
testnet: false,
|
|
115
|
+
logoUrl: "https://arbiscan.io/images/svg/brands/arbitrum-light.svg?v=0.0.36",
|
|
116
|
+
vmType: "EVM"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
chainId: 10,
|
|
120
|
+
name: "Optimism",
|
|
121
|
+
rpcUrl: "https://optimism-mainnet.g.alchemy.com/v2/TFdA4BilCnKIwaqtypk0d",
|
|
122
|
+
explorerUrl: "https://optimistic.etherscan.io",
|
|
123
|
+
nativeToken: {
|
|
124
|
+
name: "Ether",
|
|
125
|
+
symbol: "ETH",
|
|
126
|
+
decimals: 18,
|
|
127
|
+
},
|
|
128
|
+
testnet: false,
|
|
129
|
+
logoUrl: "https://optimism.io/images/optimism-logo-light.svg",
|
|
130
|
+
vmType: "EVM"
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
//add for polygon
|
|
134
|
+
{
|
|
135
|
+
chainId: 137,
|
|
136
|
+
name: "Polygon",
|
|
137
|
+
rpcUrl: "https://polygon-mainnet.g.alchemy.com/v2/TFdA4BilCnKIwaqtypk0d",
|
|
138
|
+
explorerUrl: "https://polygonscan.com",
|
|
139
|
+
nativeToken: {
|
|
140
|
+
name: "MATIC",
|
|
141
|
+
symbol: "MATIC",
|
|
142
|
+
decimals: 18,
|
|
143
|
+
},
|
|
144
|
+
testnet: false,
|
|
145
|
+
logoUrl: "https://polygonscan.com/images/svg/brands/polygon-light.svg?v=0.0.36",
|
|
146
|
+
vmType: "EVM"
|
|
100
147
|
}
|
|
101
148
|
|
|
102
149
|
|
|
@@ -45,7 +45,6 @@ export async function createKernel7702Account(
|
|
|
45
45
|
const {
|
|
46
46
|
chain,
|
|
47
47
|
owner,
|
|
48
|
-
bundlerManager,
|
|
49
48
|
entryPointVersion = '0.7',
|
|
50
49
|
kernelVersion = '0.3.3',
|
|
51
50
|
aaConfig
|
|
@@ -113,22 +112,37 @@ export async function createKernelAuthorization(
|
|
|
113
112
|
config: {
|
|
114
113
|
owner: PrivateKeyAccount;
|
|
115
114
|
chain: Chain;
|
|
116
|
-
bundlerManager: BundlerManager;
|
|
117
115
|
kernelVersion?: KernelVersion;
|
|
116
|
+
aaConfig?: import('./type').AA_SupportConfig;
|
|
118
117
|
}
|
|
119
118
|
): Promise<SignAuthorizationReturnType | undefined> {
|
|
120
|
-
const { owner, chain,
|
|
121
|
-
|
|
122
|
-
const bundlerClient = bundlerManager.getClient(chain);
|
|
119
|
+
const { owner, chain, kernelVersion = '0.3.3', aaConfig } = config;
|
|
123
120
|
|
|
124
121
|
// Create public client for eth_getCode (bundler clients don't support it)
|
|
125
122
|
const publicClient = createPublicClient({
|
|
126
123
|
chain,
|
|
127
|
-
transport: http()
|
|
124
|
+
transport: http(chain.rpcUrls.default.http[0])
|
|
128
125
|
});
|
|
129
126
|
|
|
130
|
-
// Get Kernel implementation address
|
|
131
|
-
|
|
127
|
+
// Get Kernel implementation address from aaConfig or fallback to default
|
|
128
|
+
let delegateAddress: Hex;
|
|
129
|
+
|
|
130
|
+
if (aaConfig && aaConfig.kernelImplementations.length > 0) {
|
|
131
|
+
// Try to find matching kernel version (currently only 0.3.3 / version 3 is supported)
|
|
132
|
+
const versionNumber = 3; // kernel version 0.3.3 maps to version 3
|
|
133
|
+
const kernelImpl = aaConfig.kernelImplementations.find(impl => impl.version === versionNumber);
|
|
134
|
+
|
|
135
|
+
if (kernelImpl) {
|
|
136
|
+
delegateAddress = kernelImpl.address as Hex;
|
|
137
|
+
} else {
|
|
138
|
+
// Fallback to first implementation if version not found
|
|
139
|
+
console.warn(`Kernel version ${kernelVersion} (v${versionNumber}) not found in aaConfig, using first available`);
|
|
140
|
+
delegateAddress = aaConfig.kernelImplementations[0].address as Hex;
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
// Fallback to hardcoded map if no config
|
|
144
|
+
delegateAddress = KernelVersionToAddressesMap[KERNEL_V3_3].accountImplementationAddress;
|
|
145
|
+
}
|
|
132
146
|
|
|
133
147
|
// Check if already delegated
|
|
134
148
|
const code = await publicClient.getCode({ address: owner.address });
|
|
@@ -194,6 +208,7 @@ export async function sendBatchTransaction(config: BatchTransactionConfig): Prom
|
|
|
194
208
|
|
|
195
209
|
const bundlerClient = bundlerManager.getClient(kernelAccount.chain);
|
|
196
210
|
|
|
211
|
+
|
|
197
212
|
// Normalize calls to ensure value and data are set
|
|
198
213
|
const normalizedCalls = calls.map(call => ({
|
|
199
214
|
to: call.to,
|
|
@@ -14,17 +14,20 @@
|
|
|
14
14
|
import { Hex, Address, createPublicClient, http, parseAbi, parseUnits, parseEther } from 'viem';
|
|
15
15
|
import { Chain } from 'viem/chains';
|
|
16
16
|
import { PrivateKeyAccount, privateKeyToAccount, generatePrivateKey } from 'viem/accounts';
|
|
17
|
+
import { entryPoint07Address } from 'viem/account-abstraction';
|
|
17
18
|
import {
|
|
18
19
|
createKernelAccount,
|
|
19
20
|
createKernelAccountClient,
|
|
20
21
|
addressToEmptyAccount,
|
|
22
|
+
CreateKernelAccountReturnType,
|
|
21
23
|
// serializePermissionAccount,
|
|
22
24
|
// deserializePermissionAccount
|
|
23
25
|
} from '@zerodev/sdk';
|
|
24
26
|
import { toECDSASigner } from '@zerodev/permissions/signers';
|
|
25
|
-
import { toPermissionValidator, ModularSigner } from '@zerodev/permissions';
|
|
26
|
-
import { toSudoPolicy, toCallPolicy, CallPolicyVersion } from '@zerodev/permissions/policies';
|
|
27
|
+
import { toPermissionValidator, ModularSigner, serializePermissionAccount, deserializePermissionAccount } from '@zerodev/permissions';
|
|
28
|
+
import { toSudoPolicy, toCallPolicy, CallPolicyVersion, ParamCondition } from '@zerodev/permissions/policies';
|
|
27
29
|
import { getEntryPoint, KERNEL_V3_3 } from '@zerodev/sdk/constants';
|
|
30
|
+
import { createPimlicoClient } from 'permissionless/clients/pimlico';
|
|
28
31
|
|
|
29
32
|
// ============================================
|
|
30
33
|
// Types
|
|
@@ -39,6 +42,7 @@ export interface SessionKeyPermissionRule {
|
|
|
39
42
|
|
|
40
43
|
export interface CreateSessionKeyApprovalOptions {
|
|
41
44
|
sessionKeyAddress: Address;
|
|
45
|
+
sessionKeyPrivateKey: Hex;
|
|
42
46
|
owner: PrivateKeyAccount;
|
|
43
47
|
chain: Chain;
|
|
44
48
|
entryPointVersion?: '0.6' | '0.7';
|
|
@@ -64,19 +68,22 @@ export interface DeserializedSessionKey {
|
|
|
64
68
|
/**
|
|
65
69
|
* Generate a new session key
|
|
66
70
|
*
|
|
67
|
-
* Creates a new keypair for use as a session key.
|
|
71
|
+
* Creates a new keypair for use as a session key or use the one that was passed if available.
|
|
68
72
|
* The private key should be stored securely and shared with the agent.
|
|
69
73
|
* The address should be shared with the owner for approval.
|
|
70
74
|
*
|
|
71
75
|
* @returns Session key info including private key, address, and signer
|
|
72
76
|
*
|
|
73
77
|
* @example
|
|
74
|
-
* const sessionKey = await generateSessionKey();
|
|
78
|
+
* const sessionKey = await generateSessionKey(); or
|
|
79
|
+
* const privateKey = '0x...'; // Existing private key
|
|
80
|
+
* const sessionKey = await generateSessionKey(privateKey);
|
|
81
|
+
*
|
|
75
82
|
* console.log("Share this address with owner:", sessionKey.address);
|
|
76
83
|
* console.log("Keep this private key secure:", sessionKey.privateKey);
|
|
77
84
|
*/
|
|
78
|
-
export async function generateSessionKey(): Promise<SessionKeyInfo> {
|
|
79
|
-
const sessionPrivateKey = generatePrivateKey();
|
|
85
|
+
export async function generateSessionKey(privateKey?: Hex): Promise<SessionKeyInfo> {
|
|
86
|
+
const sessionPrivateKey = privateKey || generatePrivateKey();
|
|
80
87
|
const sessionKeyAccount = privateKeyToAccount(sessionPrivateKey);
|
|
81
88
|
const sessionKeySigner = await toECDSASigner({
|
|
82
89
|
signer: sessionKeyAccount as any,
|
|
@@ -89,29 +96,7 @@ export async function generateSessionKey(): Promise<SessionKeyInfo> {
|
|
|
89
96
|
};
|
|
90
97
|
}
|
|
91
98
|
|
|
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
99
|
|
|
109
|
-
return {
|
|
110
|
-
privateKey,
|
|
111
|
-
address: sessionKeyAccount.address,
|
|
112
|
-
signer: sessionKeySigner
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
100
|
|
|
116
101
|
// ============================================
|
|
117
102
|
// Owner Side: Create Approval
|
|
@@ -146,6 +131,7 @@ export async function createSessionKeyApproval(
|
|
|
146
131
|
): Promise<string> {
|
|
147
132
|
const {
|
|
148
133
|
sessionKeyAddress,
|
|
134
|
+
sessionKeyPrivateKey,
|
|
149
135
|
owner,
|
|
150
136
|
chain,
|
|
151
137
|
entryPointVersion = '0.7',
|
|
@@ -160,11 +146,10 @@ export async function createSessionKeyApproval(
|
|
|
160
146
|
|
|
161
147
|
const entryPoint = getEntryPoint(entryPointVersion);
|
|
162
148
|
|
|
163
|
-
// Create
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
signer: emptyAccount
|
|
149
|
+
// Create session key signer from private key (NOT addressToEmptyAccount!)
|
|
150
|
+
const sessionKeyAccount = privateKeyToAccount(sessionKeyPrivateKey);
|
|
151
|
+
const sessionKeySigner = await toECDSASigner({
|
|
152
|
+
signer: sessionKeyAccount
|
|
168
153
|
});
|
|
169
154
|
|
|
170
155
|
// Create permission plugin
|
|
@@ -192,26 +177,27 @@ export async function createSessionKeyApproval(
|
|
|
192
177
|
|
|
193
178
|
const permissionPlugin = await toPermissionValidator(publicClient as any, {
|
|
194
179
|
entryPoint,
|
|
195
|
-
signer:
|
|
180
|
+
signer: sessionKeySigner,
|
|
196
181
|
policies,
|
|
197
182
|
kernelVersion: KERNEL_V3_3,
|
|
198
183
|
});
|
|
199
184
|
|
|
200
|
-
// Create kernel account with eip7702Account
|
|
201
|
-
const
|
|
185
|
+
// Create kernel account with eip7702Account AND address
|
|
186
|
+
const kernelSessionKeyAccount = await createKernelAccount(publicClient as any, {
|
|
202
187
|
entryPoint,
|
|
203
|
-
eip7702Account: owner as any,
|
|
188
|
+
eip7702Account: owner as any,
|
|
204
189
|
plugins: {
|
|
205
190
|
regular: permissionPlugin,
|
|
206
191
|
},
|
|
207
192
|
kernelVersion: KERNEL_V3_3,
|
|
208
|
-
//
|
|
193
|
+
address: owner.address as Hex, // Include owner's address
|
|
209
194
|
});
|
|
210
195
|
|
|
211
|
-
// Serialize approval
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
196
|
+
// Serialize approval WITH session key private key (critical!)
|
|
197
|
+
const approval = await serializePermissionAccount(
|
|
198
|
+
kernelSessionKeyAccount as any,
|
|
199
|
+
sessionKeyPrivateKey
|
|
200
|
+
);
|
|
215
201
|
|
|
216
202
|
return approval;
|
|
217
203
|
}
|
|
@@ -246,7 +232,7 @@ export async function deserializeSessionKey(options: {
|
|
|
246
232
|
sessionKeySigner: ModularSigner;
|
|
247
233
|
chain: Chain;
|
|
248
234
|
entryPointVersion?: '0.6' | '0.7';
|
|
249
|
-
}): Promise<
|
|
235
|
+
}): Promise<CreateKernelAccountReturnType<"0.6" | "0.7">> {
|
|
250
236
|
const {
|
|
251
237
|
approval,
|
|
252
238
|
sessionKeySigner,
|
|
@@ -263,17 +249,13 @@ export async function deserializeSessionKey(options: {
|
|
|
263
249
|
|
|
264
250
|
// Deserialize WITH the session key signer
|
|
265
251
|
// This is the 5-parameter version (not 4!)
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
// );
|
|
274
|
-
|
|
275
|
-
// Placeholder until SDK is available
|
|
276
|
-
const sessionKeyAccount = null;
|
|
252
|
+
const sessionKeyAccount = await deserializePermissionAccount(
|
|
253
|
+
publicClient,
|
|
254
|
+
entryPoint,
|
|
255
|
+
KERNEL_V3_3,
|
|
256
|
+
approval,
|
|
257
|
+
sessionKeySigner // ← Must pass the signer!
|
|
258
|
+
);
|
|
277
259
|
|
|
278
260
|
return sessionKeyAccount;
|
|
279
261
|
}
|
|
@@ -301,24 +283,35 @@ export function createSessionKeyClient(options: {
|
|
|
301
283
|
chain: Chain;
|
|
302
284
|
bundlerUrl: string;
|
|
303
285
|
paymasterUrl?: string;
|
|
286
|
+
entryPoint?: { address: Hex; version: '0.6' | '0.7' };
|
|
304
287
|
}): any {
|
|
305
288
|
const {
|
|
306
289
|
account,
|
|
307
290
|
chain,
|
|
308
291
|
bundlerUrl,
|
|
309
|
-
paymasterUrl
|
|
292
|
+
paymasterUrl,
|
|
293
|
+
entryPoint = { address: entryPoint07Address, version: '0.7' as const }
|
|
310
294
|
} = options;
|
|
311
295
|
|
|
296
|
+
// Create Pimlico client for gas estimation
|
|
297
|
+
const paymasterClient = createPimlicoClient({
|
|
298
|
+
transport: http(bundlerUrl),
|
|
299
|
+
entryPoint
|
|
300
|
+
});
|
|
301
|
+
|
|
312
302
|
const clientOptions: any = {
|
|
313
303
|
account,
|
|
314
304
|
chain,
|
|
315
|
-
bundlerTransport: http(bundlerUrl)
|
|
305
|
+
bundlerTransport: http(bundlerUrl),
|
|
306
|
+
userOperation: {
|
|
307
|
+
estimateFeesPerGas: async () => (await paymasterClient.getUserOperationGasPrice()).fast,
|
|
308
|
+
}
|
|
316
309
|
};
|
|
317
310
|
|
|
318
311
|
// Add paymaster if provided
|
|
319
312
|
if (paymasterUrl) {
|
|
320
313
|
// Note: Paymaster client creation would go here
|
|
321
|
-
// For now
|
|
314
|
+
// For now using Pimlico gas estimation
|
|
322
315
|
}
|
|
323
316
|
|
|
324
317
|
const kernelClient = createKernelAccountClient(clientOptions);
|
|
@@ -347,16 +340,21 @@ export function createSessionKeyClient(options: {
|
|
|
347
340
|
*/
|
|
348
341
|
export function createUSDCTransferPermission(
|
|
349
342
|
usdcAddress: Hex,
|
|
350
|
-
maxAmount: string
|
|
343
|
+
maxAmount: string,
|
|
344
|
+
destinationAddress: Hex
|
|
351
345
|
): SessionKeyPermissionRule {
|
|
352
346
|
return {
|
|
353
347
|
target: usdcAddress,
|
|
354
348
|
abi: parseAbi(['function transfer(address to, uint256 amount) returns (bool)']) as any,
|
|
355
349
|
functionName: 'transfer',
|
|
356
350
|
args: [
|
|
357
|
-
null, // Any recipient
|
|
358
351
|
{
|
|
359
|
-
condition:
|
|
352
|
+
condition: ParamCondition.EQUAL,
|
|
353
|
+
value: destinationAddress,
|
|
354
|
+
}
|
|
355
|
+
, // Specific recipient
|
|
356
|
+
{
|
|
357
|
+
condition: ParamCondition.LESS_THAN_OR_EQUAL, // LESS_THAN_OR_EQUAL
|
|
360
358
|
value: parseUnits(maxAmount, 6) // USDC has 6 decimals
|
|
361
359
|
}
|
|
362
360
|
]
|
|
@@ -56,7 +56,6 @@ export interface SingleTransactionConfig {
|
|
|
56
56
|
export interface KernelAccountConfig {
|
|
57
57
|
chain: Chain;
|
|
58
58
|
owner: PrivateKeyAccount;
|
|
59
|
-
bundlerManager: BundlerManager;
|
|
60
59
|
entryPointVersion?: EntryPointVersion;
|
|
61
60
|
kernelVersion?: KernelVersion;
|
|
62
61
|
aaConfig?: AA_SupportConfig;
|
|
@@ -141,6 +140,8 @@ export interface GasEstimate {
|
|
|
141
140
|
export interface SessionKeyApprovalOptions {
|
|
142
141
|
/** Session key address to approve */
|
|
143
142
|
sessionKeyAddress: Hex;
|
|
143
|
+
/** Session key private key (needed for serialization) */
|
|
144
|
+
sessionKeyPrivateKey: Hex;
|
|
144
145
|
/** Permission rules for the session key */
|
|
145
146
|
permissions?: SessionKeyPermissionRule[];
|
|
146
147
|
/** Use unrestricted sudo policy (not recommended for production) */
|
|
@@ -45,7 +45,6 @@ import {
|
|
|
45
45
|
} from '../lib/kernel-modules';
|
|
46
46
|
import {
|
|
47
47
|
generateSessionKey,
|
|
48
|
-
recreateSessionKey,
|
|
49
48
|
createSessionKeyApproval,
|
|
50
49
|
deserializeSessionKey,
|
|
51
50
|
createSessionKeyClient,
|
|
@@ -103,8 +102,6 @@ export class AccountAbstractionService {
|
|
|
103
102
|
private static instance: AccountAbstractionService | null = null;
|
|
104
103
|
private bundlerManager: BundlerManager;
|
|
105
104
|
private aaConfig: AA_SupportConfig | undefined;
|
|
106
|
-
private accountCache: Map<string, KernelAccountInstance> = new Map();
|
|
107
|
-
private authorizationCache: Map<string, SignAuthorizationReturnType> = new Map();
|
|
108
105
|
private publicClientCache: Map<number, PublicClient> = new Map();
|
|
109
106
|
|
|
110
107
|
/**
|
|
@@ -142,21 +139,7 @@ export class AccountAbstractionService {
|
|
|
142
139
|
AccountAbstractionService.instance = null;
|
|
143
140
|
}
|
|
144
141
|
|
|
145
|
-
/**
|
|
146
|
-
* Update bundler configuration (creates new bundler manager)
|
|
147
|
-
*/
|
|
148
|
-
updateBundlerConfig(config: AAServiceConfig): void {
|
|
149
|
-
const bundlerConfig: BundlerConfig = {
|
|
150
|
-
provider: config.bundlerProvider,
|
|
151
|
-
apiKey: config.apiKey,
|
|
152
|
-
customUrl: config.customBundlerUrl,
|
|
153
|
-
aaConfig: config.aaConfig
|
|
154
|
-
};
|
|
155
142
|
|
|
156
|
-
this.bundlerManager = createBundlerManager(bundlerConfig);
|
|
157
|
-
this.aaConfig = config.aaConfig;
|
|
158
|
-
this.clearCache();
|
|
159
|
-
}
|
|
160
143
|
|
|
161
144
|
// ============================================
|
|
162
145
|
// Account Management
|
|
@@ -173,12 +156,6 @@ export class AccountAbstractionService {
|
|
|
173
156
|
aaConfig
|
|
174
157
|
} = options;
|
|
175
158
|
|
|
176
|
-
const cacheKey = this.getAccountCacheKey(chain, owner, entryPointVersion);
|
|
177
|
-
|
|
178
|
-
// Return cached account if exists
|
|
179
|
-
if (this.accountCache.has(cacheKey)) {
|
|
180
|
-
return this.accountCache.get(cacheKey)!;
|
|
181
|
-
}
|
|
182
159
|
|
|
183
160
|
// Use aaConfig from options or fallback to service-level config
|
|
184
161
|
const config = aaConfig || this.aaConfig;
|
|
@@ -187,27 +164,13 @@ export class AccountAbstractionService {
|
|
|
187
164
|
const account = await createKernel7702Account({
|
|
188
165
|
chain,
|
|
189
166
|
owner,
|
|
190
|
-
bundlerManager: this.bundlerManager,
|
|
191
167
|
entryPointVersion,
|
|
192
168
|
aaConfig: config
|
|
193
169
|
});
|
|
194
|
-
|
|
195
|
-
// Cache and return
|
|
196
|
-
this.accountCache.set(cacheKey, account);
|
|
197
170
|
return account;
|
|
198
171
|
}
|
|
199
172
|
|
|
200
|
-
|
|
201
|
-
* Get cached account (if exists)
|
|
202
|
-
*/
|
|
203
|
-
getCachedAccount(
|
|
204
|
-
chain: Chain,
|
|
205
|
-
owner: PrivateKeyAccount,
|
|
206
|
-
entryPointVersion: EntryPointVersion = '0.7'
|
|
207
|
-
): KernelAccountInstance | undefined {
|
|
208
|
-
const cacheKey = this.getAccountCacheKey(chain, owner, entryPointVersion);
|
|
209
|
-
return this.accountCache.get(cacheKey);
|
|
210
|
-
}
|
|
173
|
+
|
|
211
174
|
|
|
212
175
|
/**
|
|
213
176
|
* Check if account is already delegated to Kernel
|
|
@@ -230,24 +193,16 @@ export class AccountAbstractionService {
|
|
|
230
193
|
}): Promise<SignAuthorizationReturnType | undefined> {
|
|
231
194
|
const { owner, chain } = options;
|
|
232
195
|
|
|
233
|
-
const cacheKey = this.getAuthorizationCacheKey(chain, owner);
|
|
234
196
|
|
|
235
|
-
// Return cached authorization if exists
|
|
236
|
-
if (this.authorizationCache.has(cacheKey)) {
|
|
237
|
-
return this.authorizationCache.get(cacheKey);
|
|
238
|
-
}
|
|
239
197
|
|
|
240
198
|
// Create authorization
|
|
241
199
|
const authorization = await createKernelAuthorization({
|
|
242
200
|
owner,
|
|
243
201
|
chain,
|
|
244
|
-
|
|
202
|
+
aaConfig: this.aaConfig
|
|
245
203
|
});
|
|
246
204
|
|
|
247
|
-
|
|
248
|
-
if (authorization) {
|
|
249
|
-
this.authorizationCache.set(cacheKey, authorization);
|
|
250
|
-
}
|
|
205
|
+
|
|
251
206
|
|
|
252
207
|
return authorization;
|
|
253
208
|
}
|
|
@@ -340,7 +295,6 @@ export class AccountAbstractionService {
|
|
|
340
295
|
data = '0x',
|
|
341
296
|
authorization
|
|
342
297
|
} = options;
|
|
343
|
-
|
|
344
298
|
// If no authorization provided, try to create one
|
|
345
299
|
let auth = authorization;
|
|
346
300
|
if (!auth) {
|
|
@@ -535,15 +489,7 @@ export class AccountAbstractionService {
|
|
|
535
489
|
return this.bundlerManager;
|
|
536
490
|
}
|
|
537
491
|
|
|
538
|
-
|
|
539
|
-
* Clear all caches
|
|
540
|
-
*/
|
|
541
|
-
clearCache(): void {
|
|
542
|
-
this.accountCache.clear();
|
|
543
|
-
this.authorizationCache.clear();
|
|
544
|
-
this.publicClientCache.clear();
|
|
545
|
-
this.bundlerManager.clearCache();
|
|
546
|
-
}
|
|
492
|
+
|
|
547
493
|
|
|
548
494
|
// ============================================
|
|
549
495
|
// Module Management (ERC-7579)
|
|
@@ -844,21 +790,7 @@ export class AccountAbstractionService {
|
|
|
844
790
|
return await generateSessionKey();
|
|
845
791
|
}
|
|
846
792
|
|
|
847
|
-
|
|
848
|
-
* Recreate session key from private key
|
|
849
|
-
*
|
|
850
|
-
* Recreates a session key signer from a stored private key.
|
|
851
|
-
*
|
|
852
|
-
* @param privateKey - The session key private key
|
|
853
|
-
* @returns Session key info
|
|
854
|
-
*
|
|
855
|
-
* @example
|
|
856
|
-
* // Agent recreates session key from storage
|
|
857
|
-
* const sessionKey = await aaService.recreateSessionKey(storedPrivateKey);
|
|
858
|
-
*/
|
|
859
|
-
async recreateSessionKey(privateKey: Hex): Promise<SessionKeyInfo> {
|
|
860
|
-
return await recreateSessionKey(privateKey);
|
|
861
|
-
}
|
|
793
|
+
|
|
862
794
|
|
|
863
795
|
/**
|
|
864
796
|
* Create session key approval (Owner side)
|
|
@@ -892,6 +824,7 @@ export class AccountAbstractionService {
|
|
|
892
824
|
*/
|
|
893
825
|
async createSessionKeyApproval(options: {
|
|
894
826
|
sessionKeyAddress: Hex;
|
|
827
|
+
sessionKeyPrivateKey: Hex;
|
|
895
828
|
owner: PrivateKeyAccount;
|
|
896
829
|
chain: Chain;
|
|
897
830
|
entryPointVersion?: '0.6' | '0.7';
|
|
@@ -924,7 +857,7 @@ export class AccountAbstractionService {
|
|
|
924
857
|
sessionKeySigner: ModularSigner;
|
|
925
858
|
chain: Chain;
|
|
926
859
|
entryPointVersion?: '0.6' | '0.7';
|
|
927
|
-
})
|
|
860
|
+
}) {
|
|
928
861
|
return await deserializeSessionKey(options);
|
|
929
862
|
}
|
|
930
863
|
|
|
@@ -976,9 +909,10 @@ export class AccountAbstractionService {
|
|
|
976
909
|
*/
|
|
977
910
|
createUSDCTransferPermission(
|
|
978
911
|
usdcAddress: Hex,
|
|
979
|
-
maxAmount: string
|
|
912
|
+
maxAmount: string,
|
|
913
|
+
destinationAddress: Hex
|
|
980
914
|
): SessionKeyPermissionRule {
|
|
981
|
-
return createUSDCTransferPermission(usdcAddress, maxAmount);
|
|
915
|
+
return createUSDCTransferPermission(usdcAddress, maxAmount, destinationAddress);
|
|
982
916
|
}
|
|
983
917
|
|
|
984
918
|
/**
|
|
@@ -91,7 +91,8 @@ class PimlicoBundler implements BundlerService {
|
|
|
91
91
|
chain,
|
|
92
92
|
userOperation: {
|
|
93
93
|
estimateFeesPerGas: async () => (await paymasterClient.getUserOperationGasPrice()).fast,
|
|
94
|
-
}
|
|
94
|
+
},
|
|
95
|
+
// paymaster: paymasterClient,
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
this.clientCache.set(chain.id, client);
|