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.
Files changed (189) 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/types.js +3 -0
  16. package/dist/cjs/extensions/types.js.map +1 -0
  17. package/dist/cjs/gas/estimate-l1-fee.js +3 -4
  18. package/dist/cjs/gas/estimate-l1-fee.js.map +1 -1
  19. package/dist/cjs/react/core/hooks/contract/useReadContract.js +31 -29
  20. package/dist/cjs/react/core/hooks/contract/useReadContract.js.map +1 -1
  21. package/dist/cjs/react/core/hooks/types.js +3 -0
  22. package/dist/cjs/react/core/hooks/types.js.map +1 -0
  23. package/dist/cjs/transaction/actions/eip7702/authorization.js +33 -0
  24. package/dist/cjs/transaction/actions/eip7702/authorization.js.map +1 -0
  25. package/dist/cjs/transaction/actions/estimate-gas.js +16 -4
  26. package/dist/cjs/transaction/actions/estimate-gas.js.map +1 -1
  27. package/dist/cjs/transaction/actions/send-transaction.js +32 -1
  28. package/dist/cjs/transaction/actions/send-transaction.js.map +1 -1
  29. package/dist/cjs/transaction/actions/to-serializable-transaction.js +13 -4
  30. package/dist/cjs/transaction/actions/to-serializable-transaction.js.map +1 -1
  31. package/dist/cjs/transaction/prepare-transaction.js.map +1 -1
  32. package/dist/cjs/transaction/serialize-transaction.js +11 -0
  33. package/dist/cjs/transaction/serialize-transaction.js.map +1 -1
  34. package/dist/cjs/utils/abi/decodeError.js +3 -3
  35. package/dist/cjs/utils/abi/decodeError.js.map +1 -1
  36. package/dist/cjs/utils/abi/decodeFunctionData.js +3 -3
  37. package/dist/cjs/utils/abi/decodeFunctionData.js.map +1 -1
  38. package/dist/cjs/utils/abi/decodeFunctionResult.js +3 -3
  39. package/dist/cjs/utils/abi/decodeFunctionResult.js.map +1 -1
  40. package/dist/cjs/utils/hashing/hashMessage.js +2 -2
  41. package/dist/cjs/utils/hashing/hashMessage.js.map +1 -1
  42. package/dist/cjs/version.js +1 -1
  43. package/dist/cjs/wallets/create-wallet.js +16 -0
  44. package/dist/cjs/wallets/create-wallet.js.map +1 -1
  45. package/dist/cjs/wallets/private-key.js +9 -0
  46. package/dist/cjs/wallets/private-key.js.map +1 -1
  47. package/dist/cjs/wallets/smart/index.js +20 -19
  48. package/dist/cjs/wallets/smart/index.js.map +1 -1
  49. package/dist/cjs/wallets/smart/lib/signing.js +139 -54
  50. package/dist/cjs/wallets/smart/lib/signing.js.map +1 -1
  51. package/dist/cjs/wallets/smart/presets/7579.js +11 -10
  52. package/dist/cjs/wallets/smart/presets/7579.js.map +1 -1
  53. package/dist/esm/adapters/ethers5.js +1 -1
  54. package/dist/esm/adapters/ethers5.js.map +1 -1
  55. package/dist/esm/auth/verify-hash.js +13 -9
  56. package/dist/esm/auth/verify-hash.js.map +1 -1
  57. package/dist/esm/contract/types.js +2 -0
  58. package/dist/esm/contract/types.js.map +1 -0
  59. package/dist/esm/exports/thirdweb.js +2 -0
  60. package/dist/esm/exports/thirdweb.js.map +1 -1
  61. package/dist/esm/exports/transaction.js +1 -0
  62. package/dist/esm/exports/transaction.js.map +1 -1
  63. package/dist/esm/exports/wallets.js +1 -0
  64. package/dist/esm/exports/wallets.js.map +1 -1
  65. package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js +1 -1
  66. package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js.map +1 -1
  67. package/dist/esm/extensions/types.js +2 -0
  68. package/dist/esm/extensions/types.js.map +1 -0
  69. package/dist/esm/gas/estimate-l1-fee.js +2 -3
  70. package/dist/esm/gas/estimate-l1-fee.js.map +1 -1
  71. package/dist/esm/react/core/hooks/contract/useReadContract.js +31 -29
  72. package/dist/esm/react/core/hooks/contract/useReadContract.js.map +1 -1
  73. package/dist/esm/react/core/hooks/types.js +2 -0
  74. package/dist/esm/react/core/hooks/types.js.map +1 -0
  75. package/dist/esm/transaction/actions/eip7702/authorization.js +30 -0
  76. package/dist/esm/transaction/actions/eip7702/authorization.js.map +1 -0
  77. package/dist/esm/transaction/actions/estimate-gas.js +16 -4
  78. package/dist/esm/transaction/actions/estimate-gas.js.map +1 -1
  79. package/dist/esm/transaction/actions/send-transaction.js +32 -1
  80. package/dist/esm/transaction/actions/send-transaction.js.map +1 -1
  81. package/dist/esm/transaction/actions/to-serializable-transaction.js +13 -4
  82. package/dist/esm/transaction/actions/to-serializable-transaction.js.map +1 -1
  83. package/dist/esm/transaction/prepare-transaction.js.map +1 -1
  84. package/dist/esm/transaction/serialize-transaction.js +11 -0
  85. package/dist/esm/transaction/serialize-transaction.js.map +1 -1
  86. package/dist/esm/utils/abi/decodeError.js +3 -3
  87. package/dist/esm/utils/abi/decodeError.js.map +1 -1
  88. package/dist/esm/utils/abi/decodeFunctionData.js +3 -3
  89. package/dist/esm/utils/abi/decodeFunctionData.js.map +1 -1
  90. package/dist/esm/utils/abi/decodeFunctionResult.js +3 -3
  91. package/dist/esm/utils/abi/decodeFunctionResult.js.map +1 -1
  92. package/dist/esm/utils/hashing/hashMessage.js +1 -1
  93. package/dist/esm/utils/hashing/hashMessage.js.map +1 -1
  94. package/dist/esm/version.js +1 -1
  95. package/dist/esm/wallets/create-wallet.js +16 -0
  96. package/dist/esm/wallets/create-wallet.js.map +1 -1
  97. package/dist/esm/wallets/private-key.js +9 -0
  98. package/dist/esm/wallets/private-key.js.map +1 -1
  99. package/dist/esm/wallets/smart/index.js +20 -19
  100. package/dist/esm/wallets/smart/index.js.map +1 -1
  101. package/dist/esm/wallets/smart/lib/signing.js +137 -53
  102. package/dist/esm/wallets/smart/lib/signing.js.map +1 -1
  103. package/dist/esm/wallets/smart/presets/7579.js +11 -10
  104. package/dist/esm/wallets/smart/presets/7579.js.map +1 -1
  105. package/dist/types/auth/verify-hash.d.ts +6 -0
  106. package/dist/types/auth/verify-hash.d.ts.map +1 -1
  107. package/dist/types/contract/types.d.ts +7 -0
  108. package/dist/types/contract/types.d.ts.map +1 -0
  109. package/dist/types/exports/thirdweb.d.ts +6 -0
  110. package/dist/types/exports/thirdweb.d.ts.map +1 -1
  111. package/dist/types/exports/transaction.d.ts +5 -0
  112. package/dist/types/exports/transaction.d.ts.map +1 -1
  113. package/dist/types/exports/wallets.d.ts +1 -0
  114. package/dist/types/exports/wallets.d.ts.map +1 -1
  115. package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts +1 -1
  116. package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts.map +1 -1
  117. package/dist/types/extensions/types.d.ts +4 -0
  118. package/dist/types/extensions/types.d.ts.map +1 -0
  119. package/dist/types/gas/estimate-l1-fee.d.ts.map +1 -1
  120. package/dist/types/react/core/hooks/contract/useReadContract.d.ts +9 -16
  121. package/dist/types/react/core/hooks/contract/useReadContract.d.ts.map +1 -1
  122. package/dist/types/react/core/hooks/types.d.ts +13 -0
  123. package/dist/types/react/core/hooks/types.d.ts.map +1 -0
  124. package/dist/types/transaction/actions/eip7702/authorization.d.ts +48 -0
  125. package/dist/types/transaction/actions/eip7702/authorization.d.ts.map +1 -0
  126. package/dist/types/transaction/actions/estimate-gas.d.ts +3 -1
  127. package/dist/types/transaction/actions/estimate-gas.d.ts.map +1 -1
  128. package/dist/types/transaction/actions/send-transaction.d.ts +31 -0
  129. package/dist/types/transaction/actions/send-transaction.d.ts.map +1 -1
  130. package/dist/types/transaction/actions/to-serializable-transaction.d.ts +19 -2
  131. package/dist/types/transaction/actions/to-serializable-transaction.d.ts.map +1 -1
  132. package/dist/types/transaction/prepare-transaction.d.ts +2 -0
  133. package/dist/types/transaction/prepare-transaction.d.ts.map +1 -1
  134. package/dist/types/transaction/serialize-transaction.d.ts +2 -0
  135. package/dist/types/transaction/serialize-transaction.d.ts.map +1 -1
  136. package/dist/types/utils/abi/decodeError.d.ts +2 -2
  137. package/dist/types/utils/abi/decodeError.d.ts.map +1 -1
  138. package/dist/types/utils/abi/decodeFunctionData.d.ts +6 -4
  139. package/dist/types/utils/abi/decodeFunctionData.d.ts.map +1 -1
  140. package/dist/types/utils/abi/decodeFunctionResult.d.ts +6 -4
  141. package/dist/types/utils/abi/decodeFunctionResult.d.ts.map +1 -1
  142. package/dist/types/utils/hashing/hashMessage.d.ts +1 -1
  143. package/dist/types/utils/hashing/hashMessage.d.ts.map +1 -1
  144. package/dist/types/version.d.ts +1 -1
  145. package/dist/types/wallets/create-wallet.d.ts +16 -0
  146. package/dist/types/wallets/create-wallet.d.ts.map +1 -1
  147. package/dist/types/wallets/interfaces/wallet.d.ts +9 -0
  148. package/dist/types/wallets/interfaces/wallet.d.ts.map +1 -1
  149. package/dist/types/wallets/private-key.d.ts.map +1 -1
  150. package/dist/types/wallets/smart/lib/signing.d.ts +46 -2
  151. package/dist/types/wallets/smart/lib/signing.d.ts.map +1 -1
  152. package/dist/types/wallets/smart/presets/7579.d.ts.map +1 -1
  153. package/package.json +1 -1
  154. package/src/adapters/ethers5.ts +1 -1
  155. package/src/auth/verify-hash.ts +12 -9
  156. package/src/contract/types.ts +8 -0
  157. package/src/exports/thirdweb.ts +10 -0
  158. package/src/exports/transaction.ts +9 -0
  159. package/src/exports/wallets.ts +2 -0
  160. package/src/extensions/erc721/lazyMinting/read/getBatchesToReveal.ts +2 -2
  161. package/src/extensions/types.ts +6 -0
  162. package/src/gas/estimate-l1-fee.ts +2 -3
  163. package/src/react/core/hooks/contract/useReadContract.ts +83 -74
  164. package/src/react/core/hooks/types.ts +13 -0
  165. package/src/transaction/actions/eip7702/authorization.test.ts +27 -0
  166. package/src/transaction/actions/eip7702/authorization.ts +58 -0
  167. package/src/transaction/actions/estimate-gas.ts +26 -9
  168. package/src/transaction/actions/send-transaction.ts +32 -2
  169. package/src/transaction/actions/to-serializable-transaction.test.ts +68 -0
  170. package/src/transaction/actions/to-serializable-transaction.ts +42 -30
  171. package/src/transaction/prepare-transaction.test.ts +28 -0
  172. package/src/transaction/prepare-transaction.ts +3 -0
  173. package/src/transaction/serialize-transaction.test.ts +108 -1
  174. package/src/transaction/serialize-transaction.ts +18 -0
  175. package/src/utils/abi/decodeError.ts +5 -4
  176. package/src/utils/abi/decodeFunctionData.ts +7 -5
  177. package/src/utils/abi/decodeFunctionResult.ts +7 -5
  178. package/src/utils/hashing/hashMessage.ts +1 -1
  179. package/src/utils/signatures/sign-message.test.ts +2 -2
  180. package/src/version.ts +1 -1
  181. package/src/wallets/create-wallet.ts +16 -0
  182. package/src/wallets/interfaces/wallet.ts +15 -0
  183. package/src/wallets/private-key.test.ts +1 -0
  184. package/src/wallets/private-key.ts +10 -0
  185. package/src/wallets/smart/index.ts +20 -19
  186. package/src/wallets/smart/lib/signing.ts +154 -59
  187. package/src/wallets/smart/presets/7579.ts +13 -12
  188. package/src/wallets/smart/smart-wallet-integration-v07.test.ts +49 -9
  189. package/src/wallets/smart/smart-wallet-integration.test.ts +48 -1
@@ -129,8 +129,7 @@ export async function verifyHash({
129
129
  try {
130
130
  const result = await eth_call(rpcRequest, verificationData);
131
131
  return hexToBool(result);
132
- } catch (err) {
133
- console.error("Error verifying ERC-6492 signature", err);
132
+ } catch {
134
133
  // Some chains do not support the eth_call simulation and will fail, so we fall back to regular EIP1271 validation
135
134
  const validEip1271 = await verifyEip1271Signature({
136
135
  hash,
@@ -154,7 +153,7 @@ export async function verifyHash({
154
153
  }
155
154
 
156
155
  const EIP_1271_MAGIC_VALUE = "0x1626ba7e";
157
- async function verifyEip1271Signature({
156
+ export async function verifyEip1271Signature({
158
157
  hash,
159
158
  signature,
160
159
  contract,
@@ -163,10 +162,14 @@ async function verifyEip1271Signature({
163
162
  signature: Hex;
164
163
  contract: ThirdwebContract;
165
164
  }): Promise<boolean> {
166
- const result = await isValidSignature({
167
- hash,
168
- signature,
169
- contract,
170
- });
171
- return result === EIP_1271_MAGIC_VALUE;
165
+ try {
166
+ const result = await isValidSignature({
167
+ hash,
168
+ signature,
169
+ contract,
170
+ });
171
+ return result === EIP_1271_MAGIC_VALUE;
172
+ } catch {
173
+ return false;
174
+ }
172
175
  }
@@ -0,0 +1,8 @@
1
+ import type { Abi, AbiFunction } from "abitype";
2
+ import type { ThirdwebContract } from "./contract.js";
3
+
4
+ export type AbiOfLength<TLength> = { length: TLength };
5
+
6
+ export type AsyncGetAbiFunctionFromContract<TAbi extends Abi> = (
7
+ contract: ThirdwebContract<TAbi>,
8
+ ) => Promise<AbiFunction>;
@@ -302,3 +302,13 @@ export {
302
302
  type VerifyTypedDataParams,
303
303
  verifyTypedData,
304
304
  } from "../auth/verify-typed-data.js";
305
+
306
+ /**
307
+ * EIP-7702
308
+ */
309
+ export type {
310
+ AuthorizationRequest,
311
+ SignedAuthorization,
312
+ } from "../transaction/actions/eip7702/authorization.js";
313
+ export { signAuthorization } from "../transaction/actions/eip7702/authorization.js";
314
+ export { deploySmartAccount } from "../wallets/smart/lib/signing.js";
@@ -78,3 +78,12 @@ export type { GaslessOptions } from "../transaction/actions/gasless/types.js";
78
78
  export type { EngineOptions } from "../transaction/actions/gasless/providers/engine.js";
79
79
  export type { OpenZeppelinOptions } from "../transaction/actions/gasless/providers/openzeppelin.js";
80
80
  export type { BiconomyOptions } from "../transaction/actions/gasless/providers/biconomy.js";
81
+
82
+ /**
83
+ * EIP-7702
84
+ */
85
+ export type {
86
+ AuthorizationRequest,
87
+ SignedAuthorization,
88
+ } from "../transaction/actions/eip7702/authorization.js";
89
+ export { signAuthorization } from "../transaction/actions/eip7702/authorization.js";
@@ -160,3 +160,5 @@ export * as EIP1193 from "../adapters/eip1193/index.js";
160
160
  export { injectedProvider } from "../wallets/injected/mipdStore.js";
161
161
 
162
162
  export type { ConnectionManager } from "../wallets/manager/index.js";
163
+
164
+ export { deploySmartAccount } from "../wallets/smart/lib/signing.js";
@@ -15,7 +15,7 @@ import * as TokenURI from "../../__generated__/IERC721A/read/tokenURI.js";
15
15
  export interface BatchToReveal {
16
16
  batchId: bigint;
17
17
  batchUri: string;
18
- placeholderMetadata: NFTMetadata;
18
+ placeholderMetadata: NFTMetadata | undefined;
19
19
  }
20
20
 
21
21
  /**
@@ -82,7 +82,7 @@ export async function getBatchesToReveal(
82
82
  tokenId: BigInt(i),
83
83
  tokenUri: uri,
84
84
  client: options.contract.client,
85
- });
85
+ }).catch(() => undefined);
86
86
  }),
87
87
  );
88
88
 
@@ -0,0 +1,6 @@
1
+ import type { Abi } from "abitype";
2
+ import type { BaseTransactionOptions } from "../transaction/types.js";
3
+
4
+ export type Extension<TAbi extends Abi, TParams extends object, TResult> = (
5
+ options: BaseTransactionOptions<TParams, TAbi>,
6
+ ) => Promise<TResult>;
@@ -1,8 +1,8 @@
1
- import { serializeTransaction } from "viem";
2
1
  import { getContract } from "../contract/contract.js";
3
2
  import { toSerializableTransaction } from "../transaction/actions/to-serializable-transaction.js";
4
3
  import type { PreparedTransaction } from "../transaction/prepare-transaction.js";
5
4
  import { readContract } from "../transaction/read-contract.js";
5
+ import { serializeTransaction } from "../transaction/serialize-transaction.js";
6
6
 
7
7
  type EstimateL1FeeOptions = {
8
8
  transaction: PreparedTransaction;
@@ -29,8 +29,7 @@ export async function estimateL1Fee(options: EstimateL1FeeOptions) {
29
29
  transaction,
30
30
  });
31
31
  const serialized = serializeTransaction({
32
- ...serializableTx,
33
- type: "eip1559",
32
+ transaction: serializableTx,
34
33
  });
35
34
  //serializeTransaction(transaction);
36
35
  return readContract({
@@ -4,7 +4,11 @@ import {
4
4
  useQuery,
5
5
  } from "@tanstack/react-query";
6
6
  import type { Abi, AbiFunction, ExtractAbiFunctionNames } from "abitype";
7
- import type { ThirdwebContract } from "../../../../contract/contract.js";
7
+ import type {
8
+ AbiOfLength,
9
+ AsyncGetAbiFunctionFromContract,
10
+ } from "../../../../contract/types.js";
11
+ import type { Extension } from "../../../../extensions/types.js";
8
12
  import {
9
13
  type ReadContractOptions,
10
14
  type ReadContractResult,
@@ -17,17 +21,16 @@ import type {
17
21
  import type { PreparedMethod } from "../../../../utils/abi/prepare-method.js";
18
22
  import { getFunctionId } from "../../../../utils/function-id.js";
19
23
  import { stringify } from "../../../../utils/json.js";
20
-
21
- type PickedQueryOptions = {
22
- enabled?: boolean;
23
- refetchInterval?: number;
24
- retry?: number;
25
- };
24
+ import type {
25
+ PickedOnceQueryOptions,
26
+ WithPickedOnceQueryOptions,
27
+ } from "../types.js";
26
28
 
27
29
  /**
28
30
  * A hook to read state from a contract that automatically updates when the contract changes.
29
31
  *
30
- * You can use raw read calls or read [extensions](https://portal.thirdweb.com/react/v5/extensions) to read from a contract.
32
+ * You can use raw read calls or read [extensions](https://portal.thirdweb.com/react/v5/extensions) to read from a
33
+ * contract.
31
34
  *
32
35
  * @param options - The options for reading from a contract
33
36
  * @returns a UseQueryResult object.
@@ -52,20 +55,19 @@ type PickedQueryOptions = {
52
55
  * @contract
53
56
  */
54
57
  export function useReadContract<
55
- const abi extends Abi,
56
- const method extends abi extends { length: 0 }
58
+ const TAbi extends Abi,
59
+ const TMethod extends TAbi extends AbiOfLength<0>
57
60
  ? AbiFunction | string
58
- : ExtractAbiFunctionNames<abi>,
61
+ : ExtractAbiFunctionNames<TAbi>,
59
62
  >(
60
- options: ReadContractOptions<abi, method> & {
61
- queryOptions?: PickedQueryOptions;
62
- },
63
+ options: WithPickedOnceQueryOptions<ReadContractOptions<TAbi, TMethod>>,
63
64
  ): UseQueryResult<
64
- ReadContractResult<PreparedMethod<ParseMethod<abi, method>>[2]>
65
+ ReadContractResult<PreparedMethod<ParseMethod<TAbi, TMethod>>[2]>
65
66
  >;
66
67
  /**
67
68
  * A hook to read state from a contract that automatically updates when the contract changes.
68
- * You can use raw read calls or read [extensions](https://portal.thirdweb.com/react/v5/extensions) to read from a contract.
69
+ * You can use raw read calls or read [extensions](https://portal.thirdweb.com/react/v5/extensions) to read from a
70
+ * contract.
69
71
  *
70
72
  * @param extension - An extension to call.
71
73
  * @param options - The read extension params.
@@ -82,38 +84,42 @@ export function useReadContract<
82
84
  * ```
83
85
  */
84
86
  export function useReadContract<
85
- const abi extends Abi,
86
- const params extends object,
87
- result,
87
+ const TAbi extends Abi,
88
+ const TParams extends object,
89
+ TResult,
88
90
  >(
89
- extension: (options: BaseTransactionOptions<params, abi>) => Promise<result>,
90
- options: BaseTransactionOptions<params, abi> & {
91
- queryOptions?: PickedQueryOptions;
92
- },
93
- ): UseQueryResult<result>;
91
+ extension: Extension<TAbi, TParams, TResult>,
92
+ options: WithPickedOnceQueryOptions<BaseTransactionOptions<TParams, TAbi>>,
93
+ ): UseQueryResult<TResult>;
94
94
 
95
95
  export function useReadContract<
96
- const abi extends Abi,
97
- const method extends abi extends {
98
- length: 0;
99
- }
100
- ?
101
- | AbiFunction
102
- | `function ${string}`
103
- | ((contract: ThirdwebContract<abi>) => Promise<AbiFunction>)
104
- : ExtractAbiFunctionNames<abi>,
105
- const params extends object,
106
- result,
96
+ const TAbi extends Abi,
97
+ const TMethod extends TAbi extends AbiOfLength<0>
98
+ ? AbiFunction | `function ${string}` | AsyncGetAbiFunctionFromContract<TAbi>
99
+ : ExtractAbiFunctionNames<TAbi>,
100
+ const TParams extends object,
101
+ TResult,
107
102
  >(
108
103
  extensionOrOptions:
109
- | ((options: BaseTransactionOptions<params, abi>) => Promise<result>)
110
- | (ReadContractOptions<abi, method> & {
111
- queryOptions?: PickedQueryOptions;
112
- }),
113
- options?: BaseTransactionOptions<params, abi> & {
114
- queryOptions?: PickedQueryOptions;
115
- },
104
+ | Extension<TAbi, TParams, TResult>
105
+ | WithPickedOnceQueryOptions<ReadContractOptions<TAbi, TMethod>>,
106
+ options?: WithPickedOnceQueryOptions<BaseTransactionOptions<TParams, TAbi>>,
116
107
  ) {
108
+ type QueryKey = readonly [
109
+ "readContract",
110
+ number | string,
111
+ string,
112
+ string | PreparedMethod<ParseMethod<TAbi, TMethod>>,
113
+ string,
114
+ ];
115
+ type QueryFn = () => Promise<
116
+ TResult | ReadContractResult<PreparedMethod<ParseMethod<TAbi, TMethod>>[2]>
117
+ >;
118
+
119
+ let queryKey: QueryKey | undefined;
120
+ let queryFn: QueryFn | undefined;
121
+ let queryOpts: PickedOnceQueryOptions | undefined;
122
+
117
123
  // extension case
118
124
  if (typeof extensionOrOptions === "function") {
119
125
  if (!options) {
@@ -122,46 +128,49 @@ export function useReadContract<
122
128
  ) as never;
123
129
  }
124
130
  const { queryOptions, contract, ...params } = options;
131
+ queryOpts = queryOptions;
125
132
 
126
- const query = defineQuery({
127
- queryKey: [
128
- "readContract",
129
- contract.chain.id,
130
- contract.address,
131
- getFunctionId(extensionOrOptions),
132
- stringify(params),
133
- ] as const,
134
- // @ts-expect-error - TODO: clean up the type issues here
135
- queryFn: () => extensionOrOptions({ ...params, contract }),
136
- ...queryOptions,
137
- });
133
+ queryKey = [
134
+ "readContract",
135
+ contract.chain.id,
136
+ contract.address,
137
+ getFunctionId(extensionOrOptions),
138
+ stringify(params),
139
+ ] as const;
138
140
 
139
- // TODO - FIX LATER
140
- // biome-ignore lint/correctness/useHookAtTopLevel: <explanation>
141
- return useQuery(query);
141
+ queryFn = () =>
142
+ extensionOrOptions({
143
+ ...(params as TParams),
144
+ contract,
145
+ });
142
146
  }
143
147
  // raw tx case
144
148
  if ("method" in extensionOrOptions) {
145
149
  const { queryOptions, ...tx } = extensionOrOptions;
150
+ queryOpts = queryOptions;
146
151
 
147
- const query = defineQuery({
148
- queryKey: [
149
- "readContract",
150
- tx.contract.chain.id,
151
- tx.contract.address,
152
- tx.method,
153
- stringify(tx.params),
154
- ] as const,
155
- queryFn: () => readContract(extensionOrOptions),
156
- ...queryOptions,
157
- });
152
+ queryKey = [
153
+ "readContract",
154
+ tx.contract.chain.id,
155
+ tx.contract.address,
156
+ tx.method,
157
+ stringify(tx.params),
158
+ ] as const;
159
+
160
+ queryFn = () => readContract(extensionOrOptions);
161
+ }
158
162
 
159
- // TODO - FIX LATER
160
- // biome-ignore lint/correctness/useHookAtTopLevel: <explanation>
161
- return useQuery(query);
163
+ if (!queryKey || !queryFn) {
164
+ throw new Error(
165
+ `Invalid "useReadContract" options. Expected either a read extension or a transaction object.`,
166
+ ) as never;
162
167
  }
163
168
 
164
- throw new Error(
165
- `Invalid "useReadContract" options. Expected either a read extension or a transaction object.`,
166
- ) as never;
169
+ return useQuery(
170
+ defineQuery({
171
+ queryKey: queryKey as QueryKey,
172
+ queryFn: queryFn as QueryFn,
173
+ ...(queryOpts ?? {}),
174
+ }),
175
+ );
167
176
  }
@@ -0,0 +1,13 @@
1
+ import type { Prettify } from "../../../utils/type-utils.js";
2
+
3
+ type BasePickedQueryOptions<T = object> = T & {
4
+ enabled?: boolean;
5
+ };
6
+
7
+ export type PickedOnceQueryOptions = Prettify<
8
+ BasePickedQueryOptions & { refetchInterval?: number; retry?: number }
9
+ >;
10
+
11
+ export type WithPickedOnceQueryOptions<T> = T & {
12
+ queryOptions?: PickedOnceQueryOptions;
13
+ };
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { TEST_WALLET_B } from "~test/addresses.js";
3
+ import { TEST_ACCOUNT_A } from "~test/test-wallets.js";
4
+ import { signAuthorization } from "./authorization.js";
5
+
6
+ describe("signAuthorization", () => {
7
+ it("should sign an authorization", async () => {
8
+ const authorization = await signAuthorization({
9
+ account: TEST_ACCOUNT_A,
10
+ request: {
11
+ address: TEST_WALLET_B,
12
+ chainId: 911867,
13
+ nonce: 0n,
14
+ },
15
+ });
16
+ expect(authorization).toMatchInlineSnapshot(`
17
+ {
18
+ "address": "0x0000000000000000000000000000000000000002",
19
+ "chainId": 911867,
20
+ "nonce": 0n,
21
+ "r": 3720526934953059641417422884731844424204826752871127418111522219225437830766n,
22
+ "s": 23451045058292828843243765241045958975073226494910356096978666517928790374894n,
23
+ "yParity": 1,
24
+ }
25
+ `);
26
+ });
27
+ });
@@ -0,0 +1,58 @@
1
+ import type * as ox__Authorization from "ox/Authorization";
2
+ import type { Address } from "../../../utils/address.js";
3
+ import type { Account } from "../../../wallets/interfaces/wallet.js";
4
+
5
+ /**
6
+ * An EIP-7702 authorization object fully prepared and ready for signing.
7
+ *
8
+ * @beta
9
+ * @transaction
10
+ */
11
+ export type AuthorizationRequest = {
12
+ address: Address;
13
+ chainId: number;
14
+ nonce: bigint;
15
+ };
16
+
17
+ /**
18
+ * Represents a signed EIP-7702 authorization object.
19
+ *
20
+ * @beta
21
+ * @transaction
22
+ */
23
+ export type SignedAuthorization = ox__Authorization.ListSigned[number];
24
+
25
+ /**
26
+ * Sign the given EIP-7702 authorization object.
27
+ * @param options - The options for `signAuthorization`
28
+ * Refer to the type [`SignAuthorizationOptions`](https://portal.thirdweb.com/references/typescript/v5/SignAuthorizationOptions)
29
+ * @returns The signed authorization object
30
+ *
31
+ * ```ts
32
+ * import { signAuthorization } from "thirdweb";
33
+ *
34
+ * const authorization = await signAuthorization({
35
+ * request: {
36
+ * address: "0x...",
37
+ * chainId: 911867,
38
+ * nonce: 100n,
39
+ * },
40
+ * account: myAccount,
41
+ * });
42
+ * ```
43
+ *
44
+ * @beta
45
+ * @transaction
46
+ */
47
+ export async function signAuthorization(options: {
48
+ account: Account;
49
+ request: AuthorizationRequest;
50
+ }): Promise<SignedAuthorization> {
51
+ const { account, request } = options;
52
+ if (typeof account.signAuthorization === "undefined") {
53
+ throw new Error(
54
+ "This account type does not yet support signing EIP-7702 authorizations",
55
+ );
56
+ }
57
+ return account.signAuthorization(request);
58
+ }
@@ -1,3 +1,4 @@
1
+ import * as ox__Hex from "ox/Hex";
1
2
  import { formatTransactionRequest } from "viem";
2
3
  import { roundUpGas } from "../../gas/op-gas-fee-reducer.js";
3
4
  import { resolvePromisedValue } from "../../utils/promise/resolve-promised-value.js";
@@ -18,6 +19,8 @@ export type EstimateGasOptions = Prettify<
18
19
  | {
19
20
  /**
20
21
  * The account the transaction would be sent from.
22
+ *
23
+ * @deprecated Use `from` instead
21
24
  */
22
25
  account: Account;
23
26
  from?: never;
@@ -27,7 +30,7 @@ export type EstimateGasOptions = Prettify<
27
30
  /**
28
31
  * The address the transaction would be sent from.
29
32
  */
30
- from?: string;
33
+ from?: string | Account;
31
34
  }
32
35
  )
33
36
  >;
@@ -60,8 +63,11 @@ export async function estimateGas(
60
63
  // 1. the user specified from address
61
64
  // 2. the passed in account address
62
65
  // 3. the passed in wallet's account address
63
- const from = options.from ?? options.account?.address ?? undefined;
64
- const txWithFrom = { ...options.transaction, from };
66
+ const fromAddress =
67
+ typeof options.from === "string"
68
+ ? (options.from ?? undefined)
69
+ : (options.from?.address ?? options.account?.address);
70
+ const txWithFrom = { ...options.transaction, from: fromAddress };
65
71
  if (cache.has(txWithFrom)) {
66
72
  // biome-ignore lint/style/noNonNullAssertion: the `has` above ensures that this will always be set
67
73
  return cache.get(txWithFrom)!;
@@ -92,11 +98,13 @@ export async function estimateGas(
92
98
 
93
99
  // load up encode function if we need it
94
100
  const { encode } = await import("./encode.js");
95
- const [encodedData, toAddress, value] = await Promise.all([
96
- encode(options.transaction),
97
- resolvePromisedValue(options.transaction.to),
98
- resolvePromisedValue(options.transaction.value),
99
- ]);
101
+ const [encodedData, toAddress, value, authorizationList] =
102
+ await Promise.all([
103
+ encode(options.transaction),
104
+ resolvePromisedValue(options.transaction.to),
105
+ resolvePromisedValue(options.transaction.value),
106
+ resolvePromisedValue(options.transaction.authorizationList),
107
+ ]);
100
108
 
101
109
  // load up the rpc client and the estimateGas function if we need it
102
110
  const [{ getRpcClient }, { eth_estimateGas }] = await Promise.all([
@@ -111,10 +119,19 @@ export async function estimateGas(
111
119
  formatTransactionRequest({
112
120
  to: toAddress,
113
121
  data: encodedData,
114
- from,
122
+ from: fromAddress,
115
123
  value,
124
+ // TODO: Remove this casting when we migrate this file to Ox
125
+ authorizationList: authorizationList?.map((auth) => ({
126
+ ...auth,
127
+ r: ox__Hex.fromNumber(auth.r),
128
+ s: ox__Hex.fromNumber(auth.s),
129
+ nonce: Number(auth.nonce),
130
+ contractAddress: auth.address,
131
+ })),
116
132
  }),
117
133
  );
134
+
118
135
  if (options.transaction.chain.experimental?.increaseZeroByteCount) {
119
136
  gas = roundUpGas(gas);
120
137
  }
@@ -110,6 +110,37 @@ export interface SendTransactionOptions {
110
110
  * });
111
111
  * ```
112
112
  *
113
+ * ### Send an EIP-7702 Transaction
114
+ *
115
+ * **Note: This feature is in beta and is subject to breaking changes**
116
+ *
117
+ * ```ts
118
+ * import { sendTransaction, prepareTransaction, signAuthorization } from "thirdweb";
119
+ * import { sepolia } from "thirdweb/chains";
120
+ *
121
+ * const authorization = await signAuthorization({
122
+ * request: {
123
+ * address: "0x...",
124
+ * chainId: 1,
125
+ * nonce: 0n,
126
+ * },
127
+ * account: myAccount,
128
+ * });
129
+ *
130
+ * const transaction = prepareTransaction({
131
+ * chain: sepolia,
132
+ * client: client,
133
+ * to: "0x...",
134
+ * value: 0n,
135
+ * authorizationList: [authorization],
136
+ * });
137
+ *
138
+ * const { transactionHash } = await sendTransaction({
139
+ * account,
140
+ * transaction,
141
+ * });
142
+ * ```
143
+ *
113
144
  * ### Gasless usage with [thirdweb Engine](https://portal.thirdweb.com/engine)
114
145
  * ```ts
115
146
  * const { transactionHash } = await sendTransaction({
@@ -166,9 +197,8 @@ export async function sendTransaction(
166
197
 
167
198
  const serializableTransaction = await toSerializableTransaction({
168
199
  transaction: transaction,
169
- from: account.address,
200
+ from: account,
170
201
  });
171
-
172
202
  // branch for gasless transactions
173
203
  if (gasless) {
174
204
  // lazy load the gasless tx function because it's only needed for gasless transactions
@@ -3,6 +3,7 @@ import { beforeAll, describe, expect, test } from "vitest";
3
3
  import { TEST_WALLET_B } from "../../../test/src/addresses.js";
4
4
  import { FORKED_ETHEREUM_CHAIN } from "../../../test/src/chains.js";
5
5
  import { TEST_CLIENT } from "../../../test/src/test-clients.js";
6
+ import { TEST_ACCOUNT_A } from "../../../test/src/test-wallets.js";
6
7
  import { arbitrumSepolia } from "../../chains/chain-definitions/arbitrum-sepolia.js";
7
8
  import { toWei } from "../../utils/units.js";
8
9
  import {
@@ -10,6 +11,7 @@ import {
10
11
  prepareTransaction,
11
12
  } from "../prepare-transaction.js";
12
13
  import { serializeTransaction } from "../serialize-transaction.js";
14
+ import { signAuthorization } from "./eip7702/authorization.js";
13
15
  import { toSerializableTransaction } from "./to-serializable-transaction.js";
14
16
 
15
17
  describe.runIf(process.env.TW_SECRET_KEY)("toSerializableTransaction", () => {
@@ -272,6 +274,72 @@ describe.runIf(process.env.TW_SECRET_KEY)("toSerializableTransaction", () => {
272
274
  });
273
275
  });
274
276
 
277
+ describe("authorizations", () => {
278
+ test("should be able to be set", async () => {
279
+ const authorization = await signAuthorization({
280
+ account: TEST_ACCOUNT_A,
281
+ request: {
282
+ address: TEST_WALLET_B,
283
+ chainId: 1,
284
+ nonce: 100n,
285
+ },
286
+ });
287
+
288
+ const serializableTransaction = await toSerializableTransaction({
289
+ transaction: {
290
+ ...transaction,
291
+ authorizationList: [authorization],
292
+ },
293
+ from: TEST_ACCOUNT_A,
294
+ });
295
+
296
+ expect(serializableTransaction.authorizationList).toMatchInlineSnapshot(`
297
+ [
298
+ {
299
+ "address": "0x0000000000000000000000000000000000000002",
300
+ "chainId": 1,
301
+ "nonce": 100n,
302
+ "r": 80806665504145908662094143605220407474886149466352261863122583017203514896219n,
303
+ "s": 35406481756212480507222011619049260135807579374282360733409834151386668114999n,
304
+ "yParity": 1,
305
+ },
306
+ ]
307
+ `);
308
+ });
309
+
310
+ test("should be able to be a promised value", async () => {
311
+ const authorization = await signAuthorization({
312
+ account: TEST_ACCOUNT_A,
313
+ request: {
314
+ address: TEST_WALLET_B,
315
+ chainId: 1,
316
+ nonce: 100n,
317
+ },
318
+ });
319
+
320
+ const serializableTransaction = await toSerializableTransaction({
321
+ transaction: {
322
+ ...transaction,
323
+ authorizationList: async () => Promise.resolve([authorization]),
324
+ },
325
+ from: TEST_ACCOUNT_A,
326
+ });
327
+
328
+ expect(serializableTransaction.authorizationList).toMatchInlineSnapshot(`
329
+ [
330
+ {
331
+ "address": "0x0000000000000000000000000000000000000002",
332
+ "chainId": 1,
333
+ "nonce": 100n,
334
+ "r": 80806665504145908662094143605220407474886149466352261863122583017203514896219n,
335
+ "s": 35406481756212480507222011619049260135807579374282360733409834151386668114999n,
336
+ "yParity": 1,
337
+ },
338
+ ]
339
+ `);
340
+ });
341
+ });
342
+
275
343
  describe("extraGas override", () => {
276
344
  let gas: bigint;
277
345
  beforeAll(() => {