thirdweb 5.81.0 → 5.82.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/adapters/ethers5.js +1 -1
- package/dist/cjs/adapters/ethers5.js.map +1 -1
- package/dist/cjs/auth/verify-hash.js +13 -8
- package/dist/cjs/auth/verify-hash.js.map +1 -1
- package/dist/cjs/contract/types.js +3 -0
- package/dist/cjs/contract/types.js.map +1 -0
- package/dist/cjs/exports/thirdweb.js +5 -1
- package/dist/cjs/exports/thirdweb.js.map +1 -1
- package/dist/cjs/exports/transaction.js +3 -1
- package/dist/cjs/exports/transaction.js.map +1 -1
- package/dist/cjs/exports/wallets.js +3 -1
- package/dist/cjs/exports/wallets.js.map +1 -1
- package/dist/cjs/extensions/erc721/lazyMinting/read/getBatchesToReveal.js +1 -1
- package/dist/cjs/extensions/erc721/lazyMinting/read/getBatchesToReveal.js.map +1 -1
- package/dist/cjs/extensions/types.js +3 -0
- package/dist/cjs/extensions/types.js.map +1 -0
- package/dist/cjs/gas/estimate-l1-fee.js +3 -4
- package/dist/cjs/gas/estimate-l1-fee.js.map +1 -1
- package/dist/cjs/react/core/hooks/contract/useReadContract.js +31 -29
- package/dist/cjs/react/core/hooks/contract/useReadContract.js.map +1 -1
- package/dist/cjs/react/core/hooks/types.js +3 -0
- package/dist/cjs/react/core/hooks/types.js.map +1 -0
- package/dist/cjs/transaction/actions/eip7702/authorization.js +33 -0
- package/dist/cjs/transaction/actions/eip7702/authorization.js.map +1 -0
- package/dist/cjs/transaction/actions/estimate-gas.js +16 -4
- package/dist/cjs/transaction/actions/estimate-gas.js.map +1 -1
- package/dist/cjs/transaction/actions/send-transaction.js +32 -1
- package/dist/cjs/transaction/actions/send-transaction.js.map +1 -1
- package/dist/cjs/transaction/actions/to-serializable-transaction.js +13 -4
- package/dist/cjs/transaction/actions/to-serializable-transaction.js.map +1 -1
- package/dist/cjs/transaction/prepare-transaction.js.map +1 -1
- package/dist/cjs/transaction/serialize-transaction.js +11 -0
- package/dist/cjs/transaction/serialize-transaction.js.map +1 -1
- package/dist/cjs/utils/abi/decodeError.js +3 -3
- package/dist/cjs/utils/abi/decodeError.js.map +1 -1
- package/dist/cjs/utils/abi/decodeFunctionData.js +3 -3
- package/dist/cjs/utils/abi/decodeFunctionData.js.map +1 -1
- package/dist/cjs/utils/abi/decodeFunctionResult.js +3 -3
- package/dist/cjs/utils/abi/decodeFunctionResult.js.map +1 -1
- package/dist/cjs/utils/hashing/hashMessage.js +2 -2
- package/dist/cjs/utils/hashing/hashMessage.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wallets/create-wallet.js +16 -0
- package/dist/cjs/wallets/create-wallet.js.map +1 -1
- package/dist/cjs/wallets/private-key.js +9 -0
- package/dist/cjs/wallets/private-key.js.map +1 -1
- package/dist/cjs/wallets/smart/index.js +20 -19
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/signing.js +139 -54
- package/dist/cjs/wallets/smart/lib/signing.js.map +1 -1
- package/dist/cjs/wallets/smart/presets/7579.js +11 -10
- package/dist/cjs/wallets/smart/presets/7579.js.map +1 -1
- package/dist/esm/adapters/ethers5.js +1 -1
- package/dist/esm/adapters/ethers5.js.map +1 -1
- package/dist/esm/auth/verify-hash.js +13 -9
- package/dist/esm/auth/verify-hash.js.map +1 -1
- package/dist/esm/contract/types.js +2 -0
- package/dist/esm/contract/types.js.map +1 -0
- package/dist/esm/exports/thirdweb.js +2 -0
- package/dist/esm/exports/thirdweb.js.map +1 -1
- package/dist/esm/exports/transaction.js +1 -0
- package/dist/esm/exports/transaction.js.map +1 -1
- package/dist/esm/exports/wallets.js +1 -0
- package/dist/esm/exports/wallets.js.map +1 -1
- package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js +1 -1
- package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js.map +1 -1
- package/dist/esm/extensions/types.js +2 -0
- package/dist/esm/extensions/types.js.map +1 -0
- package/dist/esm/gas/estimate-l1-fee.js +2 -3
- package/dist/esm/gas/estimate-l1-fee.js.map +1 -1
- package/dist/esm/react/core/hooks/contract/useReadContract.js +31 -29
- package/dist/esm/react/core/hooks/contract/useReadContract.js.map +1 -1
- package/dist/esm/react/core/hooks/types.js +2 -0
- package/dist/esm/react/core/hooks/types.js.map +1 -0
- package/dist/esm/transaction/actions/eip7702/authorization.js +30 -0
- package/dist/esm/transaction/actions/eip7702/authorization.js.map +1 -0
- package/dist/esm/transaction/actions/estimate-gas.js +16 -4
- package/dist/esm/transaction/actions/estimate-gas.js.map +1 -1
- package/dist/esm/transaction/actions/send-transaction.js +32 -1
- package/dist/esm/transaction/actions/send-transaction.js.map +1 -1
- package/dist/esm/transaction/actions/to-serializable-transaction.js +13 -4
- package/dist/esm/transaction/actions/to-serializable-transaction.js.map +1 -1
- package/dist/esm/transaction/prepare-transaction.js.map +1 -1
- package/dist/esm/transaction/serialize-transaction.js +11 -0
- package/dist/esm/transaction/serialize-transaction.js.map +1 -1
- package/dist/esm/utils/abi/decodeError.js +3 -3
- package/dist/esm/utils/abi/decodeError.js.map +1 -1
- package/dist/esm/utils/abi/decodeFunctionData.js +3 -3
- package/dist/esm/utils/abi/decodeFunctionData.js.map +1 -1
- package/dist/esm/utils/abi/decodeFunctionResult.js +3 -3
- package/dist/esm/utils/abi/decodeFunctionResult.js.map +1 -1
- package/dist/esm/utils/hashing/hashMessage.js +1 -1
- package/dist/esm/utils/hashing/hashMessage.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/wallets/create-wallet.js +16 -0
- package/dist/esm/wallets/create-wallet.js.map +1 -1
- package/dist/esm/wallets/private-key.js +9 -0
- package/dist/esm/wallets/private-key.js.map +1 -1
- package/dist/esm/wallets/smart/index.js +20 -19
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/esm/wallets/smart/lib/signing.js +137 -53
- package/dist/esm/wallets/smart/lib/signing.js.map +1 -1
- package/dist/esm/wallets/smart/presets/7579.js +11 -10
- package/dist/esm/wallets/smart/presets/7579.js.map +1 -1
- package/dist/types/auth/verify-hash.d.ts +6 -0
- package/dist/types/auth/verify-hash.d.ts.map +1 -1
- package/dist/types/contract/types.d.ts +7 -0
- package/dist/types/contract/types.d.ts.map +1 -0
- package/dist/types/exports/thirdweb.d.ts +6 -0
- package/dist/types/exports/thirdweb.d.ts.map +1 -1
- package/dist/types/exports/transaction.d.ts +5 -0
- package/dist/types/exports/transaction.d.ts.map +1 -1
- package/dist/types/exports/wallets.d.ts +1 -0
- package/dist/types/exports/wallets.d.ts.map +1 -1
- package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts +1 -1
- package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts.map +1 -1
- package/dist/types/extensions/types.d.ts +4 -0
- package/dist/types/extensions/types.d.ts.map +1 -0
- package/dist/types/gas/estimate-l1-fee.d.ts.map +1 -1
- package/dist/types/react/core/hooks/contract/useReadContract.d.ts +9 -16
- package/dist/types/react/core/hooks/contract/useReadContract.d.ts.map +1 -1
- package/dist/types/react/core/hooks/types.d.ts +13 -0
- package/dist/types/react/core/hooks/types.d.ts.map +1 -0
- package/dist/types/transaction/actions/eip7702/authorization.d.ts +48 -0
- package/dist/types/transaction/actions/eip7702/authorization.d.ts.map +1 -0
- package/dist/types/transaction/actions/estimate-gas.d.ts +3 -1
- package/dist/types/transaction/actions/estimate-gas.d.ts.map +1 -1
- package/dist/types/transaction/actions/send-transaction.d.ts +31 -0
- package/dist/types/transaction/actions/send-transaction.d.ts.map +1 -1
- package/dist/types/transaction/actions/to-serializable-transaction.d.ts +19 -2
- package/dist/types/transaction/actions/to-serializable-transaction.d.ts.map +1 -1
- package/dist/types/transaction/prepare-transaction.d.ts +2 -0
- package/dist/types/transaction/prepare-transaction.d.ts.map +1 -1
- package/dist/types/transaction/serialize-transaction.d.ts +2 -0
- package/dist/types/transaction/serialize-transaction.d.ts.map +1 -1
- package/dist/types/utils/abi/decodeError.d.ts +2 -2
- package/dist/types/utils/abi/decodeError.d.ts.map +1 -1
- package/dist/types/utils/abi/decodeFunctionData.d.ts +6 -4
- package/dist/types/utils/abi/decodeFunctionData.d.ts.map +1 -1
- package/dist/types/utils/abi/decodeFunctionResult.d.ts +6 -4
- package/dist/types/utils/abi/decodeFunctionResult.d.ts.map +1 -1
- package/dist/types/utils/hashing/hashMessage.d.ts +1 -1
- package/dist/types/utils/hashing/hashMessage.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/wallets/create-wallet.d.ts +16 -0
- package/dist/types/wallets/create-wallet.d.ts.map +1 -1
- package/dist/types/wallets/interfaces/wallet.d.ts +9 -0
- package/dist/types/wallets/interfaces/wallet.d.ts.map +1 -1
- package/dist/types/wallets/private-key.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/signing.d.ts +46 -2
- package/dist/types/wallets/smart/lib/signing.d.ts.map +1 -1
- package/dist/types/wallets/smart/presets/7579.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/adapters/ethers5.ts +1 -1
- package/src/auth/verify-hash.ts +12 -9
- package/src/contract/types.ts +8 -0
- package/src/exports/thirdweb.ts +10 -0
- package/src/exports/transaction.ts +9 -0
- package/src/exports/wallets.ts +2 -0
- package/src/extensions/erc721/lazyMinting/read/getBatchesToReveal.ts +2 -2
- package/src/extensions/types.ts +6 -0
- package/src/gas/estimate-l1-fee.ts +2 -3
- package/src/react/core/hooks/contract/useReadContract.ts +83 -74
- package/src/react/core/hooks/types.ts +13 -0
- package/src/transaction/actions/eip7702/authorization.test.ts +27 -0
- package/src/transaction/actions/eip7702/authorization.ts +58 -0
- package/src/transaction/actions/estimate-gas.ts +26 -9
- package/src/transaction/actions/send-transaction.ts +32 -2
- package/src/transaction/actions/to-serializable-transaction.test.ts +68 -0
- package/src/transaction/actions/to-serializable-transaction.ts +42 -30
- package/src/transaction/prepare-transaction.test.ts +28 -0
- package/src/transaction/prepare-transaction.ts +3 -0
- package/src/transaction/serialize-transaction.test.ts +108 -1
- package/src/transaction/serialize-transaction.ts +18 -0
- package/src/utils/abi/decodeError.ts +5 -4
- package/src/utils/abi/decodeFunctionData.ts +7 -5
- package/src/utils/abi/decodeFunctionResult.ts +7 -5
- package/src/utils/hashing/hashMessage.ts +1 -1
- package/src/utils/signatures/sign-message.test.ts +2 -2
- package/src/version.ts +1 -1
- package/src/wallets/create-wallet.ts +16 -0
- package/src/wallets/interfaces/wallet.ts +15 -0
- package/src/wallets/private-key.test.ts +1 -0
- package/src/wallets/private-key.ts +10 -0
- package/src/wallets/smart/index.ts +20 -19
- package/src/wallets/smart/lib/signing.ts +154 -59
- package/src/wallets/smart/presets/7579.ts +13 -12
- package/src/wallets/smart/smart-wallet-integration-v07.test.ts +49 -9
- package/src/wallets/smart/smart-wallet-integration.test.ts +48 -1
@@ -1,6 +1,11 @@
|
|
1
1
|
import type * as ox__TypedData from "ox/TypedData";
|
2
2
|
import { serializeErc6492Signature } from "../../../auth/serialize-erc6492-signature.js";
|
3
|
-
import {
|
3
|
+
import {
|
4
|
+
verifyEip1271Signature,
|
5
|
+
verifyHash,
|
6
|
+
} from "../../../auth/verify-hash.js";
|
7
|
+
import type { Chain } from "../../../chains/types.js";
|
8
|
+
import type { ThirdwebClient } from "../../../client/client.js";
|
4
9
|
import {
|
5
10
|
type ThirdwebContract,
|
6
11
|
getContract,
|
@@ -8,14 +13,22 @@ import {
|
|
8
13
|
import { encode } from "../../../transaction/actions/encode.js";
|
9
14
|
import { readContract } from "../../../transaction/read-contract.js";
|
10
15
|
import { encodeAbiParameters } from "../../../utils/abi/encodeAbiParameters.js";
|
16
|
+
import { isContractDeployed } from "../../../utils/bytecode/is-contract-deployed.js";
|
11
17
|
import type { Hex } from "../../../utils/encoding/hex.js";
|
12
18
|
import { hashMessage } from "../../../utils/hashing/hashMessage.js";
|
13
19
|
import { hashTypedData } from "../../../utils/hashing/hashTypedData.js";
|
14
20
|
import type { SignableMessage } from "../../../utils/types.js";
|
21
|
+
import type { Account } from "../../../wallets/interfaces/wallet.js";
|
15
22
|
import type { SmartAccountOptions } from "../types.js";
|
16
23
|
import { prepareCreateAccount } from "./calls.js";
|
17
24
|
|
18
|
-
|
25
|
+
/**
|
26
|
+
* If the account is already deployed, generate an ERC-1271 signature.
|
27
|
+
* If the account is not deployed, generate an ERC-6492 signature unless otherwise specified.
|
28
|
+
*
|
29
|
+
* @internal
|
30
|
+
*/
|
31
|
+
export async function smartAccountSignMessage({
|
19
32
|
accountContract,
|
20
33
|
factoryContract,
|
21
34
|
options,
|
@@ -55,40 +68,51 @@ export async function deployAndSignMessage({
|
|
55
68
|
sig = await options.personalAccount.signMessage({ message });
|
56
69
|
}
|
57
70
|
|
58
|
-
const
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
71
|
+
const isDeployed = await isContractDeployed(accountContract);
|
72
|
+
if (isDeployed) {
|
73
|
+
const isValid = await verifyEip1271Signature({
|
74
|
+
hash: originalMsgHash,
|
75
|
+
signature: sig,
|
76
|
+
contract: accountContract,
|
77
|
+
});
|
78
|
+
if (isValid) {
|
79
|
+
return sig;
|
80
|
+
}
|
81
|
+
throw new Error("Failed to verify signature");
|
82
|
+
} else {
|
83
|
+
const deployTx = prepareCreateAccount({
|
84
|
+
factoryContract,
|
85
|
+
adminAddress: options.personalAccount.address,
|
86
|
+
accountSalt: options.overrides?.accountSalt,
|
87
|
+
createAccountOverride: options.overrides?.createAccount,
|
88
|
+
});
|
89
|
+
if (!deployTx) {
|
90
|
+
throw new Error("Create account override not provided");
|
91
|
+
}
|
92
|
+
const initCode = await encode(deployTx);
|
93
|
+
const erc6492Sig = serializeErc6492Signature({
|
94
|
+
address: factoryContract.address,
|
95
|
+
data: initCode,
|
96
|
+
signature: sig,
|
97
|
+
});
|
73
98
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
99
|
+
// check if the signature is valid
|
100
|
+
const isValid = await verifyHash({
|
101
|
+
hash: originalMsgHash,
|
102
|
+
signature: erc6492Sig,
|
103
|
+
address: accountContract.address,
|
104
|
+
chain: accountContract.chain,
|
105
|
+
client: accountContract.client,
|
106
|
+
});
|
82
107
|
|
83
|
-
|
84
|
-
|
108
|
+
if (isValid) {
|
109
|
+
return erc6492Sig;
|
110
|
+
}
|
111
|
+
throw new Error("Unable to verify ERC-6492 signature after signing.");
|
85
112
|
}
|
86
|
-
throw new Error(
|
87
|
-
"Unable to verify signature on smart account, please make sure the admin wallet has permissions and the signature is valid.",
|
88
|
-
);
|
89
113
|
}
|
90
114
|
|
91
|
-
export async function
|
115
|
+
export async function smartAccountSignTypedData<
|
92
116
|
const typedData extends ox__TypedData.TypedData | Record<string, unknown>,
|
93
117
|
primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
|
94
118
|
>({
|
@@ -142,37 +166,50 @@ export async function deployAndSignTypedData<
|
|
142
166
|
sig = await options.personalAccount.signTypedData(typedData);
|
143
167
|
}
|
144
168
|
|
145
|
-
const
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
169
|
+
const isDeployed = await isContractDeployed(accountContract);
|
170
|
+
if (isDeployed) {
|
171
|
+
const isValid = await verifyEip1271Signature({
|
172
|
+
hash: originalMsgHash,
|
173
|
+
signature: sig,
|
174
|
+
contract: accountContract,
|
175
|
+
});
|
176
|
+
if (isValid) {
|
177
|
+
return sig;
|
178
|
+
}
|
179
|
+
throw new Error("Failed to verify signature");
|
180
|
+
} else {
|
181
|
+
const deployTx = prepareCreateAccount({
|
182
|
+
factoryContract,
|
183
|
+
adminAddress: options.personalAccount.address,
|
184
|
+
accountSalt: options.overrides?.accountSalt,
|
185
|
+
createAccountOverride: options.overrides?.createAccount,
|
186
|
+
});
|
187
|
+
if (!deployTx) {
|
188
|
+
throw new Error("Create account override not provided");
|
189
|
+
}
|
190
|
+
const initCode = await encode(deployTx);
|
191
|
+
const erc6492Sig = serializeErc6492Signature({
|
192
|
+
address: factoryContract.address,
|
193
|
+
data: initCode,
|
194
|
+
signature: sig,
|
195
|
+
});
|
160
196
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
197
|
+
// check if the signature is valid
|
198
|
+
const isValid = await verifyHash({
|
199
|
+
hash: originalMsgHash,
|
200
|
+
signature: erc6492Sig,
|
201
|
+
address: accountContract.address,
|
202
|
+
chain: accountContract.chain,
|
203
|
+
client: accountContract.client,
|
204
|
+
});
|
169
205
|
|
170
|
-
|
171
|
-
|
206
|
+
if (isValid) {
|
207
|
+
return erc6492Sig;
|
208
|
+
}
|
209
|
+
throw new Error(
|
210
|
+
"Unable to verify signature on smart account, please make sure the admin wallet has permissions and the signature is valid.",
|
211
|
+
);
|
172
212
|
}
|
173
|
-
throw new Error(
|
174
|
-
"Unable to verify signature on smart account, please make sure the admin wallet has permissions and the signature is valid.",
|
175
|
-
);
|
176
213
|
}
|
177
214
|
|
178
215
|
export async function confirmContractDeployment(args: {
|
@@ -229,3 +266,61 @@ async function checkFor712Factory({
|
|
229
266
|
return false;
|
230
267
|
}
|
231
268
|
}
|
269
|
+
|
270
|
+
/**
|
271
|
+
* Deployes a smart account via a dummy transaction.
|
272
|
+
*
|
273
|
+
* @param args - Arguments for the deployment.
|
274
|
+
* @param args.smartAccount - The smart account to deploy.
|
275
|
+
* @param args.chain - The chain to deploy on.
|
276
|
+
* @param args.client - The client to use for the deployment.
|
277
|
+
* @param args.accountContract - The account contract to deploy.
|
278
|
+
*
|
279
|
+
* @example
|
280
|
+
* ```ts
|
281
|
+
* import { deploySmartAccount } from "thirdweb";
|
282
|
+
*
|
283
|
+
* const account = await deploySmartAccount({
|
284
|
+
* smartAccount,
|
285
|
+
* chain,
|
286
|
+
* client,
|
287
|
+
* accountContract,
|
288
|
+
* });
|
289
|
+
* ```
|
290
|
+
*
|
291
|
+
* @wallets
|
292
|
+
*/
|
293
|
+
export async function deploySmartAccount(args: {
|
294
|
+
smartAccount: Account;
|
295
|
+
chain: Chain;
|
296
|
+
client: ThirdwebClient;
|
297
|
+
accountContract: ThirdwebContract;
|
298
|
+
}) {
|
299
|
+
const { chain, client, smartAccount, accountContract } = args;
|
300
|
+
const isDeployed = await isContractDeployed(accountContract);
|
301
|
+
if (isDeployed) {
|
302
|
+
return;
|
303
|
+
}
|
304
|
+
|
305
|
+
const [{ sendTransaction }, { prepareTransaction }] = await Promise.all([
|
306
|
+
import("../../../transaction/actions/send-transaction.js"),
|
307
|
+
import("../../../transaction/prepare-transaction.js"),
|
308
|
+
]);
|
309
|
+
const dummyTx = prepareTransaction({
|
310
|
+
client: client,
|
311
|
+
chain: chain,
|
312
|
+
to: accountContract.address,
|
313
|
+
value: 0n,
|
314
|
+
gas: 50000n, // force gas to avoid simulation error
|
315
|
+
});
|
316
|
+
const deployResult = await sendTransaction({
|
317
|
+
transaction: dummyTx,
|
318
|
+
account: smartAccount,
|
319
|
+
});
|
320
|
+
|
321
|
+
await confirmContractDeployment({
|
322
|
+
accountContract,
|
323
|
+
});
|
324
|
+
|
325
|
+
return deployResult;
|
326
|
+
}
|
@@ -1,4 +1,5 @@
|
|
1
|
-
import
|
1
|
+
import * as ox__AbiParameters from "ox/AbiParameters";
|
2
|
+
import * as ox__Hex from "ox/Hex";
|
2
3
|
import { serializeErc6492Signature } from "../../../auth/serialize-erc6492-signature.js";
|
3
4
|
import { verifyHash } from "../../../auth/verify-hash.js";
|
4
5
|
import { ZERO_ADDRESS } from "../../../constants/addresses.js";
|
@@ -56,9 +57,9 @@ export type ERC7579Config = SmartWalletOptions & {
|
|
56
57
|
export function erc7579(options: ERC7579Config): SmartWalletOptions {
|
57
58
|
const saltHex =
|
58
59
|
options.overrides?.accountSalt &&
|
59
|
-
|
60
|
+
ox__Hex.validate(options.overrides.accountSalt)
|
60
61
|
? options.overrides.accountSalt
|
61
|
-
:
|
62
|
+
: ox__Hex.fromString(options.overrides?.accountSalt ?? "");
|
62
63
|
const defaultValidator = getAddress(options.validatorAddress);
|
63
64
|
const modularAccountOptions: SmartWalletOptions = {
|
64
65
|
...options,
|
@@ -75,7 +76,7 @@ export function erc7579(options: ERC7579Config): SmartWalletOptions {
|
|
75
76
|
{
|
76
77
|
moduleTypeId: 1n, // validator type id
|
77
78
|
module: defaultValidator,
|
78
|
-
initData:
|
79
|
+
initData: ox__Hex.fromString(""),
|
79
80
|
},
|
80
81
|
];
|
81
82
|
return {
|
@@ -99,8 +100,8 @@ export function erc7579(options: ERC7579Config): SmartWalletOptions {
|
|
99
100
|
contract: accountContract,
|
100
101
|
async asyncParams() {
|
101
102
|
return {
|
102
|
-
mode:
|
103
|
-
executionCalldata:
|
103
|
+
mode: ox__Hex.padRight("0x00", 32), // single execution
|
104
|
+
executionCalldata: ox__AbiParameters.encodePacked(
|
104
105
|
["address", "uint256", "bytes"],
|
105
106
|
[
|
106
107
|
transaction.to || ZERO_ADDRESS,
|
@@ -117,8 +118,8 @@ export function erc7579(options: ERC7579Config): SmartWalletOptions {
|
|
117
118
|
contract: accountContract,
|
118
119
|
async asyncParams() {
|
119
120
|
return {
|
120
|
-
mode:
|
121
|
-
executionCalldata:
|
121
|
+
mode: ox__Hex.padRight("0x01", 32), // batch execution
|
122
|
+
executionCalldata: ox__AbiParameters.encode(
|
122
123
|
[
|
123
124
|
{
|
124
125
|
type: "tuple[]",
|
@@ -152,10 +153,10 @@ export function erc7579(options: ERC7579Config): SmartWalletOptions {
|
|
152
153
|
sender: accountContract.address,
|
153
154
|
});
|
154
155
|
// TODO (msa) - could be different if validator for the deployed account is different
|
155
|
-
const withValidator =
|
156
|
-
`${defaultValidator}${
|
156
|
+
const withValidator = ox__Hex.from(
|
157
|
+
`${defaultValidator}${ox__Hex.fromNumber(entryPointNonce).slice(42)}`,
|
157
158
|
);
|
158
|
-
return
|
159
|
+
return ox__Hex.toBigInt(withValidator);
|
159
160
|
},
|
160
161
|
async signMessage(options) {
|
161
162
|
const { accountContract, factoryContract, adminAccount, message } =
|
@@ -201,7 +202,7 @@ async function generateSignature(options: {
|
|
201
202
|
accountContract: ThirdwebContract;
|
202
203
|
factoryContract: ThirdwebContract;
|
203
204
|
adminAccount: Account;
|
204
|
-
originalMsgHash:
|
205
|
+
originalMsgHash: ox__Hex.Hex;
|
205
206
|
defaultValidator: string;
|
206
207
|
createAccount: (
|
207
208
|
factoryContract: ThirdwebContract,
|
@@ -6,6 +6,7 @@ import { type ThirdwebContract, getContract } from "../../contract/contract.js";
|
|
6
6
|
import { parseEventLogs } from "../../event/actions/parse-logs.js";
|
7
7
|
|
8
8
|
import { TEST_WALLET_A } from "~test/addresses.js";
|
9
|
+
import { verifyEip1271Signature } from "../../auth/verify-hash.js";
|
9
10
|
import { verifyTypedData } from "../../auth/verify-typed-data.js";
|
10
11
|
import { baseSepolia } from "../../chains/chain-definitions/base-sepolia.js";
|
11
12
|
import { sepolia } from "../../chains/chain-definitions/sepolia.js";
|
@@ -13,7 +14,6 @@ import {
|
|
13
14
|
addAdmin,
|
14
15
|
adminUpdatedEvent,
|
15
16
|
} from "../../exports/extensions/erc4337.js";
|
16
|
-
import { balanceOf } from "../../extensions/erc1155/__generated__/IERC1155/read/balanceOf.js";
|
17
17
|
import { claimTo } from "../../extensions/erc1155/drops/write/claimTo.js";
|
18
18
|
import { setContractURI } from "../../extensions/marketplace/__generated__/IMarketplace/write/setContractURI.js";
|
19
19
|
import { estimateGasCost } from "../../transaction/actions/estimate-gas-cost.js";
|
@@ -21,14 +21,18 @@ import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-co
|
|
21
21
|
import { sendBatchTransaction } from "../../transaction/actions/send-batch-transaction.js";
|
22
22
|
import { waitForReceipt } from "../../transaction/actions/wait-for-tx-receipt.js";
|
23
23
|
import { prepareTransaction } from "../../transaction/prepare-transaction.js";
|
24
|
-
import { getAddress } from "../../utils/address.js";
|
25
24
|
import { isContractDeployed } from "../../utils/bytecode/is-contract-deployed.js";
|
25
|
+
import { hashMessage } from "../../utils/hashing/hashMessage.js";
|
26
|
+
import { hashTypedData } from "../../utils/hashing/hashTypedData.js";
|
26
27
|
import { sleep } from "../../utils/sleep.js";
|
27
28
|
import type { Account, Wallet } from "../interfaces/wallet.js";
|
28
29
|
import { generateAccount } from "../utils/generateAccount.js";
|
29
30
|
import { predictSmartAccountAddress } from "./lib/calls.js";
|
30
31
|
import { DEFAULT_ACCOUNT_FACTORY_V0_7 } from "./lib/constants.js";
|
31
|
-
import {
|
32
|
+
import {
|
33
|
+
confirmContractDeployment,
|
34
|
+
deploySmartAccount,
|
35
|
+
} from "./lib/signing.js";
|
32
36
|
import { smartWallet } from "./smart-wallet.js";
|
33
37
|
|
34
38
|
let wallet: Wallet;
|
@@ -98,6 +102,27 @@ describe.runIf(process.env.TW_SECRET_KEY)(
|
|
98
102
|
expect(isValid).toEqual(true);
|
99
103
|
});
|
100
104
|
|
105
|
+
it("should use ERC-1271 signatures after deployment", async () => {
|
106
|
+
await deploySmartAccount({
|
107
|
+
chain,
|
108
|
+
client,
|
109
|
+
smartAccount,
|
110
|
+
accountContract,
|
111
|
+
});
|
112
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); // pause for a second to prevent race condition
|
113
|
+
|
114
|
+
const signature = await smartAccount.signMessage({
|
115
|
+
message: "hello world",
|
116
|
+
});
|
117
|
+
|
118
|
+
const isValid = await verifyEip1271Signature({
|
119
|
+
hash: hashMessage("hello world"),
|
120
|
+
signature,
|
121
|
+
contract: accountContract,
|
122
|
+
});
|
123
|
+
expect(isValid).toEqual(true);
|
124
|
+
});
|
125
|
+
|
101
126
|
it("can sign typed data", async () => {
|
102
127
|
const signature = await smartAccount.signTypedData(typedData.basic);
|
103
128
|
const isValid = await verifyTypedData({
|
@@ -110,6 +135,27 @@ describe.runIf(process.env.TW_SECRET_KEY)(
|
|
110
135
|
expect(isValid).toEqual(true);
|
111
136
|
});
|
112
137
|
|
138
|
+
it("should use ERC-1271 typed data signatures after deployment", async () => {
|
139
|
+
await deploySmartAccount({
|
140
|
+
chain,
|
141
|
+
client,
|
142
|
+
smartAccount,
|
143
|
+
accountContract,
|
144
|
+
});
|
145
|
+
|
146
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); // pause for a second to prevent race condition
|
147
|
+
|
148
|
+
const signature = await smartAccount.signTypedData(typedData.basic);
|
149
|
+
|
150
|
+
const messageHash = hashTypedData(typedData.basic);
|
151
|
+
const isValid = await verifyEip1271Signature({
|
152
|
+
signature,
|
153
|
+
hash: messageHash,
|
154
|
+
contract: accountContract,
|
155
|
+
});
|
156
|
+
expect(isValid).toEqual(true);
|
157
|
+
});
|
158
|
+
|
113
159
|
it("can send a transaction on another chain", async () => {
|
114
160
|
const tx = await sendAndConfirmTransaction({
|
115
161
|
transaction: prepareTransaction({
|
@@ -155,12 +201,6 @@ describe.runIf(process.env.TW_SECRET_KEY)(
|
|
155
201
|
await confirmContractDeployment({ accountContract });
|
156
202
|
const isDeployed = await isContractDeployed(accountContract);
|
157
203
|
expect(isDeployed).toEqual(true);
|
158
|
-
const balance = await balanceOf({
|
159
|
-
contract,
|
160
|
-
owner: getAddress(smartWalletAddress),
|
161
|
-
tokenId: 0n,
|
162
|
-
});
|
163
|
-
expect(balance).toEqual(1n);
|
164
204
|
});
|
165
205
|
|
166
206
|
it("can estimate a tx", async () => {
|
@@ -2,6 +2,7 @@ import { beforeAll, describe, expect, it } from "vitest";
|
|
2
2
|
import { TEST_WALLET_A } from "~test/addresses.js";
|
3
3
|
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
|
4
4
|
import { typedData } from "../../../test/src/typed-data.js";
|
5
|
+
import { verifyEip1271Signature } from "../../auth/verify-hash.js";
|
5
6
|
import { verifySignature } from "../../auth/verify-signature.js";
|
6
7
|
import { verifyTypedData } from "../../auth/verify-typed-data.js";
|
7
8
|
import { arbitrumSepolia } from "../../chains/chain-definitions/arbitrum-sepolia.js";
|
@@ -22,10 +23,13 @@ import { sendTransaction } from "../../transaction/actions/send-transaction.js";
|
|
22
23
|
import { waitForReceipt } from "../../transaction/actions/wait-for-tx-receipt.js";
|
23
24
|
import { prepareTransaction } from "../../transaction/prepare-transaction.js";
|
24
25
|
import { isContractDeployed } from "../../utils/bytecode/is-contract-deployed.js";
|
26
|
+
import { hashMessage } from "../../utils/hashing/hashMessage.js";
|
27
|
+
import { hashTypedData } from "../../utils/hashing/hashTypedData.js";
|
25
28
|
import { sleep } from "../../utils/sleep.js";
|
26
29
|
import type { Account, Wallet } from "../interfaces/wallet.js";
|
27
30
|
import { generateAccount } from "../utils/generateAccount.js";
|
28
31
|
import { predictSmartAccountAddress } from "./lib/calls.js";
|
32
|
+
import { deploySmartAccount } from "./lib/signing.js";
|
29
33
|
import { smartWallet } from "./smart-wallet.js";
|
30
34
|
|
31
35
|
let wallet: Wallet;
|
@@ -94,6 +98,27 @@ describe.runIf(process.env.TW_SECRET_KEY).sequential(
|
|
94
98
|
expect(isValid).toEqual(true);
|
95
99
|
});
|
96
100
|
|
101
|
+
it("should use ERC-1271 signatures after deployment", async () => {
|
102
|
+
await deploySmartAccount({
|
103
|
+
chain,
|
104
|
+
client,
|
105
|
+
smartAccount,
|
106
|
+
accountContract,
|
107
|
+
});
|
108
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); // pause for a second to prevent race condition
|
109
|
+
|
110
|
+
const signature = await smartAccount.signMessage({
|
111
|
+
message: "hello world",
|
112
|
+
});
|
113
|
+
|
114
|
+
const isValid = await verifyEip1271Signature({
|
115
|
+
hash: hashMessage("hello world"),
|
116
|
+
signature,
|
117
|
+
contract: accountContract,
|
118
|
+
});
|
119
|
+
expect(isValid).toEqual(true);
|
120
|
+
});
|
121
|
+
|
97
122
|
it("can sign typed data", async () => {
|
98
123
|
const signature = await smartAccount.signTypedData(typedData.basic);
|
99
124
|
const isValid = await verifyTypedData({
|
@@ -106,6 +131,27 @@ describe.runIf(process.env.TW_SECRET_KEY).sequential(
|
|
106
131
|
expect(isValid).toEqual(true);
|
107
132
|
});
|
108
133
|
|
134
|
+
it("should use ERC-1271 typed data signatures after deployment", async () => {
|
135
|
+
await deploySmartAccount({
|
136
|
+
chain,
|
137
|
+
client,
|
138
|
+
smartAccount,
|
139
|
+
accountContract,
|
140
|
+
});
|
141
|
+
|
142
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); // pause for a second to prevent race condition
|
143
|
+
|
144
|
+
const signature = await smartAccount.signTypedData(typedData.basic);
|
145
|
+
|
146
|
+
const messageHash = hashTypedData(typedData.basic);
|
147
|
+
const isValid = await verifyEip1271Signature({
|
148
|
+
signature,
|
149
|
+
hash: messageHash,
|
150
|
+
contract: accountContract,
|
151
|
+
});
|
152
|
+
expect(isValid).toEqual(true);
|
153
|
+
});
|
154
|
+
|
109
155
|
it("should revert on unsuccessful transactions", async () => {
|
110
156
|
const tx = sendAndConfirmTransaction({
|
111
157
|
transaction: setContractURI({
|
@@ -184,7 +230,7 @@ describe.runIf(process.env.TW_SECRET_KEY).sequential(
|
|
184
230
|
expect(result.status).toEqual("success");
|
185
231
|
});
|
186
232
|
|
187
|
-
it("can sign and verify
|
233
|
+
it("can sign and verify with replay protection", async () => {
|
188
234
|
const message = "hello world";
|
189
235
|
const signature = await smartAccount.signMessage({ message });
|
190
236
|
const isValidV1 = await verifySignature({
|
@@ -371,6 +417,7 @@ describe.runIf(process.env.TW_SECRET_KEY).sequential(
|
|
371
417
|
expect(txs.every((t) => t.transactionHash.length === 66)).toBe(true);
|
372
418
|
|
373
419
|
isDeployed = await isContractDeployed(newSmartAccountContract);
|
420
|
+
await sleep(1000);
|
374
421
|
expect(isDeployed).toEqual(true);
|
375
422
|
const balance = await balanceOf({
|
376
423
|
contract,
|