@alchemy/smart-accounts 5.0.0-beta.9 → 5.0.1
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 +45 -0
- package/dist/esm/errors/InvalidEntityIdError.d.ts +2 -1
- package/dist/esm/errors/InvalidEntityIdError.js +4 -2
- package/dist/esm/errors/InvalidEntityIdError.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/ma-v2/accounts/account.d.ts +39 -0
- package/dist/esm/ma-v2/accounts/account.js +39 -0
- package/dist/esm/ma-v2/accounts/account.js.map +1 -1
- package/dist/esm/ma-v2/decorators/deferralActions.d.ts +3 -3
- package/dist/esm/ma-v2/decorators/deferralActions.js +3 -3
- package/dist/esm/ma-v2/decorators/deferralActions.js.map +1 -1
- package/dist/esm/ma-v2/permissionBuilder.d.ts +2 -2
- package/dist/esm/ma-v2/permissionBuilder.js +61 -17
- package/dist/esm/ma-v2/permissionBuilder.js.map +1 -1
- package/dist/esm/ma-v2/utils/deferredActions.d.ts +6 -6
- package/dist/esm/ma-v2/utils/deferredActions.js +5 -5
- package/dist/esm/ma-v2/utils/deferredActions.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/errors/InvalidEntityIdError.d.ts +2 -1
- package/dist/types/errors/InvalidEntityIdError.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/ma-v2/accounts/account.d.ts +39 -0
- package/dist/types/ma-v2/accounts/account.d.ts.map +1 -1
- package/dist/types/ma-v2/decorators/deferralActions.d.ts +3 -3
- package/dist/types/ma-v2/decorators/deferralActions.d.ts.map +1 -1
- package/dist/types/ma-v2/permissionBuilder.d.ts +2 -2
- package/dist/types/ma-v2/permissionBuilder.d.ts.map +1 -1
- package/dist/types/ma-v2/utils/deferredActions.d.ts +6 -6
- package/dist/types/ma-v2/utils/deferredActions.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 +4 -4
- package/src/errors/InvalidEntityIdError.ts +7 -2
- package/src/index.ts +1 -1
- package/src/ma-v2/accounts/account.ts +39 -0
- package/src/ma-v2/decorators/deferralActions.ts +7 -7
- package/src/ma-v2/permissionBuilder.ts +70 -20
- package/src/ma-v2/utils/deferredActions.ts +9 -9
- package/src/version.ts +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @alchemy/smart-accounts
|
|
2
2
|
|
|
3
|
+
This package replaces `@account-kit/smart-contracts`. This is a low-level package. Most users should use [`@alchemy/wallet-apis`](https://www.alchemy.com/docs/wallets/reference/wallet-apis) unless you need to use interface with Smart Accounts directly via viem.
|
|
4
|
+
|
|
3
5
|
Viem-compatible smart account implementations for Alchemy's smart contract accounts. Supports LightAccount, Modular Account v1, and Modular Account v2 with EIP-7702.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
@@ -8,6 +10,49 @@ Viem-compatible smart account implementations for Alchemy's smart contract accou
|
|
|
8
10
|
npm install @alchemy/smart-accounts @alchemy/common viem
|
|
9
11
|
```
|
|
10
12
|
|
|
13
|
+
## Example Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { createPublicClient } from "viem";
|
|
17
|
+
import {
|
|
18
|
+
createBundlerClient,
|
|
19
|
+
createPaymasterClient,
|
|
20
|
+
} from "viem/account-abstraction";
|
|
21
|
+
import { sepolia } from "viem/chains";
|
|
22
|
+
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
|
23
|
+
import { alchemyTransport } from "@alchemy/common";
|
|
24
|
+
import { estimateFeesPerGas } from "@alchemy/aa-infra";
|
|
25
|
+
import { toModularAccountV2 } from "@alchemy/smart-accounts";
|
|
26
|
+
|
|
27
|
+
const transport = alchemyTransport({ apiKey: "YOUR_API_KEY" });
|
|
28
|
+
|
|
29
|
+
// 1. Create a MAv2 smart account
|
|
30
|
+
const account = await toModularAccountV2({
|
|
31
|
+
client: createPublicClient({ chain: sepolia, transport }),
|
|
32
|
+
owner: privateKeyToAccount(generatePrivateKey()),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// 2. Create a bundler client with the account
|
|
36
|
+
const bundlerClient = createBundlerClient({
|
|
37
|
+
account,
|
|
38
|
+
chain: sepolia,
|
|
39
|
+
transport,
|
|
40
|
+
userOperation: {
|
|
41
|
+
estimateFeesPerGas,
|
|
42
|
+
},
|
|
43
|
+
// Optional: sponsor gas with a paymaster
|
|
44
|
+
paymaster: createPaymasterClient({ transport }),
|
|
45
|
+
paymasterContext: { policyId: "YOUR_POLICY_ID" },
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// 3. Send a user operation
|
|
49
|
+
const hash = await bundlerClient.sendUserOperation({
|
|
50
|
+
calls: [{ to: "0x...", value: 0n, data: "0x" }],
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const receipt = await bundlerClient.waitForUserOperationReceipt({ hash });
|
|
54
|
+
```
|
|
55
|
+
|
|
11
56
|
## Key Exports
|
|
12
57
|
|
|
13
58
|
### LightAccount
|
|
@@ -8,6 +8,7 @@ export declare class InvalidEntityIdError extends BaseError {
|
|
|
8
8
|
* Initializes a new instance of the error message with a default message indicating that the entity id is invalid because it's too large.
|
|
9
9
|
*
|
|
10
10
|
* @param {number} entityId the invalid entityId used
|
|
11
|
+
* @param {number | bigint} [maxAllowedInclusive] inclusive upper bound the entityId must not exceed. Defaults to `uint32.max`.
|
|
11
12
|
*/
|
|
12
|
-
constructor(entityId: number);
|
|
13
|
+
constructor(entityId: number, maxAllowedInclusive?: number | bigint);
|
|
13
14
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseError } from "@alchemy/common";
|
|
2
|
+
import { maxUint32 } from "viem";
|
|
2
3
|
/**
|
|
3
4
|
* Error class denoting that the provided entity id is invalid because it's too large.
|
|
4
5
|
*/
|
|
@@ -7,9 +8,10 @@ export class InvalidEntityIdError extends BaseError {
|
|
|
7
8
|
* Initializes a new instance of the error message with a default message indicating that the entity id is invalid because it's too large.
|
|
8
9
|
*
|
|
9
10
|
* @param {number} entityId the invalid entityId used
|
|
11
|
+
* @param {number | bigint} [maxAllowedInclusive] inclusive upper bound the entityId must not exceed. Defaults to `uint32.max`.
|
|
10
12
|
*/
|
|
11
|
-
constructor(entityId) {
|
|
12
|
-
super(`Entity ID used is ${entityId}, but must be less than or equal to
|
|
13
|
+
constructor(entityId, maxAllowedInclusive = maxUint32) {
|
|
14
|
+
super(`Entity ID used is ${entityId}, but must be less than or equal to ${maxAllowedInclusive}`);
|
|
13
15
|
Object.defineProperty(this, "name", {
|
|
14
16
|
enumerable: true,
|
|
15
17
|
configurable: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvalidEntityIdError.js","sourceRoot":"","sources":["../../../src/errors/InvalidEntityIdError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"InvalidEntityIdError.js","sourceRoot":"","sources":["../../../src/errors/InvalidEntityIdError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IAGjD;;;;;OAKG;IACH,YACE,QAAgB,EAChB,sBAAuC,SAAS;QAEhD,KAAK,CACH,qBAAqB,QAAQ,uCAAuC,mBAAmB,EAAE,CAC1F,CAAC;QAdK;;;;mBAAO,sBAAsB;WAAC;IAevC,CAAC;CACF","sourcesContent":["import { BaseError } from \"@alchemy/common\";\nimport { maxUint32 } from \"viem\";\n\n/**\n * Error class denoting that the provided entity id is invalid because it's too large.\n */\nexport class InvalidEntityIdError extends BaseError {\n override name = \"InvalidEntityIdError\";\n\n /**\n * Initializes a new instance of the error message with a default message indicating that the entity id is invalid because it's too large.\n *\n * @param {number} entityId the invalid entityId used\n * @param {number | bigint} [maxAllowedInclusive] inclusive upper bound the entityId must not exceed. Defaults to `uint32.max`.\n */\n constructor(\n entityId: number,\n maxAllowedInclusive: number | bigint = maxUint32,\n ) {\n super(\n `Entity ID used is ${entityId}, but must be less than or equal to ${maxAllowedInclusive}`,\n );\n }\n}\n"]}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export type * from "./ma-v2/types.js";
|
|
|
43
43
|
export type * from "./ma-v2/utils/account.js";
|
|
44
44
|
export { DefaultAddress, DefaultModuleAddress, DEFAULT_OWNER_ENTITY_ID, EXECUTE_USER_OP_SELECTOR, getMAV2UpgradeToData, buildFullNonceKey, serializeModuleEntity, isModularAccountV2, } from "./ma-v2/utils/account.js";
|
|
45
45
|
export type * from "./ma-v2/utils/deferredActions.js";
|
|
46
|
-
export { parseDeferredAction,
|
|
46
|
+
export { parseDeferredAction, encodeDeferredActionWithSignature, } from "./ma-v2/utils/deferredActions.js";
|
|
47
47
|
export type * from "./ma-v2/utils/hooks.js";
|
|
48
48
|
export { serializeValidationConfig, serializeHookConfig, } from "./ma-v2/utils/hooks.js";
|
|
49
49
|
export type * from "./ma-v2/utils/signature.js";
|
package/dist/esm/index.js
CHANGED
|
@@ -26,7 +26,7 @@ export { TimeRangeModule } from "./ma-v2/modules/time-range-module/module.js";
|
|
|
26
26
|
export { PermissionBuilder, PermissionType, } from "./ma-v2/permissionBuilder.js";
|
|
27
27
|
export { predictModularAccountV2Address } from "./ma-v2/predictAddress.js";
|
|
28
28
|
export { DefaultAddress, DefaultModuleAddress, DEFAULT_OWNER_ENTITY_ID, EXECUTE_USER_OP_SELECTOR, getMAV2UpgradeToData, buildFullNonceKey, serializeModuleEntity, isModularAccountV2, } from "./ma-v2/utils/account.js";
|
|
29
|
-
export { parseDeferredAction,
|
|
29
|
+
export { parseDeferredAction, encodeDeferredActionWithSignature, } from "./ma-v2/utils/deferredActions.js";
|
|
30
30
|
export { serializeValidationConfig, serializeHookConfig, } from "./ma-v2/utils/hooks.js";
|
|
31
31
|
export { packUOSignature, pack1271Signature, toReplaySafeTypedData, } from "./ma-v2/utils/signature.js";
|
|
32
32
|
// Errors
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAGrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,iDAAiD,CAAC;AAG3F,OAAO,EACL,0BAA0B,EAC1B,oCAAoC,GACrC,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,oCAAoC,EACpC,gCAAgC,GACjC,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,aAAa,EACb,aAAa,GACd,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC5B,4BAA4B,EAC5B,4BAA4B,EAC5B,sCAAsC,GACvC,MAAM,2CAA2C,CAAC;AAInD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AAGvF,OAAO,EAAE,wCAAwC,EAAE,MAAM,2BAA2B,CAAC;AAErF,OAAO,EAAE,kCAAkC,EAAE,MAAM,2BAA2B,CAAC;AAE/E,OAAO,EACL,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,eAAe,EACf,eAAe,GAChB,MAAM,mCAAmC,CAAC;AAI3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EACL,eAAe,EACf,eAAe,GAChB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAGxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAEnF,OAAO,EACL,8BAA8B,EAC9B,gCAAgC,GACjC,MAAM,2BAA2B,CAAC;AAGnC,UAAU;AACV,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,qDAAqD,CAAC;AAC7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AACxF,OAAO,EAAE,4BAA4B,EAAE,MAAM,oDAAoD,CAAC;AAClG,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAG9E,OAAO,EACL,iBAAiB,EACjB,cAAc,GACf,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAK3E,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export type * from \"./types.js\";\n\n// LightAccount\nexport type * from \"./light-account/accounts/account.js\";\nexport { toLightAccount } from \"./light-account/accounts/account.js\";\n\nexport type * from \"./light-account/accounts/multi-owner-account.js\";\nexport { toMultiOwnerLightAccount } from \"./light-account/accounts/multi-owner-account.js\";\n\nexport type * from \"./light-account/predictAddress.js\";\nexport {\n predictLightAccountAddress,\n predictMultiOwnerLightAccountAddress,\n} from \"./light-account/predictAddress.js\";\n\nexport { AccountVersionRegistry } from \"./light-account/registry.js\";\nexport type * from \"./light-account/registry.js\";\nexport {\n defaultLightAccountVersion,\n getLightAccountImplAddress,\n LightAccountUnsupported1271Factories,\n LightAccountUnsupported1271Impls,\n} from \"./light-account/utils.js\";\n\nexport {\n encodeCallsLA,\n decodeCallsLA,\n} from \"./light-account/accounts/calldataCodec.js\";\n\nexport {\n lightAccountStaticImplV1_0_1,\n lightAccountStaticImplV1_0_2,\n lightAccountStaticImplV1_1_0,\n lightAccountStaticImplV2_0_0,\n multiOwnerLightAccountStaticImplV2_0_0,\n} from \"./light-account/lightAccountStaticImpl.js\";\n\n// ModularAccountV1\nexport type * from \"./ma-v1/accounts/base.js\";\nexport { toModularAccountV1Base } from \"./ma-v1/accounts/base.js\";\n\nexport type * from \"./ma-v1/accounts/multi-owner-account.js\";\nexport { toMultiOwnerModularAccountV1 } from \"./ma-v1/accounts/multi-owner-account.js\";\n\nexport type * from \"./ma-v1/predictAddress.js\";\nexport { predictMultiOwnerModularAccountV1Address } from \"./ma-v1/predictAddress.js\";\n\nexport { multiOwnerModularAccountStaticImpl } from \"./ma-v1/mav1StaticImpl.js\";\n\nexport {\n DefaultMaV1Address,\n DefaultMaV1PluginAddress,\n} from \"./ma-v1/account.js\";\n\nexport {\n encodeCallsMAv1,\n decodeCallsMAv1,\n} from \"./ma-v1/accounts/calldataCodec.js\";\n\n// ModularAccountV2\nexport type * from \"./ma-v2/accounts/account.js\";\nexport { toModularAccountV2 } from \"./ma-v2/accounts/account.js\";\n\nexport type * from \"./ma-v2/accounts/base.js\";\nexport { toModularAccountV2Base } from \"./ma-v2/accounts/base.js\";\n\nexport {\n encodeCallsMAv2,\n decodeCallsMAv2,\n} from \"./ma-v2/accounts/calldataCodec.js\";\n\nexport type * from \"./ma-v2/decorators/deferralActions.js\";\nexport { deferralActions } from \"./ma-v2/decorators/deferralActions.js\";\n\nexport type * from \"./ma-v2/decorators/installValidation.js\";\nexport { installValidationActions } from \"./ma-v2/decorators/installValidation.js\";\n\nexport {\n semiModularAccountV2StaticImpl,\n semiModularAccount7702StaticImpl,\n} from \"./ma-v2/mav2StaticImpl.js\";\nexport type * from \"./ma-v2/mav2StaticImpl.js\";\n\n// Modules\nexport { AllowlistModule } from \"./ma-v2/modules/allowlist-module/module.js\";\nexport { NativeTokenLimitModule } from \"./ma-v2/modules/native-token-limit-module/module.js\";\nexport { PaymasterGuardModule } from \"./ma-v2/modules/paymaster-guard-module/module.js\";\nexport { SingleSignerValidationModule } from \"./ma-v2/modules/single-signer-validation/module.js\";\nexport { TimeRangeModule } from \"./ma-v2/modules/time-range-module/module.js\";\n\nexport type * from \"./ma-v2/permissionBuilder.js\";\nexport {\n PermissionBuilder,\n PermissionType,\n} from \"./ma-v2/permissionBuilder.js\";\n\nexport type * from \"./ma-v2/predictAddress.js\";\nexport { predictModularAccountV2Address } from \"./ma-v2/predictAddress.js\";\n\nexport type * from \"./ma-v2/types.js\";\n\nexport type * from \"./ma-v2/utils/account.js\";\nexport {\n DefaultAddress,\n DefaultModuleAddress,\n DEFAULT_OWNER_ENTITY_ID,\n EXECUTE_USER_OP_SELECTOR,\n getMAV2UpgradeToData,\n buildFullNonceKey,\n serializeModuleEntity,\n isModularAccountV2,\n} from \"./ma-v2/utils/account.js\";\n\nexport type * from \"./ma-v2/utils/deferredActions.js\";\nexport {\n parseDeferredAction,\n encodeDeferredActionWithSignature,\n} from \"./ma-v2/utils/deferredActions.js\";\n\nexport type * from \"./ma-v2/utils/hooks.js\";\nexport {\n serializeValidationConfig,\n serializeHookConfig,\n} from \"./ma-v2/utils/hooks.js\";\n\nexport type * from \"./ma-v2/utils/signature.js\";\nexport {\n packUOSignature,\n pack1271Signature,\n toReplaySafeTypedData,\n} from \"./ma-v2/utils/signature.js\";\n\n// Errors\nexport { EntityIdOverrideError } from \"./errors/EntityIdOverrideError.js\";\nexport { InvalidDeferredActionNonceError } from \"./errors/InvalidDeferredActionNonceError.js\";\nexport { InvalidEntityIdError } from \"./errors/InvalidEntityIdError.js\";\nexport { InvalidNonceKeyError } from \"./errors/InvalidNonceKeyError.js\";\nexport { InvalidOwnerError } from \"./errors/InvalidOwnerError.js\";\nexport {\n PermissionBuilderError,\n RootPermissionOnlyError,\n AccountAddressAsTargetError,\n DuplicateTargetAddressError,\n NoFunctionsProvidedError,\n ExpiredDeadlineError,\n DeadlineOverLimitError,\n ValidationConfigUnsetError,\n MultipleNativeTokenTransferError,\n ZeroAddressError,\n MultipleGasLimitError,\n UnsupportedPermissionTypeError,\n SelectorNotAllowed,\n} from \"./errors/permissionBuilderErrors.js\";\n"]}
|
|
@@ -30,6 +30,45 @@ export type ToModularAccountV2Params<TMode extends Mode | undefined = Mode | und
|
|
|
30
30
|
*
|
|
31
31
|
* @param {ToModularAccountV2Params} param0 - The parameters for creating a MAv2 account.
|
|
32
32
|
* @returns {Promise<ModularAccountV2>} A MAv2 account.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { createPublicClient } from "viem";
|
|
37
|
+
* import { createBundlerClient, createPaymasterClient } from "viem/account-abstraction";
|
|
38
|
+
* import { sepolia } from "viem/chains";
|
|
39
|
+
* import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
|
40
|
+
* import { alchemyTransport } from "@alchemy/common";
|
|
41
|
+
* import { estimateFeesPerGas } from "@alchemy/aa-infra";
|
|
42
|
+
* import { toModularAccountV2 } from "@alchemy/smart-accounts";
|
|
43
|
+
*
|
|
44
|
+
* const transport = alchemyTransport({ apiKey: "YOUR_API_KEY" });
|
|
45
|
+
*
|
|
46
|
+
* // 1. Create a MAv2 smart account
|
|
47
|
+
* const account = await toModularAccountV2({
|
|
48
|
+
* client: createPublicClient({ chain: sepolia, transport }),
|
|
49
|
+
* owner: privateKeyToAccount(generatePrivateKey()),
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* // 2. Create a bundler client with the account
|
|
53
|
+
* const bundlerClient = createBundlerClient({
|
|
54
|
+
* account,
|
|
55
|
+
* chain: sepolia,
|
|
56
|
+
* transport,
|
|
57
|
+
* userOperation: {
|
|
58
|
+
* estimateFeesPerGas,
|
|
59
|
+
* },
|
|
60
|
+
* // Optional: sponsor gas with a paymaster
|
|
61
|
+
* paymaster: createPaymasterClient({ transport }),
|
|
62
|
+
* paymasterContext: { policyId: "YOUR_POLICY_ID" },
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* // 3. Send a user operation
|
|
66
|
+
* const hash = await bundlerClient.sendUserOperation({
|
|
67
|
+
* calls: [{ to: "0x...", value: 0n, data: "0x" }],
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* const receipt = await bundlerClient.waitForUserOperationReceipt({ hash });
|
|
71
|
+
* ```
|
|
33
72
|
*/
|
|
34
73
|
export declare function toModularAccountV2<TMode extends Mode = Mode>({ client, owner, deferredAction, signerEntity, accountAddress: accountAddress_, salt, factory, factoryData: factoryData_, implementationAddress: implementationAddress_, mode, }: ToModularAccountV2Params<TMode>): Promise<ModularAccountV2>;
|
|
35
74
|
export {};
|
|
@@ -12,6 +12,45 @@ import { LOGGER } from "../../logger.js";
|
|
|
12
12
|
*
|
|
13
13
|
* @param {ToModularAccountV2Params} param0 - The parameters for creating a MAv2 account.
|
|
14
14
|
* @returns {Promise<ModularAccountV2>} A MAv2 account.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { createPublicClient } from "viem";
|
|
19
|
+
* import { createBundlerClient, createPaymasterClient } from "viem/account-abstraction";
|
|
20
|
+
* import { sepolia } from "viem/chains";
|
|
21
|
+
* import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
|
22
|
+
* import { alchemyTransport } from "@alchemy/common";
|
|
23
|
+
* import { estimateFeesPerGas } from "@alchemy/aa-infra";
|
|
24
|
+
* import { toModularAccountV2 } from "@alchemy/smart-accounts";
|
|
25
|
+
*
|
|
26
|
+
* const transport = alchemyTransport({ apiKey: "YOUR_API_KEY" });
|
|
27
|
+
*
|
|
28
|
+
* // 1. Create a MAv2 smart account
|
|
29
|
+
* const account = await toModularAccountV2({
|
|
30
|
+
* client: createPublicClient({ chain: sepolia, transport }),
|
|
31
|
+
* owner: privateKeyToAccount(generatePrivateKey()),
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* // 2. Create a bundler client with the account
|
|
35
|
+
* const bundlerClient = createBundlerClient({
|
|
36
|
+
* account,
|
|
37
|
+
* chain: sepolia,
|
|
38
|
+
* transport,
|
|
39
|
+
* userOperation: {
|
|
40
|
+
* estimateFeesPerGas,
|
|
41
|
+
* },
|
|
42
|
+
* // Optional: sponsor gas with a paymaster
|
|
43
|
+
* paymaster: createPaymasterClient({ transport }),
|
|
44
|
+
* paymasterContext: { policyId: "YOUR_POLICY_ID" },
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* // 3. Send a user operation
|
|
48
|
+
* const hash = await bundlerClient.sendUserOperation({
|
|
49
|
+
* calls: [{ to: "0x...", value: 0n, data: "0x" }],
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* const receipt = await bundlerClient.waitForUserOperationReceipt({ hash });
|
|
53
|
+
* ```
|
|
15
54
|
*/
|
|
16
55
|
export async function toModularAccountV2({ client, owner, deferredAction, signerEntity, accountAddress: accountAddress_, salt = 0n, factory, factoryData: factoryData_, implementationAddress: implementationAddress_, mode, }) {
|
|
17
56
|
const is7702 = mode === "7702";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../../../src/ma-v2/accounts/account.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n encodeFunctionData,\n type Address,\n type Chain,\n type Client,\n type Hex,\n type JsonRpcAccount,\n type LocalAccount,\n type PrivateKeyAccount,\n type Transport,\n} from \"viem\";\nimport {\n type ToSmartAccountParameters,\n entryPoint07Address,\n} from \"viem/account-abstraction\";\nimport { toModularAccountV2Base, type ModularAccountV2Base } from \"./base.js\";\nimport type { SignerEntity } from \"../types.js\";\nimport {\n getModularAccountV2AddressFromFactoryData,\n predictModularAccountV2Address,\n} from \"../predictAddress.js\";\nimport { accountFactoryAbi } from \"../abis/accountFactoryAbi.js\";\nimport { EntityIdOverrideError } from \"../../errors/EntityIdOverrideError.js\";\nimport { InvalidOwnerError } from \"../../errors/InvalidOwnerError.js\";\nimport { DEFAULT_OWNER_ENTITY_ID, DefaultAddress } from \"../utils/account.js\";\nimport { LOGGER } from \"../../logger.js\";\n\ntype Mode = \"default\" | \"7702\";\n\n// This may be extended in the future with additional MAv2-specific methods.\nexport type ModularAccountV2 = ModularAccountV2Base & {};\n\nexport type ToModularAccountV2Params<\n TMode extends Mode | undefined = Mode | undefined,\n> = {\n client: Client<Transport, Chain, JsonRpcAccount | LocalAccount | undefined>;\n owner: JsonRpcAccount | LocalAccount;\n deferredAction?: Hex;\n signerEntity?: SignerEntity;\n accountAddress?: Address;\n mode?: TMode;\n} & (TMode extends \"7702\"\n ? {\n salt?: never;\n factory?: never;\n factoryData?: never;\n implementationAddress?: never;\n }\n : {\n factory?: Address;\n implementationAddress?: Address;\n } & (\n | {\n salt?: bigint;\n factoryData?: never;\n }\n | {\n salt?: never;\n factoryData?: Hex;\n }\n ));\n\n/**\n * Creates a MAv2 account.\n *\n * @param {ToModularAccountV2Params} param0 - The parameters for creating a MAv2 account.\n * @returns {Promise<ModularAccountV2>} A MAv2 account.\n */\nexport async function toModularAccountV2<TMode extends Mode = Mode>({\n client,\n owner,\n deferredAction,\n signerEntity,\n accountAddress: accountAddress_,\n salt = 0n,\n factory,\n factoryData: factoryData_,\n implementationAddress: implementationAddress_,\n mode,\n}: ToModularAccountV2Params<TMode>): Promise<ModularAccountV2> {\n const is7702 = mode === \"7702\";\n\n LOGGER.debug(\"toModularAccountV2:start\", {\n ownerType: owner.type,\n mode,\n hasDeferredAction: !!deferredAction,\n hasAccountAddress: !!accountAddress_,\n });\n\n const entityId = signerEntity?.entityId ?? DEFAULT_OWNER_ENTITY_ID;\n\n const factoryAddress = factory ?? DefaultAddress.MAV2_FACTORY;\n\n const implementationAddress =\n implementationAddress_ ??\n (is7702 ? DefaultAddress.SMAV2_7702 : DefaultAddress.SMAV2_BYTECODE);\n\n const getFactoryArgs = async () => {\n if (is7702) {\n // This is only for EP 0.8.0.\n // return {\n // factory: \"0x7702\",\n // factoryData: \"0x\",\n // } as const;\n return {\n factory: undefined,\n factoryData: undefined,\n } as const;\n }\n\n return {\n factory: factoryAddress,\n factoryData:\n factoryData_ ??\n encodeFunctionData({\n abi: accountFactoryAbi,\n functionName: \"createSemiModularAccount\",\n args: [owner.address, salt],\n }),\n };\n };\n\n const accountAddress =\n accountAddress_ ??\n (is7702\n ? owner.address\n : factoryData_\n ? await getModularAccountV2AddressFromFactoryData({\n client,\n factoryAddress,\n factoryData: factoryData_,\n implementationAddress,\n entryPoint: {\n version: \"0.7\",\n address: entryPoint07Address,\n },\n })\n : predictModularAccountV2Address({\n factoryAddress,\n implementationAddress,\n salt,\n type: \"SMA\",\n ownerAddress: owner.address,\n }));\n\n LOGGER.debug(\"toModularAccountV2:address-resolved\", {\n accountAddress,\n is7702,\n });\n\n let authorization: ToSmartAccountParameters[\"authorization\"];\n if (is7702) {\n LOGGER.debug(\"toModularAccountV2:7702-mode\");\n if (owner.type !== \"local\") {\n LOGGER.error(\"toModularAccountV2:invalid-owner-type\", {\n ownerType: owner.type,\n });\n throw new InvalidOwnerError(\n `Owner of type ${owner.type} is unsupported for 7702 mode.`,\n );\n }\n if (owner.signAuthorization == null) {\n LOGGER.error(\"toModularAccountV2:missing-signAuthorization\");\n throw new InvalidOwnerError(\n \"Owner must implement `signAuthorization` to be used with 7702 mode.\",\n );\n }\n if (\n entityId === DEFAULT_OWNER_ENTITY_ID &&\n owner.address !== accountAddress\n ) {\n LOGGER.error(\"toModularAccountV2:entity-id-override\");\n throw new EntityIdOverrideError();\n }\n authorization = {\n // The current version of Viem has some pretty strict constraints\n // on a `PrivateKeyAccount`, but this seems safe as long as the\n // owner is able to `signAuthorization`.\n account: owner as PrivateKeyAccount,\n address: DefaultAddress.SMAV2_7702,\n };\n }\n\n const base = await toModularAccountV2Base({\n client,\n owner,\n accountAddress,\n getFactoryArgs,\n signerEntity,\n deferredAction,\n authorization,\n });\n\n return {\n ...base,\n // This may be extended in the future with additional MAv2-specific methods.\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../../../src/ma-v2/accounts/account.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n encodeFunctionData,\n type Address,\n type Chain,\n type Client,\n type Hex,\n type JsonRpcAccount,\n type LocalAccount,\n type PrivateKeyAccount,\n type Transport,\n} from \"viem\";\nimport {\n type ToSmartAccountParameters,\n entryPoint07Address,\n} from \"viem/account-abstraction\";\nimport { toModularAccountV2Base, type ModularAccountV2Base } from \"./base.js\";\nimport type { SignerEntity } from \"../types.js\";\nimport {\n getModularAccountV2AddressFromFactoryData,\n predictModularAccountV2Address,\n} from \"../predictAddress.js\";\nimport { accountFactoryAbi } from \"../abis/accountFactoryAbi.js\";\nimport { EntityIdOverrideError } from \"../../errors/EntityIdOverrideError.js\";\nimport { InvalidOwnerError } from \"../../errors/InvalidOwnerError.js\";\nimport { DEFAULT_OWNER_ENTITY_ID, DefaultAddress } from \"../utils/account.js\";\nimport { LOGGER } from \"../../logger.js\";\n\ntype Mode = \"default\" | \"7702\";\n\n// This may be extended in the future with additional MAv2-specific methods.\nexport type ModularAccountV2 = ModularAccountV2Base & {};\n\nexport type ToModularAccountV2Params<\n TMode extends Mode | undefined = Mode | undefined,\n> = {\n client: Client<Transport, Chain, JsonRpcAccount | LocalAccount | undefined>;\n owner: JsonRpcAccount | LocalAccount;\n deferredAction?: Hex;\n signerEntity?: SignerEntity;\n accountAddress?: Address;\n mode?: TMode;\n} & (TMode extends \"7702\"\n ? {\n salt?: never;\n factory?: never;\n factoryData?: never;\n implementationAddress?: never;\n }\n : {\n factory?: Address;\n implementationAddress?: Address;\n } & (\n | {\n salt?: bigint;\n factoryData?: never;\n }\n | {\n salt?: never;\n factoryData?: Hex;\n }\n ));\n\n/**\n * Creates a MAv2 account.\n *\n * @param {ToModularAccountV2Params} param0 - The parameters for creating a MAv2 account.\n * @returns {Promise<ModularAccountV2>} A MAv2 account.\n *\n * @example\n * ```ts\n * import { createPublicClient } from \"viem\";\n * import { createBundlerClient, createPaymasterClient } from \"viem/account-abstraction\";\n * import { sepolia } from \"viem/chains\";\n * import { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\n * import { alchemyTransport } from \"@alchemy/common\";\n * import { estimateFeesPerGas } from \"@alchemy/aa-infra\";\n * import { toModularAccountV2 } from \"@alchemy/smart-accounts\";\n *\n * const transport = alchemyTransport({ apiKey: \"YOUR_API_KEY\" });\n *\n * // 1. Create a MAv2 smart account\n * const account = await toModularAccountV2({\n * client: createPublicClient({ chain: sepolia, transport }),\n * owner: privateKeyToAccount(generatePrivateKey()),\n * });\n *\n * // 2. Create a bundler client with the account\n * const bundlerClient = createBundlerClient({\n * account,\n * chain: sepolia,\n * transport,\n * userOperation: {\n * estimateFeesPerGas,\n * },\n * // Optional: sponsor gas with a paymaster\n * paymaster: createPaymasterClient({ transport }),\n * paymasterContext: { policyId: \"YOUR_POLICY_ID\" },\n * });\n *\n * // 3. Send a user operation\n * const hash = await bundlerClient.sendUserOperation({\n * calls: [{ to: \"0x...\", value: 0n, data: \"0x\" }],\n * });\n *\n * const receipt = await bundlerClient.waitForUserOperationReceipt({ hash });\n * ```\n */\nexport async function toModularAccountV2<TMode extends Mode = Mode>({\n client,\n owner,\n deferredAction,\n signerEntity,\n accountAddress: accountAddress_,\n salt = 0n,\n factory,\n factoryData: factoryData_,\n implementationAddress: implementationAddress_,\n mode,\n}: ToModularAccountV2Params<TMode>): Promise<ModularAccountV2> {\n const is7702 = mode === \"7702\";\n\n LOGGER.debug(\"toModularAccountV2:start\", {\n ownerType: owner.type,\n mode,\n hasDeferredAction: !!deferredAction,\n hasAccountAddress: !!accountAddress_,\n });\n\n const entityId = signerEntity?.entityId ?? DEFAULT_OWNER_ENTITY_ID;\n\n const factoryAddress = factory ?? DefaultAddress.MAV2_FACTORY;\n\n const implementationAddress =\n implementationAddress_ ??\n (is7702 ? DefaultAddress.SMAV2_7702 : DefaultAddress.SMAV2_BYTECODE);\n\n const getFactoryArgs = async () => {\n if (is7702) {\n // This is only for EP 0.8.0.\n // return {\n // factory: \"0x7702\",\n // factoryData: \"0x\",\n // } as const;\n return {\n factory: undefined,\n factoryData: undefined,\n } as const;\n }\n\n return {\n factory: factoryAddress,\n factoryData:\n factoryData_ ??\n encodeFunctionData({\n abi: accountFactoryAbi,\n functionName: \"createSemiModularAccount\",\n args: [owner.address, salt],\n }),\n };\n };\n\n const accountAddress =\n accountAddress_ ??\n (is7702\n ? owner.address\n : factoryData_\n ? await getModularAccountV2AddressFromFactoryData({\n client,\n factoryAddress,\n factoryData: factoryData_,\n implementationAddress,\n entryPoint: {\n version: \"0.7\",\n address: entryPoint07Address,\n },\n })\n : predictModularAccountV2Address({\n factoryAddress,\n implementationAddress,\n salt,\n type: \"SMA\",\n ownerAddress: owner.address,\n }));\n\n LOGGER.debug(\"toModularAccountV2:address-resolved\", {\n accountAddress,\n is7702,\n });\n\n let authorization: ToSmartAccountParameters[\"authorization\"];\n if (is7702) {\n LOGGER.debug(\"toModularAccountV2:7702-mode\");\n if (owner.type !== \"local\") {\n LOGGER.error(\"toModularAccountV2:invalid-owner-type\", {\n ownerType: owner.type,\n });\n throw new InvalidOwnerError(\n `Owner of type ${owner.type} is unsupported for 7702 mode.`,\n );\n }\n if (owner.signAuthorization == null) {\n LOGGER.error(\"toModularAccountV2:missing-signAuthorization\");\n throw new InvalidOwnerError(\n \"Owner must implement `signAuthorization` to be used with 7702 mode.\",\n );\n }\n if (\n entityId === DEFAULT_OWNER_ENTITY_ID &&\n owner.address !== accountAddress\n ) {\n LOGGER.error(\"toModularAccountV2:entity-id-override\");\n throw new EntityIdOverrideError();\n }\n authorization = {\n // The current version of Viem has some pretty strict constraints\n // on a `PrivateKeyAccount`, but this seems safe as long as the\n // owner is able to `signAuthorization`.\n account: owner as PrivateKeyAccount,\n address: DefaultAddress.SMAV2_7702,\n };\n }\n\n const base = await toModularAccountV2Base({\n client,\n owner,\n accountAddress,\n getFactoryArgs,\n signerEntity,\n deferredAction,\n authorization,\n });\n\n return {\n ...base,\n // This may be extended in the future with additional MAv2-specific methods.\n };\n}\n"]}
|
|
@@ -25,7 +25,7 @@ export type CreateDeferredActionTypedDataParams = {
|
|
|
25
25
|
deadline: number;
|
|
26
26
|
nonce: bigint;
|
|
27
27
|
};
|
|
28
|
-
export type
|
|
28
|
+
export type BuildPreSignatureDeferredActionPayloadParams = {
|
|
29
29
|
typedData: DeferredActionTypedData;
|
|
30
30
|
};
|
|
31
31
|
export type EntityIdAndNonceParams = {
|
|
@@ -36,7 +36,7 @@ export type EntityIdAndNonceParams = {
|
|
|
36
36
|
};
|
|
37
37
|
export type DeferralActions = {
|
|
38
38
|
createDeferredActionTypedDataObject: (args: CreateDeferredActionTypedDataParams) => Promise<DeferredActionReturnData>;
|
|
39
|
-
|
|
39
|
+
buildPreSignatureDeferredActionPayload: (args: BuildPreSignatureDeferredActionPayloadParams) => Hex;
|
|
40
40
|
getEntityIdAndNonce: (args: EntityIdAndNonceParams) => Promise<{
|
|
41
41
|
nonce: bigint;
|
|
42
42
|
entityId: number;
|
|
@@ -46,6 +46,6 @@ export type DeferralActions = {
|
|
|
46
46
|
* Provides deferred action functionalities for a MA v2 client, ensuring compatibility with `SmartAccountClient`.
|
|
47
47
|
*
|
|
48
48
|
* @param {ModularAccountV2Client} client - The client instance which provides account and sendUserOperation functionality.
|
|
49
|
-
* @returns {object} - An object containing three methods: `createDeferredActionTypedDataObject`, `
|
|
49
|
+
* @returns {object} - An object containing three methods: `createDeferredActionTypedDataObject`, `buildPreSignatureDeferredActionPayload`, and `buildUserOperationWithDeferredAction`.
|
|
50
50
|
*/
|
|
51
51
|
export declare const deferralActions: <TTransport extends Transport = Transport, TChain extends Chain = Chain, TAccount extends SmartAccount = SmartAccount>(client: Client<TTransport, TChain, TAccount>) => DeferralActions;
|
|
@@ -10,7 +10,7 @@ export const ENTITY_ID_AND_NONCE_READER_BYTECODE = "0x60806040523480156100105760
|
|
|
10
10
|
* Provides deferred action functionalities for a MA v2 client, ensuring compatibility with `SmartAccountClient`.
|
|
11
11
|
*
|
|
12
12
|
* @param {ModularAccountV2Client} client - The client instance which provides account and sendUserOperation functionality.
|
|
13
|
-
* @returns {object} - An object containing three methods: `createDeferredActionTypedDataObject`, `
|
|
13
|
+
* @returns {object} - An object containing three methods: `createDeferredActionTypedDataObject`, `buildPreSignatureDeferredActionPayload`, and `buildUserOperationWithDeferredAction`.
|
|
14
14
|
*/
|
|
15
15
|
export const deferralActions = (client) => {
|
|
16
16
|
const createDeferredActionTypedDataObject = async ({ callData, deadline, nonce, }) => {
|
|
@@ -40,7 +40,7 @@ export const deferralActions = (client) => {
|
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
42
|
};
|
|
43
|
-
const
|
|
43
|
+
const buildPreSignatureDeferredActionPayload = ({ typedData, }) => {
|
|
44
44
|
const account = client.account;
|
|
45
45
|
if (!account || !isModularAccountV2(account)) {
|
|
46
46
|
throw new AccountNotFoundError();
|
|
@@ -93,7 +93,7 @@ export const deferralActions = (client) => {
|
|
|
93
93
|
};
|
|
94
94
|
return {
|
|
95
95
|
createDeferredActionTypedDataObject,
|
|
96
|
-
|
|
96
|
+
buildPreSignatureDeferredActionPayload,
|
|
97
97
|
getEntityIdAndNonce,
|
|
98
98
|
};
|
|
99
99
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deferralActions.js","sourceRoot":"","sources":["../../../../src/ma-v2/decorators/deferralActions.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAKT,YAAY,EACZ,IAAI,EACJ,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,KAAK,GAEN,MAAM,MAAM,CAAC;AAEd,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAElE,MAAM,CAAC,MAAM,mCAAmC,GAC9C,s+EAAs+E,CAAC;AA8Cz+E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAK7B,MAA4C,EAC3B,EAAE;IACnB,MAAM,mCAAmC,GAAG,KAAK,EAAE,EACjD,QAAQ,EACR,QAAQ,EACR,KAAK,GAC+B,EAAqC,EAAE;QAC3E,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,oBAAoB,EAAE,CAAC;QACnC,CAAC;QAED,OAAO;YACL,SAAS,EAAE;gBACT,MAAM,EAAE;oBACN,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE;oBACxB,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO;iBAC1C;gBACD,KAAK,EAAE;oBACL,cAAc,EAAE;wBACd,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;wBAClC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACpC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;qBAChC;iBACF;gBACD,WAAW,EAAE,gBAAgB;gBAC7B,OAAO,EAAE;oBACP,KAAK,EAAE,KAAK;oBACZ,QAAQ,EAAE,QAAQ;oBAClB,IAAI,EAAE,QAAQ;iBACf;aACF;SACF,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,qCAAqC,GAAG,CAAC,EAC7C,SAAS,GACmC,EAAO,EAAE;QACrD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,oBAAoB,EAAE,CAAC;QACnC,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QAC1C,MAAM,iBAAiB,GACrB,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACrC,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAE9C,MAAM,eAAe,GAAG,YAAY,CAClC,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,EAC9B,CAAC,iBAAiB,EAAE,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CACxE,CAAC;QAEF,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,SAAS,CAAC;YAC5B,KAAK,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACrC,eAAe;SAChB,CAAC,CAAC;QACH,OAAO,WAAW,CAAC;IACrB,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,KAAK,EAAE,EACjC,QAAQ,GAAG,CAAC,EACZ,QAAQ,GAAG,EAAE,EACb,kBAAkB,EAClB,gBAAgB,GAAG,IAAI,GACA,EAAE,EAAE;QAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,oBAAoB,EAAE,CAAC;QACnC,CAAC;QAED,IAAI,QAAQ,GAAG,UAAU,EAAE,CAAC;YAC1B,MAAM,IAAI,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC;YAChC,GAAG,EAAE,yBAAyB;YAC9B,QAAQ,EAAE,mCAAmC;YAC7C,IAAI,EAAE;gBACJ,OAAO,CAAC,OAAO;gBACf,OAAO,CAAC,UAAU,CAAC,OAAO;gBAC1B,iBAAiB,CAAC;oBAChB,QAAQ;oBACR,QAAQ;oBACR,kBAAkB;oBAClB,gBAAgB;iBACjB,CAAC;aACH;SACF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,SAAS,CAAC,qCAAqC,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACjB,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC;YACnB,QAAQ,EAAE,WAAW,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;SACjD,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO;QACL,mCAAmC;QACnC,qCAAqC;QACrC,mBAAmB;KACpB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n concatHex,\n type Hex,\n type Client,\n type Chain,\n type Transport,\n encodePacked,\n size,\n toHex,\n maxUint152,\n encodeDeployData,\n hexToNumber,\n isHex,\n type TypedDataDefinition,\n} from \"viem\";\nimport type { SmartAccount } from \"viem/account-abstraction\";\nimport { entityIdAndNonceReaderAbi } from \"../abis/entityIdAndNonceReader.js\";\nimport { getAction } from \"viem/utils\";\nimport { call } from \"viem/actions\";\nimport { InvalidNonceKeyError } from \"../../errors/InvalidNonceKeyError.js\";\nimport { buildFullNonceKey, isModularAccountV2 } from \"../utils/account.js\";\nimport { AccountNotFoundError, BaseError } from \"@alchemy/common\";\n\nexport const ENTITY_ID_AND_NONCE_READER_BYTECODE =\n \"0x608060405234801561001057600080fd5b506040516104f13803806104f183398101604081905261002f916101e5565b60006008826001600160c01b0316901c90506000808263ffffffff1611610057576001610059565b815b90506001600160a01b0385163b15610133575b60006001600160a01b03861663d31b575b6bffffffff0000000000000000604085901b166040516001600160e01b031960e084901b1681526001600160401b03199091166004820152602401600060405180830381865afa1580156100d5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526100fd91908101906103c6565b805190915060ff161580156101155750606081015151155b156101205750610133565b8161012a816104a4565b9250505061006c565b604051631aab3f0d60e11b81526001600160a01b03868116600483015264ffffffff01600160c01b038516600884901b64ffffffff0016176024830152600091908616906335567e1a90604401602060405180830381865afa15801561019d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c191906104d7565b90508060005260206000f35b6001600160a01b03811681146101e257600080fd5b50565b6000806000606084860312156101fa57600080fd5b8351610205816101cd565b6020850151909350610216816101cd565b60408501519092506001600160c01b038116811461023357600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156102765761027661023e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156102a4576102a461023e565b604052919050565b60006001600160401b038211156102c5576102c561023e565b5060051b60200190565b600082601f8301126102e057600080fd5b81516102f36102ee826102ac565b61027c565b8082825260208201915060208360051b86010192508583111561031557600080fd5b602085015b8381101561034857805166ffffffffffffff198116811461033a57600080fd5b83526020928301920161031a565b5095945050505050565b600082601f83011261036357600080fd5b81516103716102ee826102ac565b8082825260208201915060208360051b86010192508583111561039357600080fd5b602085015b838110156103485780516001600160e01b0319811681146103b857600080fd5b835260209283019201610398565b6000602082840312156103d857600080fd5b81516001600160401b038111156103ee57600080fd5b82016080818503121561040057600080fd5b610408610254565b815160ff8116811461041957600080fd5b815260208201516001600160401b0381111561043457600080fd5b610440868285016102cf565b60208301525060408201516001600160401b0381111561045f57600080fd5b61046b868285016102cf565b60408301525060608201516001600160401b0381111561048a57600080fd5b61049686828501610352565b606083015250949350505050565b600063ffffffff821663ffffffff81036104ce57634e487b7160e01b600052601160045260246000fd5b60010192915050565b6000602082840312156104e957600080fd5b505191905056fe\";\n\nexport type DeferredActionTypedData = TypedDataDefinition<\n {\n DeferredAction: [\n { name: \"nonce\"; type: \"uint256\" },\n { name: \"deadline\"; type: \"uint48\" },\n { name: \"call\"; type: \"bytes\" },\n ];\n },\n \"DeferredAction\"\n>;\n\nexport type DeferredActionReturnData = {\n typedData: DeferredActionTypedData;\n};\n\nexport type CreateDeferredActionTypedDataParams = {\n callData: Hex;\n deadline: number;\n nonce: bigint;\n};\n\nexport type BuildPreSignatureDeferredActionDigestParams = {\n typedData: DeferredActionTypedData;\n};\n\nexport type EntityIdAndNonceParams = {\n entityId?: number;\n nonceKey?: bigint;\n isGlobalValidation: boolean;\n isDeferredAction?: boolean;\n};\n\nexport type DeferralActions = {\n createDeferredActionTypedDataObject: (\n args: CreateDeferredActionTypedDataParams,\n ) => Promise<DeferredActionReturnData>;\n buildPreSignatureDeferredActionDigest: (\n args: BuildPreSignatureDeferredActionDigestParams,\n ) => Hex;\n getEntityIdAndNonce: (\n args: EntityIdAndNonceParams,\n ) => Promise<{ nonce: bigint; entityId: number }>;\n};\n\n/**\n * Provides deferred action functionalities for a MA v2 client, ensuring compatibility with `SmartAccountClient`.\n *\n * @param {ModularAccountV2Client} client - The client instance which provides account and sendUserOperation functionality.\n * @returns {object} - An object containing three methods: `createDeferredActionTypedDataObject`, `buildDeferredActionDigest`, and `buildUserOperationWithDeferredAction`.\n */\nexport const deferralActions = <\n TTransport extends Transport = Transport,\n TChain extends Chain = Chain,\n TAccount extends SmartAccount = SmartAccount,\n>(\n client: Client<TTransport, TChain, TAccount>,\n): DeferralActions => {\n const createDeferredActionTypedDataObject = async ({\n callData,\n deadline,\n nonce,\n }: CreateDeferredActionTypedDataParams): Promise<DeferredActionReturnData> => {\n const account = client.account;\n if (!account || !isModularAccountV2(account)) {\n throw new AccountNotFoundError();\n }\n\n return {\n typedData: {\n domain: {\n chainId: client.chain.id,\n verifyingContract: client.account.address,\n },\n types: {\n DeferredAction: [\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint48\" },\n { name: \"call\", type: \"bytes\" },\n ],\n },\n primaryType: \"DeferredAction\",\n message: {\n nonce: nonce,\n deadline: deadline,\n call: callData,\n },\n },\n };\n };\n\n const buildPreSignatureDeferredActionDigest = ({\n typedData,\n }: BuildPreSignatureDeferredActionDigestParams): Hex => {\n const account = client.account;\n if (!account || !isModularAccountV2(account)) {\n throw new AccountNotFoundError();\n }\n\n const signerEntity = account.signerEntity;\n const validationLocator =\n (BigInt(signerEntity.entityId) << 8n) |\n (signerEntity.isGlobalValidation ? 1n : 0n);\n\n const encodedCallData = encodePacked(\n [\"uint168\", \"uint48\", \"bytes\"],\n [validationLocator, typedData.message.deadline, typedData.message.call],\n );\n\n const encodedDataLength = size(encodedCallData);\n const encodedData = concatHex([\n toHex(encodedDataLength, { size: 4 }),\n encodedCallData,\n ]);\n return encodedData;\n };\n\n const getEntityIdAndNonce = async ({\n entityId = 1,\n nonceKey = 0n,\n isGlobalValidation,\n isDeferredAction = true,\n }: EntityIdAndNonceParams) => {\n const account = client.account;\n if (!account || !isModularAccountV2(account)) {\n throw new AccountNotFoundError();\n }\n\n if (nonceKey > maxUint152) {\n throw new InvalidNonceKeyError(nonceKey);\n }\n\n const bytecode = encodeDeployData({\n abi: entityIdAndNonceReaderAbi,\n bytecode: ENTITY_ID_AND_NONCE_READER_BYTECODE,\n args: [\n account.address,\n account.entryPoint.address,\n buildFullNonceKey({\n nonceKey,\n entityId,\n isGlobalValidation,\n isDeferredAction,\n }),\n ],\n });\n\n const action = getAction(client, call, \"call\");\n const { data } = await action({ data: bytecode });\n if (!data) {\n throw new BaseError(\"No data returned from contract call\");\n }\n if (!isHex(data)) {\n throw new BaseError(\"Expected hex data from contract call\");\n }\n\n return {\n nonce: BigInt(data),\n entityId: hexToNumber(`0x${data.slice(40, 48)}`),\n };\n };\n\n return {\n createDeferredActionTypedDataObject,\n buildPreSignatureDeferredActionDigest,\n getEntityIdAndNonce,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"deferralActions.js","sourceRoot":"","sources":["../../../../src/ma-v2/decorators/deferralActions.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n concatHex,\n type Hex,\n type Client,\n type Chain,\n type Transport,\n encodePacked,\n size,\n toHex,\n maxUint152,\n encodeDeployData,\n hexToNumber,\n isHex,\n type TypedDataDefinition,\n} from \"viem\";\nimport type { SmartAccount } from \"viem/account-abstraction\";\nimport { entityIdAndNonceReaderAbi } from \"../abis/entityIdAndNonceReader.js\";\nimport { getAction } from \"viem/utils\";\nimport { call } from \"viem/actions\";\nimport { InvalidNonceKeyError } from \"../../errors/InvalidNonceKeyError.js\";\nimport { buildFullNonceKey, isModularAccountV2 } from \"../utils/account.js\";\nimport { AccountNotFoundError, BaseError } from \"@alchemy/common\";\n\nexport const ENTITY_ID_AND_NONCE_READER_BYTECODE =\n \"0x608060405234801561001057600080fd5b506040516104f13803806104f183398101604081905261002f916101e5565b60006008826001600160c01b0316901c90506000808263ffffffff1611610057576001610059565b815b90506001600160a01b0385163b15610133575b60006001600160a01b03861663d31b575b6bffffffff0000000000000000604085901b166040516001600160e01b031960e084901b1681526001600160401b03199091166004820152602401600060405180830381865afa1580156100d5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526100fd91908101906103c6565b805190915060ff161580156101155750606081015151155b156101205750610133565b8161012a816104a4565b9250505061006c565b604051631aab3f0d60e11b81526001600160a01b03868116600483015264ffffffff01600160c01b038516600884901b64ffffffff0016176024830152600091908616906335567e1a90604401602060405180830381865afa15801561019d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c191906104d7565b90508060005260206000f35b6001600160a01b03811681146101e257600080fd5b50565b6000806000606084860312156101fa57600080fd5b8351610205816101cd565b6020850151909350610216816101cd565b60408501519092506001600160c01b038116811461023357600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156102765761027661023e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156102a4576102a461023e565b604052919050565b60006001600160401b038211156102c5576102c561023e565b5060051b60200190565b600082601f8301126102e057600080fd5b81516102f36102ee826102ac565b61027c565b8082825260208201915060208360051b86010192508583111561031557600080fd5b602085015b8381101561034857805166ffffffffffffff198116811461033a57600080fd5b83526020928301920161031a565b5095945050505050565b600082601f83011261036357600080fd5b81516103716102ee826102ac565b8082825260208201915060208360051b86010192508583111561039357600080fd5b602085015b838110156103485780516001600160e01b0319811681146103b857600080fd5b835260209283019201610398565b6000602082840312156103d857600080fd5b81516001600160401b038111156103ee57600080fd5b82016080818503121561040057600080fd5b610408610254565b815160ff8116811461041957600080fd5b815260208201516001600160401b0381111561043457600080fd5b610440868285016102cf565b60208301525060408201516001600160401b0381111561045f57600080fd5b61046b868285016102cf565b60408301525060608201516001600160401b0381111561048a57600080fd5b61049686828501610352565b606083015250949350505050565b600063ffffffff821663ffffffff81036104ce57634e487b7160e01b600052601160045260246000fd5b60010192915050565b6000602082840312156104e957600080fd5b505191905056fe\";\n\nexport type DeferredActionTypedData = TypedDataDefinition<\n {\n DeferredAction: [\n { name: \"nonce\"; type: \"uint256\" },\n { name: \"deadline\"; type: \"uint48\" },\n { name: \"call\"; type: \"bytes\" },\n ];\n },\n \"DeferredAction\"\n>;\n\nexport type DeferredActionReturnData = {\n typedData: DeferredActionTypedData;\n};\n\nexport type CreateDeferredActionTypedDataParams = {\n callData: Hex;\n deadline: number;\n nonce: bigint;\n};\n\nexport type BuildPreSignatureDeferredActionPayloadParams = {\n typedData: DeferredActionTypedData;\n};\n\nexport type EntityIdAndNonceParams = {\n entityId?: number;\n nonceKey?: bigint;\n isGlobalValidation: boolean;\n isDeferredAction?: boolean;\n};\n\nexport type DeferralActions = {\n createDeferredActionTypedDataObject: (\n args: CreateDeferredActionTypedDataParams,\n ) => Promise<DeferredActionReturnData>;\n buildPreSignatureDeferredActionPayload: (\n args: BuildPreSignatureDeferredActionPayloadParams,\n ) => Hex;\n getEntityIdAndNonce: (\n args: EntityIdAndNonceParams,\n ) => Promise<{ nonce: bigint; entityId: number }>;\n};\n\n/**\n * Provides deferred action functionalities for a MA v2 client, ensuring compatibility with `SmartAccountClient`.\n *\n * @param {ModularAccountV2Client} client - The client instance which provides account and sendUserOperation functionality.\n * @returns {object} - An object containing three methods: `createDeferredActionTypedDataObject`, `buildPreSignatureDeferredActionPayload`, and `buildUserOperationWithDeferredAction`.\n */\nexport const deferralActions = <\n TTransport extends Transport = Transport,\n TChain extends Chain = Chain,\n TAccount extends SmartAccount = SmartAccount,\n>(\n client: Client<TTransport, TChain, TAccount>,\n): DeferralActions => {\n const createDeferredActionTypedDataObject = async ({\n callData,\n deadline,\n nonce,\n }: CreateDeferredActionTypedDataParams): Promise<DeferredActionReturnData> => {\n const account = client.account;\n if (!account || !isModularAccountV2(account)) {\n throw new AccountNotFoundError();\n }\n\n return {\n typedData: {\n domain: {\n chainId: client.chain.id,\n verifyingContract: client.account.address,\n },\n types: {\n DeferredAction: [\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint48\" },\n { name: \"call\", type: \"bytes\" },\n ],\n },\n primaryType: \"DeferredAction\",\n message: {\n nonce: nonce,\n deadline: deadline,\n call: callData,\n },\n },\n };\n };\n\n const buildPreSignatureDeferredActionPayload = ({\n typedData,\n }: BuildPreSignatureDeferredActionPayloadParams): Hex => {\n const account = client.account;\n if (!account || !isModularAccountV2(account)) {\n throw new AccountNotFoundError();\n }\n\n const signerEntity = account.signerEntity;\n const validationLocator =\n (BigInt(signerEntity.entityId) << 8n) |\n (signerEntity.isGlobalValidation ? 1n : 0n);\n\n const encodedCallData = encodePacked(\n [\"uint168\", \"uint48\", \"bytes\"],\n [validationLocator, typedData.message.deadline, typedData.message.call],\n );\n\n const encodedDataLength = size(encodedCallData);\n const encodedData = concatHex([\n toHex(encodedDataLength, { size: 4 }),\n encodedCallData,\n ]);\n return encodedData;\n };\n\n const getEntityIdAndNonce = async ({\n entityId = 1,\n nonceKey = 0n,\n isGlobalValidation,\n isDeferredAction = true,\n }: EntityIdAndNonceParams) => {\n const account = client.account;\n if (!account || !isModularAccountV2(account)) {\n throw new AccountNotFoundError();\n }\n\n if (nonceKey > maxUint152) {\n throw new InvalidNonceKeyError(nonceKey);\n }\n\n const bytecode = encodeDeployData({\n abi: entityIdAndNonceReaderAbi,\n bytecode: ENTITY_ID_AND_NONCE_READER_BYTECODE,\n args: [\n account.address,\n account.entryPoint.address,\n buildFullNonceKey({\n nonceKey,\n entityId,\n isGlobalValidation,\n isDeferredAction,\n }),\n ],\n });\n\n const action = getAction(client, call, \"call\");\n const { data } = await action({ data: bytecode });\n if (!data) {\n throw new BaseError(\"No data returned from contract call\");\n }\n if (!isHex(data)) {\n throw new BaseError(\"Expected hex data from contract call\");\n }\n\n return {\n nonce: BigInt(data),\n entityId: hexToNumber(`0x${data.slice(40, 48)}`),\n };\n };\n\n return {\n createDeferredActionTypedDataObject,\n buildPreSignatureDeferredActionPayload,\n getEntityIdAndNonce,\n };\n};\n"]}
|
|
@@ -133,11 +133,11 @@ export declare class PermissionBuilder {
|
|
|
133
133
|
/**
|
|
134
134
|
* Compiles the deferred action typed data to sign.
|
|
135
135
|
*
|
|
136
|
-
* @returns {Promise<{typedData: DeferredActionTypedData,
|
|
136
|
+
* @returns {Promise<{typedData: DeferredActionTypedData, fullPreSignatureDeferredActionPayload: Hex}>} The deferred action typed data and the full pre-signature deferred action payload.
|
|
137
137
|
*/
|
|
138
138
|
compileDeferred(): Promise<{
|
|
139
139
|
typedData: DeferredActionTypedData;
|
|
140
|
-
|
|
140
|
+
fullPreSignatureDeferredActionPayload: Hex;
|
|
141
141
|
}>;
|
|
142
142
|
/**
|
|
143
143
|
* Compiles the raw install arguments for the installValidation function.
|
|
@@ -8,13 +8,52 @@ import { deferralActions, } from "./decorators/deferralActions.js";
|
|
|
8
8
|
import { installValidationActions, } from "./decorators/installValidation.js";
|
|
9
9
|
import { assertNever, AccountNotFoundError } from "@alchemy/common";
|
|
10
10
|
import { AccountAddressAsTargetError, DeadlineOverLimitError, DuplicateTargetAddressError, ExpiredDeadlineError, MultipleGasLimitError, MultipleNativeTokenTransferError, NoFunctionsProvidedError, RootPermissionOnlyError, SelectorNotAllowed, ValidationConfigUnsetError, ZeroAddressError, } from "../errors/permissionBuilderErrors.js";
|
|
11
|
+
import { InvalidEntityIdError } from "../errors/InvalidEntityIdError.js";
|
|
11
12
|
import { DefaultModuleAddress, isModularAccountV2 } from "./utils/account.js";
|
|
12
|
-
//
|
|
13
|
+
// Reserved offset for hooks that would otherwise collide on shared module storage
|
|
14
|
+
// (ERC20 spend limit vs PREVAL_ALLOWLIST on AllowlistModule; GAS_LIMIT vs
|
|
15
|
+
// NATIVE_TOKEN_TRANSFER on NativeTokenLimitModule). Any user-supplied entityId
|
|
16
|
+
// must be strictly less than this so the offset namespace stays disjoint.
|
|
13
17
|
const HALF_UINT32 = 2147483647;
|
|
14
18
|
const ERC20_APPROVE_SELECTOR = "0x095ea7b3";
|
|
15
19
|
const ERC20_TRANSFER_SELECTOR = "0xa9059cbb";
|
|
16
20
|
const ACCOUNT_EXECUTE_SELECTOR = "0xb61d27f6";
|
|
17
21
|
const ACCOUNT_EXECUTEBATCH_SELECTOR = "0x34fcd5be";
|
|
22
|
+
const ACCOUNT_PERFORM_CREATE_SELECTOR = "0x5998db5c";
|
|
23
|
+
const ACCOUNT_EXECUTE_WITH_RUNTIME_VALIDATION_SELECTOR = "0xf2680c0f";
|
|
24
|
+
const ACCOUNT_INSTALL_VALIDATION_SELECTOR = "0x1bbf564c";
|
|
25
|
+
const ACCOUNT_UNINSTALL_VALIDATION_SELECTOR = "0xb6b1ccfe";
|
|
26
|
+
const ACCOUNT_INSTALL_EXECUTION_SELECTOR = "0x1d37e7d6";
|
|
27
|
+
const ACCOUNT_UNINSTALL_EXECUTION_SELECTOR = "0x0b7cad71";
|
|
28
|
+
const ACCOUNT_UPGRADE_TO_AND_CALL_SELECTOR = "0x4f1ef286";
|
|
29
|
+
// Wrapped native functions that must not be added to a session key's selector allowlist.
|
|
30
|
+
const PRIVILEGED_SELECTORS = {
|
|
31
|
+
[ACCOUNT_PERFORM_CREATE_SELECTOR]: "performCreate",
|
|
32
|
+
[ACCOUNT_EXECUTE_WITH_RUNTIME_VALIDATION_SELECTOR]: "executeWithRuntimeValidation",
|
|
33
|
+
[ACCOUNT_INSTALL_VALIDATION_SELECTOR]: "installValidation",
|
|
34
|
+
[ACCOUNT_UNINSTALL_VALIDATION_SELECTOR]: "uninstallValidation",
|
|
35
|
+
[ACCOUNT_INSTALL_EXECUTION_SELECTOR]: "installExecution",
|
|
36
|
+
[ACCOUNT_UNINSTALL_EXECUTION_SELECTOR]: "uninstallExecution",
|
|
37
|
+
[ACCOUNT_UPGRADE_TO_AND_CALL_SELECTOR]: "upgradeToAndCall",
|
|
38
|
+
};
|
|
39
|
+
// Auto-added by translatePermissions when a PREVAL_ALLOWLIST hook exists.
|
|
40
|
+
// Blocked from manual addition to ensure they're only added with proper hook context.
|
|
41
|
+
const SYSTEM_MANAGED_SELECTORS = {
|
|
42
|
+
[ACCOUNT_EXECUTE_SELECTOR]: "execute",
|
|
43
|
+
[ACCOUNT_EXECUTEBATCH_SELECTOR]: "executeBatch",
|
|
44
|
+
};
|
|
45
|
+
function assertNotForbiddenSelector(selector) {
|
|
46
|
+
const normalized = selector.toLowerCase();
|
|
47
|
+
const match = PRIVILEGED_SELECTORS[normalized] ?? SYSTEM_MANAGED_SELECTORS[normalized];
|
|
48
|
+
if (match != null) {
|
|
49
|
+
throw new SelectorNotAllowed(match);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function assertNoForbiddenSelectors(selectors) {
|
|
53
|
+
for (const selector of selectors) {
|
|
54
|
+
assertNotForbiddenSelector(selector);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
18
57
|
/**
|
|
19
58
|
* A pseudo-enum for permission types.
|
|
20
59
|
*/
|
|
@@ -115,6 +154,12 @@ export class PermissionBuilder {
|
|
|
115
154
|
if (!account || !isModularAccountV2(account)) {
|
|
116
155
|
throw new AccountNotFoundError();
|
|
117
156
|
}
|
|
157
|
+
// EntityIds in [HALF_UINT32, uint32.max] overlap the offset namespace used by
|
|
158
|
+
// ERC20 spend-limit and GAS_LIMIT hooks, which would silently corrupt the
|
|
159
|
+
// shared module storage. Reject early.
|
|
160
|
+
if (entityId >= HALF_UINT32) {
|
|
161
|
+
throw new InvalidEntityIdError(entityId, HALF_UINT32 - 1);
|
|
162
|
+
}
|
|
118
163
|
this.client = client;
|
|
119
164
|
this.validationConfig = {
|
|
120
165
|
moduleAddress: DefaultModuleAddress.SINGLE_SIGNER_VALIDATION,
|
|
@@ -128,8 +173,10 @@ export class PermissionBuilder {
|
|
|
128
173
|
signer: key.publicKey,
|
|
129
174
|
});
|
|
130
175
|
this.nonce = nonce;
|
|
131
|
-
if (selectors)
|
|
176
|
+
if (selectors) {
|
|
177
|
+
assertNoForbiddenSelectors(selectors);
|
|
132
178
|
this.selectors = selectors;
|
|
179
|
+
}
|
|
133
180
|
if (hooks)
|
|
134
181
|
this.hooks = hooks;
|
|
135
182
|
if (deadline)
|
|
@@ -142,6 +189,7 @@ export class PermissionBuilder {
|
|
|
142
189
|
* @returns {this} The permission builder instance.
|
|
143
190
|
*/
|
|
144
191
|
addSelector({ selector }) {
|
|
192
|
+
assertNotForbiddenSelector(selector);
|
|
145
193
|
this.selectors.push(selector);
|
|
146
194
|
return this;
|
|
147
195
|
}
|
|
@@ -193,13 +241,7 @@ export class PermissionBuilder {
|
|
|
193
241
|
if (permission.data.functions.length === 0) {
|
|
194
242
|
throw new NoFunctionsProvidedError(permission);
|
|
195
243
|
}
|
|
196
|
-
|
|
197
|
-
if (permission.data.functions.includes(ACCOUNT_EXECUTE_SELECTOR)) {
|
|
198
|
-
throw new SelectorNotAllowed("execute");
|
|
199
|
-
}
|
|
200
|
-
else if (permission.data.functions.includes(ACCOUNT_EXECUTEBATCH_SELECTOR)) {
|
|
201
|
-
throw new SelectorNotAllowed("executeBatch");
|
|
202
|
-
}
|
|
244
|
+
assertNoForbiddenSelectors(permission.data.functions);
|
|
203
245
|
this.selectors = [...this.selectors, ...permission.data.functions];
|
|
204
246
|
}
|
|
205
247
|
this.permissions.push(permission);
|
|
@@ -222,7 +264,7 @@ export class PermissionBuilder {
|
|
|
222
264
|
/**
|
|
223
265
|
* Compiles the deferred action typed data to sign.
|
|
224
266
|
*
|
|
225
|
-
* @returns {Promise<{typedData: DeferredActionTypedData,
|
|
267
|
+
* @returns {Promise<{typedData: DeferredActionTypedData, fullPreSignatureDeferredActionPayload: Hex}>} The deferred action typed data and the full pre-signature deferred action payload.
|
|
226
268
|
*/
|
|
227
269
|
async compileDeferred() {
|
|
228
270
|
// Add time range module hook via expiry
|
|
@@ -245,14 +287,14 @@ export class PermissionBuilder {
|
|
|
245
287
|
deadline: this.deadline,
|
|
246
288
|
nonce: this.nonce,
|
|
247
289
|
});
|
|
248
|
-
const
|
|
249
|
-
// Encode additional information to build the full pre-signature
|
|
250
|
-
const
|
|
290
|
+
const preSignaturePayload = deferralActions(this.client).buildPreSignatureDeferredActionPayload({ typedData });
|
|
291
|
+
// Encode additional information to build the full pre-signature payload
|
|
292
|
+
const fullPreSignatureDeferredActionPayload = `0x0${this.hasAssociatedExecHooks ? "1" : "0"}${toHex(this.nonce, {
|
|
251
293
|
size: 32,
|
|
252
|
-
}).slice(2)}${
|
|
294
|
+
}).slice(2)}${preSignaturePayload.slice(2)}`;
|
|
253
295
|
return {
|
|
254
296
|
typedData,
|
|
255
|
-
|
|
297
|
+
fullPreSignatureDeferredActionPayload,
|
|
256
298
|
};
|
|
257
299
|
}
|
|
258
300
|
/**
|
|
@@ -396,16 +438,18 @@ export class PermissionBuilder {
|
|
|
396
438
|
if (rawHooks[HookIdentifier.GAS_LIMIT] !== undefined) {
|
|
397
439
|
throw new MultipleGasLimitError(permission);
|
|
398
440
|
}
|
|
441
|
+
// Offset the entityId so GAS_LIMIT writes to a different slot than
|
|
442
|
+
// NATIVE_TOKEN_TRANSFER on the shared NativeTokenLimitModule.
|
|
399
443
|
rawHooks[HookIdentifier.GAS_LIMIT] = {
|
|
400
444
|
hookConfig: {
|
|
401
445
|
address: DefaultModuleAddress.NATIVE_TOKEN_LIMIT,
|
|
402
|
-
entityId,
|
|
446
|
+
entityId: entityId + HALF_UINT32,
|
|
403
447
|
hookType: HookType.VALIDATION,
|
|
404
448
|
hasPreHooks: true,
|
|
405
449
|
hasPostHooks: false,
|
|
406
450
|
},
|
|
407
451
|
initData: {
|
|
408
|
-
entityId,
|
|
452
|
+
entityId: entityId + HALF_UINT32,
|
|
409
453
|
spendLimit: BigInt(permission.data.limit),
|
|
410
454
|
},
|
|
411
455
|
};
|