thirdweb 5.57.0 → 5.57.1
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/client/client.js +19 -15
- package/dist/cjs/client/client.js.map +1 -1
- package/dist/cjs/extensions/erc1155/drops/write/updateMetadata.js +2 -2
- package/dist/cjs/extensions/erc1155/drops/write/updateMetadata.js.map +1 -1
- package/dist/cjs/extensions/erc721/drops/write/updateMetadata.js +2 -2
- package/dist/cjs/extensions/erc721/drops/write/updateMetadata.js.map +1 -1
- package/dist/cjs/utils/fetch.js +4 -11
- package/dist/cjs/utils/fetch.js.map +1 -1
- package/dist/cjs/utils/jwt/is-jwt.js +7 -0
- package/dist/cjs/utils/jwt/is-jwt.js.map +1 -0
- package/dist/cjs/version.js +1 -1
- package/dist/esm/client/client.js +19 -15
- package/dist/esm/client/client.js.map +1 -1
- package/dist/esm/extensions/erc1155/drops/write/updateMetadata.js +2 -2
- package/dist/esm/extensions/erc1155/drops/write/updateMetadata.js.map +1 -1
- package/dist/esm/extensions/erc721/drops/write/updateMetadata.js +2 -2
- package/dist/esm/extensions/erc721/drops/write/updateMetadata.js.map +1 -1
- package/dist/esm/utils/fetch.js +4 -11
- package/dist/esm/utils/fetch.js.map +1 -1
- package/dist/esm/utils/jwt/is-jwt.js +4 -0
- package/dist/esm/utils/jwt/is-jwt.js.map +1 -0
- package/dist/esm/version.js +1 -1
- package/dist/types/client/client.d.ts +2 -2
- package/dist/types/client/client.d.ts.map +1 -1
- package/dist/types/extensions/erc1155/drops/write/updateMetadata.d.ts +1 -3
- package/dist/types/extensions/erc1155/drops/write/updateMetadata.d.ts.map +1 -1
- package/dist/types/extensions/erc721/drops/write/updateMetadata.d.ts +0 -2
- package/dist/types/extensions/erc721/drops/write/updateMetadata.d.ts.map +1 -1
- package/dist/types/utils/fetch.d.ts.map +1 -1
- package/dist/types/utils/jwt/is-jwt.d.ts +3 -0
- package/dist/types/utils/jwt/is-jwt.d.ts.map +1 -0
- package/dist/types/utils/jwt/types.d.ts +1 -0
- package/dist/types/utils/jwt/types.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +11 -11
- package/src/client/client.test.ts +17 -2
- package/src/client/client.ts +23 -17
- package/src/extensions/erc1155/drops/write/updateMetadata.test.ts +0 -1
- package/src/extensions/erc1155/drops/write/updateMetadata.ts +4 -7
- package/src/extensions/erc721/drops/write/updateMetadata.test.ts +0 -2
- package/src/extensions/erc721/drops/write/updateMetadata.ts +2 -4
- package/src/extensions/marketplace/direct-listings/direct-listings.test.ts +317 -394
- package/src/utils/fetch.test.ts +20 -0
- package/src/utils/fetch.ts +6 -14
- package/src/utils/jwt/is-jwt.ts +5 -0
- package/src/utils/jwt/types.ts +2 -0
- package/src/version.ts +1 -1
@@ -1,25 +1,21 @@
|
|
1
|
-
import {
|
1
|
+
import { describe, expect, it } from "vitest";
|
2
|
+
import { TEST_CONTRACT_URI } from "~test/ipfs-uris.js";
|
2
3
|
import { ANVIL_CHAIN } from "../../../../test/src/chains.js";
|
3
4
|
import { TEST_CLIENT } from "../../../../test/src/test-clients.js";
|
4
5
|
import {
|
5
6
|
TEST_ACCOUNT_A,
|
6
7
|
TEST_ACCOUNT_B,
|
8
|
+
TEST_ACCOUNT_C,
|
7
9
|
} from "../../../../test/src/test-wallets.js";
|
8
|
-
import {
|
9
|
-
type ThirdwebContract,
|
10
|
-
getContract,
|
11
|
-
} from "../../../contract/contract.js";
|
10
|
+
import { getContract } from "../../../contract/contract.js";
|
12
11
|
import { parseEventLogs } from "../../../event/actions/parse-logs.js";
|
12
|
+
import { setApprovalForAll as setApprovalForAll721 } from "../../../extensions/erc721/__generated__/IERC721A/write/setApprovalForAll.js";
|
13
|
+
import { mintTo as mintToErc1155 } from "../../../extensions/erc1155/write/mintTo.js";
|
13
14
|
import { sendAndConfirmTransaction } from "../../../transaction/actions/send-and-confirm-transaction.js";
|
14
15
|
import { balanceOf as balanceOfErc721 } from "../../erc721/__generated__/IERC721A/read/balanceOf.js";
|
15
|
-
import { approve as approveErc721 } from "../../erc721/__generated__/IERC721A/write/approve.js";
|
16
|
-
import { tokensMintedEvent as tokensMintedEventErc721 } from "../../erc721/__generated__/IMintableERC721/events/TokensMinted.js";
|
17
16
|
import { mintTo as mintToErc721 } from "../../erc721/write/mintTo.js";
|
18
17
|
import { balanceOf as balanceOfErc1155 } from "../../erc1155/__generated__/IERC1155/read/balanceOf.js";
|
19
|
-
import { setApprovalForAll } from "../../erc1155/__generated__/IERC1155/write/setApprovalForAll.js";
|
20
|
-
import { claimTo } from "../../erc1155/drops/write/claimTo.js";
|
21
|
-
import { setClaimConditions } from "../../erc1155/drops/write/setClaimConditions.js";
|
22
|
-
import { lazyMint } from "../../erc1155/write/lazyMint.js";
|
18
|
+
import { setApprovalForAll as setApprovalForAll1155 } from "../../erc1155/__generated__/IERC1155/write/setApprovalForAll.js";
|
23
19
|
import { deployERC721Contract } from "../../prebuilts/deploy-erc721.js";
|
24
20
|
import { deployERC1155Contract } from "../../prebuilts/deploy-erc1155.js";
|
25
21
|
import { deployMarketplaceContract } from "../../prebuilts/deploy-marketplace.js";
|
@@ -32,434 +28,361 @@ import { isListingValid } from "./utils.js";
|
|
32
28
|
import { buyFromListing } from "./write/buyFromListing.js";
|
33
29
|
import { createListing } from "./write/createListing.js";
|
34
30
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
}
|
31
|
+
const chain = ANVIL_CHAIN;
|
32
|
+
const client = TEST_CLIENT;
|
33
|
+
|
34
|
+
describe.runIf(process.env.TW_SECRET_KEY)("Marketplace Direct Listings", () => {
|
35
|
+
it("should work with ERC721 and ERC1155", async () => {
|
36
|
+
const marketplaceAddress = await deployMarketplaceContract({
|
37
|
+
account: TEST_ACCOUNT_A,
|
38
|
+
chain,
|
39
|
+
client,
|
40
|
+
params: {
|
41
|
+
name: "TestMarketPlace",
|
42
|
+
contractURI: TEST_CONTRACT_URI,
|
43
|
+
},
|
44
|
+
});
|
45
|
+
const erc721Address = await deployERC721Contract({
|
46
|
+
type: "TokenERC721",
|
47
|
+
account: TEST_ACCOUNT_B,
|
48
|
+
chain,
|
49
|
+
client,
|
50
|
+
params: {
|
51
|
+
name: "TestERC721",
|
52
|
+
contractURI: TEST_CONTRACT_URI,
|
53
|
+
},
|
54
|
+
});
|
55
|
+
const erc1155Address = await deployERC1155Contract({
|
56
|
+
type: "TokenERC1155",
|
57
|
+
account: TEST_ACCOUNT_C,
|
58
|
+
chain,
|
59
|
+
client,
|
60
|
+
params: {
|
61
|
+
name: "TestERC1155",
|
62
|
+
contractURI: TEST_CONTRACT_URI,
|
63
|
+
},
|
64
|
+
});
|
65
|
+
|
66
|
+
const marketplaceContract = getContract({
|
67
|
+
address: marketplaceAddress,
|
68
|
+
chain,
|
69
|
+
client,
|
70
|
+
});
|
71
|
+
const erc721Contract = getContract({
|
72
|
+
address: erc721Address,
|
73
|
+
chain,
|
74
|
+
client,
|
75
|
+
});
|
76
|
+
const erc1155Contract = getContract({
|
77
|
+
address: erc1155Address,
|
78
|
+
chain,
|
79
|
+
client,
|
80
|
+
});
|
68
81
|
|
69
|
-
|
82
|
+
// Mint some NFTs in parallel
|
83
|
+
await Promise.all([
|
84
|
+
sendAndConfirmTransaction({
|
85
|
+
account: TEST_ACCOUNT_B,
|
70
86
|
transaction: mintToErc721({
|
71
87
|
contract: erc721Contract,
|
72
|
-
|
73
|
-
|
88
|
+
nft: { name: "erc721 #0" },
|
89
|
+
to: TEST_ACCOUNT_B.address,
|
74
90
|
}),
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
91
|
+
}),
|
92
|
+
sendAndConfirmTransaction({
|
93
|
+
account: TEST_ACCOUNT_C,
|
94
|
+
transaction: mintToErc1155({
|
95
|
+
contract: erc1155Contract,
|
96
|
+
nft: { name: "erc1155 #0" },
|
97
|
+
to: TEST_ACCOUNT_C.address,
|
98
|
+
supply: 100n,
|
99
|
+
}),
|
100
|
+
}),
|
101
|
+
]);
|
82
102
|
|
83
|
-
|
84
|
-
|
103
|
+
// Set NFT approvals
|
104
|
+
await Promise.all([
|
105
|
+
sendAndConfirmTransaction({
|
106
|
+
account: TEST_ACCOUNT_B,
|
107
|
+
transaction: setApprovalForAll721({
|
108
|
+
contract: erc721Contract,
|
109
|
+
approved: true,
|
110
|
+
operator: marketplaceAddress,
|
111
|
+
}),
|
112
|
+
}),
|
113
|
+
sendAndConfirmTransaction({
|
114
|
+
account: TEST_ACCOUNT_C,
|
115
|
+
transaction: setApprovalForAll1155({
|
116
|
+
contract: erc1155Contract,
|
117
|
+
approved: true,
|
118
|
+
operator: marketplaceAddress,
|
119
|
+
}),
|
120
|
+
}),
|
121
|
+
]);
|
85
122
|
|
86
|
-
|
87
|
-
// does a lot of stuff, this may take a while
|
88
|
-
}, 120_000);
|
123
|
+
// ---- set up completed ---- //
|
89
124
|
|
90
|
-
|
91
|
-
|
92
|
-
|
125
|
+
// listings should be 0 length to start
|
126
|
+
const [allListings, totalListingCount] = await Promise.all([
|
127
|
+
getAllListings({
|
93
128
|
contract: marketplaceContract,
|
94
|
-
})
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
tokenId: nftTokenId,
|
104
|
-
});
|
105
|
-
|
106
|
-
await sendAndConfirmTransaction({
|
107
|
-
transaction: approveTx,
|
108
|
-
account: TEST_ACCOUNT_A,
|
109
|
-
});
|
110
|
-
|
111
|
-
const transaction = createListing({
|
129
|
+
}),
|
130
|
+
totalListings({ contract: marketplaceContract }),
|
131
|
+
]);
|
132
|
+
expect(allListings.length).toBe(0);
|
133
|
+
// oh and so should totalListings
|
134
|
+
expect(totalListingCount).toBe(0n);
|
135
|
+
|
136
|
+
const receipt = await sendAndConfirmTransaction({
|
137
|
+
transaction: createListing({
|
112
138
|
contract: marketplaceContract,
|
113
139
|
assetContractAddress: erc721Contract.address,
|
114
|
-
tokenId:
|
140
|
+
tokenId: 0n,
|
115
141
|
pricePerToken: "1",
|
116
|
-
})
|
117
|
-
|
118
|
-
|
119
|
-
account: TEST_ACCOUNT_A,
|
120
|
-
});
|
142
|
+
}),
|
143
|
+
account: TEST_ACCOUNT_B,
|
144
|
+
});
|
121
145
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
146
|
+
const listingEvents = parseEventLogs({
|
147
|
+
events: [newListingEvent()],
|
148
|
+
logs: receipt.logs,
|
149
|
+
});
|
126
150
|
|
127
|
-
|
151
|
+
expect(listingEvents.length).toBe(1);
|
128
152
|
|
129
|
-
|
130
|
-
|
153
|
+
// biome-ignore lint/style/noNonNullAssertion: OK in tests
|
154
|
+
const listingEvent = listingEvents[0]!;
|
131
155
|
|
132
|
-
|
133
|
-
|
156
|
+
expect(listingEvent.args.listingCreator).toBe(TEST_ACCOUNT_B.address);
|
157
|
+
expect(listingEvent.args.assetContract).toBe(erc721Contract.address);
|
134
158
|
|
135
|
-
|
136
|
-
|
159
|
+
const [
|
160
|
+
listingsAfter,
|
161
|
+
validListings,
|
162
|
+
totalListingCount2,
|
163
|
+
firstListing,
|
164
|
+
nftBalanceOfAccountABeforePurchase,
|
165
|
+
] = await Promise.all([
|
166
|
+
getAllListings({
|
137
167
|
contract: marketplaceContract,
|
138
|
-
})
|
139
|
-
|
140
|
-
// valid listings should also be 1!
|
141
|
-
const validListings = await getAllValidListings({
|
168
|
+
}),
|
169
|
+
getAllValidListings({
|
142
170
|
contract: marketplaceContract,
|
143
|
-
})
|
144
|
-
|
145
|
-
|
146
|
-
expect(await totalListings({ contract: marketplaceContract })).toBe(1n);
|
147
|
-
|
148
|
-
// explicitly retrieve the listing!
|
149
|
-
const listing = await getListing({
|
171
|
+
}),
|
172
|
+
totalListings({ contract: marketplaceContract }),
|
173
|
+
getListing({
|
150
174
|
contract: marketplaceContract,
|
151
175
|
listingId: listingEvent.args.listingId,
|
152
|
-
})
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
176
|
+
}),
|
177
|
+
balanceOfErc721({
|
178
|
+
contract: erc721Contract,
|
179
|
+
owner: TEST_ACCOUNT_A.address,
|
180
|
+
}),
|
181
|
+
]);
|
182
|
+
|
183
|
+
// at this point listings should be 1
|
184
|
+
expect(listingsAfter.length).toBe(1);
|
185
|
+
// valid listings should also be 1!
|
186
|
+
expect(validListings.length).toBe(1);
|
187
|
+
// and totalListings should be 1
|
188
|
+
expect(totalListingCount2).toBe(1n);
|
189
|
+
expect(firstListing).toBeDefined();
|
190
|
+
expect(firstListing.status).toBe("ACTIVE");
|
191
|
+
expect(firstListing.creatorAddress).toBe(TEST_ACCOUNT_B.address);
|
192
|
+
expect(firstListing.assetContractAddress).toBe(erc721Contract.address);
|
193
|
+
expect(firstListing.tokenId).toBe(0n);
|
194
|
+
expect(firstListing.currencyValuePerToken).toMatchInlineSnapshot(`
|
195
|
+
{
|
196
|
+
"decimals": 18,
|
197
|
+
"displayValue": "1",
|
198
|
+
"name": "Anvil Ether",
|
199
|
+
"symbol": "ETH",
|
200
|
+
"value": 1000000000000000000n,
|
201
|
+
}
|
202
|
+
`);
|
203
|
+
expect(firstListing.asset.metadata.name).toBe("erc721 #0");
|
204
|
+
expect(firstListing.asset.id).toBe(0n);
|
205
|
+
expect(firstListing.asset.owner).toBe(null);
|
206
|
+
// check the listing is valid
|
207
|
+
const firstListingValidity = await isListingValid({
|
208
|
+
listing: firstListing,
|
209
|
+
contract: marketplaceContract,
|
210
|
+
quantity: 1n,
|
211
|
+
});
|
186
212
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
213
|
+
expect(firstListingValidity).toMatchInlineSnapshot(`
|
214
|
+
{
|
215
|
+
"valid": true,
|
216
|
+
}
|
191
217
|
`);
|
218
|
+
expect(nftBalanceOfAccountABeforePurchase).toBe(0n);
|
192
219
|
|
193
|
-
|
194
|
-
|
195
|
-
balanceOfErc721({
|
196
|
-
contract: erc721Contract,
|
197
|
-
owner: TEST_ACCOUNT_B.address,
|
198
|
-
}),
|
199
|
-
).resolves.toBe(0n);
|
200
|
-
|
201
|
-
const buyTx = buyFromListing({
|
220
|
+
await sendAndConfirmTransaction({
|
221
|
+
transaction: buyFromListing({
|
202
222
|
contract: marketplaceContract,
|
203
223
|
listingId: listingEvent.args.listingId,
|
204
|
-
recipient:
|
224
|
+
recipient: TEST_ACCOUNT_A.address,
|
205
225
|
quantity: 1n,
|
206
|
-
})
|
207
|
-
|
208
|
-
await sendAndConfirmTransaction({
|
209
|
-
transaction: buyTx,
|
210
|
-
account: TEST_ACCOUNT_B,
|
211
|
-
});
|
212
|
-
|
213
|
-
// expect the buyer to have a new balance of 1
|
214
|
-
await expect(
|
215
|
-
balanceOfErc721({
|
216
|
-
contract: erc721Contract,
|
217
|
-
owner: TEST_ACCOUNT_B.address,
|
218
|
-
}),
|
219
|
-
).resolves.toBe(1n);
|
220
|
-
// expect the seller to no longer have the token
|
221
|
-
await expect(
|
222
|
-
balanceOfErc721({
|
223
|
-
contract: erc721Contract,
|
224
|
-
owner: TEST_ACCOUNT_A.address,
|
225
|
-
}),
|
226
|
-
).resolves.toBe(0n);
|
226
|
+
}),
|
227
|
+
account: TEST_ACCOUNT_A,
|
227
228
|
});
|
228
|
-
});
|
229
|
-
|
230
|
-
describe("ERC1155 Drop", () => {
|
231
|
-
let nftTokenId: bigint;
|
232
|
-
let marketplaceContract: ThirdwebContract;
|
233
|
-
let erc1155Contract: ThirdwebContract;
|
234
|
-
beforeAll(async () => {
|
235
|
-
marketplaceContract = getContract({
|
236
|
-
address: await deployMarketplaceContract({
|
237
|
-
account: TEST_ACCOUNT_A,
|
238
|
-
chain: ANVIL_CHAIN,
|
239
|
-
client: TEST_CLIENT,
|
240
|
-
params: {
|
241
|
-
name: "TestMarketPlace",
|
242
|
-
},
|
243
|
-
}),
|
244
|
-
client: TEST_CLIENT,
|
245
|
-
chain: ANVIL_CHAIN,
|
246
|
-
});
|
247
|
-
|
248
|
-
// also deploy an ERC721 contract
|
249
|
-
erc1155Contract = getContract({
|
250
|
-
address: await deployERC1155Contract({
|
251
|
-
type: "DropERC1155",
|
252
|
-
account: TEST_ACCOUNT_A,
|
253
|
-
chain: ANVIL_CHAIN,
|
254
|
-
client: TEST_CLIENT,
|
255
|
-
params: {
|
256
|
-
name: "TestERC1155",
|
257
|
-
},
|
258
|
-
}),
|
259
|
-
client: TEST_CLIENT,
|
260
|
-
chain: ANVIL_CHAIN,
|
261
|
-
});
|
262
|
-
|
263
|
-
// lazy mint 10 tokens
|
264
|
-
await expect(
|
265
|
-
sendAndConfirmTransaction({
|
266
|
-
transaction: lazyMint({
|
267
|
-
contract: erc1155Contract,
|
268
|
-
nfts: [{ name: "Test:ERC1155:DirectListing" }],
|
269
|
-
}),
|
270
|
-
account: TEST_ACCOUNT_A,
|
271
|
-
}),
|
272
|
-
).resolves.toBeDefined();
|
273
|
-
|
274
|
-
// set claim condition (just public is fine)
|
275
|
-
await expect(
|
276
|
-
sendAndConfirmTransaction({
|
277
|
-
transaction: setClaimConditions({
|
278
|
-
contract: erc1155Contract,
|
279
|
-
tokenId: 0n,
|
280
|
-
phases: [{}],
|
281
|
-
}),
|
282
|
-
account: TEST_ACCOUNT_A,
|
283
|
-
}),
|
284
|
-
).resolves.toBeDefined();
|
285
|
-
|
286
|
-
// claim 10 tokens
|
287
|
-
await expect(
|
288
|
-
sendAndConfirmTransaction({
|
289
|
-
transaction: claimTo({
|
290
|
-
contract: erc1155Contract,
|
291
|
-
tokenId: 0n,
|
292
|
-
to: TEST_ACCOUNT_A.address,
|
293
|
-
quantity: 10n,
|
294
|
-
}),
|
295
|
-
account: TEST_ACCOUNT_A,
|
296
|
-
}),
|
297
|
-
).resolves.toBeDefined();
|
298
|
-
|
299
|
-
nftTokenId = 0n;
|
300
|
-
// does a lot of stuff, this may take a while
|
301
|
-
}, 120_000);
|
302
|
-
|
303
|
-
it("should work for basic listings (Native Currency)", async () => {
|
304
|
-
// listings should be 0 length to start
|
305
|
-
const listings = await getAllListings({
|
306
|
-
contract: marketplaceContract,
|
307
|
-
});
|
308
|
-
expect(listings.length).toBe(0);
|
309
|
-
// oh and so should totalListings
|
310
|
-
expect(await totalListings({ contract: marketplaceContract })).toBe(0n);
|
311
229
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
contract: ${marketplaceContract.address}
|
339
|
-
chainId: 31337]
|
340
|
-
`);
|
341
|
-
|
342
|
-
// this should work because we're listing the correct amount
|
343
|
-
const receipt = await sendAndConfirmTransaction({
|
230
|
+
const [
|
231
|
+
nftBalanceOfAccountAAfterPurchase,
|
232
|
+
nftBalanceOfAccountBAfterPurchase,
|
233
|
+
] = await Promise.all([
|
234
|
+
balanceOfErc721({
|
235
|
+
contract: erc721Contract,
|
236
|
+
owner: TEST_ACCOUNT_A.address,
|
237
|
+
}),
|
238
|
+
balanceOfErc721({
|
239
|
+
contract: erc721Contract,
|
240
|
+
owner: TEST_ACCOUNT_B.address,
|
241
|
+
}),
|
242
|
+
]);
|
243
|
+
// expect the buyer to have a new balance of 1
|
244
|
+
expect(nftBalanceOfAccountAAfterPurchase).toBe(1n);
|
245
|
+
// expect the seller to no longer have the nft
|
246
|
+
expect(nftBalanceOfAccountBAfterPurchase).toBe(0n);
|
247
|
+
|
248
|
+
/**
|
249
|
+
* ============ now do the same tests but for ERC1155 =============
|
250
|
+
*/
|
251
|
+
|
252
|
+
// this should fail because we're listing more than we have
|
253
|
+
await expect(
|
254
|
+
sendAndConfirmTransaction({
|
344
255
|
transaction: createListing({
|
345
256
|
contract: marketplaceContract,
|
346
257
|
assetContractAddress: erc1155Contract.address,
|
347
|
-
tokenId:
|
348
|
-
pricePerToken: "
|
349
|
-
quantity:
|
258
|
+
tokenId: 0n,
|
259
|
+
pricePerToken: "1",
|
260
|
+
quantity: 101n,
|
350
261
|
}),
|
351
|
-
account:
|
352
|
-
})
|
262
|
+
account: TEST_ACCOUNT_C,
|
263
|
+
}),
|
264
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
265
|
+
[TransactionError: Error - Marketplace: not owner or approved tokens.
|
353
266
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
});
|
267
|
+
contract: ${marketplaceContract.address}
|
268
|
+
chainId: 31337]
|
269
|
+
`);
|
358
270
|
|
359
|
-
|
271
|
+
const receipt1155 = await sendAndConfirmTransaction({
|
272
|
+
transaction: createListing({
|
273
|
+
contract: marketplaceContract,
|
274
|
+
assetContractAddress: erc1155Contract.address,
|
275
|
+
tokenId: 0n,
|
276
|
+
pricePerToken: "0.01",
|
277
|
+
quantity: 1n,
|
278
|
+
}),
|
279
|
+
account: TEST_ACCOUNT_C,
|
280
|
+
});
|
360
281
|
|
361
|
-
|
362
|
-
|
282
|
+
const listingEvents1155 = parseEventLogs({
|
283
|
+
events: [newListingEvent()],
|
284
|
+
logs: receipt1155.logs,
|
285
|
+
});
|
363
286
|
|
364
|
-
|
365
|
-
expect(listingEvent.args.assetContract).toBe(erc1155Contract.address);
|
287
|
+
expect(listingEvents.length).toBe(1);
|
366
288
|
|
367
|
-
|
368
|
-
|
369
|
-
contract: marketplaceContract,
|
370
|
-
});
|
371
|
-
expect(listingsAfter.length).toBe(1);
|
372
|
-
// valid listings should also be 1!
|
373
|
-
const validListings = await getAllValidListings({
|
374
|
-
contract: marketplaceContract,
|
375
|
-
});
|
376
|
-
expect(validListings.length).toBe(1);
|
377
|
-
// and totalListings should be 1
|
378
|
-
expect(await totalListings({ contract: marketplaceContract })).toBe(1n);
|
289
|
+
// biome-ignore lint/style/noNonNullAssertion: OK in tests
|
290
|
+
const listingEvent1155 = listingEvents1155[0]!;
|
379
291
|
|
380
|
-
|
381
|
-
|
292
|
+
expect(listingEvent1155.args.listingCreator).toBe(TEST_ACCOUNT_C.address);
|
293
|
+
expect(listingEvent1155.args.assetContract).toBe(erc1155Contract.address);
|
294
|
+
|
295
|
+
const [
|
296
|
+
listings1155After,
|
297
|
+
validListings1155,
|
298
|
+
totalListingCountAfter1155,
|
299
|
+
secondListing,
|
300
|
+
nft1155BalanceOfAccountABeforePurchase,
|
301
|
+
] = await Promise.all([
|
302
|
+
getAllListings({
|
382
303
|
contract: marketplaceContract,
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
expect(listing).toBeDefined();
|
387
|
-
expect(listing.status).toBe("ACTIVE");
|
388
|
-
expect(listing.creatorAddress).toBe(TEST_ACCOUNT_A.address);
|
389
|
-
expect(listing.assetContractAddress).toBe(erc1155Contract.address);
|
390
|
-
expect(listing.tokenId).toBe(nftTokenId);
|
391
|
-
expect(listing.currencyValuePerToken).toMatchInlineSnapshot(`
|
392
|
-
{
|
393
|
-
"decimals": 18,
|
394
|
-
"displayValue": "0.01",
|
395
|
-
"name": "Anvil Ether",
|
396
|
-
"symbol": "ETH",
|
397
|
-
"value": 10000000000000000n,
|
398
|
-
}
|
399
|
-
`);
|
400
|
-
expect(listing.asset).toMatchInlineSnapshot(`
|
401
|
-
{
|
402
|
-
"id": 0n,
|
403
|
-
"metadata": {
|
404
|
-
"name": "Test:ERC1155:DirectListing",
|
405
|
-
},
|
406
|
-
"owner": null,
|
407
|
-
"supply": 10n,
|
408
|
-
"tokenURI": "ipfs://QmdwzcoSGSzoRSMBk2efkHjGVRsyUaR2Lm79YTuL324NtM/0",
|
409
|
-
"type": "ERC1155",
|
410
|
-
}
|
411
|
-
`);
|
412
|
-
|
413
|
-
// check the listing is valid
|
414
|
-
const listingValidity = await isListingValid({
|
415
|
-
listing,
|
304
|
+
}),
|
305
|
+
getAllValidListings({
|
416
306
|
contract: marketplaceContract,
|
417
|
-
|
418
|
-
})
|
307
|
+
}),
|
308
|
+
totalListings({ contract: marketplaceContract }),
|
309
|
+
getListing({
|
310
|
+
contract: marketplaceContract,
|
311
|
+
listingId: listingEvent1155.args.listingId,
|
312
|
+
}),
|
313
|
+
balanceOfErc1155({
|
314
|
+
contract: erc1155Contract,
|
315
|
+
owner: TEST_ACCOUNT_A.address,
|
316
|
+
tokenId: 0n,
|
317
|
+
}),
|
318
|
+
]);
|
319
|
+
|
320
|
+
// at this point listings should be 2
|
321
|
+
expect(listings1155After.length).toBe(2);
|
322
|
+
// valid listings should be 1 still because the first listing has been bought
|
323
|
+
expect(validListings1155.length).toBe(1);
|
324
|
+
// and totalListings should be 2
|
325
|
+
expect(totalListingCountAfter1155).toBe(2n);
|
326
|
+
expect(secondListing).toBeDefined();
|
327
|
+
expect(secondListing.status).toBe("ACTIVE");
|
328
|
+
expect(secondListing.creatorAddress).toBe(TEST_ACCOUNT_C.address);
|
329
|
+
expect(secondListing.assetContractAddress).toBe(erc1155Contract.address);
|
330
|
+
expect(secondListing.tokenId).toBe(0n);
|
331
|
+
expect(secondListing.currencyValuePerToken).toMatchInlineSnapshot(`
|
332
|
+
{
|
333
|
+
"decimals": 18,
|
334
|
+
"displayValue": "0.01",
|
335
|
+
"name": "Anvil Ether",
|
336
|
+
"symbol": "ETH",
|
337
|
+
"value": 10000000000000000n,
|
338
|
+
}
|
339
|
+
`);
|
340
|
+
expect(secondListing.asset.metadata.name).toBe("erc1155 #0");
|
341
|
+
expect(secondListing.asset.id).toBe(0n);
|
342
|
+
|
343
|
+
// check the listing is valid
|
344
|
+
const listingValidity = await isListingValid({
|
345
|
+
listing: secondListing,
|
346
|
+
contract: marketplaceContract,
|
347
|
+
quantity: 1n,
|
348
|
+
});
|
419
349
|
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
350
|
+
expect(listingValidity).toMatchInlineSnapshot(`
|
351
|
+
{
|
352
|
+
"valid": true,
|
353
|
+
}
|
354
|
+
`);
|
425
355
|
|
426
|
-
|
427
|
-
await expect(
|
428
|
-
balanceOfErc1155({
|
429
|
-
contract: erc1155Contract,
|
430
|
-
owner: TEST_ACCOUNT_B.address,
|
431
|
-
tokenId: nftTokenId,
|
432
|
-
}),
|
433
|
-
).resolves.toBe(0n);
|
356
|
+
expect(nft1155BalanceOfAccountABeforePurchase).toBe(0n);
|
434
357
|
|
435
|
-
|
358
|
+
await sendAndConfirmTransaction({
|
359
|
+
transaction: buyFromListing({
|
436
360
|
contract: marketplaceContract,
|
437
|
-
listingId:
|
438
|
-
recipient:
|
361
|
+
listingId: listingEvent1155.args.listingId,
|
362
|
+
recipient: TEST_ACCOUNT_A.address,
|
439
363
|
quantity: 1n,
|
440
|
-
})
|
441
|
-
|
442
|
-
await sendAndConfirmTransaction({
|
443
|
-
transaction: buyTx,
|
444
|
-
account: TEST_ACCOUNT_B,
|
445
|
-
});
|
446
|
-
|
447
|
-
// expect the buyer to have a new balance of 1
|
448
|
-
await expect(
|
449
|
-
balanceOfErc1155({
|
450
|
-
contract: erc1155Contract,
|
451
|
-
owner: TEST_ACCOUNT_B.address,
|
452
|
-
tokenId: nftTokenId,
|
453
|
-
}),
|
454
|
-
).resolves.toBe(1n);
|
455
|
-
// expect the seller to only have 9 of the tokens
|
456
|
-
await expect(
|
457
|
-
balanceOfErc1155({
|
458
|
-
contract: erc1155Contract,
|
459
|
-
owner: TEST_ACCOUNT_A.address,
|
460
|
-
tokenId: nftTokenId,
|
461
|
-
}),
|
462
|
-
).resolves.toBe(9n);
|
364
|
+
}),
|
365
|
+
account: TEST_ACCOUNT_A,
|
463
366
|
});
|
367
|
+
|
368
|
+
const [
|
369
|
+
nft1155BalanceOfAccountAAfterPurchase,
|
370
|
+
nft1155BalanceOfAccountCAfterPurchase,
|
371
|
+
] = await Promise.all([
|
372
|
+
balanceOfErc1155({
|
373
|
+
contract: erc1155Contract,
|
374
|
+
owner: TEST_ACCOUNT_A.address,
|
375
|
+
tokenId: 0n,
|
376
|
+
}),
|
377
|
+
balanceOfErc1155({
|
378
|
+
contract: erc1155Contract,
|
379
|
+
owner: TEST_ACCOUNT_C.address,
|
380
|
+
tokenId: 0n,
|
381
|
+
}),
|
382
|
+
]);
|
383
|
+
// expect the buyer to have a new balance of 1
|
384
|
+
expect(nft1155BalanceOfAccountAAfterPurchase).toBe(1n);
|
385
|
+
// expect the seller to have one less 1155 token
|
386
|
+
expect(nft1155BalanceOfAccountCAfterPurchase).toBe(99n);
|
464
387
|
});
|
465
388
|
});
|