thirdweb 5.81.0 → 5.82.1-nightly-5e2eec3b178bcad0988ba7086e31514a3fb7b5d5-20250108000440

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.
Files changed (198) hide show
  1. package/dist/cjs/adapters/ethers5.js +1 -1
  2. package/dist/cjs/adapters/ethers5.js.map +1 -1
  3. package/dist/cjs/auth/verify-hash.js +13 -8
  4. package/dist/cjs/auth/verify-hash.js.map +1 -1
  5. package/dist/cjs/contract/types.js +3 -0
  6. package/dist/cjs/contract/types.js.map +1 -0
  7. package/dist/cjs/exports/thirdweb.js +5 -1
  8. package/dist/cjs/exports/thirdweb.js.map +1 -1
  9. package/dist/cjs/exports/transaction.js +3 -1
  10. package/dist/cjs/exports/transaction.js.map +1 -1
  11. package/dist/cjs/exports/wallets.js +3 -1
  12. package/dist/cjs/exports/wallets.js.map +1 -1
  13. package/dist/cjs/extensions/erc721/lazyMinting/read/getBatchesToReveal.js +1 -1
  14. package/dist/cjs/extensions/erc721/lazyMinting/read/getBatchesToReveal.js.map +1 -1
  15. package/dist/cjs/extensions/marketplace/utils.js +1 -1
  16. package/dist/cjs/extensions/marketplace/utils.js.map +1 -1
  17. package/dist/cjs/extensions/types.js +3 -0
  18. package/dist/cjs/extensions/types.js.map +1 -0
  19. package/dist/cjs/gas/estimate-l1-fee.js +3 -4
  20. package/dist/cjs/gas/estimate-l1-fee.js.map +1 -1
  21. package/dist/cjs/react/core/hooks/contract/useReadContract.js +31 -29
  22. package/dist/cjs/react/core/hooks/contract/useReadContract.js.map +1 -1
  23. package/dist/cjs/react/core/hooks/types.js +3 -0
  24. package/dist/cjs/react/core/hooks/types.js.map +1 -0
  25. package/dist/cjs/transaction/actions/eip7702/authorization.js +33 -0
  26. package/dist/cjs/transaction/actions/eip7702/authorization.js.map +1 -0
  27. package/dist/cjs/transaction/actions/estimate-gas.js +16 -4
  28. package/dist/cjs/transaction/actions/estimate-gas.js.map +1 -1
  29. package/dist/cjs/transaction/actions/send-transaction.js +32 -1
  30. package/dist/cjs/transaction/actions/send-transaction.js.map +1 -1
  31. package/dist/cjs/transaction/actions/to-serializable-transaction.js +13 -4
  32. package/dist/cjs/transaction/actions/to-serializable-transaction.js.map +1 -1
  33. package/dist/cjs/transaction/prepare-transaction.js.map +1 -1
  34. package/dist/cjs/transaction/serialize-transaction.js +11 -0
  35. package/dist/cjs/transaction/serialize-transaction.js.map +1 -1
  36. package/dist/cjs/utils/abi/decodeError.js +3 -3
  37. package/dist/cjs/utils/abi/decodeError.js.map +1 -1
  38. package/dist/cjs/utils/abi/decodeFunctionData.js +3 -3
  39. package/dist/cjs/utils/abi/decodeFunctionData.js.map +1 -1
  40. package/dist/cjs/utils/abi/decodeFunctionResult.js +3 -3
  41. package/dist/cjs/utils/abi/decodeFunctionResult.js.map +1 -1
  42. package/dist/cjs/utils/hashing/hashMessage.js +2 -2
  43. package/dist/cjs/utils/hashing/hashMessage.js.map +1 -1
  44. package/dist/cjs/version.js +1 -1
  45. package/dist/cjs/version.js.map +1 -1
  46. package/dist/cjs/wallets/create-wallet.js +16 -0
  47. package/dist/cjs/wallets/create-wallet.js.map +1 -1
  48. package/dist/cjs/wallets/private-key.js +9 -0
  49. package/dist/cjs/wallets/private-key.js.map +1 -1
  50. package/dist/cjs/wallets/smart/index.js +20 -19
  51. package/dist/cjs/wallets/smart/index.js.map +1 -1
  52. package/dist/cjs/wallets/smart/lib/signing.js +139 -54
  53. package/dist/cjs/wallets/smart/lib/signing.js.map +1 -1
  54. package/dist/cjs/wallets/smart/presets/7579.js +11 -10
  55. package/dist/cjs/wallets/smart/presets/7579.js.map +1 -1
  56. package/dist/esm/adapters/ethers5.js +1 -1
  57. package/dist/esm/adapters/ethers5.js.map +1 -1
  58. package/dist/esm/auth/verify-hash.js +13 -9
  59. package/dist/esm/auth/verify-hash.js.map +1 -1
  60. package/dist/esm/contract/types.js +2 -0
  61. package/dist/esm/contract/types.js.map +1 -0
  62. package/dist/esm/exports/thirdweb.js +2 -0
  63. package/dist/esm/exports/thirdweb.js.map +1 -1
  64. package/dist/esm/exports/transaction.js +1 -0
  65. package/dist/esm/exports/transaction.js.map +1 -1
  66. package/dist/esm/exports/wallets.js +1 -0
  67. package/dist/esm/exports/wallets.js.map +1 -1
  68. package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js +1 -1
  69. package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js.map +1 -1
  70. package/dist/esm/extensions/marketplace/utils.js +1 -1
  71. package/dist/esm/extensions/marketplace/utils.js.map +1 -1
  72. package/dist/esm/extensions/types.js +2 -0
  73. package/dist/esm/extensions/types.js.map +1 -0
  74. package/dist/esm/gas/estimate-l1-fee.js +2 -3
  75. package/dist/esm/gas/estimate-l1-fee.js.map +1 -1
  76. package/dist/esm/react/core/hooks/contract/useReadContract.js +31 -29
  77. package/dist/esm/react/core/hooks/contract/useReadContract.js.map +1 -1
  78. package/dist/esm/react/core/hooks/types.js +2 -0
  79. package/dist/esm/react/core/hooks/types.js.map +1 -0
  80. package/dist/esm/transaction/actions/eip7702/authorization.js +30 -0
  81. package/dist/esm/transaction/actions/eip7702/authorization.js.map +1 -0
  82. package/dist/esm/transaction/actions/estimate-gas.js +16 -4
  83. package/dist/esm/transaction/actions/estimate-gas.js.map +1 -1
  84. package/dist/esm/transaction/actions/send-transaction.js +32 -1
  85. package/dist/esm/transaction/actions/send-transaction.js.map +1 -1
  86. package/dist/esm/transaction/actions/to-serializable-transaction.js +13 -4
  87. package/dist/esm/transaction/actions/to-serializable-transaction.js.map +1 -1
  88. package/dist/esm/transaction/prepare-transaction.js.map +1 -1
  89. package/dist/esm/transaction/serialize-transaction.js +11 -0
  90. package/dist/esm/transaction/serialize-transaction.js.map +1 -1
  91. package/dist/esm/utils/abi/decodeError.js +3 -3
  92. package/dist/esm/utils/abi/decodeError.js.map +1 -1
  93. package/dist/esm/utils/abi/decodeFunctionData.js +3 -3
  94. package/dist/esm/utils/abi/decodeFunctionData.js.map +1 -1
  95. package/dist/esm/utils/abi/decodeFunctionResult.js +3 -3
  96. package/dist/esm/utils/abi/decodeFunctionResult.js.map +1 -1
  97. package/dist/esm/utils/hashing/hashMessage.js +1 -1
  98. package/dist/esm/utils/hashing/hashMessage.js.map +1 -1
  99. package/dist/esm/version.js +1 -1
  100. package/dist/esm/version.js.map +1 -1
  101. package/dist/esm/wallets/create-wallet.js +16 -0
  102. package/dist/esm/wallets/create-wallet.js.map +1 -1
  103. package/dist/esm/wallets/private-key.js +9 -0
  104. package/dist/esm/wallets/private-key.js.map +1 -1
  105. package/dist/esm/wallets/smart/index.js +20 -19
  106. package/dist/esm/wallets/smart/index.js.map +1 -1
  107. package/dist/esm/wallets/smart/lib/signing.js +137 -53
  108. package/dist/esm/wallets/smart/lib/signing.js.map +1 -1
  109. package/dist/esm/wallets/smart/presets/7579.js +11 -10
  110. package/dist/esm/wallets/smart/presets/7579.js.map +1 -1
  111. package/dist/types/auth/verify-hash.d.ts +6 -0
  112. package/dist/types/auth/verify-hash.d.ts.map +1 -1
  113. package/dist/types/contract/types.d.ts +7 -0
  114. package/dist/types/contract/types.d.ts.map +1 -0
  115. package/dist/types/exports/thirdweb.d.ts +6 -0
  116. package/dist/types/exports/thirdweb.d.ts.map +1 -1
  117. package/dist/types/exports/transaction.d.ts +5 -0
  118. package/dist/types/exports/transaction.d.ts.map +1 -1
  119. package/dist/types/exports/wallets.d.ts +1 -0
  120. package/dist/types/exports/wallets.d.ts.map +1 -1
  121. package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts +1 -1
  122. package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts.map +1 -1
  123. package/dist/types/extensions/types.d.ts +4 -0
  124. package/dist/types/extensions/types.d.ts.map +1 -0
  125. package/dist/types/gas/estimate-l1-fee.d.ts.map +1 -1
  126. package/dist/types/react/core/hooks/contract/useReadContract.d.ts +9 -16
  127. package/dist/types/react/core/hooks/contract/useReadContract.d.ts.map +1 -1
  128. package/dist/types/react/core/hooks/types.d.ts +13 -0
  129. package/dist/types/react/core/hooks/types.d.ts.map +1 -0
  130. package/dist/types/transaction/actions/eip7702/authorization.d.ts +48 -0
  131. package/dist/types/transaction/actions/eip7702/authorization.d.ts.map +1 -0
  132. package/dist/types/transaction/actions/estimate-gas.d.ts +3 -1
  133. package/dist/types/transaction/actions/estimate-gas.d.ts.map +1 -1
  134. package/dist/types/transaction/actions/send-transaction.d.ts +31 -0
  135. package/dist/types/transaction/actions/send-transaction.d.ts.map +1 -1
  136. package/dist/types/transaction/actions/to-serializable-transaction.d.ts +19 -2
  137. package/dist/types/transaction/actions/to-serializable-transaction.d.ts.map +1 -1
  138. package/dist/types/transaction/prepare-transaction.d.ts +2 -0
  139. package/dist/types/transaction/prepare-transaction.d.ts.map +1 -1
  140. package/dist/types/transaction/serialize-transaction.d.ts +2 -0
  141. package/dist/types/transaction/serialize-transaction.d.ts.map +1 -1
  142. package/dist/types/utils/abi/decodeError.d.ts +2 -2
  143. package/dist/types/utils/abi/decodeError.d.ts.map +1 -1
  144. package/dist/types/utils/abi/decodeFunctionData.d.ts +6 -4
  145. package/dist/types/utils/abi/decodeFunctionData.d.ts.map +1 -1
  146. package/dist/types/utils/abi/decodeFunctionResult.d.ts +6 -4
  147. package/dist/types/utils/abi/decodeFunctionResult.d.ts.map +1 -1
  148. package/dist/types/utils/hashing/hashMessage.d.ts +1 -1
  149. package/dist/types/utils/hashing/hashMessage.d.ts.map +1 -1
  150. package/dist/types/version.d.ts +1 -1
  151. package/dist/types/version.d.ts.map +1 -1
  152. package/dist/types/wallets/create-wallet.d.ts +16 -0
  153. package/dist/types/wallets/create-wallet.d.ts.map +1 -1
  154. package/dist/types/wallets/interfaces/wallet.d.ts +9 -0
  155. package/dist/types/wallets/interfaces/wallet.d.ts.map +1 -1
  156. package/dist/types/wallets/private-key.d.ts.map +1 -1
  157. package/dist/types/wallets/smart/lib/signing.d.ts +46 -2
  158. package/dist/types/wallets/smart/lib/signing.d.ts.map +1 -1
  159. package/dist/types/wallets/smart/presets/7579.d.ts.map +1 -1
  160. package/package.json +2 -2
  161. package/src/adapters/ethers5.ts +1 -1
  162. package/src/auth/verify-hash.ts +12 -9
  163. package/src/contract/types.ts +8 -0
  164. package/src/exports/thirdweb.ts +10 -0
  165. package/src/exports/transaction.ts +9 -0
  166. package/src/exports/wallets.ts +2 -0
  167. package/src/extensions/erc721/lazyMinting/read/getBatchesToReveal.ts +2 -2
  168. package/src/extensions/marketplace/getAllInBatches.test.ts +54 -0
  169. package/src/extensions/marketplace/utils.ts +1 -1
  170. package/src/extensions/types.ts +6 -0
  171. package/src/gas/estimate-l1-fee.ts +2 -3
  172. package/src/react/core/hooks/contract/useReadContract.ts +83 -74
  173. package/src/react/core/hooks/types.ts +13 -0
  174. package/src/transaction/actions/eip7702/authorization.test.ts +27 -0
  175. package/src/transaction/actions/eip7702/authorization.ts +58 -0
  176. package/src/transaction/actions/estimate-gas.ts +26 -9
  177. package/src/transaction/actions/send-transaction.ts +32 -2
  178. package/src/transaction/actions/to-serializable-transaction.test.ts +68 -0
  179. package/src/transaction/actions/to-serializable-transaction.ts +42 -30
  180. package/src/transaction/prepare-transaction.test.ts +28 -0
  181. package/src/transaction/prepare-transaction.ts +3 -0
  182. package/src/transaction/serialize-transaction.test.ts +108 -1
  183. package/src/transaction/serialize-transaction.ts +18 -0
  184. package/src/utils/abi/decodeError.ts +5 -4
  185. package/src/utils/abi/decodeFunctionData.ts +7 -5
  186. package/src/utils/abi/decodeFunctionResult.ts +7 -5
  187. package/src/utils/hashing/hashMessage.ts +1 -1
  188. package/src/utils/signatures/sign-message.test.ts +2 -2
  189. package/src/version.ts +1 -1
  190. package/src/wallets/create-wallet.ts +16 -0
  191. package/src/wallets/interfaces/wallet.ts +15 -0
  192. package/src/wallets/private-key.test.ts +1 -0
  193. package/src/wallets/private-key.ts +10 -0
  194. package/src/wallets/smart/index.ts +20 -19
  195. package/src/wallets/smart/lib/signing.ts +154 -59
  196. package/src/wallets/smart/presets/7579.ts +13 -12
  197. package/src/wallets/smart/smart-wallet-integration-v07.test.ts +49 -9
  198. package/src/wallets/smart/smart-wallet-integration.test.ts +48 -1
@@ -210,7 +210,7 @@ async function createSmartAccount(
210
210
  }
211
211
  }
212
212
 
213
- const { accountContract } = options;
213
+ let accountContract = options.accountContract;
214
214
  const account: Account = {
215
215
  address: getAddress(accountContract.address),
216
216
  async sendTransaction(transaction: SendTransactionOption) {
@@ -237,21 +237,17 @@ async function createSmartAccount(
237
237
  paymasterOverride = options.overrides?.paymaster;
238
238
  }
239
239
 
240
- const accountContractForTransaction = (() => {
241
- // If this transaction is for a different chain than the initial one, get the account contract for that chain
242
- if (transaction.chainId !== accountContract.chain.id) {
243
- return getContract({
244
- address: account.address,
245
- chain: getCachedChain(transaction.chainId),
246
- client: options.client,
247
- });
248
- }
249
- // Default to the existing account contract
250
- return accountContract;
251
- })();
240
+ // If this transaction is for a different chain than the initial one, get the account contract for that chain
241
+ if (transaction.chainId !== accountContract.chain.id) {
242
+ accountContract = getContract({
243
+ address: account.address,
244
+ chain: getCachedChain(transaction.chainId),
245
+ client: options.client,
246
+ });
247
+ }
252
248
 
253
249
  const executeTx = prepareExecute({
254
- accountContract: accountContractForTransaction,
250
+ accountContract: accountContract,
255
251
  transaction,
256
252
  executeOverride: options.overrides?.execute,
257
253
  });
@@ -260,6 +256,7 @@ async function createSmartAccount(
260
256
  options: {
261
257
  ...options,
262
258
  chain: getCachedChain(transaction.chainId),
259
+ accountContract,
263
260
  overrides: {
264
261
  ...options.overrides,
265
262
  paymaster: paymasterOverride,
@@ -275,7 +272,11 @@ async function createSmartAccount(
275
272
  });
276
273
  return _sendUserOp({
277
274
  executeTx,
278
- options,
275
+ options: {
276
+ ...options,
277
+ chain: getCachedChain(transactions[0]?.chainId ?? options.chain.id),
278
+ accountContract,
279
+ },
279
280
  });
280
281
  },
281
282
  async signMessage({ message }: { message: SignableMessage }) {
@@ -288,8 +289,8 @@ async function createSmartAccount(
288
289
  });
289
290
  }
290
291
 
291
- const { deployAndSignMessage } = await import("./lib/signing.js");
292
- return deployAndSignMessage({
292
+ const { smartAccountSignMessage } = await import("./lib/signing.js");
293
+ return smartAccountSignMessage({
293
294
  accountContract,
294
295
  factoryContract: options.factoryContract,
295
296
  options,
@@ -309,8 +310,8 @@ async function createSmartAccount(
309
310
  });
310
311
  }
311
312
 
312
- const { deployAndSignTypedData } = await import("./lib/signing.js");
313
- return deployAndSignTypedData({
313
+ const { smartAccountSignTypedData } = await import("./lib/signing.js");
314
+ return smartAccountSignTypedData({
314
315
  accountContract,
315
316
  factoryContract: options.factoryContract,
316
317
  options,
@@ -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 { verifyHash } from "../../../auth/verify-hash.js";
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
- export async function deployAndSignMessage({
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 deployTx = prepareCreateAccount({
59
- factoryContract,
60
- adminAddress: options.personalAccount.address,
61
- accountSalt: options.overrides?.accountSalt,
62
- createAccountOverride: options.overrides?.createAccount,
63
- });
64
- if (!deployTx) {
65
- throw new Error("Create account override not provided");
66
- }
67
- const initCode = await encode(deployTx);
68
- const erc6492Sig = serializeErc6492Signature({
69
- address: factoryContract.address,
70
- data: initCode,
71
- signature: sig,
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
- // check if the signature is valid
75
- const isValid = await verifyHash({
76
- hash: originalMsgHash,
77
- signature: erc6492Sig,
78
- address: accountContract.address,
79
- chain: accountContract.chain,
80
- client: accountContract.client,
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
- if (isValid) {
84
- return erc6492Sig;
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 deployAndSignTypedData<
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 deployTx = prepareCreateAccount({
146
- factoryContract,
147
- adminAddress: options.personalAccount.address,
148
- accountSalt: options.overrides?.accountSalt,
149
- createAccountOverride: options.overrides?.createAccount,
150
- });
151
- if (!deployTx) {
152
- throw new Error("Create account override not provided");
153
- }
154
- const initCode = await encode(deployTx);
155
- const erc6492Sig = serializeErc6492Signature({
156
- address: factoryContract.address,
157
- data: initCode,
158
- signature: sig,
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
- // check if the signature is valid
162
- const isValid = await verifyHash({
163
- hash: originalMsgHash,
164
- signature: erc6492Sig,
165
- address: accountContract.address,
166
- chain: accountContract.chain,
167
- client: accountContract.client,
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
- if (isValid) {
171
- return erc6492Sig;
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 { AbiParameters, Hex } from "ox";
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
- Hex.validate(options.overrides.accountSalt)
60
+ ox__Hex.validate(options.overrides.accountSalt)
60
61
  ? options.overrides.accountSalt
61
- : Hex.fromString(options.overrides?.accountSalt ?? "");
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: Hex.fromString(""),
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: Hex.padRight("0x00", 32), // single execution
103
- executionCalldata: AbiParameters.encodePacked(
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: Hex.padRight("0x01", 32), // batch execution
121
- executionCalldata: AbiParameters.encode(
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 = Hex.from(
156
- `${defaultValidator}${Hex.fromNumber(entryPointNonce).slice(42)}`,
156
+ const withValidator = ox__Hex.from(
157
+ `${defaultValidator}${ox__Hex.fromNumber(entryPointNonce).slice(42)}`,
157
158
  );
158
- return Hex.toBigInt(withValidator);
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: Hex.Hex;
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 { confirmContractDeployment } from "./lib/signing.js";
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 1271 with replay protection", async () => {
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,