@alchemy/smart-accounts 0.0.0-alpha.9 → 5.0.0-beta.2
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/LICENSE +1 -1
- package/README.md +36 -0
- package/dist/esm/index.d.ts +2 -4
- package/dist/esm/index.js +2 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/light-account/accounts/account.d.ts +7 -3
- package/dist/esm/light-account/accounts/account.js +20 -10
- package/dist/esm/light-account/accounts/account.js.map +1 -1
- package/dist/esm/light-account/accounts/base.js +50 -23
- package/dist/esm/light-account/accounts/base.js.map +1 -1
- package/dist/esm/light-account/accounts/calldataCodec.js +3 -2
- package/dist/esm/light-account/accounts/calldataCodec.js.map +1 -1
- package/dist/esm/light-account/accounts/multi-owner-account.d.ts +6 -2
- package/dist/esm/light-account/accounts/multi-owner-account.js +14 -6
- package/dist/esm/light-account/accounts/multi-owner-account.js.map +1 -1
- package/dist/esm/light-account/lightAccountStaticImpl.d.ts +3 -1
- package/dist/esm/light-account/lightAccountStaticImpl.js +57 -7
- package/dist/esm/light-account/lightAccountStaticImpl.js.map +1 -1
- package/dist/esm/light-account/predictAddress.d.ts +40 -2
- package/dist/esm/light-account/predictAddress.js +83 -3
- package/dist/esm/light-account/predictAddress.js.map +1 -1
- package/dist/esm/light-account/registry.d.ts +3410 -0
- package/dist/esm/light-account/registry.js +33 -1
- package/dist/esm/light-account/registry.js.map +1 -1
- package/dist/esm/logger.d.ts +1 -1
- package/dist/esm/logger.js +1 -1
- package/dist/esm/logger.js.map +1 -1
- package/dist/esm/ma-v1/accounts/multi-owner-account.d.ts +6 -2
- package/dist/esm/ma-v1/accounts/multi-owner-account.js +18 -7
- package/dist/esm/ma-v1/accounts/multi-owner-account.js.map +1 -1
- package/dist/esm/ma-v1/predictAddress.d.ts +20 -1
- package/dist/esm/ma-v1/predictAddress.js +38 -2
- package/dist/esm/ma-v1/predictAddress.js.map +1 -1
- package/dist/esm/ma-v2/accounts/account.d.ts +8 -5
- package/dist/esm/ma-v2/accounts/account.js +23 -42
- package/dist/esm/ma-v2/accounts/account.js.map +1 -1
- package/dist/esm/ma-v2/accounts/base.d.ts +2 -2
- package/dist/esm/ma-v2/accounts/base.js +12 -59
- package/dist/esm/ma-v2/accounts/base.js.map +1 -1
- package/dist/esm/ma-v2/mav2StaticImpl.d.ts +1 -15
- package/dist/esm/ma-v2/mav2StaticImpl.js +0 -33
- package/dist/esm/ma-v2/mav2StaticImpl.js.map +1 -1
- package/dist/esm/ma-v2/modules/time-range-module/module.js +3 -2
- package/dist/esm/ma-v2/modules/time-range-module/module.js.map +1 -1
- package/dist/esm/ma-v2/predictAddress.d.ts +22 -6
- package/dist/esm/ma-v2/predictAddress.js +46 -12
- package/dist/esm/ma-v2/predictAddress.js.map +1 -1
- package/dist/esm/ma-v2/utils/account.d.ts +0 -3
- package/dist/esm/ma-v2/utils/account.js +0 -3
- package/dist/esm/ma-v2/utils/account.js.map +1 -1
- package/dist/esm/ma-v2/utils/signature.d.ts +1 -16
- package/dist/esm/ma-v2/utils/signature.js +1 -38
- package/dist/esm/ma-v2/utils/signature.js.map +1 -1
- package/dist/esm/utils.d.ts +24 -11
- package/dist/esm/utils.js +67 -21
- package/dist/esm/utils.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 +2 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/light-account/accounts/account.d.ts +7 -3
- package/dist/types/light-account/accounts/account.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.map +1 -1
- package/dist/types/light-account/accounts/multi-owner-account.d.ts +6 -2
- package/dist/types/light-account/accounts/multi-owner-account.d.ts.map +1 -1
- package/dist/types/light-account/lightAccountStaticImpl.d.ts +3 -1
- package/dist/types/light-account/lightAccountStaticImpl.d.ts.map +1 -1
- package/dist/types/light-account/predictAddress.d.ts +40 -2
- package/dist/types/light-account/predictAddress.d.ts.map +1 -1
- package/dist/types/light-account/registry.d.ts +3410 -0
- package/dist/types/light-account/registry.d.ts.map +1 -1
- package/dist/types/logger.d.ts +1 -1
- package/dist/types/logger.d.ts.map +1 -1
- package/dist/types/ma-v1/accounts/multi-owner-account.d.ts +6 -2
- package/dist/types/ma-v1/accounts/multi-owner-account.d.ts.map +1 -1
- package/dist/types/ma-v1/predictAddress.d.ts +20 -1
- package/dist/types/ma-v1/predictAddress.d.ts.map +1 -1
- package/dist/types/ma-v2/accounts/account.d.ts +8 -5
- package/dist/types/ma-v2/accounts/account.d.ts.map +1 -1
- package/dist/types/ma-v2/accounts/base.d.ts +2 -2
- package/dist/types/ma-v2/accounts/base.d.ts.map +1 -1
- package/dist/types/ma-v2/mav2StaticImpl.d.ts +1 -15
- package/dist/types/ma-v2/mav2StaticImpl.d.ts.map +1 -1
- package/dist/types/ma-v2/modules/time-range-module/module.d.ts.map +1 -1
- package/dist/types/ma-v2/predictAddress.d.ts +22 -6
- package/dist/types/ma-v2/predictAddress.d.ts.map +1 -1
- package/dist/types/ma-v2/utils/account.d.ts +0 -3
- package/dist/types/ma-v2/utils/account.d.ts.map +1 -1
- package/dist/types/ma-v2/utils/signature.d.ts +1 -16
- package/dist/types/ma-v2/utils/signature.d.ts.map +1 -1
- package/dist/types/utils.d.ts +24 -11
- package/dist/types/utils.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 +9 -8
- package/src/index.ts +0 -6
- package/src/light-account/accounts/account.ts +30 -16
- package/src/light-account/accounts/base.ts +62 -23
- package/src/light-account/accounts/calldataCodec.ts +3 -2
- package/src/light-account/accounts/multi-owner-account.ts +22 -9
- package/src/light-account/lightAccountStaticImpl.ts +84 -11
- package/src/light-account/predictAddress.ts +124 -3
- package/src/light-account/registry.ts +44 -0
- package/src/logger.ts +2 -2
- package/src/ma-v1/accounts/multi-owner-account.ts +26 -11
- package/src/ma-v1/predictAddress.ts +60 -3
- package/src/ma-v2/accounts/account.ts +39 -52
- package/src/ma-v2/accounts/base.ts +11 -84
- package/src/ma-v2/mav2StaticImpl.ts +1 -52
- package/src/ma-v2/modules/time-range-module/module.ts +3 -2
- package/src/ma-v2/predictAddress.ts +68 -30
- package/src/ma-v2/utils/account.ts +0 -3
- package/src/ma-v2/utils/signature.ts +2 -57
- package/src/utils.ts +111 -27
- package/src/version.ts +1 -1
- package/dist/esm/ma-v2/abis/webAuthnFactoryAbi.d.ts +0 -330
- package/dist/esm/ma-v2/abis/webAuthnFactoryAbi.js +0 -260
- package/dist/esm/ma-v2/abis/webAuthnFactoryAbi.js.map +0 -1
- package/dist/esm/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.d.ts +0 -287
- package/dist/esm/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.js +0 -374
- package/dist/esm/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.js.map +0 -1
- package/dist/esm/ma-v2/modules/webauthn-validation/module.d.ts +0 -11
- package/dist/esm/ma-v2/modules/webauthn-validation/module.js +0 -16
- package/dist/esm/ma-v2/modules/webauthn-validation/module.js.map +0 -1
- package/dist/types/ma-v2/abis/webAuthnFactoryAbi.d.ts +0 -331
- package/dist/types/ma-v2/abis/webAuthnFactoryAbi.d.ts.map +0 -1
- package/dist/types/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.d.ts +0 -288
- package/dist/types/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.d.ts.map +0 -1
- package/dist/types/ma-v2/modules/webauthn-validation/module.d.ts +0 -12
- package/dist/types/ma-v2/modules/webauthn-validation/module.d.ts.map +0 -1
- package/src/ma-v2/abis/webAuthnFactoryAbi.ts +0 -259
- package/src/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.ts +0 -373
- package/src/ma-v2/modules/webauthn-validation/module.ts +0 -28
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type Address,
|
|
3
|
-
|
|
3
|
+
type Client,
|
|
4
|
+
concatHex,
|
|
5
|
+
decodeFunctionData,
|
|
4
6
|
encodeAbiParameters,
|
|
7
|
+
getContractAddress,
|
|
8
|
+
isAddressEqual,
|
|
5
9
|
keccak256,
|
|
6
|
-
concatHex,
|
|
7
10
|
type Hex,
|
|
8
11
|
} from "viem";
|
|
12
|
+
import type { EntryPointVersion } from "viem/account-abstraction";
|
|
9
13
|
import { DefaultMaV1Address } from "./account.js";
|
|
14
|
+
import { MultiOwnerModularAccountFactoryAbi } from "./abis/MultiOwnerModularAccountFactory.js";
|
|
10
15
|
import { BaseError } from "@alchemy/common";
|
|
16
|
+
import { getSenderFromFactoryData } from "../utils.js";
|
|
11
17
|
|
|
12
18
|
export type PredictMultiOwnerModularAccountV1AddressParams = {
|
|
13
19
|
salt: bigint;
|
|
@@ -46,7 +52,7 @@ export const predictMultiOwnerModularAccountV1Address = ({
|
|
|
46
52
|
throw new BaseError("Owners array cannot be empty");
|
|
47
53
|
}
|
|
48
54
|
if (ownerAddresses.length > 100) {
|
|
49
|
-
throw new
|
|
55
|
+
throw new BaseError("Maximum 100 owners on creation");
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
const combinedSalt = getCombinedSalt(salt, ownerAddresses);
|
|
@@ -83,3 +89,54 @@ function getERC1967ProxyInitCodeHash(implementationAddress: Address): Hex {
|
|
|
83
89
|
|
|
84
90
|
return keccak256(concatHex([ERC1967_PROXY_BYTECODE, constructorArgs]));
|
|
85
91
|
}
|
|
92
|
+
|
|
93
|
+
export type GetMultiOwnerModularAccountV1AddressFromFactoryDataParams = {
|
|
94
|
+
client: Client;
|
|
95
|
+
factoryAddress: Address;
|
|
96
|
+
factoryData: Hex;
|
|
97
|
+
entryPoint: {
|
|
98
|
+
version: EntryPointVersion;
|
|
99
|
+
address: Address;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Gets the multi-owner modular account v1 address from factory data.
|
|
105
|
+
* If the factory is a known default, decodes the args and predicts without RPC.
|
|
106
|
+
* Otherwise falls back to calling the entry point's getSenderAddress.
|
|
107
|
+
*
|
|
108
|
+
* @param {GetMultiOwnerModularAccountV1AddressFromFactoryDataParams} params - The parameters
|
|
109
|
+
* @returns {Promise<Address>} The account address
|
|
110
|
+
*/
|
|
111
|
+
export async function getMultiOwnerModularAccountV1AddressFromFactoryData({
|
|
112
|
+
client,
|
|
113
|
+
factoryAddress,
|
|
114
|
+
factoryData,
|
|
115
|
+
entryPoint,
|
|
116
|
+
}: GetMultiOwnerModularAccountV1AddressFromFactoryDataParams): Promise<Address> {
|
|
117
|
+
if (
|
|
118
|
+
isAddressEqual(factoryAddress, DefaultMaV1Address.MULTI_OWNER_MAV1_FACTORY)
|
|
119
|
+
) {
|
|
120
|
+
try {
|
|
121
|
+
const decoded = decodeFunctionData({
|
|
122
|
+
abi: MultiOwnerModularAccountFactoryAbi,
|
|
123
|
+
data: factoryData,
|
|
124
|
+
});
|
|
125
|
+
if (decoded.functionName === "createAccount") {
|
|
126
|
+
const [decodedSalt, decodedOwners] = decoded.args;
|
|
127
|
+
return predictMultiOwnerModularAccountV1Address({
|
|
128
|
+
factoryAddress,
|
|
129
|
+
salt: decodedSalt,
|
|
130
|
+
ownerAddresses: [...decodedOwners],
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
} catch {
|
|
134
|
+
// Decode failed, fall through to RPC
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return getSenderFromFactoryData(client, {
|
|
138
|
+
factory: factoryAddress,
|
|
139
|
+
factoryData,
|
|
140
|
+
entryPoint,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
@@ -9,16 +9,17 @@ import {
|
|
|
9
9
|
type PrivateKeyAccount,
|
|
10
10
|
type Transport,
|
|
11
11
|
} from "viem";
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
import {
|
|
13
|
+
type ToSmartAccountParameters,
|
|
14
|
+
entryPoint07Address,
|
|
15
15
|
} from "viem/account-abstraction";
|
|
16
16
|
import { toModularAccountV2Base, type ModularAccountV2Base } from "./base.js";
|
|
17
17
|
import type { SignerEntity } from "../types.js";
|
|
18
|
-
import {
|
|
19
|
-
|
|
18
|
+
import {
|
|
19
|
+
getModularAccountV2AddressFromFactoryData,
|
|
20
|
+
predictModularAccountV2Address,
|
|
21
|
+
} from "../predictAddress.js";
|
|
20
22
|
import { accountFactoryAbi } from "../abis/accountFactoryAbi.js";
|
|
21
|
-
import { webAuthnFactoryAbi } from "../abis/webAuthnFactoryAbi.js";
|
|
22
23
|
import { EntityIdOverrideError } from "../../errors/EntityIdOverrideError.js";
|
|
23
24
|
import { InvalidOwnerError } from "../../errors/InvalidOwnerError.js";
|
|
24
25
|
import { DEFAULT_OWNER_ENTITY_ID, DefaultAddress } from "../utils/account.js";
|
|
@@ -33,7 +34,7 @@ export type ToModularAccountV2Params<
|
|
|
33
34
|
TMode extends Mode | undefined = Mode | undefined,
|
|
34
35
|
> = {
|
|
35
36
|
client: Client<Transport, Chain, JsonRpcAccount | LocalAccount | undefined>;
|
|
36
|
-
owner: JsonRpcAccount | LocalAccount
|
|
37
|
+
owner: JsonRpcAccount | LocalAccount;
|
|
37
38
|
deferredAction?: Hex;
|
|
38
39
|
signerEntity?: SignerEntity;
|
|
39
40
|
accountAddress?: Address;
|
|
@@ -46,11 +47,18 @@ export type ToModularAccountV2Params<
|
|
|
46
47
|
implementationAddress?: never;
|
|
47
48
|
}
|
|
48
49
|
: {
|
|
49
|
-
salt?: bigint;
|
|
50
50
|
factory?: Address;
|
|
51
|
-
factoryData?: Hex;
|
|
52
51
|
implementationAddress?: Address;
|
|
53
|
-
}
|
|
52
|
+
} & (
|
|
53
|
+
| {
|
|
54
|
+
salt?: bigint;
|
|
55
|
+
factoryData?: never;
|
|
56
|
+
}
|
|
57
|
+
| {
|
|
58
|
+
salt?: never;
|
|
59
|
+
factoryData?: Hex;
|
|
60
|
+
}
|
|
61
|
+
));
|
|
54
62
|
|
|
55
63
|
/**
|
|
56
64
|
* Creates a MAv2 account.
|
|
@@ -81,19 +89,11 @@ export async function toModularAccountV2<TMode extends Mode = Mode>({
|
|
|
81
89
|
|
|
82
90
|
const entityId = signerEntity?.entityId ?? DEFAULT_OWNER_ENTITY_ID;
|
|
83
91
|
|
|
84
|
-
const factoryAddress =
|
|
85
|
-
factory ??
|
|
86
|
-
(owner.type === "webAuthn"
|
|
87
|
-
? DefaultAddress.MAV2_FACTORY_WEBAUTHN
|
|
88
|
-
: DefaultAddress.MAV2_FACTORY);
|
|
92
|
+
const factoryAddress = factory ?? DefaultAddress.MAV2_FACTORY;
|
|
89
93
|
|
|
90
94
|
const implementationAddress =
|
|
91
95
|
implementationAddress_ ??
|
|
92
|
-
(is7702
|
|
93
|
-
? DefaultAddress.SMAV2_7702
|
|
94
|
-
: owner.type === "webAuthn"
|
|
95
|
-
? DefaultAddress.MAV2
|
|
96
|
-
: DefaultAddress.SMAV2_BYTECODE);
|
|
96
|
+
(is7702 ? DefaultAddress.SMAV2_7702 : DefaultAddress.SMAV2_BYTECODE);
|
|
97
97
|
|
|
98
98
|
const getFactoryArgs = async () => {
|
|
99
99
|
if (is7702) {
|
|
@@ -108,20 +108,6 @@ export async function toModularAccountV2<TMode extends Mode = Mode>({
|
|
|
108
108
|
} as const;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
if (owner.type === "webAuthn") {
|
|
112
|
-
const { x, y } = parsePublicKey(owner.publicKey);
|
|
113
|
-
return {
|
|
114
|
-
factory: factoryAddress,
|
|
115
|
-
factoryData:
|
|
116
|
-
factoryData_ ??
|
|
117
|
-
encodeFunctionData({
|
|
118
|
-
abi: webAuthnFactoryAbi,
|
|
119
|
-
functionName: "createWebAuthnAccount",
|
|
120
|
-
args: [x, y, salt, entityId],
|
|
121
|
-
}),
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
111
|
return {
|
|
126
112
|
factory: factoryAddress,
|
|
127
113
|
factoryData:
|
|
@@ -136,24 +122,26 @@ export async function toModularAccountV2<TMode extends Mode = Mode>({
|
|
|
136
122
|
|
|
137
123
|
const accountAddress =
|
|
138
124
|
accountAddress_ ??
|
|
139
|
-
(
|
|
125
|
+
(is7702
|
|
140
126
|
? owner.address
|
|
141
|
-
:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
127
|
+
: factoryData_
|
|
128
|
+
? await getModularAccountV2AddressFromFactoryData({
|
|
129
|
+
client,
|
|
130
|
+
factoryAddress,
|
|
131
|
+
factoryData: factoryData_,
|
|
132
|
+
implementationAddress,
|
|
133
|
+
entryPoint: {
|
|
134
|
+
version: "0.7",
|
|
135
|
+
address: entryPoint07Address,
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
: predictModularAccountV2Address({
|
|
139
|
+
factoryAddress,
|
|
140
|
+
implementationAddress,
|
|
141
|
+
salt,
|
|
142
|
+
type: "SMA",
|
|
143
|
+
ownerAddress: owner.address,
|
|
144
|
+
}));
|
|
157
145
|
|
|
158
146
|
LOGGER.debug("toModularAccountV2:address-resolved", {
|
|
159
147
|
accountAddress,
|
|
@@ -163,7 +151,6 @@ export async function toModularAccountV2<TMode extends Mode = Mode>({
|
|
|
163
151
|
let authorization: ToSmartAccountParameters["authorization"];
|
|
164
152
|
if (is7702) {
|
|
165
153
|
LOGGER.debug("toModularAccountV2:7702-mode");
|
|
166
|
-
// TODO(v5): Ensure this works w/ our signer types.
|
|
167
154
|
if (owner.type !== "local") {
|
|
168
155
|
LOGGER.error("toModularAccountV2:invalid-owner-type", {
|
|
169
156
|
ownerType: owner.type,
|
|
@@ -22,10 +22,7 @@ import {
|
|
|
22
22
|
entryPoint07Address,
|
|
23
23
|
getUserOperationHash,
|
|
24
24
|
toSmartAccount,
|
|
25
|
-
type WebAuthnAccount,
|
|
26
25
|
type ToSmartAccountParameters,
|
|
27
|
-
estimateUserOperationGas,
|
|
28
|
-
type UserOperation,
|
|
29
26
|
} from "viem/account-abstraction";
|
|
30
27
|
import {
|
|
31
28
|
getCode,
|
|
@@ -60,15 +57,13 @@ import {
|
|
|
60
57
|
import { parseDeferredAction } from "../utils/deferredActions.js";
|
|
61
58
|
import {
|
|
62
59
|
pack1271Signature,
|
|
63
|
-
toWebAuthnSignature,
|
|
64
60
|
toReplaySafeTypedData,
|
|
65
61
|
packUOSignature,
|
|
66
|
-
WEBAUTHN_DUMMY_SIGNATURE,
|
|
67
62
|
} from "../utils/signature.js";
|
|
68
|
-
import { chainHas7212 } from "../../utils.js";
|
|
69
63
|
import { InvalidDeferredActionNonceError } from "../../errors/InvalidDeferredActionNonceError.js";
|
|
70
64
|
import { InvalidNonceKeyError } from "../../errors/InvalidNonceKeyError.js";
|
|
71
65
|
import { InvalidEntityIdError } from "../../errors/InvalidEntityIdError.js";
|
|
66
|
+
import { is7702Delegated } from "../../utils.js";
|
|
72
67
|
|
|
73
68
|
export type ValidationDataParams =
|
|
74
69
|
| {
|
|
@@ -104,7 +99,7 @@ export type ToModularAccountV2BaseParams<
|
|
|
104
99
|
TTransport extends Transport = Transport,
|
|
105
100
|
> = {
|
|
106
101
|
client: Client<TTransport, Chain, JsonRpcAccount | LocalAccount | undefined>;
|
|
107
|
-
owner: JsonRpcAccount | LocalAccount
|
|
102
|
+
owner: JsonRpcAccount | LocalAccount;
|
|
108
103
|
accountAddress: Address;
|
|
109
104
|
getFactoryArgs: () => Promise<{
|
|
110
105
|
factory?: Address | undefined;
|
|
@@ -155,7 +150,9 @@ export async function toModularAccountV2Base<
|
|
|
155
150
|
}
|
|
156
151
|
const action = getAction(client, getCode, "getCode");
|
|
157
152
|
const code = await action({ address: accountAddress });
|
|
158
|
-
isDeployed =
|
|
153
|
+
isDeployed = authorization
|
|
154
|
+
? is7702Delegated(authorization.address, code)
|
|
155
|
+
: !!code;
|
|
159
156
|
return isDeployed;
|
|
160
157
|
};
|
|
161
158
|
|
|
@@ -303,17 +300,12 @@ export async function toModularAccountV2Base<
|
|
|
303
300
|
data: toReplaySafeTypedData({
|
|
304
301
|
chainId: client.chain.id,
|
|
305
302
|
hash,
|
|
306
|
-
...(
|
|
307
|
-
? {
|
|
308
|
-
|
|
303
|
+
...(entityId === DEFAULT_OWNER_ENTITY_ID
|
|
304
|
+
? { address: accountAddress }
|
|
305
|
+
: {
|
|
306
|
+
address: DefaultModuleAddress.SINGLE_SIGNER_VALIDATION,
|
|
309
307
|
salt: concatHex([`0x${"00".repeat(12)}`, accountAddress]),
|
|
310
|
-
}
|
|
311
|
-
: entityId === DEFAULT_OWNER_ENTITY_ID
|
|
312
|
-
? { address: accountAddress }
|
|
313
|
-
: {
|
|
314
|
-
address: DefaultModuleAddress.SINGLE_SIGNER_VALIDATION,
|
|
315
|
-
salt: concatHex([`0x${"00".repeat(12)}`, accountAddress]),
|
|
316
|
-
}),
|
|
308
|
+
}),
|
|
317
309
|
}),
|
|
318
310
|
};
|
|
319
311
|
};
|
|
@@ -321,8 +313,7 @@ export async function toModularAccountV2Base<
|
|
|
321
313
|
const formatSignature = async (signature: Hex): Promise<Hex> => {
|
|
322
314
|
return pack1271Signature({
|
|
323
315
|
entityId,
|
|
324
|
-
validationSignaturePrefix:
|
|
325
|
-
owner.type === "webAuthn" ? null : SignaturePrefix.EOA,
|
|
316
|
+
validationSignaturePrefix: SignaturePrefix.EOA,
|
|
326
317
|
validationSignature: signature,
|
|
327
318
|
});
|
|
328
319
|
};
|
|
@@ -418,10 +409,6 @@ export async function toModularAccountV2Base<
|
|
|
418
409
|
},
|
|
419
410
|
|
|
420
411
|
async getStubSignature() {
|
|
421
|
-
if (owner.type === "webAuthn") {
|
|
422
|
-
return WEBAUTHN_DUMMY_SIGNATURE;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
412
|
const sig = packUOSignature({
|
|
426
413
|
validationSignature:
|
|
427
414
|
"0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c",
|
|
@@ -435,13 +422,6 @@ export async function toModularAccountV2Base<
|
|
|
435
422
|
data: message,
|
|
436
423
|
});
|
|
437
424
|
|
|
438
|
-
if (owner.type === "webAuthn") {
|
|
439
|
-
const validationSignature = toWebAuthnSignature(
|
|
440
|
-
await owner.sign({ hash: hashTypedData(data) }),
|
|
441
|
-
);
|
|
442
|
-
return formatSignature(validationSignature);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
425
|
const action = getAction(client, signTypedData, "signTypedData");
|
|
446
426
|
|
|
447
427
|
const signature = await action({
|
|
@@ -465,15 +445,6 @@ export async function toModularAccountV2Base<
|
|
|
465
445
|
data: td as TypedDataDefinition, // TODO(v5): Try harder to satisfy this w/o casting.
|
|
466
446
|
});
|
|
467
447
|
|
|
468
|
-
if (owner.type === "webAuthn") {
|
|
469
|
-
const validationSignature = toWebAuthnSignature(
|
|
470
|
-
await owner.sign({ hash: hashTypedData(data) }),
|
|
471
|
-
);
|
|
472
|
-
return isDeferredAction
|
|
473
|
-
? validationSignature
|
|
474
|
-
: formatSignature(validationSignature);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
448
|
const action = getAction(client, signTypedData, "signTypedData");
|
|
478
449
|
|
|
479
450
|
const signature = await action({
|
|
@@ -497,21 +468,6 @@ export async function toModularAccountV2Base<
|
|
|
497
468
|
},
|
|
498
469
|
});
|
|
499
470
|
|
|
500
|
-
if (owner.type === "webAuthn") {
|
|
501
|
-
const validationSignature = toWebAuthnSignature(
|
|
502
|
-
await owner.sign({
|
|
503
|
-
hash: hashMessage({ raw: hash }),
|
|
504
|
-
}),
|
|
505
|
-
);
|
|
506
|
-
|
|
507
|
-
const signature = deferredActionData
|
|
508
|
-
? concatHex([deferredActionData, validationSignature])
|
|
509
|
-
: validationSignature;
|
|
510
|
-
deferredActionData = undefined; // clear once used
|
|
511
|
-
hasAssociatedExecHooks = false; // set to falsy value once used
|
|
512
|
-
return concatHex(["0xff", signature]);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
471
|
const signMessageAction = getAction(client, signMessage, "signMessage");
|
|
516
472
|
|
|
517
473
|
const validationSignature = await signMessageAction({
|
|
@@ -533,35 +489,6 @@ export async function toModularAccountV2Base<
|
|
|
533
489
|
return signature;
|
|
534
490
|
},
|
|
535
491
|
|
|
536
|
-
userOperation: {
|
|
537
|
-
estimateGas: async (uo) => {
|
|
538
|
-
if (owner.type !== "webAuthn") {
|
|
539
|
-
// Uses the default gas estimator.
|
|
540
|
-
// Note that we get 7702 support automatically from Viem.
|
|
541
|
-
return undefined;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
const estimateGasAction = getAction(
|
|
545
|
-
client,
|
|
546
|
-
estimateUserOperationGas,
|
|
547
|
-
"estimateUserOperationGas",
|
|
548
|
-
);
|
|
549
|
-
|
|
550
|
-
const estimate = await estimateGasAction({
|
|
551
|
-
...(uo as UserOperation<typeof entryPoint.version>),
|
|
552
|
-
entryPointAddress: entryPoint.address,
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
const buffer = (await chainHas7212(client)) ? 10000n : 300000n;
|
|
556
|
-
|
|
557
|
-
// TODO(v4): iterate numbers. Aim to have ~1000 gas buffer to account for longer authenticatorDatas and clientDataJSONs.
|
|
558
|
-
return {
|
|
559
|
-
...estimate,
|
|
560
|
-
verificationGasLimit: estimate.verificationGasLimit + buffer,
|
|
561
|
-
};
|
|
562
|
-
},
|
|
563
|
-
},
|
|
564
|
-
|
|
565
492
|
extend: {
|
|
566
493
|
smartAccountType: "ModularAccountV2" as const,
|
|
567
494
|
signerEntity: {
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import { encodeFunctionData, type Address
|
|
1
|
+
import { encodeFunctionData, type Address } from "viem";
|
|
2
2
|
import { entryPoint07Abi, entryPoint07Address } from "viem/account-abstraction";
|
|
3
3
|
import { lowerAddress } from "@alchemy/common";
|
|
4
4
|
import type { StaticSmartAccountImplementation } from "../types.js";
|
|
5
5
|
import { semiModularAccountBytecodeAbi } from "./abis/semiModularAccountBytecodeAbi.js";
|
|
6
6
|
import { accountFactoryAbi } from "./abis/accountFactoryAbi.js";
|
|
7
|
-
import { webAuthnFactoryAbi } from "./abis/webAuthnFactoryAbi.js";
|
|
8
7
|
import { DefaultAddress as DefaultMAV2Address } from "./utils/account.js";
|
|
9
8
|
import { predictModularAccountV2Address } from "./predictAddress.js";
|
|
10
|
-
import { modularAccountAbi } from "./abis/modularAccountAbi.js";
|
|
11
|
-
import { parsePublicKey } from "webauthn-p256";
|
|
12
9
|
|
|
13
10
|
export type SemiModularAccountV2FactoryArgs = {
|
|
14
11
|
owner: Address;
|
|
@@ -84,51 +81,3 @@ export const semiModularAccount7702StaticImpl: SemiModularAccount7702StaticImpl
|
|
|
84
81
|
...semiModularAccountBase,
|
|
85
82
|
delegationAddress: lowerAddress(DefaultMAV2Address.SMAV2_7702),
|
|
86
83
|
};
|
|
87
|
-
|
|
88
|
-
export type WebAuthnModularAccountV2FactoryArgs = {
|
|
89
|
-
ownerPublicKey: Hex;
|
|
90
|
-
salt: bigint;
|
|
91
|
-
entityId: number;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
export type WebAuthnModularAccountV2StaticImpl =
|
|
95
|
-
StaticSmartAccountImplementation<
|
|
96
|
-
false,
|
|
97
|
-
"0.7",
|
|
98
|
-
WebAuthnModularAccountV2FactoryArgs,
|
|
99
|
-
typeof entryPoint07Abi,
|
|
100
|
-
typeof modularAccountAbi,
|
|
101
|
-
typeof webAuthnFactoryAbi
|
|
102
|
-
>;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Static implementation logic for WebAuthnModularAccountV2.
|
|
106
|
-
*
|
|
107
|
-
* TODO(v5): update JSDoc format when doc-gen supports structs or records.
|
|
108
|
-
*/
|
|
109
|
-
export const webAuthnModularAccountV2StaticImpl: WebAuthnModularAccountV2StaticImpl =
|
|
110
|
-
{
|
|
111
|
-
entryPoint,
|
|
112
|
-
accountAbi: modularAccountAbi,
|
|
113
|
-
accountImplementation: lowerAddress(DefaultMAV2Address.MAV2),
|
|
114
|
-
factoryAddress: lowerAddress(DefaultMAV2Address.MAV2_FACTORY_WEBAUTHN),
|
|
115
|
-
factoryAbi: webAuthnFactoryAbi,
|
|
116
|
-
getFactoryData: (args: WebAuthnModularAccountV2FactoryArgs) => {
|
|
117
|
-
const { x, y } = parsePublicKey(args.ownerPublicKey);
|
|
118
|
-
return encodeFunctionData({
|
|
119
|
-
abi: webAuthnFactoryAbi,
|
|
120
|
-
functionName: "createWebAuthnAccount",
|
|
121
|
-
args: [x, y, args.salt, args.entityId],
|
|
122
|
-
});
|
|
123
|
-
},
|
|
124
|
-
predictAccountAddress: (args: WebAuthnModularAccountV2FactoryArgs) => {
|
|
125
|
-
return predictModularAccountV2Address({
|
|
126
|
-
factoryAddress: DefaultMAV2Address.MAV2_FACTORY_WEBAUTHN,
|
|
127
|
-
implementationAddress: DefaultMAV2Address.MAV2,
|
|
128
|
-
type: "WebAuthn",
|
|
129
|
-
salt: args.salt,
|
|
130
|
-
ownerPublicKey: args.ownerPublicKey,
|
|
131
|
-
entityId: args.entityId,
|
|
132
|
-
});
|
|
133
|
-
},
|
|
134
|
-
};
|
|
@@ -2,6 +2,7 @@ import { encodeAbiParameters, type Address, type Hex } from "viem";
|
|
|
2
2
|
|
|
3
3
|
import { timeRangeModuleAbi } from "./abis/timeRangeModuleAbi.js";
|
|
4
4
|
import { HookType, type HookConfig } from "../../types.js";
|
|
5
|
+
import { BaseError } from "@alchemy/common";
|
|
5
6
|
|
|
6
7
|
export const TimeRangeModule = {
|
|
7
8
|
abi: timeRangeModuleAbi,
|
|
@@ -14,13 +15,13 @@ export const TimeRangeModule = {
|
|
|
14
15
|
address: Address,
|
|
15
16
|
): { hookConfig: HookConfig; initData: Hex } => {
|
|
16
17
|
if (installArgs.validUntil > 2 ** 48 - 1) {
|
|
17
|
-
throw new
|
|
18
|
+
throw new BaseError(
|
|
18
19
|
"TimeRangeModule.buildHook: validUntil > type(uint48).max",
|
|
19
20
|
);
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
if (installArgs.validAfter > 2 ** 48 - 1) {
|
|
23
|
-
throw new
|
|
24
|
+
throw new BaseError(
|
|
24
25
|
"TimeRangeModule.buildHook: validAfter > type(uint48).max",
|
|
25
26
|
);
|
|
26
27
|
}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { assertNever } from "@alchemy/common";
|
|
2
2
|
import {
|
|
3
3
|
concatHex,
|
|
4
|
+
decodeFunctionData,
|
|
4
5
|
encodePacked,
|
|
5
6
|
getContractAddress,
|
|
7
|
+
isAddressEqual,
|
|
6
8
|
keccak256,
|
|
7
9
|
type Address,
|
|
10
|
+
type Client,
|
|
8
11
|
type Hex,
|
|
9
12
|
} from "viem";
|
|
10
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
entryPoint07Address,
|
|
15
|
+
type EntryPointVersion,
|
|
16
|
+
} from "viem/account-abstraction";
|
|
17
|
+
import { accountFactoryAbi } from "./abis/accountFactoryAbi.js";
|
|
18
|
+
import { DefaultAddress } from "./utils/account.js";
|
|
19
|
+
import { getSenderFromFactoryData } from "../utils.js";
|
|
11
20
|
|
|
12
21
|
export type PredictModularAccountV2AddressParams = {
|
|
13
22
|
factoryAddress: Address;
|
|
@@ -23,15 +32,10 @@ export type PredictModularAccountV2AddressParams = {
|
|
|
23
32
|
type: "SMA";
|
|
24
33
|
ownerAddress: Address;
|
|
25
34
|
}
|
|
26
|
-
| {
|
|
27
|
-
type: "WebAuthn";
|
|
28
|
-
ownerPublicKey: Hex;
|
|
29
|
-
entityId: number;
|
|
30
|
-
}
|
|
31
35
|
);
|
|
32
36
|
|
|
33
37
|
/**
|
|
34
|
-
* Predicts the address of a modular account V2 based on the provided parameters, which include factory address, salt, and implementation address. This function supports different types of accounts including "SMA"
|
|
38
|
+
* Predicts the address of a modular account V2 based on the provided parameters, which include factory address, salt, and implementation address. This function supports different types of accounts including "SMA" and "MA".
|
|
35
39
|
*
|
|
36
40
|
* @example
|
|
37
41
|
* ```ts
|
|
@@ -80,16 +84,6 @@ export function predictModularAccountV2Address(
|
|
|
80
84
|
),
|
|
81
85
|
initcode: getProxyBytecode(implementationAddress),
|
|
82
86
|
};
|
|
83
|
-
case "WebAuthn":
|
|
84
|
-
const { x, y } = parsePublicKey(params.ownerPublicKey);
|
|
85
|
-
return {
|
|
86
|
-
combinedSalt: getCombinedSaltWebAuthn(
|
|
87
|
-
{ x, y },
|
|
88
|
-
salt,
|
|
89
|
-
params.entityId,
|
|
90
|
-
),
|
|
91
|
-
initcode: getProxyBytecode(implementationAddress),
|
|
92
|
-
};
|
|
93
87
|
default:
|
|
94
88
|
return assertNever(params, "Unexpected MAv2 type");
|
|
95
89
|
}
|
|
@@ -116,19 +110,6 @@ function getCombinedSaltK1(
|
|
|
116
110
|
);
|
|
117
111
|
}
|
|
118
112
|
|
|
119
|
-
function getCombinedSaltWebAuthn(
|
|
120
|
-
ownerPublicKey: { x: bigint; y: bigint },
|
|
121
|
-
salt: bigint,
|
|
122
|
-
entityId: number,
|
|
123
|
-
): Hex {
|
|
124
|
-
return keccak256(
|
|
125
|
-
encodePacked(
|
|
126
|
-
["uint256", "uint256", "uint256", "uint32"],
|
|
127
|
-
[ownerPublicKey.x, ownerPublicKey.y, salt, entityId],
|
|
128
|
-
),
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
113
|
function getProxyBytecode(implementationAddress: Address): Hex {
|
|
133
114
|
return concatHex([
|
|
134
115
|
"0x603d3d8160223d3973",
|
|
@@ -147,3 +128,60 @@ function getProxyBytecodeWithImmutableArgs(
|
|
|
147
128
|
2,
|
|
148
129
|
)}`;
|
|
149
130
|
}
|
|
131
|
+
|
|
132
|
+
export type GetModularAccountV2AddressFromFactoryDataParams = {
|
|
133
|
+
client: Client;
|
|
134
|
+
factoryAddress: Address;
|
|
135
|
+
factoryData: Hex;
|
|
136
|
+
implementationAddress: Address;
|
|
137
|
+
entryPoint?: {
|
|
138
|
+
version: EntryPointVersion;
|
|
139
|
+
address: Address;
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Gets the modular account v2 address from factory data.
|
|
145
|
+
* If the factory is a known default (SMA), decodes the args and predicts without RPC.
|
|
146
|
+
* Otherwise falls back to calling the entry point's getSenderAddress.
|
|
147
|
+
*
|
|
148
|
+
* @param {GetModularAccountV2AddressFromFactoryDataParams} params - The parameters
|
|
149
|
+
* @returns {Promise<Address>} The account address
|
|
150
|
+
*/
|
|
151
|
+
export async function getModularAccountV2AddressFromFactoryData({
|
|
152
|
+
client,
|
|
153
|
+
factoryAddress,
|
|
154
|
+
factoryData,
|
|
155
|
+
implementationAddress,
|
|
156
|
+
entryPoint = {
|
|
157
|
+
version: "0.7",
|
|
158
|
+
address: entryPoint07Address,
|
|
159
|
+
},
|
|
160
|
+
}: GetModularAccountV2AddressFromFactoryDataParams): Promise<Address> {
|
|
161
|
+
// Try SMA factory
|
|
162
|
+
if (isAddressEqual(factoryAddress, DefaultAddress.MAV2_FACTORY)) {
|
|
163
|
+
try {
|
|
164
|
+
const decoded = decodeFunctionData({
|
|
165
|
+
abi: accountFactoryAbi,
|
|
166
|
+
data: factoryData,
|
|
167
|
+
});
|
|
168
|
+
if (decoded.functionName === "createSemiModularAccount") {
|
|
169
|
+
const [decodedOwner, decodedSalt] = decoded.args;
|
|
170
|
+
return predictModularAccountV2Address({
|
|
171
|
+
factoryAddress,
|
|
172
|
+
implementationAddress,
|
|
173
|
+
salt: decodedSalt,
|
|
174
|
+
type: "SMA",
|
|
175
|
+
ownerAddress: decodedOwner,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
} catch {
|
|
179
|
+
// Decode failed, fall through to RPC
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return getSenderFromFactoryData(client, {
|
|
183
|
+
factory: factoryAddress,
|
|
184
|
+
factoryData,
|
|
185
|
+
entryPoint,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
@@ -16,11 +16,9 @@ import type { ModularAccountV2Base } from "../accounts/base.js";
|
|
|
16
16
|
*/
|
|
17
17
|
export const DefaultAddress = {
|
|
18
18
|
MAV2_FACTORY: "0x00000000000017c61b5bEe81050EC8eFc9c6fecd",
|
|
19
|
-
MAV2_FACTORY_WEBAUTHN: "0x55010E571dCf07e254994bfc88b9C1C8FAe31960",
|
|
20
19
|
SMAV2_BYTECODE: "0x000000000000c5A9089039570Dd36455b5C07383",
|
|
21
20
|
SMAV2_STORAGE: "0x0000000000006E2f9d80CaEc0Da6500f005EB25A",
|
|
22
21
|
SMAV2_7702: "0x69007702764179f14F51cdce752f4f775d74E139",
|
|
23
|
-
MAV2: "0x00000000000002377B26b1EdA7b0BC371C60DD4f",
|
|
24
22
|
} satisfies Record<string, Address>;
|
|
25
23
|
|
|
26
24
|
/**
|
|
@@ -28,7 +26,6 @@ export const DefaultAddress = {
|
|
|
28
26
|
*/
|
|
29
27
|
export const DefaultModuleAddress = {
|
|
30
28
|
SINGLE_SIGNER_VALIDATION: "0x00000000000099DE0BF6fA90dEB851E2A2df7d83",
|
|
31
|
-
WEBAUTHN_VALIDATION: "0x0000000000001D9d34E07D9834274dF9ae575217",
|
|
32
29
|
TIME_RANGE: "0x00000000000082B8e2012be914dFA4f62A0573eA",
|
|
33
30
|
PAYMASTER_GUARD: "0x0000000000001aA7A7F7E29abe0be06c72FD42A1",
|
|
34
31
|
NATIVE_TOKEN_LIMIT: "0x00000000000001e541f0D090868FBe24b59Fbe06",
|