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
package/src/auth/verify-hash.ts
CHANGED
@@ -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
|
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
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
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>;
|
package/src/exports/thirdweb.ts
CHANGED
@@ -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";
|
package/src/exports/wallets.ts
CHANGED
@@ -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
|
|
@@ -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
|
-
|
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 {
|
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
|
-
|
22
|
-
|
23
|
-
|
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
|
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
|
56
|
-
const
|
58
|
+
const TAbi extends Abi,
|
59
|
+
const TMethod extends TAbi extends AbiOfLength<0>
|
57
60
|
? AbiFunction | string
|
58
|
-
: ExtractAbiFunctionNames<
|
61
|
+
: ExtractAbiFunctionNames<TAbi>,
|
59
62
|
>(
|
60
|
-
options: ReadContractOptions<
|
61
|
-
queryOptions?: PickedQueryOptions;
|
62
|
-
},
|
63
|
+
options: WithPickedOnceQueryOptions<ReadContractOptions<TAbi, TMethod>>,
|
63
64
|
): UseQueryResult<
|
64
|
-
ReadContractResult<PreparedMethod<ParseMethod<
|
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
|
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
|
86
|
-
const
|
87
|
-
|
87
|
+
const TAbi extends Abi,
|
88
|
+
const TParams extends object,
|
89
|
+
TResult,
|
88
90
|
>(
|
89
|
-
extension:
|
90
|
-
options: BaseTransactionOptions<
|
91
|
-
|
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
|
97
|
-
const
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
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
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
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
|
-
|
140
|
-
|
141
|
-
|
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
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
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
|
-
|
160
|
-
|
161
|
-
|
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
|
-
|
165
|
-
|
166
|
-
|
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
|
64
|
-
|
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] =
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
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(() => {
|