@alchemy/smart-accounts 5.0.0-beta.2 → 5.0.0-beta.21
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 +0 -2
- package/dist/esm/index.d.ts +3 -6
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/light-account/accounts/base.js +0 -1
- package/dist/esm/light-account/accounts/base.js.map +1 -1
- package/dist/esm/light-account/accounts/calldataCodec.d.ts +17 -0
- package/dist/esm/light-account/accounts/calldataCodec.js +17 -0
- package/dist/esm/light-account/accounts/calldataCodec.js.map +1 -1
- package/dist/esm/light-account/utils.js +0 -5
- package/dist/esm/light-account/utils.js.map +1 -1
- package/dist/esm/ma-v1/accounts/base.js +6 -50
- package/dist/esm/ma-v1/accounts/base.js.map +1 -1
- package/dist/esm/ma-v1/accounts/calldataCodec.d.ts +20 -0
- package/dist/esm/ma-v1/accounts/calldataCodec.js +69 -0
- package/dist/esm/ma-v1/accounts/calldataCodec.js.map +1 -0
- package/dist/esm/ma-v1/mav1StaticImpl.d.ts +0 -2
- package/dist/esm/ma-v1/mav1StaticImpl.js +0 -2
- package/dist/esm/ma-v1/mav1StaticImpl.js.map +1 -1
- package/dist/esm/ma-v2/accounts/account.js +1 -1
- package/dist/esm/ma-v2/accounts/account.js.map +1 -1
- package/dist/esm/ma-v2/accounts/base.js +7 -54
- package/dist/esm/ma-v2/accounts/base.js.map +1 -1
- package/dist/esm/ma-v2/accounts/calldataCodec.d.ts +20 -0
- package/dist/esm/ma-v2/accounts/calldataCodec.js +77 -0
- package/dist/esm/ma-v2/accounts/calldataCodec.js.map +1 -0
- package/dist/esm/ma-v2/decorators/installValidation.d.ts +8 -20
- package/dist/esm/ma-v2/decorators/installValidation.js +7 -58
- package/dist/esm/ma-v2/decorators/installValidation.js.map +1 -1
- package/dist/esm/ma-v2/mav2StaticImpl.d.ts +0 -4
- package/dist/esm/ma-v2/mav2StaticImpl.js +0 -4
- package/dist/esm/ma-v2/mav2StaticImpl.js.map +1 -1
- package/dist/esm/ma-v2/utils/account.js +0 -2
- package/dist/esm/ma-v2/utils/account.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/types/index.d.ts +3 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/light-account/accounts/base.d.ts.map +1 -1
- package/dist/types/light-account/accounts/calldataCodec.d.ts +17 -0
- package/dist/types/light-account/accounts/calldataCodec.d.ts.map +1 -1
- package/dist/types/light-account/utils.d.ts.map +1 -1
- package/dist/types/ma-v1/accounts/base.d.ts.map +1 -1
- package/dist/types/ma-v1/accounts/calldataCodec.d.ts +21 -0
- package/dist/types/ma-v1/accounts/calldataCodec.d.ts.map +1 -0
- package/dist/types/ma-v1/mav1StaticImpl.d.ts +0 -2
- package/dist/types/ma-v1/mav1StaticImpl.d.ts.map +1 -1
- package/dist/types/ma-v2/accounts/base.d.ts.map +1 -1
- package/dist/types/ma-v2/accounts/calldataCodec.d.ts +21 -0
- package/dist/types/ma-v2/accounts/calldataCodec.d.ts.map +1 -0
- package/dist/types/ma-v2/decorators/installValidation.d.ts +8 -20
- package/dist/types/ma-v2/decorators/installValidation.d.ts.map +1 -1
- package/dist/types/ma-v2/mav2StaticImpl.d.ts +0 -4
- package/dist/types/ma-v2/mav2StaticImpl.d.ts.map +1 -1
- package/dist/types/ma-v2/utils/account.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/index.ts +15 -13
- package/src/light-account/accounts/base.ts +0 -1
- package/src/light-account/accounts/calldataCodec.ts +17 -0
- package/src/light-account/utils.ts +0 -6
- package/src/ma-v1/accounts/base.ts +4 -55
- package/src/ma-v1/accounts/calldataCodec.ts +80 -0
- package/src/ma-v1/mav1StaticImpl.ts +0 -2
- package/src/ma-v2/accounts/account.ts +2 -2
- package/src/ma-v2/accounts/base.ts +6 -68
- package/src/ma-v2/accounts/calldataCodec.ts +89 -0
- package/src/ma-v2/decorators/installValidation.ts +8 -83
- package/src/ma-v2/mav2StaticImpl.ts +0 -4
- package/src/ma-v2/utils/account.ts +0 -2
- package/src/version.ts +1 -1
- package/dist/esm/light-account/decorators/multiOwner.d.ts +0 -17
- package/dist/esm/light-account/decorators/multiOwner.js +0 -39
- package/dist/esm/light-account/decorators/multiOwner.js.map +0 -1
- package/dist/esm/light-account/decorators/singleOwner.d.ts +0 -16
- package/dist/esm/light-account/decorators/singleOwner.js +0 -35
- package/dist/esm/light-account/decorators/singleOwner.js.map +0 -1
- package/dist/esm/ma-v1/decorators/multiOwner.d.ts +0 -17
- package/dist/esm/ma-v1/decorators/multiOwner.js +0 -39
- package/dist/esm/ma-v1/decorators/multiOwner.js.map +0 -1
- package/dist/types/light-account/decorators/multiOwner.d.ts +0 -18
- package/dist/types/light-account/decorators/multiOwner.d.ts.map +0 -1
- package/dist/types/light-account/decorators/singleOwner.d.ts +0 -17
- package/dist/types/light-account/decorators/singleOwner.d.ts.map +0 -1
- package/dist/types/ma-v1/decorators/multiOwner.d.ts +0 -18
- package/dist/types/ma-v1/decorators/multiOwner.d.ts.map +0 -1
- package/src/light-account/decorators/multiOwner.ts +0 -72
- package/src/light-account/decorators/singleOwner.ts +0 -63
- package/src/ma-v1/decorators/multiOwner.ts +0 -72
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
type Transport,
|
|
9
9
|
type Hash,
|
|
10
10
|
type TypedDataDefinition,
|
|
11
|
-
encodeFunctionData,
|
|
12
11
|
} from "viem";
|
|
13
12
|
import {
|
|
14
13
|
entryPoint06Abi,
|
|
@@ -21,16 +20,15 @@ import type {
|
|
|
21
20
|
SignatureRequest,
|
|
22
21
|
SmartAccountWithDecodeCalls,
|
|
23
22
|
} from "../../types.js";
|
|
24
|
-
import { IStandardExecutorAbi } from "../abis/IStandardExecutor.js";
|
|
25
23
|
import { signMessage, signTypedData } from "viem/actions";
|
|
26
24
|
import {
|
|
27
|
-
decodeFunctionData,
|
|
28
25
|
getAction,
|
|
29
26
|
hashMessage,
|
|
30
27
|
hashTypedData,
|
|
31
28
|
isAddressEqual,
|
|
32
29
|
} from "viem/utils";
|
|
33
30
|
import { BaseError } from "@alchemy/common";
|
|
31
|
+
import { encodeCallsMAv1, decodeCallsMAv1 } from "./calldataCodec.js";
|
|
34
32
|
|
|
35
33
|
type MaV1AccountType = "MultiOwnerModularAccountV1"; // Currently no SDK v5 support for "MultiSigModularAccountV1".
|
|
36
34
|
|
|
@@ -112,10 +110,6 @@ export async function toModularAccountV1Base<
|
|
|
112
110
|
},
|
|
113
111
|
|
|
114
112
|
async encodeCalls(calls) {
|
|
115
|
-
if (!calls.length) {
|
|
116
|
-
throw new BaseError("No calls to encode.");
|
|
117
|
-
}
|
|
118
|
-
|
|
119
113
|
if (calls.length === 1) {
|
|
120
114
|
const call = calls[0];
|
|
121
115
|
|
|
@@ -127,59 +121,14 @@ export async function toModularAccountV1Base<
|
|
|
127
121
|
|
|
128
122
|
return call.data;
|
|
129
123
|
}
|
|
130
|
-
|
|
131
|
-
return encodeFunctionData({
|
|
132
|
-
abi: IStandardExecutorAbi,
|
|
133
|
-
functionName: "execute",
|
|
134
|
-
args: [call.to, call.value ?? 0n, call.data ?? "0x"],
|
|
135
|
-
});
|
|
136
124
|
}
|
|
137
125
|
|
|
138
|
-
return
|
|
139
|
-
abi: IStandardExecutorAbi,
|
|
140
|
-
functionName: "executeBatch",
|
|
141
|
-
args: [
|
|
142
|
-
calls.map((call) => ({
|
|
143
|
-
target: call.to,
|
|
144
|
-
value: call.value ?? 0n,
|
|
145
|
-
data: call.data ?? "0x",
|
|
146
|
-
})),
|
|
147
|
-
],
|
|
148
|
-
});
|
|
126
|
+
return encodeCallsMAv1(calls);
|
|
149
127
|
},
|
|
150
128
|
|
|
151
129
|
// Inverse of `encodeCalls`.
|
|
152
130
|
async decodeCalls(data) {
|
|
153
|
-
|
|
154
|
-
abi: IStandardExecutorAbi,
|
|
155
|
-
data,
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
if (decoded.functionName === "execute") {
|
|
159
|
-
return [
|
|
160
|
-
{
|
|
161
|
-
to: decoded.args[0],
|
|
162
|
-
value: decoded.args[1],
|
|
163
|
-
data: decoded.args[2],
|
|
164
|
-
},
|
|
165
|
-
];
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (decoded.functionName === "executeBatch") {
|
|
169
|
-
return decoded.args[0].map((call) => ({
|
|
170
|
-
to: call.target,
|
|
171
|
-
value: call.value,
|
|
172
|
-
data: call.data,
|
|
173
|
-
}));
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// If the data is not for an `execute` or `executeBatch` call, we treat it as a single call to the account itself.
|
|
177
|
-
return [
|
|
178
|
-
{
|
|
179
|
-
to: accountAddress,
|
|
180
|
-
data,
|
|
181
|
-
},
|
|
182
|
-
];
|
|
131
|
+
return decodeCallsMAv1(data, accountAddress);
|
|
183
132
|
},
|
|
184
133
|
|
|
185
134
|
async getStubSignature() {
|
|
@@ -211,7 +160,7 @@ export async function toModularAccountV1Base<
|
|
|
211
160
|
);
|
|
212
161
|
const { type, data } = await prepareSignature({
|
|
213
162
|
type: "eth_signTypedData_v4",
|
|
214
|
-
data: params as TypedDataDefinition,
|
|
163
|
+
data: params as TypedDataDefinition,
|
|
215
164
|
});
|
|
216
165
|
return type === "personal_sign"
|
|
217
166
|
? signMessageAction({ account: owner, message: data })
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decodeFunctionData,
|
|
3
|
+
encodeFunctionData,
|
|
4
|
+
type Address,
|
|
5
|
+
type Call,
|
|
6
|
+
type Hex,
|
|
7
|
+
} from "viem";
|
|
8
|
+
import { IStandardExecutorAbi } from "../abis/IStandardExecutor.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Encodes an array of calls into ModularAccountV1 calldata for `execute` or `executeBatch`.
|
|
12
|
+
* Used internally by the ModularAccountV1 SmartAccount implementation. Typically not needed
|
|
13
|
+
* directly unless you have an advanced use case.
|
|
14
|
+
*
|
|
15
|
+
* @param {Call[]} calls The calls to encode.
|
|
16
|
+
* @returns {Hex} The encoded calldata.
|
|
17
|
+
*/
|
|
18
|
+
export function encodeCallsMAv1(calls: readonly Call[]): Hex {
|
|
19
|
+
if (calls.length === 1) {
|
|
20
|
+
return encodeFunctionData({
|
|
21
|
+
abi: IStandardExecutorAbi,
|
|
22
|
+
functionName: "execute",
|
|
23
|
+
args: [calls[0].to, calls[0].value ?? 0n, calls[0].data ?? "0x"],
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return encodeFunctionData({
|
|
28
|
+
abi: IStandardExecutorAbi,
|
|
29
|
+
functionName: "executeBatch",
|
|
30
|
+
args: [
|
|
31
|
+
calls.map((call) => ({
|
|
32
|
+
target: call.to,
|
|
33
|
+
value: call.value ?? 0n,
|
|
34
|
+
data: call.data ?? "0x",
|
|
35
|
+
})),
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Decodes ModularAccountV1 calldata back into an array of calls.
|
|
42
|
+
* Used internally by the ModularAccountV1 SmartAccount implementation. Typically not needed
|
|
43
|
+
* directly unless you have an advanced use case.
|
|
44
|
+
*
|
|
45
|
+
* @param {Hex} data The calldata to decode.
|
|
46
|
+
* @param {Address} accountAddress The account address, used as the `to` for unrecognized selectors.
|
|
47
|
+
* @returns {Call[]} The decoded calls.
|
|
48
|
+
*/
|
|
49
|
+
export function decodeCallsMAv1(data: Hex, accountAddress: Address): Call[] {
|
|
50
|
+
const decoded = decodeFunctionData({
|
|
51
|
+
abi: IStandardExecutorAbi,
|
|
52
|
+
data,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (decoded.functionName === "execute") {
|
|
56
|
+
return [
|
|
57
|
+
{
|
|
58
|
+
to: decoded.args[0],
|
|
59
|
+
value: decoded.args[1],
|
|
60
|
+
data: decoded.args[2],
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (decoded.functionName === "executeBatch") {
|
|
66
|
+
return decoded.args[0].map((call) => ({
|
|
67
|
+
to: call.target,
|
|
68
|
+
value: call.value,
|
|
69
|
+
data: call.data,
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// If the data is not for an `execute` or `executeBatch` call, treat it as a single call to the account itself.
|
|
74
|
+
return [
|
|
75
|
+
{
|
|
76
|
+
to: accountAddress,
|
|
77
|
+
data,
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
}
|
|
@@ -14,8 +14,6 @@ export type MultiOwnerModularAccountV1FactoryArgs = {
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Static implementation logic for ModularAccountV1.
|
|
17
|
-
*
|
|
18
|
-
* TODO(v5): update JSDoc format when doc-gen supports structs or records.
|
|
19
17
|
*/
|
|
20
18
|
export const multiOwnerModularAccountStaticImpl: StaticSmartAccountImplementation<
|
|
21
19
|
false,
|
|
@@ -27,7 +27,7 @@ import { LOGGER } from "../../logger.js";
|
|
|
27
27
|
|
|
28
28
|
type Mode = "default" | "7702";
|
|
29
29
|
|
|
30
|
-
//
|
|
30
|
+
// This may be extended in the future with additional MAv2-specific methods.
|
|
31
31
|
export type ModularAccountV2 = ModularAccountV2Base & {};
|
|
32
32
|
|
|
33
33
|
export type ToModularAccountV2Params<
|
|
@@ -193,6 +193,6 @@ export async function toModularAccountV2<TMode extends Mode = Mode>({
|
|
|
193
193
|
|
|
194
194
|
return {
|
|
195
195
|
...base,
|
|
196
|
-
//
|
|
196
|
+
// This may be extended in the future with additional MAv2-specific methods.
|
|
197
197
|
};
|
|
198
198
|
}
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
type Transport,
|
|
9
9
|
concat,
|
|
10
10
|
concatHex,
|
|
11
|
-
encodeFunctionData,
|
|
12
11
|
hashMessage,
|
|
13
12
|
hashTypedData,
|
|
14
13
|
type TypedDataDefinition,
|
|
@@ -42,12 +41,7 @@ import type {
|
|
|
42
41
|
SignatureRequest,
|
|
43
42
|
SmartAccountWithDecodeCalls,
|
|
44
43
|
} from "../../types.js";
|
|
45
|
-
import {
|
|
46
|
-
decodeFunctionData,
|
|
47
|
-
getAction,
|
|
48
|
-
isAddressEqual,
|
|
49
|
-
sliceHex,
|
|
50
|
-
} from "viem/utils";
|
|
44
|
+
import { getAction, isAddressEqual } from "viem/utils";
|
|
51
45
|
import {
|
|
52
46
|
DEFAULT_OWNER_ENTITY_ID,
|
|
53
47
|
DefaultModuleAddress,
|
|
@@ -64,6 +58,7 @@ import { InvalidDeferredActionNonceError } from "../../errors/InvalidDeferredAct
|
|
|
64
58
|
import { InvalidNonceKeyError } from "../../errors/InvalidNonceKeyError.js";
|
|
65
59
|
import { InvalidEntityIdError } from "../../errors/InvalidEntityIdError.js";
|
|
66
60
|
import { is7702Delegated } from "../../utils.js";
|
|
61
|
+
import { encodeCallsMAv2, decodeCallsMAv2 } from "./calldataCodec.js";
|
|
67
62
|
|
|
68
63
|
export type ValidationDataParams =
|
|
69
64
|
| {
|
|
@@ -336,76 +331,19 @@ export async function toModularAccountV2Base<
|
|
|
336
331
|
if (isAddressEqual(call.to, accountAddress)) {
|
|
337
332
|
// If the call is to the account itself, we need to avoid wrapping it in an `execute` call.
|
|
338
333
|
|
|
339
|
-
if (call.data
|
|
334
|
+
if (call.data == null) {
|
|
340
335
|
throw new BaseError("Data is required for an account self-call.");
|
|
341
336
|
}
|
|
342
337
|
|
|
343
338
|
return encodeCallData(call.data);
|
|
344
339
|
}
|
|
345
|
-
|
|
346
|
-
return encodeCallData(
|
|
347
|
-
encodeFunctionData({
|
|
348
|
-
abi: modularAccountAbi,
|
|
349
|
-
functionName: "execute",
|
|
350
|
-
args: [call.to, call.value ?? 0n, call.data ?? "0x"],
|
|
351
|
-
}),
|
|
352
|
-
);
|
|
353
340
|
}
|
|
354
341
|
|
|
355
|
-
return encodeCallData(
|
|
356
|
-
encodeFunctionData({
|
|
357
|
-
abi: modularAccountAbi,
|
|
358
|
-
functionName: "executeBatch",
|
|
359
|
-
args: [
|
|
360
|
-
calls.map((call) => ({
|
|
361
|
-
target: call.to,
|
|
362
|
-
data: call.data ?? "0x",
|
|
363
|
-
value: call.value ?? 0n,
|
|
364
|
-
})),
|
|
365
|
-
],
|
|
366
|
-
}),
|
|
367
|
-
);
|
|
342
|
+
return encodeCallData(encodeCallsMAv2(calls));
|
|
368
343
|
},
|
|
369
344
|
|
|
370
345
|
async decodeCalls(data) {
|
|
371
|
-
|
|
372
|
-
// Trim the EXECUTE_USER_OP_SELECTOR if it is present.
|
|
373
|
-
const trimmedData = data
|
|
374
|
-
.toLowerCase()
|
|
375
|
-
.startsWith(EXECUTE_USER_OP_SELECTOR.toLowerCase())
|
|
376
|
-
? sliceHex(data, 4)
|
|
377
|
-
: data;
|
|
378
|
-
|
|
379
|
-
const decoded = decodeFunctionData({
|
|
380
|
-
abi: modularAccountAbi,
|
|
381
|
-
data: trimmedData,
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
if (decoded.functionName === "execute") {
|
|
385
|
-
return [
|
|
386
|
-
{
|
|
387
|
-
to: decoded.args[0],
|
|
388
|
-
value: decoded.args[1],
|
|
389
|
-
data: decoded.args[2],
|
|
390
|
-
},
|
|
391
|
-
];
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (decoded.functionName === "executeBatch") {
|
|
395
|
-
return decoded.args[0].map((call) => ({
|
|
396
|
-
to: call.target,
|
|
397
|
-
value: call.value,
|
|
398
|
-
data: call.data,
|
|
399
|
-
}));
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// If the data is not for an `execute` or `executeBatch` call, we treat it as a single call to the account itself.
|
|
403
|
-
return [
|
|
404
|
-
{
|
|
405
|
-
to: accountAddress,
|
|
406
|
-
data,
|
|
407
|
-
},
|
|
408
|
-
];
|
|
346
|
+
return decodeCallsMAv2(data, accountAddress);
|
|
409
347
|
},
|
|
410
348
|
|
|
411
349
|
async getStubSignature() {
|
|
@@ -442,7 +380,7 @@ export async function toModularAccountV2Base<
|
|
|
442
380
|
|
|
443
381
|
const { data } = await prepareSignature({
|
|
444
382
|
type: "eth_signTypedData_v4",
|
|
445
|
-
data: td as TypedDataDefinition,
|
|
383
|
+
data: td as TypedDataDefinition,
|
|
446
384
|
});
|
|
447
385
|
|
|
448
386
|
const action = getAction(client, signTypedData, "signTypedData");
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decodeFunctionData,
|
|
3
|
+
encodeFunctionData,
|
|
4
|
+
type Address,
|
|
5
|
+
type Call,
|
|
6
|
+
type Hex,
|
|
7
|
+
} from "viem";
|
|
8
|
+
import { sliceHex } from "viem/utils";
|
|
9
|
+
import { modularAccountAbi } from "../abis/modularAccountAbi.js";
|
|
10
|
+
import { EXECUTE_USER_OP_SELECTOR } from "../utils/account.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Encodes an array of calls into ModularAccountV2 calldata for `execute` or `executeBatch`.
|
|
14
|
+
* Used internally by the ModularAccountV2 SmartAccount implementation. Typically not needed
|
|
15
|
+
* directly unless you have an advanced use case.
|
|
16
|
+
*
|
|
17
|
+
* @param {Call[]} calls The calls to encode.
|
|
18
|
+
* @returns {Hex} The encoded calldata.
|
|
19
|
+
*/
|
|
20
|
+
export function encodeCallsMAv2(calls: readonly Call[]): Hex {
|
|
21
|
+
if (calls.length === 1) {
|
|
22
|
+
return encodeFunctionData({
|
|
23
|
+
abi: modularAccountAbi,
|
|
24
|
+
functionName: "execute",
|
|
25
|
+
args: [calls[0].to, calls[0].value ?? 0n, calls[0].data ?? "0x"],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return encodeFunctionData({
|
|
30
|
+
abi: modularAccountAbi,
|
|
31
|
+
functionName: "executeBatch",
|
|
32
|
+
args: [
|
|
33
|
+
calls.map((call) => ({
|
|
34
|
+
target: call.to,
|
|
35
|
+
data: call.data ?? "0x",
|
|
36
|
+
value: call.value ?? 0n,
|
|
37
|
+
})),
|
|
38
|
+
],
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Decodes ModularAccountV2 calldata back into an array of calls. Strips the `EXECUTE_USER_OP_SELECTOR` prefix if present.
|
|
44
|
+
* Used internally by the ModularAccountV2 SmartAccount implementation. Typically not needed
|
|
45
|
+
* directly unless you have an advanced use case.
|
|
46
|
+
*
|
|
47
|
+
* @param {Hex} data The calldata to decode.
|
|
48
|
+
* @param {Address} accountAddress The account address, used as the `to` for unrecognized selectors.
|
|
49
|
+
* @returns {Call[]} The decoded calls.
|
|
50
|
+
*/
|
|
51
|
+
export function decodeCallsMAv2(data: Hex, accountAddress: Address): Call[] {
|
|
52
|
+
// Strip the EXECUTE_USER_OP_SELECTOR prefix if present.
|
|
53
|
+
const trimmedData = data
|
|
54
|
+
.toLowerCase()
|
|
55
|
+
.startsWith(EXECUTE_USER_OP_SELECTOR.toLowerCase())
|
|
56
|
+
? sliceHex(data, 4)
|
|
57
|
+
: data;
|
|
58
|
+
|
|
59
|
+
const decoded = decodeFunctionData({
|
|
60
|
+
abi: modularAccountAbi,
|
|
61
|
+
data: trimmedData,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
if (decoded.functionName === "execute") {
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
to: decoded.args[0],
|
|
68
|
+
value: decoded.args[1],
|
|
69
|
+
data: decoded.args[2],
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (decoded.functionName === "executeBatch") {
|
|
75
|
+
return decoded.args[0].map((call) => ({
|
|
76
|
+
to: call.target,
|
|
77
|
+
value: call.value,
|
|
78
|
+
data: call.data,
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// If the data is not for an `execute` or `executeBatch` call, treat it as a single call to the account itself.
|
|
83
|
+
return [
|
|
84
|
+
{
|
|
85
|
+
to: accountAddress,
|
|
86
|
+
data,
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
}
|
|
@@ -13,8 +13,7 @@ import type { HookConfig, ValidationConfig } from "../types.js";
|
|
|
13
13
|
import type { ModularAccountV2 } from "../accounts/account.js";
|
|
14
14
|
import type { GetAccountParameter } from "../../types.js";
|
|
15
15
|
import { semiModularAccountBytecodeAbi } from "../abis/semiModularAccountBytecodeAbi.js";
|
|
16
|
-
import {
|
|
17
|
-
import { getAction } from "viem/utils";
|
|
16
|
+
import type { SmartAccount } from "viem/account-abstraction";
|
|
18
17
|
import { AccountNotFoundError } from "@alchemy/common";
|
|
19
18
|
import { EntityIdOverrideError } from "../../errors/EntityIdOverrideError.js";
|
|
20
19
|
import {
|
|
@@ -54,33 +53,26 @@ export type InstallValidationActions<
|
|
|
54
53
|
encodeInstallValidation: (
|
|
55
54
|
args: InstallValidationParams<TAccount>,
|
|
56
55
|
) => Promise<Hex>;
|
|
57
|
-
installValidation: (args: InstallValidationParams<TAccount>) => Promise<Hex>;
|
|
58
56
|
encodeUninstallValidation: (
|
|
59
57
|
args: UninstallValidationParams<TAccount>,
|
|
60
58
|
) => Promise<Hex>;
|
|
61
|
-
uninstallValidation: (
|
|
62
|
-
args: UninstallValidationParams<TAccount>,
|
|
63
|
-
) => Promise<Hex>;
|
|
64
59
|
};
|
|
65
60
|
|
|
66
|
-
// TODO(v5): update jsdoc
|
|
67
61
|
/**
|
|
68
|
-
* Provides validation installation and uninstallation functionalities for a MA v2 client
|
|
62
|
+
* Provides validation installation and uninstallation encoding functionalities for a MA v2 client.
|
|
69
63
|
*
|
|
70
64
|
* @example
|
|
71
65
|
* ```ts
|
|
72
|
-
* import {
|
|
66
|
+
* import { installValidationActions, SingleSignerValidationModule } from "@alchemy/smart-accounts";
|
|
73
67
|
* import { Address } from "viem";
|
|
74
68
|
*
|
|
75
69
|
* const client = (await createModularAccountV2Client({ ... })).extend(installValidationActions);
|
|
76
70
|
* const sessionKeyAddress: Address = "0x1234";
|
|
77
71
|
* const sessionKeyEntityId: number = 1;
|
|
78
72
|
*
|
|
79
|
-
* await client.
|
|
73
|
+
* const callData = await client.encodeInstallValidation({
|
|
80
74
|
* validationConfig: {
|
|
81
|
-
* moduleAddress: getDefaultSingleSignerValidationModuleAddress(
|
|
82
|
-
* client.chain
|
|
83
|
-
* ),
|
|
75
|
+
* moduleAddress: getDefaultSingleSignerValidationModuleAddress(client.chain),
|
|
84
76
|
* entityId: sessionKeyEntityId,
|
|
85
77
|
* isGlobal: true,
|
|
86
78
|
* isSignatureValidation: false,
|
|
@@ -94,19 +86,11 @@ export type InstallValidationActions<
|
|
|
94
86
|
* hooks: [],
|
|
95
87
|
* });
|
|
96
88
|
*
|
|
97
|
-
* await client.
|
|
98
|
-
* moduleAddress: sessionKeyAddress,
|
|
99
|
-
* entityId: sessionKeyEntityId,
|
|
100
|
-
* uninstallData: SingleSignerValidationModule.encodeOnUninstallData({
|
|
101
|
-
* entityId: sessionKeyEntityId,
|
|
102
|
-
* }),
|
|
103
|
-
* hookUninstallDatas: [],
|
|
104
|
-
* });
|
|
105
|
-
*
|
|
89
|
+
* await client.sendUserOperation({ callData, account });
|
|
106
90
|
* ```
|
|
107
91
|
*
|
|
108
|
-
* @param {object} client - The client instance which provides account
|
|
109
|
-
* @returns {object} - An object containing
|
|
92
|
+
* @param {object} client - The client instance which provides account functionality.
|
|
93
|
+
* @returns {object} - An object containing `encodeInstallValidation` and `encodeUninstallValidation`.
|
|
110
94
|
*/
|
|
111
95
|
export function installValidationActions<
|
|
112
96
|
TTransport extends Transport = Transport,
|
|
@@ -194,64 +178,5 @@ export function installValidationActions<
|
|
|
194
178
|
return {
|
|
195
179
|
encodeInstallValidation,
|
|
196
180
|
encodeUninstallValidation,
|
|
197
|
-
installValidation: async (args) => {
|
|
198
|
-
const {
|
|
199
|
-
validationConfig,
|
|
200
|
-
selectors,
|
|
201
|
-
installData,
|
|
202
|
-
hooks,
|
|
203
|
-
account = client.account,
|
|
204
|
-
} = args;
|
|
205
|
-
|
|
206
|
-
if (!account || !isModularAccountV2(account)) {
|
|
207
|
-
throw new AccountNotFoundError();
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const callData = await encodeInstallValidation({
|
|
211
|
-
validationConfig,
|
|
212
|
-
selectors,
|
|
213
|
-
installData,
|
|
214
|
-
hooks,
|
|
215
|
-
account,
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
const action = getAction(client, sendUserOperation, "sendUserOperation");
|
|
219
|
-
const result = await action({
|
|
220
|
-
callData,
|
|
221
|
-
account,
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
return result;
|
|
225
|
-
},
|
|
226
|
-
|
|
227
|
-
uninstallValidation: async (args) => {
|
|
228
|
-
const {
|
|
229
|
-
moduleAddress,
|
|
230
|
-
entityId,
|
|
231
|
-
uninstallData,
|
|
232
|
-
hookUninstallDatas,
|
|
233
|
-
account = client.account,
|
|
234
|
-
} = args;
|
|
235
|
-
|
|
236
|
-
if (!account || !isModularAccountV2(account)) {
|
|
237
|
-
throw new AccountNotFoundError();
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const callData = await encodeUninstallValidation({
|
|
241
|
-
moduleAddress,
|
|
242
|
-
entityId,
|
|
243
|
-
uninstallData,
|
|
244
|
-
hookUninstallDatas,
|
|
245
|
-
account,
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
const action = getAction(client, sendUserOperation, "sendUserOperation");
|
|
249
|
-
const result = await action({
|
|
250
|
-
callData,
|
|
251
|
-
account,
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
return result;
|
|
255
|
-
},
|
|
256
181
|
};
|
|
257
182
|
}
|
|
@@ -36,8 +36,6 @@ const semiModularAccountBase = {
|
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Static implementation logic for SemiModularAccountV2.
|
|
39
|
-
*
|
|
40
|
-
* TODO(v5): update JSDoc format when doc-gen supports structs or records.
|
|
41
39
|
*/
|
|
42
40
|
export const semiModularAccountV2StaticImpl: SemiModularAccountV2StaticImpl = {
|
|
43
41
|
...semiModularAccountBase,
|
|
@@ -73,8 +71,6 @@ export type SemiModularAccount7702StaticImpl = StaticSmartAccountImplementation<
|
|
|
73
71
|
|
|
74
72
|
/**
|
|
75
73
|
* Static implementation logic for SemiModularAccount7702.
|
|
76
|
-
*
|
|
77
|
-
* TODO(v5): update JSDoc format when doc-gen supports structs or records.
|
|
78
74
|
*/
|
|
79
75
|
export const semiModularAccount7702StaticImpl: SemiModularAccount7702StaticImpl =
|
|
80
76
|
{
|
|
@@ -64,8 +64,6 @@ export async function getMAV2UpgradeToData(
|
|
|
64
64
|
return {
|
|
65
65
|
implAddress: DefaultAddress.SMAV2_STORAGE,
|
|
66
66
|
initializationData: initData,
|
|
67
|
-
// TODO(v5): do we need `createModularAccountV2FromExisting()` in the return type here like we had in v4 or no?
|
|
68
|
-
// Almost certainly not, but we need to clean up other parts in SDK for client-side upgrades.
|
|
69
67
|
};
|
|
70
68
|
}
|
|
71
69
|
|
package/src/version.ts
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { Address, Chain, Client, Hex, IsUndefined, Transport } from "viem";
|
|
2
|
-
import { type SmartAccount } from "viem/account-abstraction";
|
|
3
|
-
import type { GetAccountParameter } from "../../types.js";
|
|
4
|
-
import type { MultiOwnerLightAccount } from "../accounts/multi-owner-account.js";
|
|
5
|
-
export type MultiOwnerLightAccountActions<TAccount extends MultiOwnerLightAccount | undefined = MultiOwnerLightAccount | undefined> = {
|
|
6
|
-
updateOwners: (args: {
|
|
7
|
-
ownersToAdd: Address[];
|
|
8
|
-
ownersToRemove: Address[];
|
|
9
|
-
} & GetAccountParameter<TAccount, MultiOwnerLightAccount>) => Promise<Hex>;
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* Generates client actions for a multi-owner light account, including the ability to update owners.
|
|
13
|
-
*
|
|
14
|
-
* @param {Client<TTransport, TChain, TAccount>} client The client instance used to interact with the account
|
|
15
|
-
* @returns {MultiOwnerLightAccountActions<TAccount>} An object containing the client actions specifically for a multi-owner light account
|
|
16
|
-
*/
|
|
17
|
-
export declare function multiOwnerLightAccountActions<TTransport extends Transport = Transport, TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = SmartAccount | undefined>(client: Client<TTransport, TChain, TAccount>): MultiOwnerLightAccountActions<IsUndefined<TAccount> extends true ? undefined : MultiOwnerLightAccount>;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { sendUserOperation } from "viem/account-abstraction";
|
|
2
|
-
import { getAction } from "viem/utils";
|
|
3
|
-
import { AccountNotFoundError } from "@alchemy/common";
|
|
4
|
-
function isMultiOwnerLightAccount(account) {
|
|
5
|
-
return ("smartAccountType" in account &&
|
|
6
|
-
account.smartAccountType === "MultiOwnerLightAccount");
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Generates client actions for a multi-owner light account, including the ability to update owners.
|
|
10
|
-
*
|
|
11
|
-
* @param {Client<TTransport, TChain, TAccount>} client The client instance used to interact with the account
|
|
12
|
-
* @returns {MultiOwnerLightAccountActions<TAccount>} An object containing the client actions specifically for a multi-owner light account
|
|
13
|
-
*/
|
|
14
|
-
export function multiOwnerLightAccountActions(client) {
|
|
15
|
-
return {
|
|
16
|
-
// TODO(v5): Another pattern I think we should consider deprecating for v5 - actions that
|
|
17
|
-
// implicitly do a sendUserOperation internally. These are non-composable with batching
|
|
18
|
-
// and have a number of other issues that are solved with viem writeContract.
|
|
19
|
-
updateOwners: async (args) => {
|
|
20
|
-
const { ownersToAdd, ownersToRemove, account = client.account } = args;
|
|
21
|
-
if (!account || !isMultiOwnerLightAccount(account)) {
|
|
22
|
-
throw new AccountNotFoundError();
|
|
23
|
-
}
|
|
24
|
-
const data = account.encodeUpdateOwners(ownersToAdd, ownersToRemove);
|
|
25
|
-
const action = getAction(client, sendUserOperation, "sendUserOperation");
|
|
26
|
-
const result = await action({
|
|
27
|
-
calls: [
|
|
28
|
-
{
|
|
29
|
-
to: account.address,
|
|
30
|
-
data,
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
account,
|
|
34
|
-
});
|
|
35
|
-
return result;
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=multiOwner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multiOwner.js","sourceRoot":"","sources":["../../../../src/light-account/decorators/multiOwner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAqB,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAevD,SAAS,wBAAwB,CAC/B,OAAqB;IAErB,OAAO,CACL,kBAAkB,IAAI,OAAO;QAC7B,OAAO,CAAC,gBAAgB,KAAK,wBAAwB,CACtD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,6BAA6B,CAK3C,MAA4C;IAI5C,OAAO;QACL,yFAAyF;QACzF,uFAAuF;QACvF,6EAA6E;QAC7E,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAC3B,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;YAEvE,IAAI,CAAC,OAAO,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnD,MAAM,IAAI,oBAAoB,EAAE,CAAC;YACnC,CAAC;YAED,MAAM,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YAErE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,iBAAiB,EAAE,mBAAmB,CAAC,CAAC;YACzE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC;gBAC1B,KAAK,EAAE;oBACL;wBACE,EAAE,EAAE,OAAO,CAAC,OAAO;wBACnB,IAAI;qBACL;iBACF;gBACD,OAAO;aACR,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { Address, Chain, Client, Hex, IsUndefined, Transport } from \"viem\";\nimport { sendUserOperation, type SmartAccount } from \"viem/account-abstraction\";\nimport { getAction } from \"viem/utils\";\nimport type { GetAccountParameter } from \"../../types.js\";\nimport type { MultiOwnerLightAccount } from \"../accounts/multi-owner-account.js\";\nimport { AccountNotFoundError } from \"@alchemy/common\";\n\nexport type MultiOwnerLightAccountActions<\n TAccount extends MultiOwnerLightAccount | undefined =\n | MultiOwnerLightAccount\n | undefined,\n> = {\n updateOwners: (\n args: {\n ownersToAdd: Address[];\n ownersToRemove: Address[];\n } & GetAccountParameter<TAccount, MultiOwnerLightAccount>,\n ) => Promise<Hex>;\n};\n\nfunction isMultiOwnerLightAccount(\n account: SmartAccount,\n): account is MultiOwnerLightAccount {\n return (\n \"smartAccountType\" in account &&\n account.smartAccountType === \"MultiOwnerLightAccount\"\n );\n}\n\n/**\n * Generates client actions for a multi-owner light account, including the ability to update owners.\n *\n * @param {Client<TTransport, TChain, TAccount>} client The client instance used to interact with the account\n * @returns {MultiOwnerLightAccountActions<TAccount>} An object containing the client actions specifically for a multi-owner light account\n */\nexport function multiOwnerLightAccountActions<\n TTransport extends Transport = Transport,\n TChain extends Chain | undefined = Chain | undefined,\n TAccount extends SmartAccount | undefined = SmartAccount | undefined,\n>(\n client: Client<TTransport, TChain, TAccount>,\n): MultiOwnerLightAccountActions<\n IsUndefined<TAccount> extends true ? undefined : MultiOwnerLightAccount\n> {\n return {\n // TODO(v5): Another pattern I think we should consider deprecating for v5 - actions that\n // implicitly do a sendUserOperation internally. These are non-composable with batching\n // and have a number of other issues that are solved with viem writeContract.\n updateOwners: async (args) => {\n const { ownersToAdd, ownersToRemove, account = client.account } = args;\n\n if (!account || !isMultiOwnerLightAccount(account)) {\n throw new AccountNotFoundError();\n }\n\n const data = account.encodeUpdateOwners(ownersToAdd, ownersToRemove);\n\n const action = getAction(client, sendUserOperation, \"sendUserOperation\");\n const result = await action({\n calls: [\n {\n to: account.address,\n data,\n },\n ],\n account,\n });\n\n return result;\n },\n };\n}\n"]}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Address, Chain, Client, Hex, IsUndefined, Transport } from "viem";
|
|
2
|
-
import { type SmartAccount } from "viem/account-abstraction";
|
|
3
|
-
import type { GetAccountParameter } from "../../types.js";
|
|
4
|
-
import type { LightAccount } from "../accounts/account.js";
|
|
5
|
-
export type LightAccountActions<TAccount extends LightAccount | undefined = LightAccount | undefined> = {
|
|
6
|
-
transferOwnership: (args: {
|
|
7
|
-
newOwner: Address;
|
|
8
|
-
} & GetAccountParameter<TAccount, LightAccount>) => Promise<Hex>;
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* A decorator that can be used with viem's bundler client to add light account actions to the client
|
|
12
|
-
*
|
|
13
|
-
* @param {BundlerClient<TTransport, TChain, TAccount>} client The client instance for which to provide the light account actions
|
|
14
|
-
* @returns {LightAccountActions<TAccount>} An object containing the available light account actions
|
|
15
|
-
*/
|
|
16
|
-
export declare function singleOwnerLightAccountActions<TTransport extends Transport = Transport, TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = SmartAccount | undefined>(client: Client<TTransport, TChain, TAccount>): LightAccountActions<IsUndefined<TAccount> extends true ? undefined : LightAccount>;
|