thirdweb 5.101.2 → 5.102.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 (69) hide show
  1. package/dist/cjs/engine/create-server-wallet.js +46 -0
  2. package/dist/cjs/engine/create-server-wallet.js.map +1 -0
  3. package/dist/cjs/engine/get-status.js +0 -54
  4. package/dist/cjs/engine/get-status.js.map +1 -1
  5. package/dist/cjs/engine/index.js +9 -2
  6. package/dist/cjs/engine/index.js.map +1 -1
  7. package/dist/cjs/engine/list-server-wallets.js +40 -0
  8. package/dist/cjs/engine/list-server-wallets.js.map +1 -0
  9. package/dist/cjs/engine/search-transactions.js +115 -0
  10. package/dist/cjs/engine/search-transactions.js.map +1 -0
  11. package/dist/cjs/engine/server-wallet.js +97 -17
  12. package/dist/cjs/engine/server-wallet.js.map +1 -1
  13. package/dist/cjs/engine/wait-for-tx-hash.js +59 -0
  14. package/dist/cjs/engine/wait-for-tx-hash.js.map +1 -0
  15. package/dist/cjs/insight/get-nfts.js +6 -1
  16. package/dist/cjs/insight/get-nfts.js.map +1 -1
  17. package/dist/cjs/utils/fetch.js +1 -0
  18. package/dist/cjs/utils/fetch.js.map +1 -1
  19. package/dist/cjs/version.js +1 -1
  20. package/dist/esm/engine/create-server-wallet.js +43 -0
  21. package/dist/esm/engine/create-server-wallet.js.map +1 -0
  22. package/dist/esm/engine/get-status.js +0 -53
  23. package/dist/esm/engine/get-status.js.map +1 -1
  24. package/dist/esm/engine/index.js +5 -1
  25. package/dist/esm/engine/index.js.map +1 -1
  26. package/dist/esm/engine/list-server-wallets.js +37 -0
  27. package/dist/esm/engine/list-server-wallets.js.map +1 -0
  28. package/dist/esm/engine/search-transactions.js +112 -0
  29. package/dist/esm/engine/search-transactions.js.map +1 -0
  30. package/dist/esm/engine/server-wallet.js +96 -16
  31. package/dist/esm/engine/server-wallet.js.map +1 -1
  32. package/dist/esm/engine/wait-for-tx-hash.js +56 -0
  33. package/dist/esm/engine/wait-for-tx-hash.js.map +1 -0
  34. package/dist/esm/insight/get-nfts.js +6 -1
  35. package/dist/esm/insight/get-nfts.js.map +1 -1
  36. package/dist/esm/utils/fetch.js +1 -0
  37. package/dist/esm/utils/fetch.js.map +1 -1
  38. package/dist/esm/version.js +1 -1
  39. package/dist/types/engine/create-server-wallet.d.ts +29 -0
  40. package/dist/types/engine/create-server-wallet.d.ts.map +1 -0
  41. package/dist/types/engine/get-status.d.ts +0 -23
  42. package/dist/types/engine/get-status.d.ts.map +1 -1
  43. package/dist/types/engine/index.d.ts +5 -1
  44. package/dist/types/engine/index.d.ts.map +1 -1
  45. package/dist/types/engine/list-server-wallets.d.ts +25 -0
  46. package/dist/types/engine/list-server-wallets.d.ts.map +1 -0
  47. package/dist/types/engine/search-transactions.d.ts +127 -0
  48. package/dist/types/engine/search-transactions.d.ts.map +1 -0
  49. package/dist/types/engine/server-wallet.d.ts +36 -0
  50. package/dist/types/engine/server-wallet.d.ts.map +1 -1
  51. package/dist/types/engine/wait-for-tx-hash.d.ts +25 -0
  52. package/dist/types/engine/wait-for-tx-hash.d.ts.map +1 -0
  53. package/dist/types/utils/fetch.d.ts.map +1 -1
  54. package/dist/types/version.d.ts +1 -1
  55. package/package.json +2 -2
  56. package/src/bridge/Chains.test.ts +1 -1
  57. package/src/engine/create-server-wallet.ts +57 -0
  58. package/src/engine/get-status.ts +0 -69
  59. package/src/engine/index.ts +13 -1
  60. package/src/engine/list-server-wallets.ts +46 -0
  61. package/src/engine/search-transactions.ts +132 -0
  62. package/src/engine/server-wallet.test.ts +54 -0
  63. package/src/engine/server-wallet.ts +104 -17
  64. package/src/engine/wait-for-tx-hash.ts +75 -0
  65. package/src/extensions/erc1155/read/getOwnedNFTs.test.ts +25 -0
  66. package/src/extensions/erc20/drop20.test.ts +91 -1
  67. package/src/insight/get-nfts.ts +6 -1
  68. package/src/utils/fetch.ts +1 -0
  69. package/src/version.ts +1 -1
@@ -0,0 +1,132 @@
1
+ import {
2
+ type TransactionsFilterNested,
3
+ type TransactionsFilterValue,
4
+ searchTransactions as engineSearchTransactions,
5
+ } from "@thirdweb-dev/engine";
6
+ import type { ThirdwebClient } from "../client/client.js";
7
+ import { getThirdwebBaseUrl } from "../utils/domains.js";
8
+ import { getClientFetch } from "../utils/fetch.js";
9
+ import { stringify } from "../utils/json.js";
10
+
11
+ export type SearchTransactionsArgs = {
12
+ client: ThirdwebClient;
13
+ filters?: (TransactionsFilterValue | TransactionsFilterNested)[];
14
+ pageSize?: number;
15
+ page?: number;
16
+ };
17
+
18
+ /**
19
+ * Search for transactions by their ids.
20
+ * @param args - The arguments for the search.
21
+ * @param args.client - The thirdweb client to use.
22
+ * @param args.transactionIds - The ids of the transactions to search for.
23
+ * @engine
24
+ * @example
25
+ * ## Search for transactions by their ids
26
+ *
27
+ * ```ts
28
+ * import { Engine } from "thirdweb";
29
+ *
30
+ * const transactions = await Engine.searchTransactions({
31
+ * client,
32
+ * filters: [
33
+ * {
34
+ * field: "id",
35
+ * values: ["1", "2", "3"],
36
+ * },
37
+ * ],
38
+ * });
39
+ * console.log(transactions);
40
+ * ```
41
+ *
42
+ * ## Search for transactions by chain id
43
+ *
44
+ * ```ts
45
+ * import { Engine } from "thirdweb";
46
+ *
47
+ * const transactions = await Engine.searchTransactions({
48
+ * client,
49
+ * filters: [
50
+ * {
51
+ * field: "chainId",
52
+ * values: ["1", "137"],
53
+ * },
54
+ * ],
55
+ * });
56
+ * console.log(transactions);
57
+ * ```
58
+ *
59
+ * ## Search for transactions by sender wallet address
60
+ *
61
+ * ```ts
62
+ * import { Engine } from "thirdweb";
63
+ *
64
+ * const transactions = await Engine.searchTransactions({
65
+ * client,
66
+ * filters: [
67
+ * {
68
+ * field: "from",
69
+ * values: ["0x1234567890123456789012345678901234567890"],
70
+ * },
71
+ * ],
72
+ * });
73
+ * console.log(transactions);
74
+ * ```
75
+ *
76
+ * ## Combined search
77
+ *
78
+ * ```ts
79
+ * import { Engine } from "thirdweb";
80
+ *
81
+ * const transactions = await Engine.searchTransactions({
82
+ * client,
83
+ * filters: [
84
+ * {
85
+ * filters: [
86
+ * {
87
+ * field: "from",
88
+ * values: ["0x1234567890123456789012345678901234567890"],
89
+ * },
90
+ * {
91
+ * field: "chainId",
92
+ * values: ["8453"],
93
+ * },
94
+ * ],
95
+ * operation: "AND",
96
+ * },
97
+ * ],
98
+ * pageSize: 100,
99
+ * page: 0,
100
+ * });
101
+ * console.log(transactions);
102
+ * ```
103
+ */
104
+ export async function searchTransactions(args: SearchTransactionsArgs) {
105
+ const { client, filters, pageSize = 100, page = 1 } = args;
106
+ const searchResult = await engineSearchTransactions({
107
+ baseUrl: getThirdwebBaseUrl("engineCloud"),
108
+ bodySerializer: stringify,
109
+ fetch: getClientFetch(client),
110
+ body: {
111
+ filters,
112
+ limit: pageSize,
113
+ page,
114
+ },
115
+ });
116
+
117
+ if (searchResult.error) {
118
+ throw new Error(
119
+ `Error searching for transaction with filters ${stringify(filters)}: ${stringify(
120
+ searchResult.error,
121
+ )}`,
122
+ );
123
+ }
124
+
125
+ const data = searchResult.data?.result;
126
+
127
+ if (!data) {
128
+ throw new Error(`No transactions found with filters ${stringify(filters)}`);
129
+ }
130
+
131
+ return data;
132
+ }
@@ -47,6 +47,23 @@ describe.runIf(
47
47
  });
48
48
  });
49
49
 
50
+ it("should create a server wallet", async () => {
51
+ const serverWallet = await Engine.createServerWallet({
52
+ client: TEST_CLIENT,
53
+ label: "My Server Wallet",
54
+ });
55
+ expect(serverWallet).toBeDefined();
56
+
57
+ const serverWallets = await Engine.getServerWallets({
58
+ client: TEST_CLIENT,
59
+ });
60
+ expect(serverWallets).toBeDefined();
61
+ expect(serverWallets.length).toBeGreaterThan(0);
62
+ expect(
63
+ serverWallets.find((s) => s.address === serverWallet.address),
64
+ ).toBeDefined();
65
+ });
66
+
50
67
  it("should sign a message", async () => {
51
68
  const signature = await serverWallet.signMessage({
52
69
  message: "hello",
@@ -95,6 +112,16 @@ describe.runIf(
95
112
  transactionId: result.transactionId,
96
113
  });
97
114
  expect(txHash.transactionHash).toBeDefined();
115
+
116
+ const res = await Engine.searchTransactions({
117
+ client: TEST_CLIENT,
118
+ filters: [
119
+ { field: "id", values: [result.transactionId], operation: "OR" },
120
+ ],
121
+ });
122
+ expect(res).toBeDefined();
123
+ expect(res.transactions.length).toBe(1);
124
+ expect(res.transactions[0]?.id).toBe(result.transactionId);
98
125
  });
99
126
 
100
127
  it("should send a extension tx", async () => {
@@ -115,6 +142,33 @@ describe.runIf(
115
142
  expect(tx).toBeDefined();
116
143
  });
117
144
 
145
+ it("should enqueue a batch of txs", async () => {
146
+ const tokenContract = getContract({
147
+ client: TEST_CLIENT,
148
+ chain: baseSepolia,
149
+ address: "0x87C52295891f208459F334975a3beE198fE75244",
150
+ });
151
+ const claimTx1 = mintTo({
152
+ contract: tokenContract,
153
+ to: serverWallet.address,
154
+ amount: "0.001",
155
+ });
156
+ const claimTx2 = mintTo({
157
+ contract: tokenContract,
158
+ to: serverWallet.address,
159
+ amount: "0.002",
160
+ });
161
+ const tx = await serverWallet.enqueueBatchTransaction({
162
+ transactions: [claimTx1, claimTx2],
163
+ });
164
+ expect(tx.transactionId).toBeDefined();
165
+ const txHash = await Engine.waitForTransactionHash({
166
+ client: TEST_CLIENT,
167
+ transactionId: tx.transactionId,
168
+ });
169
+ expect(txHash.transactionHash).toBeDefined();
170
+ });
171
+
118
172
  it("should get revert reason", async () => {
119
173
  const nftContract = getContract({
120
174
  client: TEST_CLIENT,
@@ -19,7 +19,7 @@ import type {
19
19
  Account,
20
20
  SendTransactionOption,
21
21
  } from "../wallets/interfaces/wallet.js";
22
- import { waitForTransactionHash } from "./get-status.js";
22
+ import { waitForTransactionHash } from "./wait-for-tx-hash.js";
23
23
 
24
24
  /**
25
25
  * Options for creating an server wallet.
@@ -54,6 +54,9 @@ export type ServerWallet = Account & {
54
54
  transaction: PreparedTransaction;
55
55
  simulate?: boolean;
56
56
  }) => Promise<{ transactionId: string }>;
57
+ enqueueBatchTransaction: (args: {
58
+ transactions: PreparedTransaction[];
59
+ }) => Promise<{ transactionId: string }>;
57
60
  };
58
61
 
59
62
  /**
@@ -102,6 +105,37 @@ export type ServerWallet = Account & {
102
105
  * console.log("Transaction sent:", transactionHash);
103
106
  * ```
104
107
  *
108
+ * ### Sending a batch of transactions
109
+ * ```ts
110
+ * // prepare the transactions
111
+ * const transaction1 = claimTo({
112
+ * contract,
113
+ * to: firstRecipient,
114
+ * quantity: 1n,
115
+ * });
116
+ * const transaction2 = claimTo({
117
+ * contract,
118
+ * to: secondRecipient,
119
+ * quantity: 1n,
120
+ * });
121
+ *
122
+ *
123
+ * // enqueue the transactions in a batch
124
+ * const { transactionId } = await myServerWallet.enqueueBatchTransaction({
125
+ * transactions: [transaction1, transaction2],
126
+ * });
127
+ * ```
128
+ *
129
+ * ### Polling for the batch of transactions to be submitted onchain
130
+ * ```ts
131
+ * // optionally poll for the transaction to be submitted onchain
132
+ * const { transactionHash } = await Engine.waitForTransactionHash({
133
+ * client,
134
+ * transactionId,
135
+ * });
136
+ * console.log("Transaction sent:", transactionHash);
137
+ * ```
138
+ *
105
139
  * ### Getting the execution status of a transaction
106
140
  * ```ts
107
141
  * const executionResult = await Engine.getTransactionStatus({
@@ -130,16 +164,30 @@ export function serverWallet(options: ServerWalletOptions): ServerWallet {
130
164
  };
131
165
  };
132
166
 
133
- const enqueueTx = async (transaction: SendTransactionOption) => {
167
+ const enqueueTx = async (transaction: SendTransactionOption[]) => {
168
+ if (transaction.length === 0) {
169
+ throw new Error("No transactions to enqueue");
170
+ }
171
+ const firstTransaction = transaction[0];
172
+ if (!firstTransaction) {
173
+ throw new Error("No transactions to enqueue");
174
+ }
175
+ const chainId = firstTransaction.chainId;
176
+ // Validate all transactions are on the same chain
177
+ for (let i = 1; i < transaction.length; i++) {
178
+ if (transaction[i]?.chainId !== chainId) {
179
+ throw new Error(
180
+ `All transactions in batch must be on the same chain. Expected ${chainId}, got ${transaction[i]?.chainId} at index ${i}`,
181
+ );
182
+ }
183
+ }
134
184
  const body = {
135
- executionOptions: getExecutionOptions(transaction.chainId),
136
- params: [
137
- {
138
- to: transaction.to ?? undefined,
139
- data: transaction.data,
140
- value: transaction.value?.toString(),
141
- },
142
- ],
185
+ executionOptions: getExecutionOptions(chainId),
186
+ params: transaction.map((t) => ({
187
+ to: t.to ?? undefined,
188
+ data: t.data,
189
+ value: t.value?.toString(),
190
+ })),
143
191
  };
144
192
 
145
193
  const result = await sendTransaction({
@@ -158,11 +206,7 @@ export function serverWallet(options: ServerWalletOptions): ServerWallet {
158
206
  if (!data) {
159
207
  throw new Error("No data returned from engine");
160
208
  }
161
- const transactionId = data.transactions?.[0]?.id;
162
- if (!transactionId) {
163
- throw new Error("No transactionId returned from engine");
164
- }
165
- return transactionId;
209
+ return data.transactions.map((t) => t.id);
166
210
  };
167
211
 
168
212
  return {
@@ -193,11 +237,54 @@ export function serverWallet(options: ServerWalletOptions): ServerWallet {
193
237
  value: value ?? undefined,
194
238
  };
195
239
  }
196
- const transactionId = await enqueueTx(serializedTransaction);
240
+ const transactionIds = await enqueueTx([serializedTransaction]);
241
+ const transactionId = transactionIds[0];
242
+ if (!transactionId) {
243
+ throw new Error("No transactionId returned from engine");
244
+ }
245
+ return { transactionId };
246
+ },
247
+ enqueueBatchTransaction: async (args: {
248
+ transactions: PreparedTransaction[];
249
+ }) => {
250
+ const serializedTransactions: SendTransactionOption[] = [];
251
+ for (const transaction of args.transactions) {
252
+ const [to, data, value] = await Promise.all([
253
+ transaction.to ? resolvePromisedValue(transaction.to) : null,
254
+ encode(transaction),
255
+ transaction.value ? resolvePromisedValue(transaction.value) : null,
256
+ ]);
257
+ serializedTransactions.push({
258
+ chainId: transaction.chain.id,
259
+ data,
260
+ to: to ?? undefined,
261
+ value: value ?? undefined,
262
+ });
263
+ }
264
+ const transactionIds = await enqueueTx(serializedTransactions);
265
+ const transactionId = transactionIds[0];
266
+ if (!transactionId) {
267
+ throw new Error("No transactionId returned from engine");
268
+ }
197
269
  return { transactionId };
198
270
  },
199
271
  sendTransaction: async (transaction: SendTransactionOption) => {
200
- const transactionId = await enqueueTx(transaction);
272
+ const transactionIds = await enqueueTx([transaction]);
273
+ const transactionId = transactionIds[0];
274
+ if (!transactionId) {
275
+ throw new Error("No transactionId returned from engine");
276
+ }
277
+ return waitForTransactionHash({
278
+ client,
279
+ transactionId,
280
+ });
281
+ },
282
+ sendBatchTransaction: async (transactions: SendTransactionOption[]) => {
283
+ const transactionIds = await enqueueTx(transactions);
284
+ const transactionId = transactionIds[0];
285
+ if (!transactionId) {
286
+ throw new Error("No transactionId returned from engine");
287
+ }
201
288
  return waitForTransactionHash({
202
289
  client,
203
290
  transactionId,
@@ -0,0 +1,75 @@
1
+ import { stringify } from "viem";
2
+
3
+ import type { Hex } from "../utils/encoding/hex.js";
4
+
5
+ import type { ThirdwebClient } from "../client/client.js";
6
+ import type { WaitForReceiptOptions } from "../transaction/actions/wait-for-tx-receipt.js";
7
+ import { getTransactionStatus } from "./get-status.js";
8
+
9
+ /**
10
+ * Wait for a transaction to be submitted onchain and return the transaction hash.
11
+ * @param args - The arguments for the transaction.
12
+ * @param args.client - The thirdweb client to use.
13
+ * @param args.transactionId - The id of the transaction to wait for.
14
+ * @param args.timeoutInSeconds - The timeout in seconds.
15
+ * @engine
16
+ * @example
17
+ * ```ts
18
+ * import { Engine } from "thirdweb";
19
+ *
20
+ * const { transactionHash } = await Engine.waitForTransactionHash({
21
+ * client,
22
+ * transactionId, // the transaction id returned from enqueueTransaction
23
+ * });
24
+ * ```
25
+ */
26
+ export async function waitForTransactionHash(args: {
27
+ client: ThirdwebClient;
28
+ transactionId: string;
29
+ timeoutInSeconds?: number;
30
+ }): Promise<WaitForReceiptOptions> {
31
+ const startTime = Date.now();
32
+ const TIMEOUT_IN_MS = args.timeoutInSeconds
33
+ ? args.timeoutInSeconds * 1000
34
+ : 5 * 60 * 1000; // 5 minutes in milliseconds
35
+
36
+ while (Date.now() - startTime < TIMEOUT_IN_MS) {
37
+ const executionResult = await getTransactionStatus(args);
38
+ const status = executionResult.status;
39
+
40
+ switch (status) {
41
+ case "FAILED": {
42
+ throw new Error(
43
+ `Transaction failed: ${executionResult.error || "Unknown error"}`,
44
+ );
45
+ }
46
+ case "CONFIRMED": {
47
+ const onchainStatus =
48
+ executionResult && "onchainStatus" in executionResult
49
+ ? executionResult.onchainStatus
50
+ : null;
51
+ if (onchainStatus === "REVERTED") {
52
+ const revertData =
53
+ "revertData" in executionResult
54
+ ? executionResult.revertData
55
+ : undefined;
56
+ throw new Error(
57
+ `Transaction reverted: ${revertData?.errorName || "unknown error"} ${revertData?.errorArgs ? stringify(revertData.errorArgs) : ""} - ${executionResult.transactionHash ? executionResult.transactionHash : ""}`,
58
+ );
59
+ }
60
+ return {
61
+ transactionHash: executionResult.transactionHash as Hex,
62
+ client: args.client,
63
+ chain: executionResult.chain,
64
+ };
65
+ }
66
+ default: {
67
+ // wait for the transaction to be confirmed
68
+ await new Promise((resolve) => setTimeout(resolve, 1000));
69
+ }
70
+ }
71
+ }
72
+ throw new Error(
73
+ `Transaction timed out after ${TIMEOUT_IN_MS / 1000} seconds`,
74
+ );
75
+ }
@@ -0,0 +1,25 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { DROP1155_CONTRACT } from "~test/test-contracts.js";
4
+ import { getOwnedNFTs } from "./getOwnedNFTs.js";
5
+
6
+ describe.runIf(process.env.TW_SECRET_KEY)("erc1155.getOwnedNFTs", () => {
7
+ it("with indexer", async () => {
8
+ const nfts = await getOwnedNFTs({
9
+ contract: DROP1155_CONTRACT,
10
+ address: "0x00d4da27dedce60f859471d8f595fdb4ae861557",
11
+ });
12
+ expect(nfts.length).toBe(3);
13
+ expect(nfts.find((nft) => nft.id === 4n)?.quantityOwned).toBe(411n);
14
+ });
15
+
16
+ it("without indexer", async () => {
17
+ const nfts = await getOwnedNFTs({
18
+ contract: DROP1155_CONTRACT,
19
+ address: "0x00d4da27dedce60f859471d8f595fdb4ae861557",
20
+ useIndexer: false,
21
+ });
22
+ expect(nfts.length).toBe(3);
23
+ expect(nfts.find((nft) => nft.id === 4n)?.quantityOwned).toBe(411n);
24
+ });
25
+ });
@@ -11,7 +11,7 @@ import {
11
11
  import { type ThirdwebContract, getContract } from "../../contract/contract.js";
12
12
  import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-confirm-transaction.js";
13
13
  import { resolvePromisedValue } from "../../utils/promise/resolve-promised-value.js";
14
- import { toEther } from "../../utils/units.js";
14
+ import { toEther, toWei } from "../../utils/units.js";
15
15
  import { name } from "../common/read/name.js";
16
16
  import { deployERC20Contract } from "../prebuilts/deploy-erc20.js";
17
17
  import { canClaim } from "./drops/read/canClaim.js";
@@ -20,6 +20,8 @@ import { claimTo } from "./drops/write/claimTo.js";
20
20
  import { resetClaimEligibility } from "./drops/write/resetClaimEligibility.js";
21
21
  import { setClaimConditions } from "./drops/write/setClaimConditions.js";
22
22
  import { getBalance } from "./read/getBalance.js";
23
+ import { getApprovalForTransaction } from "./write/getApprovalForTransaction.js";
24
+ import { mintTo } from "./write/mintTo.js";
23
25
 
24
26
  describe.runIf(process.env.TW_SECRET_KEY)(
25
27
  "DropERC20",
@@ -135,6 +137,94 @@ describe.runIf(process.env.TW_SECRET_KEY)(
135
137
  ).toBe("2");
136
138
  });
137
139
 
140
+ it("should allow to claim tokens with erc20 price", async () => {
141
+ expect(
142
+ (await getBalance({ contract, address: TEST_ACCOUNT_C.address }))
143
+ .displayValue,
144
+ ).toBe("2");
145
+ const erc20ContractAddres = await deployERC20Contract({
146
+ account: TEST_ACCOUNT_A,
147
+ chain: ANVIL_CHAIN,
148
+ client: TEST_CLIENT,
149
+ type: "TokenERC20",
150
+ params: {
151
+ name: "Test DropERC20",
152
+ },
153
+ });
154
+ const erc20Contract = getContract({
155
+ address: erc20ContractAddres,
156
+ chain: ANVIL_CHAIN,
157
+ client: TEST_CLIENT,
158
+ });
159
+ const mintToTx = mintTo({
160
+ contract: erc20Contract,
161
+ to: TEST_ACCOUNT_C.address,
162
+ amount: "0.02",
163
+ });
164
+ await sendAndConfirmTransaction({
165
+ transaction: mintToTx,
166
+ account: TEST_ACCOUNT_A,
167
+ });
168
+ expect(
169
+ (
170
+ await getBalance({
171
+ contract: erc20Contract,
172
+ address: TEST_ACCOUNT_C.address,
173
+ })
174
+ ).displayValue,
175
+ ).toBe("0.02");
176
+ // set cc with price
177
+ await sendAndConfirmTransaction({
178
+ transaction: setClaimConditions({
179
+ contract,
180
+ phases: [
181
+ {
182
+ price: "0.01",
183
+ currencyAddress: erc20ContractAddres,
184
+ },
185
+ ],
186
+ }),
187
+ account: TEST_ACCOUNT_A,
188
+ });
189
+ const claimTx = claimTo({
190
+ contract,
191
+ to: TEST_ACCOUNT_C.address,
192
+ quantity: "2",
193
+ });
194
+ // assert value is set correctly
195
+ const value = await resolvePromisedValue(claimTx.erc20Value);
196
+ expect(value).toBeDefined();
197
+ if (!value) throw new Error("value is undefined");
198
+ expect(value.amountWei).toBe(toWei("0.02"));
199
+ const approve = await getApprovalForTransaction({
200
+ transaction: claimTx,
201
+ account: TEST_ACCOUNT_C,
202
+ });
203
+ if (approve) {
204
+ await sendAndConfirmTransaction({
205
+ transaction: approve,
206
+ account: TEST_ACCOUNT_C,
207
+ });
208
+ }
209
+ // claim
210
+ await sendAndConfirmTransaction({
211
+ transaction: claimTx,
212
+ account: TEST_ACCOUNT_C,
213
+ });
214
+ expect(
215
+ (await getBalance({ contract, address: TEST_ACCOUNT_C.address }))
216
+ .displayValue,
217
+ ).toBe("4");
218
+ expect(
219
+ (
220
+ await getBalance({
221
+ contract: erc20Contract,
222
+ address: TEST_ACCOUNT_C.address,
223
+ })
224
+ ).displayValue,
225
+ ).toBe("0");
226
+ });
227
+
138
228
  describe("Allowlists", () => {
139
229
  it("should allow to claim tokens with an allowlist", async () => {
140
230
  await sendAndConfirmTransaction({
@@ -319,7 +319,12 @@ async function transformNFTModel(
319
319
  });
320
320
  }
321
321
 
322
- return parsedNft;
322
+ return {
323
+ ...parsedNft,
324
+ ...(contract?.type === "erc1155"
325
+ ? { quantityOwned: balance ? BigInt(balance) : undefined }
326
+ : {}),
327
+ };
323
328
  }),
324
329
  );
325
330
  }
@@ -127,6 +127,7 @@ const THIRDWEB_DOMAINS = [
127
127
  // dev domains
128
128
  ".thirdweb.dev",
129
129
  ".thirdweb-dev.com",
130
+ ".thirdwebstorage-dev.com",
130
131
  ] as const;
131
132
 
132
133
  export const IS_THIRDWEB_URL_CACHE = new LruMap<boolean>(4096);
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.101.2";
1
+ export const version = "5.102.0";