@@ -5,22 +5,28 @@ import { VITALIK_WALLET } from "../../../test/src/addresses.js";
5
5
import { ANVIL_CHAIN } from "../../../test/src/chains.js" ;
6
6
import { TEST_CLIENT } from "../../../test/src/test-clients.js" ;
7
7
import {
8
- TEST_ACCOUNT_A ,
9
8
TEST_ACCOUNT_B ,
9
+ TEST_ACCOUNT_C ,
10
10
TEST_ACCOUNT_D ,
11
11
} from "../../../test/src/test-wallets.js" ;
12
+ import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js" ;
12
13
import { resolveContractAbi } from "../../contract/actions/resolve-abi.js" ;
13
14
import { type ThirdwebContract , getContract } from "../../contract/contract.js" ;
14
15
import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-confirm-transaction.js" ;
15
16
import { resolvePromisedValue } from "../../utils/promise/resolve-promised-value.js" ;
16
17
import { toEther } from "../../utils/units.js" ;
18
+ import { generateMerkleTreeInfoERC1155 } from "../airdrop/write/merkleInfoERC1155.js" ;
19
+ import { deployERC20Contract } from "../prebuilts/deploy-erc20.js" ;
17
20
import { deployERC1155Contract } from "../prebuilts/deploy-erc1155.js" ;
18
21
import { balanceOf } from "./__generated__/IERC1155/read/balanceOf.js" ;
22
+ import { totalSupply } from "./__generated__/IERC1155/read/totalSupply.js" ;
19
23
import { nextTokenIdToMint } from "./__generated__/IERC1155Enumerable/read/nextTokenIdToMint.js" ;
24
+ import { getActiveClaimCondition } from "./drops/read/getActiveClaimCondition.js" ;
20
25
import { getClaimConditions } from "./drops/read/getClaimConditions.js" ;
21
26
import { claimTo } from "./drops/write/claimTo.js" ;
22
27
import { resetClaimEligibility } from "./drops/write/resetClaimEligibility.js" ;
23
28
import { setClaimConditions } from "./drops/write/setClaimConditions.js" ;
29
+ import { updateMetadata } from "./drops/write/updateMetadata.js" ;
24
30
import { getNFT } from "./read/getNFT.js" ;
25
31
import { isGetNFTsSupported } from "./read/getNFTs.js" ;
26
32
import { lazyMint } from "./write/lazyMint.js" ;
@@ -35,7 +41,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
35
41
36
42
beforeAll ( async ( ) => {
37
43
const contractAddress = await deployERC1155Contract ( {
38
- account : TEST_ACCOUNT_A ,
44
+ account : TEST_ACCOUNT_C ,
39
45
chain : ANVIL_CHAIN ,
40
46
client : TEST_CLIENT ,
41
47
params : {
@@ -67,7 +73,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
67
73
} ) ;
68
74
await sendAndConfirmTransaction ( {
69
75
transaction : mintTx ,
70
- account : TEST_ACCOUNT_A ,
76
+ account : TEST_ACCOUNT_C ,
71
77
} ) ;
72
78
73
79
await expect ( nextTokenIdToMint ( { contract } ) ) . resolves . toBe ( 6n ) ;
@@ -87,36 +93,50 @@ describe.runIf(process.env.TW_SECRET_KEY)(
87
93
` ) ;
88
94
} ) ;
89
95
96
+ it ( "should update metadata" , async ( ) => {
97
+ const updateTx = updateMetadata ( {
98
+ contract,
99
+ targetTokenId : 0n ,
100
+ newMetadata : { name : "Test NFT 1" } ,
101
+ } ) ;
102
+ await sendAndConfirmTransaction ( {
103
+ transaction : updateTx ,
104
+ account : TEST_ACCOUNT_C ,
105
+ } ) ;
106
+ const token0 = await getNFT ( { contract, tokenId : 0n } ) ;
107
+ expect ( token0 . metadata . name ) . toBe ( "Test NFT 1" ) ;
108
+ } ) ;
109
+
90
110
it ( "should allow to claim tokens" , async ( ) => {
91
111
await expect (
92
- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId : 0n } ) ,
112
+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId : 0n } ) ,
93
113
) . resolves . toBe ( 0n ) ;
94
114
await sendAndConfirmTransaction ( {
95
115
transaction : setClaimConditions ( {
96
116
contract,
97
117
phases : [ { } ] ,
98
118
tokenId : 0n ,
99
119
} ) ,
100
- account : TEST_ACCOUNT_A ,
120
+ account : TEST_ACCOUNT_C ,
101
121
} ) ;
102
122
const claimTx = claimTo ( {
103
123
contract,
104
- to : TEST_ACCOUNT_A . address ,
124
+ to : TEST_ACCOUNT_C . address ,
105
125
tokenId : 0n ,
106
126
quantity : 1n ,
107
127
} ) ;
108
128
await sendAndConfirmTransaction ( {
109
129
transaction : claimTx ,
110
- account : TEST_ACCOUNT_A ,
130
+ account : TEST_ACCOUNT_C ,
111
131
} ) ;
112
132
await expect (
113
- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId : 0n } ) ,
133
+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId : 0n } ) ,
114
134
) . resolves . toBe ( 1n ) ;
115
135
} ) ;
116
136
117
137
it ( "should allow to claim tokens with price" , async ( ) => {
118
138
await expect (
119
- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId : 0n } ) ,
139
+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId : 0n } ) ,
120
140
) . resolves . toBe ( 1n ) ;
121
141
await sendAndConfirmTransaction ( {
122
142
transaction : setClaimConditions ( {
@@ -128,11 +148,11 @@ describe.runIf(process.env.TW_SECRET_KEY)(
128
148
] ,
129
149
tokenId : 0n ,
130
150
} ) ,
131
- account : TEST_ACCOUNT_A ,
151
+ account : TEST_ACCOUNT_C ,
132
152
} ) ;
133
153
const claimTx = claimTo ( {
134
154
contract,
135
- to : TEST_ACCOUNT_A . address ,
155
+ to : TEST_ACCOUNT_C . address ,
136
156
tokenId : 0n ,
137
157
quantity : 1n ,
138
158
} ) ;
@@ -143,10 +163,10 @@ describe.runIf(process.env.TW_SECRET_KEY)(
143
163
expect ( toEther ( value ) ) . toBe ( "0.001" ) ;
144
164
await sendAndConfirmTransaction ( {
145
165
transaction : claimTx ,
146
- account : TEST_ACCOUNT_A ,
166
+ account : TEST_ACCOUNT_C ,
147
167
} ) ;
148
168
await expect (
149
- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId : 0n } ) ,
169
+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId : 0n } ) ,
150
170
) . resolves . toBe ( 2n ) ;
151
171
} ) ;
152
172
@@ -159,26 +179,26 @@ describe.runIf(process.env.TW_SECRET_KEY)(
159
179
phases : [
160
180
{
161
181
overrideList : [
162
- { address : TEST_ACCOUNT_A . address , maxClaimable : "100" } ,
182
+ { address : TEST_ACCOUNT_C . address , maxClaimable : "100" } ,
163
183
{ address : VITALIK_WALLET , maxClaimable : "100" } ,
164
184
] ,
165
185
maxClaimablePerWallet : 0n ,
166
186
} ,
167
187
] ,
168
188
tokenId,
169
189
} ) ,
170
- account : TEST_ACCOUNT_A ,
190
+ account : TEST_ACCOUNT_C ,
171
191
} ) ;
172
192
173
193
await expect (
174
194
balanceOf ( { contract, owner : TEST_ACCOUNT_B . address , tokenId } ) ,
175
195
) . resolves . toBe ( 0n ) ;
176
196
177
197
await sendAndConfirmTransaction ( {
178
- account : TEST_ACCOUNT_A ,
198
+ account : TEST_ACCOUNT_C ,
179
199
transaction : claimTo ( {
180
200
contract,
181
- from : TEST_ACCOUNT_A . address ,
201
+ from : TEST_ACCOUNT_C . address ,
182
202
to : TEST_ACCOUNT_B . address ,
183
203
tokenId,
184
204
quantity : 1n ,
@@ -215,27 +235,27 @@ describe.runIf(process.env.TW_SECRET_KEY)(
215
235
phases : [
216
236
{
217
237
overrideList : [
218
- { address : TEST_ACCOUNT_A . address , maxClaimable : "1" } ,
238
+ { address : TEST_ACCOUNT_C . address , maxClaimable : "1" } ,
219
239
{ address : VITALIK_WALLET , maxClaimable : "3" } ,
220
240
] ,
221
241
maxClaimablePerWallet : 0n ,
222
242
} ,
223
243
] ,
224
244
tokenId,
225
245
} ) ,
226
- account : TEST_ACCOUNT_A ,
246
+ account : TEST_ACCOUNT_C ,
227
247
} ) ;
228
248
229
249
await expect (
230
- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId } ) ,
250
+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId } ) ,
231
251
) . resolves . toBe ( 0n ) ;
232
252
233
253
await expect (
234
254
sendAndConfirmTransaction ( {
235
- account : TEST_ACCOUNT_A ,
255
+ account : TEST_ACCOUNT_C ,
236
256
transaction : claimTo ( {
237
257
contract,
238
- to : TEST_ACCOUNT_A . address ,
258
+ to : TEST_ACCOUNT_C . address ,
239
259
tokenId,
240
260
quantity : 2n ,
241
261
} ) ,
@@ -248,17 +268,17 @@ describe.runIf(process.env.TW_SECRET_KEY)(
248
268
` ) ;
249
269
250
270
await sendAndConfirmTransaction ( {
251
- account : TEST_ACCOUNT_A ,
271
+ account : TEST_ACCOUNT_C ,
252
272
transaction : claimTo ( {
253
273
contract,
254
- to : TEST_ACCOUNT_A . address ,
274
+ to : TEST_ACCOUNT_C . address ,
255
275
tokenId,
256
276
quantity : 1n ,
257
277
} ) ,
258
278
} ) ;
259
279
260
280
await expect (
261
- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId } ) ,
281
+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId } ) ,
262
282
) . resolves . toBe ( 1n ) ;
263
283
} ) ;
264
284
} ) ;
@@ -272,7 +292,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
272
292
{
273
293
overrideList : [
274
294
{
275
- address : TEST_ACCOUNT_A . address ,
295
+ address : TEST_ACCOUNT_C . address ,
276
296
maxClaimable : "10" ,
277
297
price : "0" ,
278
298
} ,
@@ -283,25 +303,25 @@ describe.runIf(process.env.TW_SECRET_KEY)(
283
303
] ,
284
304
tokenId,
285
305
} ) ,
286
- account : TEST_ACCOUNT_A ,
306
+ account : TEST_ACCOUNT_C ,
287
307
} ) ;
288
308
289
309
await expect (
290
- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId } ) ,
310
+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId } ) ,
291
311
) . resolves . toBe ( 0n ) ;
292
312
293
313
await sendAndConfirmTransaction ( {
294
- account : TEST_ACCOUNT_A ,
314
+ account : TEST_ACCOUNT_C ,
295
315
transaction : claimTo ( {
296
316
contract,
297
- to : TEST_ACCOUNT_A . address ,
317
+ to : TEST_ACCOUNT_C . address ,
298
318
tokenId,
299
319
quantity : 1n ,
300
320
} ) ,
301
321
} ) ;
302
322
303
323
await expect (
304
- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId } ) ,
324
+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId } ) ,
305
325
) . resolves . toBe ( 1n ) ;
306
326
} ) ;
307
327
@@ -321,7 +341,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
321
341
} ,
322
342
] ,
323
343
} ) ,
324
- account : TEST_ACCOUNT_A ,
344
+ account : TEST_ACCOUNT_C ,
325
345
} ) ;
326
346
327
347
const phases = await getClaimConditions ( { contract, tokenId : 5n } ) ;
@@ -342,7 +362,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
342
362
} ,
343
363
] ,
344
364
} ) ,
345
- account : TEST_ACCOUNT_A ,
365
+ account : TEST_ACCOUNT_C ,
346
366
} ) ;
347
367
// claim one token
348
368
await sendAndConfirmTransaction ( {
@@ -384,7 +404,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
384
404
tokenId : 6n ,
385
405
contract,
386
406
} ) ,
387
- account : TEST_ACCOUNT_A ,
407
+ account : TEST_ACCOUNT_C ,
388
408
} ) ;
389
409
// attempt to claim another token (this should succeed)
390
410
await sendAndConfirmTransaction ( {
@@ -409,5 +429,115 @@ describe.runIf(process.env.TW_SECRET_KEY)(
409
429
. map ( ( f ) => toFunctionSelector ( f ) ) ;
410
430
expect ( isGetNFTsSupported ( selectors ) ) . toBe ( true ) ;
411
431
} ) ;
432
+
433
+ /**
434
+ * This is to document the behavior where one can claim without paying if the claiming address
435
+ * is the same as the PrimaryRecipientAddress, because of this Solidity code:
436
+ * ```solidity
437
+ * // CurrencyTransferLib.sol
438
+ * function safeTransferERC20(address _currency, address _from, address _to, uint256 _amount) internal {
439
+ * if (_from == _to) {
440
+ * return;
441
+ * }
442
+ * ...
443
+ * }
444
+ * ```
445
+ */
446
+ it ( "address that is the same with PrimaryFeeRecipient can claim without paying ERC20" , async ( ) => {
447
+ const tokenAddress = await deployERC20Contract ( {
448
+ client : TEST_CLIENT ,
449
+ chain : ANVIL_CHAIN ,
450
+ account : TEST_ACCOUNT_C ,
451
+ type : "TokenERC20" ,
452
+ params : {
453
+ name : "token20" ,
454
+ contractURI : TEST_CONTRACT_URI ,
455
+ } ,
456
+ } ) ;
457
+ const tokenId = 5n ;
458
+ const setClaimTx = setClaimConditions ( {
459
+ contract,
460
+ tokenId,
461
+ phases : [
462
+ {
463
+ maxClaimableSupply : 100n ,
464
+ maxClaimablePerWallet : 100n ,
465
+ currencyAddress : tokenAddress ,
466
+ price : 1000 ,
467
+ startTime : new Date ( ) ,
468
+ } ,
469
+ ] ,
470
+ } ) ;
471
+ await sendAndConfirmTransaction ( {
472
+ transaction : setClaimTx ,
473
+ account : TEST_ACCOUNT_C ,
474
+ } ) ;
475
+
476
+ const transaction = claimTo ( {
477
+ contract,
478
+ tokenId,
479
+ quantity : 50n ,
480
+ to : TEST_ACCOUNT_C . address ,
481
+ } ) ;
482
+ await sendAndConfirmTransaction ( {
483
+ transaction,
484
+ account : TEST_ACCOUNT_C ,
485
+ } ) ;
486
+ const supplyCount = await totalSupply ( { contract, id : tokenId } ) ;
487
+ expect ( supplyCount ) . toBe ( 50n ) ;
488
+ } ) ;
489
+
490
+ it ( "getActiveClaimCondition should work" , async ( ) => {
491
+ // Create a public allowlist claim phase
492
+ const snapshot = [
493
+ {
494
+ recipient : TEST_ACCOUNT_B . address ,
495
+ tokenId : 4 ,
496
+ amount : 5 ,
497
+ } ,
498
+ {
499
+ recipient : TEST_ACCOUNT_D . address ,
500
+ tokenId : 4 ,
501
+ amount : 5 ,
502
+ } ,
503
+ ] ;
504
+
505
+ const { merkleRoot } = await generateMerkleTreeInfoERC1155 ( {
506
+ contract,
507
+ tokenAddress : NATIVE_TOKEN_ADDRESS ,
508
+ snapshot,
509
+ } ) ;
510
+
511
+ const startTime = new Date ( ) ;
512
+ const setCC = setClaimConditions ( {
513
+ contract,
514
+ tokenId : 4n ,
515
+ phases : [
516
+ {
517
+ maxClaimableSupply : 100n ,
518
+ maxClaimablePerWallet : 5n ,
519
+ currencyAddress : NATIVE_TOKEN_ADDRESS ,
520
+ price : 0.006 ,
521
+ startTime,
522
+ merkleRootHash : merkleRoot ,
523
+ } ,
524
+ ] ,
525
+ } ) ;
526
+
527
+ await sendAndConfirmTransaction ( {
528
+ transaction : setCC ,
529
+ account : TEST_ACCOUNT_C ,
530
+ } ) ;
531
+
532
+ const activeCC = await getActiveClaimCondition ( { contract, tokenId : 4n } ) ;
533
+ expect ( activeCC . currency . toLowerCase ( ) ) . toBe (
534
+ NATIVE_TOKEN_ADDRESS . toLowerCase ( ) ,
535
+ ) ;
536
+ expect ( activeCC . merkleRoot ) . toBe (
537
+ "0x5baa4423af7125448ad7ca6913cdee7dd952a8d10a44f4fad4c50eea65c5c92d" ,
538
+ ) ;
539
+ expect ( activeCC . pricePerToken ) . toBe ( 6000000000000000n ) ;
540
+ expect ( activeCC . quantityLimitPerWallet ) . toBe ( 5n ) ;
541
+ } ) ;
412
542
} ,
413
543
) ;
0 commit comments