@@ -5,22 +5,28 @@ import { VITALIK_WALLET } from "../../../test/src/addresses.js";
55import { ANVIL_CHAIN } from "../../../test/src/chains.js" ;
66import { TEST_CLIENT } from "../../../test/src/test-clients.js" ;
77import {
8- TEST_ACCOUNT_A ,
98 TEST_ACCOUNT_B ,
9+ TEST_ACCOUNT_C ,
1010 TEST_ACCOUNT_D ,
1111} from "../../../test/src/test-wallets.js" ;
12+ import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js" ;
1213import { resolveContractAbi } from "../../contract/actions/resolve-abi.js" ;
1314import { type ThirdwebContract , getContract } from "../../contract/contract.js" ;
1415import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-confirm-transaction.js" ;
1516import { resolvePromisedValue } from "../../utils/promise/resolve-promised-value.js" ;
1617import { toEther } from "../../utils/units.js" ;
18+ import { generateMerkleTreeInfoERC1155 } from "../airdrop/write/merkleInfoERC1155.js" ;
19+ import { deployERC20Contract } from "../prebuilts/deploy-erc20.js" ;
1720import { deployERC1155Contract } from "../prebuilts/deploy-erc1155.js" ;
1821import { balanceOf } from "./__generated__/IERC1155/read/balanceOf.js" ;
22+ import { totalSupply } from "./__generated__/IERC1155/read/totalSupply.js" ;
1923import { nextTokenIdToMint } from "./__generated__/IERC1155Enumerable/read/nextTokenIdToMint.js" ;
24+ import { getActiveClaimCondition } from "./drops/read/getActiveClaimCondition.js" ;
2025import { getClaimConditions } from "./drops/read/getClaimConditions.js" ;
2126import { claimTo } from "./drops/write/claimTo.js" ;
2227import { resetClaimEligibility } from "./drops/write/resetClaimEligibility.js" ;
2328import { setClaimConditions } from "./drops/write/setClaimConditions.js" ;
29+ import { updateMetadata } from "./drops/write/updateMetadata.js" ;
2430import { getNFT } from "./read/getNFT.js" ;
2531import { isGetNFTsSupported } from "./read/getNFTs.js" ;
2632import { lazyMint } from "./write/lazyMint.js" ;
@@ -35,7 +41,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
3541
3642 beforeAll ( async ( ) => {
3743 const contractAddress = await deployERC1155Contract ( {
38- account : TEST_ACCOUNT_A ,
44+ account : TEST_ACCOUNT_C ,
3945 chain : ANVIL_CHAIN ,
4046 client : TEST_CLIENT ,
4147 params : {
@@ -67,7 +73,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
6773 } ) ;
6874 await sendAndConfirmTransaction ( {
6975 transaction : mintTx ,
70- account : TEST_ACCOUNT_A ,
76+ account : TEST_ACCOUNT_C ,
7177 } ) ;
7278
7379 await expect ( nextTokenIdToMint ( { contract } ) ) . resolves . toBe ( 6n ) ;
@@ -87,36 +93,50 @@ describe.runIf(process.env.TW_SECRET_KEY)(
8793 ` ) ;
8894 } ) ;
8995
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+
90110 it ( "should allow to claim tokens" , async ( ) => {
91111 await expect (
92- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId : 0n } ) ,
112+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId : 0n } ) ,
93113 ) . resolves . toBe ( 0n ) ;
94114 await sendAndConfirmTransaction ( {
95115 transaction : setClaimConditions ( {
96116 contract,
97117 phases : [ { } ] ,
98118 tokenId : 0n ,
99119 } ) ,
100- account : TEST_ACCOUNT_A ,
120+ account : TEST_ACCOUNT_C ,
101121 } ) ;
102122 const claimTx = claimTo ( {
103123 contract,
104- to : TEST_ACCOUNT_A . address ,
124+ to : TEST_ACCOUNT_C . address ,
105125 tokenId : 0n ,
106126 quantity : 1n ,
107127 } ) ;
108128 await sendAndConfirmTransaction ( {
109129 transaction : claimTx ,
110- account : TEST_ACCOUNT_A ,
130+ account : TEST_ACCOUNT_C ,
111131 } ) ;
112132 await expect (
113- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId : 0n } ) ,
133+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId : 0n } ) ,
114134 ) . resolves . toBe ( 1n ) ;
115135 } ) ;
116136
117137 it ( "should allow to claim tokens with price" , async ( ) => {
118138 await expect (
119- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId : 0n } ) ,
139+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId : 0n } ) ,
120140 ) . resolves . toBe ( 1n ) ;
121141 await sendAndConfirmTransaction ( {
122142 transaction : setClaimConditions ( {
@@ -128,11 +148,11 @@ describe.runIf(process.env.TW_SECRET_KEY)(
128148 ] ,
129149 tokenId : 0n ,
130150 } ) ,
131- account : TEST_ACCOUNT_A ,
151+ account : TEST_ACCOUNT_C ,
132152 } ) ;
133153 const claimTx = claimTo ( {
134154 contract,
135- to : TEST_ACCOUNT_A . address ,
155+ to : TEST_ACCOUNT_C . address ,
136156 tokenId : 0n ,
137157 quantity : 1n ,
138158 } ) ;
@@ -143,10 +163,10 @@ describe.runIf(process.env.TW_SECRET_KEY)(
143163 expect ( toEther ( value ) ) . toBe ( "0.001" ) ;
144164 await sendAndConfirmTransaction ( {
145165 transaction : claimTx ,
146- account : TEST_ACCOUNT_A ,
166+ account : TEST_ACCOUNT_C ,
147167 } ) ;
148168 await expect (
149- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId : 0n } ) ,
169+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId : 0n } ) ,
150170 ) . resolves . toBe ( 2n ) ;
151171 } ) ;
152172
@@ -159,26 +179,26 @@ describe.runIf(process.env.TW_SECRET_KEY)(
159179 phases : [
160180 {
161181 overrideList : [
162- { address : TEST_ACCOUNT_A . address , maxClaimable : "100" } ,
182+ { address : TEST_ACCOUNT_C . address , maxClaimable : "100" } ,
163183 { address : VITALIK_WALLET , maxClaimable : "100" } ,
164184 ] ,
165185 maxClaimablePerWallet : 0n ,
166186 } ,
167187 ] ,
168188 tokenId,
169189 } ) ,
170- account : TEST_ACCOUNT_A ,
190+ account : TEST_ACCOUNT_C ,
171191 } ) ;
172192
173193 await expect (
174194 balanceOf ( { contract, owner : TEST_ACCOUNT_B . address , tokenId } ) ,
175195 ) . resolves . toBe ( 0n ) ;
176196
177197 await sendAndConfirmTransaction ( {
178- account : TEST_ACCOUNT_A ,
198+ account : TEST_ACCOUNT_C ,
179199 transaction : claimTo ( {
180200 contract,
181- from : TEST_ACCOUNT_A . address ,
201+ from : TEST_ACCOUNT_C . address ,
182202 to : TEST_ACCOUNT_B . address ,
183203 tokenId,
184204 quantity : 1n ,
@@ -215,27 +235,27 @@ describe.runIf(process.env.TW_SECRET_KEY)(
215235 phases : [
216236 {
217237 overrideList : [
218- { address : TEST_ACCOUNT_A . address , maxClaimable : "1" } ,
238+ { address : TEST_ACCOUNT_C . address , maxClaimable : "1" } ,
219239 { address : VITALIK_WALLET , maxClaimable : "3" } ,
220240 ] ,
221241 maxClaimablePerWallet : 0n ,
222242 } ,
223243 ] ,
224244 tokenId,
225245 } ) ,
226- account : TEST_ACCOUNT_A ,
246+ account : TEST_ACCOUNT_C ,
227247 } ) ;
228248
229249 await expect (
230- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId } ) ,
250+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId } ) ,
231251 ) . resolves . toBe ( 0n ) ;
232252
233253 await expect (
234254 sendAndConfirmTransaction ( {
235- account : TEST_ACCOUNT_A ,
255+ account : TEST_ACCOUNT_C ,
236256 transaction : claimTo ( {
237257 contract,
238- to : TEST_ACCOUNT_A . address ,
258+ to : TEST_ACCOUNT_C . address ,
239259 tokenId,
240260 quantity : 2n ,
241261 } ) ,
@@ -248,17 +268,17 @@ describe.runIf(process.env.TW_SECRET_KEY)(
248268 ` ) ;
249269
250270 await sendAndConfirmTransaction ( {
251- account : TEST_ACCOUNT_A ,
271+ account : TEST_ACCOUNT_C ,
252272 transaction : claimTo ( {
253273 contract,
254- to : TEST_ACCOUNT_A . address ,
274+ to : TEST_ACCOUNT_C . address ,
255275 tokenId,
256276 quantity : 1n ,
257277 } ) ,
258278 } ) ;
259279
260280 await expect (
261- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId } ) ,
281+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId } ) ,
262282 ) . resolves . toBe ( 1n ) ;
263283 } ) ;
264284 } ) ;
@@ -272,7 +292,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
272292 {
273293 overrideList : [
274294 {
275- address : TEST_ACCOUNT_A . address ,
295+ address : TEST_ACCOUNT_C . address ,
276296 maxClaimable : "10" ,
277297 price : "0" ,
278298 } ,
@@ -283,25 +303,25 @@ describe.runIf(process.env.TW_SECRET_KEY)(
283303 ] ,
284304 tokenId,
285305 } ) ,
286- account : TEST_ACCOUNT_A ,
306+ account : TEST_ACCOUNT_C ,
287307 } ) ;
288308
289309 await expect (
290- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId } ) ,
310+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId } ) ,
291311 ) . resolves . toBe ( 0n ) ;
292312
293313 await sendAndConfirmTransaction ( {
294- account : TEST_ACCOUNT_A ,
314+ account : TEST_ACCOUNT_C ,
295315 transaction : claimTo ( {
296316 contract,
297- to : TEST_ACCOUNT_A . address ,
317+ to : TEST_ACCOUNT_C . address ,
298318 tokenId,
299319 quantity : 1n ,
300320 } ) ,
301321 } ) ;
302322
303323 await expect (
304- balanceOf ( { contract, owner : TEST_ACCOUNT_A . address , tokenId } ) ,
324+ balanceOf ( { contract, owner : TEST_ACCOUNT_C . address , tokenId } ) ,
305325 ) . resolves . toBe ( 1n ) ;
306326 } ) ;
307327
@@ -321,7 +341,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
321341 } ,
322342 ] ,
323343 } ) ,
324- account : TEST_ACCOUNT_A ,
344+ account : TEST_ACCOUNT_C ,
325345 } ) ;
326346
327347 const phases = await getClaimConditions ( { contract, tokenId : 5n } ) ;
@@ -342,7 +362,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
342362 } ,
343363 ] ,
344364 } ) ,
345- account : TEST_ACCOUNT_A ,
365+ account : TEST_ACCOUNT_C ,
346366 } ) ;
347367 // claim one token
348368 await sendAndConfirmTransaction ( {
@@ -384,7 +404,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
384404 tokenId : 6n ,
385405 contract,
386406 } ) ,
387- account : TEST_ACCOUNT_A ,
407+ account : TEST_ACCOUNT_C ,
388408 } ) ;
389409 // attempt to claim another token (this should succeed)
390410 await sendAndConfirmTransaction ( {
@@ -409,5 +429,115 @@ describe.runIf(process.env.TW_SECRET_KEY)(
409429 . map ( ( f ) => toFunctionSelector ( f ) ) ;
410430 expect ( isGetNFTsSupported ( selectors ) ) . toBe ( true ) ;
411431 } ) ;
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+ } ) ;
412542 } ,
413543) ;
0 commit comments