@net-protocol/bazaar 0.1.6 → 0.1.8
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/index.d.mts +794 -37
- package/dist/index.d.ts +794 -37
- package/dist/index.js +1093 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1074 -14
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +5 -4
- package/dist/react.d.ts +5 -4
- package/dist/react.js +1234 -14
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +1235 -15
- package/dist/react.mjs.map +1 -1
- package/dist/{types-BwfAmxpu.d.mts → types-oOrmJnNJ.d.mts} +71 -3
- package/dist/{types-BwfAmxpu.d.ts → types-oOrmJnNJ.d.ts} +71 -3
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -4,14 +4,228 @@ var react = require('react');
|
|
|
4
4
|
var wagmi = require('wagmi');
|
|
5
5
|
var react$1 = require('@net-protocol/core/react');
|
|
6
6
|
var viem = require('viem');
|
|
7
|
+
var actions = require('viem/actions');
|
|
7
8
|
var core = require('@net-protocol/core');
|
|
8
9
|
var seaportJs = require('@opensea/seaport-js');
|
|
9
10
|
var ethers = require('ethers');
|
|
10
|
-
var actions = require('viem/actions');
|
|
11
11
|
var storage = require('@net-protocol/storage');
|
|
12
12
|
|
|
13
13
|
// src/hooks/useBazaarListings.ts
|
|
14
14
|
|
|
15
|
+
// src/abis/bazaarV2.ts
|
|
16
|
+
var BAZAAR_V2_ABI = [
|
|
17
|
+
{
|
|
18
|
+
type: "function",
|
|
19
|
+
name: "submit",
|
|
20
|
+
inputs: [
|
|
21
|
+
{
|
|
22
|
+
name: "submission",
|
|
23
|
+
type: "tuple",
|
|
24
|
+
internalType: "struct BazaarV1.Submission",
|
|
25
|
+
components: [
|
|
26
|
+
{
|
|
27
|
+
name: "parameters",
|
|
28
|
+
type: "tuple",
|
|
29
|
+
internalType: "struct OrderParameters",
|
|
30
|
+
components: [
|
|
31
|
+
{ name: "offerer", type: "address", internalType: "address" },
|
|
32
|
+
{ name: "zone", type: "address", internalType: "address" },
|
|
33
|
+
{
|
|
34
|
+
name: "offer",
|
|
35
|
+
type: "tuple[]",
|
|
36
|
+
internalType: "struct OfferItem[]",
|
|
37
|
+
components: [
|
|
38
|
+
{ name: "itemType", type: "uint8", internalType: "enum ItemType" },
|
|
39
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
40
|
+
{ name: "identifierOrCriteria", type: "uint256", internalType: "uint256" },
|
|
41
|
+
{ name: "startAmount", type: "uint256", internalType: "uint256" },
|
|
42
|
+
{ name: "endAmount", type: "uint256", internalType: "uint256" }
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "consideration",
|
|
47
|
+
type: "tuple[]",
|
|
48
|
+
internalType: "struct ConsiderationItem[]",
|
|
49
|
+
components: [
|
|
50
|
+
{ name: "itemType", type: "uint8", internalType: "enum ItemType" },
|
|
51
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
52
|
+
{ name: "identifierOrCriteria", type: "uint256", internalType: "uint256" },
|
|
53
|
+
{ name: "startAmount", type: "uint256", internalType: "uint256" },
|
|
54
|
+
{ name: "endAmount", type: "uint256", internalType: "uint256" },
|
|
55
|
+
{ name: "recipient", type: "address", internalType: "address payable" }
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{ name: "orderType", type: "uint8", internalType: "enum OrderType" },
|
|
59
|
+
{ name: "startTime", type: "uint256", internalType: "uint256" },
|
|
60
|
+
{ name: "endTime", type: "uint256", internalType: "uint256" },
|
|
61
|
+
{ name: "zoneHash", type: "bytes32", internalType: "bytes32" },
|
|
62
|
+
{ name: "salt", type: "uint256", internalType: "uint256" },
|
|
63
|
+
{ name: "conduitKey", type: "bytes32", internalType: "bytes32" },
|
|
64
|
+
{ name: "totalOriginalConsiderationItems", type: "uint256", internalType: "uint256" }
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
{ name: "counter", type: "uint256", internalType: "uint256" },
|
|
68
|
+
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
outputs: [],
|
|
73
|
+
stateMutability: "nonpayable"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: "event",
|
|
77
|
+
name: "Submitted",
|
|
78
|
+
inputs: [
|
|
79
|
+
{ name: "tokenAddress", type: "address", indexed: true, internalType: "address" },
|
|
80
|
+
{ name: "tokenId", type: "uint256", indexed: true, internalType: "uint256" }
|
|
81
|
+
],
|
|
82
|
+
anonymous: false
|
|
83
|
+
},
|
|
84
|
+
{ type: "error", name: "ConsiderationItemsMustContainTwoItems", inputs: [] },
|
|
85
|
+
{ type: "error", name: "OfferItemsMustContainOneItem", inputs: [] }
|
|
86
|
+
];
|
|
87
|
+
var BAZAAR_COLLECTION_OFFERS_ABI = [
|
|
88
|
+
{
|
|
89
|
+
type: "function",
|
|
90
|
+
name: "NET_APP_NAME",
|
|
91
|
+
inputs: [],
|
|
92
|
+
outputs: [{ name: "", type: "string", internalType: "string" }],
|
|
93
|
+
stateMutability: "view"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
type: "function",
|
|
97
|
+
name: "submit",
|
|
98
|
+
inputs: [
|
|
99
|
+
{
|
|
100
|
+
name: "submission",
|
|
101
|
+
type: "tuple",
|
|
102
|
+
internalType: "struct BazaarV2CollectionOffers.Submission",
|
|
103
|
+
components: [
|
|
104
|
+
{
|
|
105
|
+
name: "parameters",
|
|
106
|
+
type: "tuple",
|
|
107
|
+
internalType: "struct OrderParameters",
|
|
108
|
+
components: [
|
|
109
|
+
{ name: "offerer", type: "address", internalType: "address" },
|
|
110
|
+
{ name: "zone", type: "address", internalType: "address" },
|
|
111
|
+
{
|
|
112
|
+
name: "offer",
|
|
113
|
+
type: "tuple[]",
|
|
114
|
+
internalType: "struct OfferItem[]",
|
|
115
|
+
components: [
|
|
116
|
+
{ name: "itemType", type: "uint8", internalType: "enum ItemType" },
|
|
117
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
118
|
+
{ name: "identifierOrCriteria", type: "uint256", internalType: "uint256" },
|
|
119
|
+
{ name: "startAmount", type: "uint256", internalType: "uint256" },
|
|
120
|
+
{ name: "endAmount", type: "uint256", internalType: "uint256" }
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "consideration",
|
|
125
|
+
type: "tuple[]",
|
|
126
|
+
internalType: "struct ConsiderationItem[]",
|
|
127
|
+
components: [
|
|
128
|
+
{ name: "itemType", type: "uint8", internalType: "enum ItemType" },
|
|
129
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
130
|
+
{ name: "identifierOrCriteria", type: "uint256", internalType: "uint256" },
|
|
131
|
+
{ name: "startAmount", type: "uint256", internalType: "uint256" },
|
|
132
|
+
{ name: "endAmount", type: "uint256", internalType: "uint256" },
|
|
133
|
+
{ name: "recipient", type: "address", internalType: "address payable" }
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{ name: "orderType", type: "uint8", internalType: "enum OrderType" },
|
|
137
|
+
{ name: "startTime", type: "uint256", internalType: "uint256" },
|
|
138
|
+
{ name: "endTime", type: "uint256", internalType: "uint256" },
|
|
139
|
+
{ name: "zoneHash", type: "bytes32", internalType: "bytes32" },
|
|
140
|
+
{ name: "salt", type: "uint256", internalType: "uint256" },
|
|
141
|
+
{ name: "conduitKey", type: "bytes32", internalType: "bytes32" },
|
|
142
|
+
{ name: "totalOriginalConsiderationItems", type: "uint256", internalType: "uint256" }
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
{ name: "counter", type: "uint256", internalType: "uint256" },
|
|
146
|
+
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
outputs: [],
|
|
151
|
+
stateMutability: "nonpayable"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: "event",
|
|
155
|
+
name: "Submitted",
|
|
156
|
+
inputs: [
|
|
157
|
+
{ name: "tokenAddress", type: "address", indexed: true, internalType: "address" },
|
|
158
|
+
{ name: "tokenId", type: "uint256", indexed: true, internalType: "uint256" }
|
|
159
|
+
],
|
|
160
|
+
anonymous: false
|
|
161
|
+
},
|
|
162
|
+
{ type: "error", name: "ConsiderationItemsMustContainTwoItems", inputs: [] },
|
|
163
|
+
{ type: "error", name: "ConsiderationItemsMustIncludeFeeAddress", inputs: [] },
|
|
164
|
+
{ type: "error", name: "ConsiderationItemsMustIncludeMsgSender", inputs: [] },
|
|
165
|
+
{ type: "error", name: "InvalidFee", inputs: [] },
|
|
166
|
+
{ type: "error", name: "OfferItemsMustContainOneItem", inputs: [] }
|
|
167
|
+
];
|
|
168
|
+
var BAZAAR_ERC20_OFFERS_ABI = [
|
|
169
|
+
{
|
|
170
|
+
type: "function",
|
|
171
|
+
name: "submit",
|
|
172
|
+
inputs: [
|
|
173
|
+
{
|
|
174
|
+
name: "submission",
|
|
175
|
+
type: "tuple",
|
|
176
|
+
internalType: "struct BazaarV2CollectionOffers.Submission",
|
|
177
|
+
components: [
|
|
178
|
+
{
|
|
179
|
+
name: "parameters",
|
|
180
|
+
type: "tuple",
|
|
181
|
+
internalType: "struct OrderParameters",
|
|
182
|
+
components: [
|
|
183
|
+
{ name: "offerer", type: "address", internalType: "address" },
|
|
184
|
+
{ name: "zone", type: "address", internalType: "address" },
|
|
185
|
+
{
|
|
186
|
+
name: "offer",
|
|
187
|
+
type: "tuple[]",
|
|
188
|
+
internalType: "struct OfferItem[]",
|
|
189
|
+
components: [
|
|
190
|
+
{ name: "itemType", type: "uint8", internalType: "enum ItemType" },
|
|
191
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
192
|
+
{ name: "identifierOrCriteria", type: "uint256", internalType: "uint256" },
|
|
193
|
+
{ name: "startAmount", type: "uint256", internalType: "uint256" },
|
|
194
|
+
{ name: "endAmount", type: "uint256", internalType: "uint256" }
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: "consideration",
|
|
199
|
+
type: "tuple[]",
|
|
200
|
+
internalType: "struct ConsiderationItem[]",
|
|
201
|
+
components: [
|
|
202
|
+
{ name: "itemType", type: "uint8", internalType: "enum ItemType" },
|
|
203
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
204
|
+
{ name: "identifierOrCriteria", type: "uint256", internalType: "uint256" },
|
|
205
|
+
{ name: "startAmount", type: "uint256", internalType: "uint256" },
|
|
206
|
+
{ name: "endAmount", type: "uint256", internalType: "uint256" },
|
|
207
|
+
{ name: "recipient", type: "address", internalType: "address payable" }
|
|
208
|
+
]
|
|
209
|
+
},
|
|
210
|
+
{ name: "orderType", type: "uint8", internalType: "enum OrderType" },
|
|
211
|
+
{ name: "startTime", type: "uint256", internalType: "uint256" },
|
|
212
|
+
{ name: "endTime", type: "uint256", internalType: "uint256" },
|
|
213
|
+
{ name: "zoneHash", type: "bytes32", internalType: "bytes32" },
|
|
214
|
+
{ name: "salt", type: "uint256", internalType: "uint256" },
|
|
215
|
+
{ name: "conduitKey", type: "bytes32", internalType: "bytes32" },
|
|
216
|
+
{ name: "totalOriginalConsiderationItems", type: "uint256", internalType: "uint256" }
|
|
217
|
+
]
|
|
218
|
+
},
|
|
219
|
+
{ name: "counter", type: "uint256", internalType: "uint256" },
|
|
220
|
+
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
],
|
|
224
|
+
outputs: [],
|
|
225
|
+
stateMutability: "nonpayable"
|
|
226
|
+
}
|
|
227
|
+
];
|
|
228
|
+
|
|
15
229
|
// src/abis/helpers.ts
|
|
16
230
|
var BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI = [
|
|
17
231
|
{ type: "constructor", inputs: [], stateMutability: "nonpayable" },
|
|
@@ -121,6 +335,161 @@ var SEAPORT_CANCEL_ABI = [
|
|
|
121
335
|
type: "function"
|
|
122
336
|
}
|
|
123
337
|
];
|
|
338
|
+
var ORDER_PARAMETERS_COMPONENTS = [
|
|
339
|
+
{ internalType: "address", name: "offerer", type: "address" },
|
|
340
|
+
{ internalType: "address", name: "zone", type: "address" },
|
|
341
|
+
{
|
|
342
|
+
components: [
|
|
343
|
+
{ internalType: "enum ItemType", name: "itemType", type: "uint8" },
|
|
344
|
+
{ internalType: "address", name: "token", type: "address" },
|
|
345
|
+
{ internalType: "uint256", name: "identifierOrCriteria", type: "uint256" },
|
|
346
|
+
{ internalType: "uint256", name: "startAmount", type: "uint256" },
|
|
347
|
+
{ internalType: "uint256", name: "endAmount", type: "uint256" }
|
|
348
|
+
],
|
|
349
|
+
internalType: "struct OfferItem[]",
|
|
350
|
+
name: "offer",
|
|
351
|
+
type: "tuple[]"
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
components: [
|
|
355
|
+
{ internalType: "enum ItemType", name: "itemType", type: "uint8" },
|
|
356
|
+
{ internalType: "address", name: "token", type: "address" },
|
|
357
|
+
{ internalType: "uint256", name: "identifierOrCriteria", type: "uint256" },
|
|
358
|
+
{ internalType: "uint256", name: "startAmount", type: "uint256" },
|
|
359
|
+
{ internalType: "uint256", name: "endAmount", type: "uint256" },
|
|
360
|
+
{ internalType: "address payable", name: "recipient", type: "address" }
|
|
361
|
+
],
|
|
362
|
+
internalType: "struct ConsiderationItem[]",
|
|
363
|
+
name: "consideration",
|
|
364
|
+
type: "tuple[]"
|
|
365
|
+
},
|
|
366
|
+
{ internalType: "enum OrderType", name: "orderType", type: "uint8" },
|
|
367
|
+
{ internalType: "uint256", name: "startTime", type: "uint256" },
|
|
368
|
+
{ internalType: "uint256", name: "endTime", type: "uint256" },
|
|
369
|
+
{ internalType: "bytes32", name: "zoneHash", type: "bytes32" },
|
|
370
|
+
{ internalType: "uint256", name: "salt", type: "uint256" },
|
|
371
|
+
{ internalType: "bytes32", name: "conduitKey", type: "bytes32" },
|
|
372
|
+
{ internalType: "uint256", name: "totalOriginalConsiderationItems", type: "uint256" }
|
|
373
|
+
];
|
|
374
|
+
var SEAPORT_FULFILL_ORDER_ABI = [
|
|
375
|
+
{
|
|
376
|
+
inputs: [
|
|
377
|
+
{
|
|
378
|
+
components: [
|
|
379
|
+
{
|
|
380
|
+
components: ORDER_PARAMETERS_COMPONENTS,
|
|
381
|
+
internalType: "struct OrderParameters",
|
|
382
|
+
name: "parameters",
|
|
383
|
+
type: "tuple"
|
|
384
|
+
},
|
|
385
|
+
{ internalType: "bytes", name: "signature", type: "bytes" }
|
|
386
|
+
],
|
|
387
|
+
internalType: "struct Order",
|
|
388
|
+
name: "",
|
|
389
|
+
type: "tuple"
|
|
390
|
+
},
|
|
391
|
+
{ internalType: "bytes32", name: "fulfillerConduitKey", type: "bytes32" }
|
|
392
|
+
],
|
|
393
|
+
name: "fulfillOrder",
|
|
394
|
+
outputs: [{ internalType: "bool", name: "fulfilled", type: "bool" }],
|
|
395
|
+
stateMutability: "payable",
|
|
396
|
+
type: "function"
|
|
397
|
+
}
|
|
398
|
+
];
|
|
399
|
+
var SEAPORT_FULFILL_ADVANCED_ORDER_ABI = [
|
|
400
|
+
{
|
|
401
|
+
inputs: [
|
|
402
|
+
{
|
|
403
|
+
components: [
|
|
404
|
+
{
|
|
405
|
+
components: ORDER_PARAMETERS_COMPONENTS,
|
|
406
|
+
internalType: "struct OrderParameters",
|
|
407
|
+
name: "parameters",
|
|
408
|
+
type: "tuple"
|
|
409
|
+
},
|
|
410
|
+
{ internalType: "uint120", name: "numerator", type: "uint120" },
|
|
411
|
+
{ internalType: "uint120", name: "denominator", type: "uint120" },
|
|
412
|
+
{ internalType: "bytes", name: "signature", type: "bytes" },
|
|
413
|
+
{ internalType: "bytes", name: "extraData", type: "bytes" }
|
|
414
|
+
],
|
|
415
|
+
internalType: "struct AdvancedOrder",
|
|
416
|
+
name: "",
|
|
417
|
+
type: "tuple"
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
components: [
|
|
421
|
+
{ internalType: "uint256", name: "orderIndex", type: "uint256" },
|
|
422
|
+
{ internalType: "enum Side", name: "side", type: "uint8" },
|
|
423
|
+
{ internalType: "uint256", name: "index", type: "uint256" },
|
|
424
|
+
{ internalType: "uint256", name: "identifier", type: "uint256" },
|
|
425
|
+
{ internalType: "bytes32[]", name: "criteriaProof", type: "bytes32[]" }
|
|
426
|
+
],
|
|
427
|
+
internalType: "struct CriteriaResolver[]",
|
|
428
|
+
name: "",
|
|
429
|
+
type: "tuple[]"
|
|
430
|
+
},
|
|
431
|
+
{ internalType: "bytes32", name: "fulfillerConduitKey", type: "bytes32" },
|
|
432
|
+
{ internalType: "address", name: "recipient", type: "address" }
|
|
433
|
+
],
|
|
434
|
+
name: "fulfillAdvancedOrder",
|
|
435
|
+
outputs: [{ internalType: "bool", name: "fulfilled", type: "bool" }],
|
|
436
|
+
stateMutability: "payable",
|
|
437
|
+
type: "function"
|
|
438
|
+
}
|
|
439
|
+
];
|
|
440
|
+
var SEAPORT_GET_COUNTER_ABI = [
|
|
441
|
+
{
|
|
442
|
+
inputs: [{ internalType: "address", name: "offerer", type: "address" }],
|
|
443
|
+
name: "getCounter",
|
|
444
|
+
outputs: [{ internalType: "uint256", name: "counter", type: "uint256" }],
|
|
445
|
+
stateMutability: "view",
|
|
446
|
+
type: "function"
|
|
447
|
+
}
|
|
448
|
+
];
|
|
449
|
+
var ERC721_APPROVAL_ABI = [
|
|
450
|
+
{
|
|
451
|
+
inputs: [
|
|
452
|
+
{ internalType: "address", name: "owner", type: "address" },
|
|
453
|
+
{ internalType: "address", name: "operator", type: "address" }
|
|
454
|
+
],
|
|
455
|
+
name: "isApprovedForAll",
|
|
456
|
+
outputs: [{ internalType: "bool", name: "", type: "bool" }],
|
|
457
|
+
stateMutability: "view",
|
|
458
|
+
type: "function"
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
inputs: [
|
|
462
|
+
{ internalType: "address", name: "operator", type: "address" },
|
|
463
|
+
{ internalType: "bool", name: "approved", type: "bool" }
|
|
464
|
+
],
|
|
465
|
+
name: "setApprovalForAll",
|
|
466
|
+
outputs: [],
|
|
467
|
+
stateMutability: "nonpayable",
|
|
468
|
+
type: "function"
|
|
469
|
+
}
|
|
470
|
+
];
|
|
471
|
+
var ERC20_APPROVAL_ABI = [
|
|
472
|
+
{
|
|
473
|
+
inputs: [
|
|
474
|
+
{ internalType: "address", name: "owner", type: "address" },
|
|
475
|
+
{ internalType: "address", name: "spender", type: "address" }
|
|
476
|
+
],
|
|
477
|
+
name: "allowance",
|
|
478
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
479
|
+
stateMutability: "view",
|
|
480
|
+
type: "function"
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
inputs: [
|
|
484
|
+
{ internalType: "address", name: "spender", type: "address" },
|
|
485
|
+
{ internalType: "uint256", name: "amount", type: "uint256" }
|
|
486
|
+
],
|
|
487
|
+
name: "approve",
|
|
488
|
+
outputs: [{ internalType: "bool", name: "", type: "bool" }],
|
|
489
|
+
stateMutability: "nonpayable",
|
|
490
|
+
type: "function"
|
|
491
|
+
}
|
|
492
|
+
];
|
|
124
493
|
|
|
125
494
|
// src/abis/index.ts
|
|
126
495
|
var BAZAAR_SUBMISSION_ABI = [
|
|
@@ -341,6 +710,12 @@ function getCollectionOffersAddress(chainId) {
|
|
|
341
710
|
function getSeaportAddress(chainId) {
|
|
342
711
|
return BAZAAR_CHAIN_CONFIGS[chainId]?.seaportAddress ?? DEFAULT_SEAPORT_ADDRESS;
|
|
343
712
|
}
|
|
713
|
+
function getFeeCollectorAddress(chainId) {
|
|
714
|
+
return BAZAAR_CHAIN_CONFIGS[chainId]?.feeCollectorAddress ?? DEFAULT_FEE_COLLECTOR_ADDRESS;
|
|
715
|
+
}
|
|
716
|
+
function getNftFeeBps(chainId) {
|
|
717
|
+
return BAZAAR_CHAIN_CONFIGS[chainId]?.nftFeeBps ?? DEFAULT_NFT_FEE_BPS;
|
|
718
|
+
}
|
|
344
719
|
function getWrappedNativeCurrency(chainId) {
|
|
345
720
|
return BAZAAR_CHAIN_CONFIGS[chainId]?.wrappedNativeCurrency;
|
|
346
721
|
}
|
|
@@ -872,6 +1247,528 @@ function parseSaleFromStoredData(storedData, chainId) {
|
|
|
872
1247
|
return null;
|
|
873
1248
|
}
|
|
874
1249
|
}
|
|
1250
|
+
var MAX_UINT256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
|
1251
|
+
async function checkErc721Approval(client, nftAddress, owner, spender) {
|
|
1252
|
+
const isApproved = await actions.readContract(client, {
|
|
1253
|
+
address: nftAddress,
|
|
1254
|
+
abi: ERC721_APPROVAL_ABI,
|
|
1255
|
+
functionName: "isApprovedForAll",
|
|
1256
|
+
args: [owner, spender]
|
|
1257
|
+
});
|
|
1258
|
+
if (isApproved) {
|
|
1259
|
+
return null;
|
|
1260
|
+
}
|
|
1261
|
+
return {
|
|
1262
|
+
to: nftAddress,
|
|
1263
|
+
functionName: "setApprovalForAll",
|
|
1264
|
+
args: [spender, true],
|
|
1265
|
+
abi: ERC721_APPROVAL_ABI
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
async function checkErc20Approval(client, tokenAddress, owner, spender, amount) {
|
|
1269
|
+
const allowance = await actions.readContract(client, {
|
|
1270
|
+
address: tokenAddress,
|
|
1271
|
+
abi: ERC20_APPROVAL_ABI,
|
|
1272
|
+
functionName: "allowance",
|
|
1273
|
+
args: [owner, spender]
|
|
1274
|
+
});
|
|
1275
|
+
if (allowance >= amount) {
|
|
1276
|
+
return null;
|
|
1277
|
+
}
|
|
1278
|
+
return {
|
|
1279
|
+
to: tokenAddress,
|
|
1280
|
+
functionName: "approve",
|
|
1281
|
+
args: [spender, MAX_UINT256],
|
|
1282
|
+
abi: ERC20_APPROVAL_ABI
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
// src/utils/fulfillment.ts
|
|
1287
|
+
var ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
1288
|
+
function formatOrderParameters(params) {
|
|
1289
|
+
return {
|
|
1290
|
+
offerer: params.offerer,
|
|
1291
|
+
zone: params.zone,
|
|
1292
|
+
offer: params.offer.map((item) => ({
|
|
1293
|
+
itemType: item.itemType,
|
|
1294
|
+
token: item.token,
|
|
1295
|
+
identifierOrCriteria: item.identifierOrCriteria,
|
|
1296
|
+
startAmount: item.startAmount,
|
|
1297
|
+
endAmount: item.endAmount
|
|
1298
|
+
})),
|
|
1299
|
+
consideration: params.consideration.map((item) => ({
|
|
1300
|
+
itemType: item.itemType,
|
|
1301
|
+
token: item.token,
|
|
1302
|
+
identifierOrCriteria: item.identifierOrCriteria,
|
|
1303
|
+
startAmount: item.startAmount,
|
|
1304
|
+
endAmount: item.endAmount,
|
|
1305
|
+
recipient: item.recipient
|
|
1306
|
+
})),
|
|
1307
|
+
orderType: params.orderType,
|
|
1308
|
+
startTime: params.startTime,
|
|
1309
|
+
endTime: params.endTime,
|
|
1310
|
+
zoneHash: params.zoneHash,
|
|
1311
|
+
salt: params.salt,
|
|
1312
|
+
conduitKey: params.conduitKey,
|
|
1313
|
+
totalOriginalConsiderationItems: params.totalOriginalConsiderationItems
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
function getNativeConsiderationValue(params) {
|
|
1317
|
+
return params.consideration.reduce((acc, item) => {
|
|
1318
|
+
if (item.itemType === 0 /* NATIVE */) {
|
|
1319
|
+
return acc + item.startAmount;
|
|
1320
|
+
}
|
|
1321
|
+
return acc;
|
|
1322
|
+
}, BigInt(0));
|
|
1323
|
+
}
|
|
1324
|
+
function buildFulfillListingTx(submission, recipient, seaportAddress) {
|
|
1325
|
+
const advancedOrder = {
|
|
1326
|
+
parameters: formatOrderParameters(submission.parameters),
|
|
1327
|
+
numerator: BigInt(1),
|
|
1328
|
+
denominator: BigInt(1),
|
|
1329
|
+
signature: submission.signature,
|
|
1330
|
+
extraData: "0x"
|
|
1331
|
+
};
|
|
1332
|
+
return {
|
|
1333
|
+
to: seaportAddress,
|
|
1334
|
+
functionName: "fulfillAdvancedOrder",
|
|
1335
|
+
args: [advancedOrder, [], ZERO_BYTES32, recipient],
|
|
1336
|
+
abi: SEAPORT_FULFILL_ADVANCED_ORDER_ABI,
|
|
1337
|
+
value: getNativeConsiderationValue(submission.parameters)
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
function buildFulfillCollectionOfferTx(submission, tokenId, recipient, seaportAddress) {
|
|
1341
|
+
const advancedOrder = {
|
|
1342
|
+
parameters: formatOrderParameters(submission.parameters),
|
|
1343
|
+
numerator: BigInt(1),
|
|
1344
|
+
denominator: BigInt(1),
|
|
1345
|
+
signature: submission.signature,
|
|
1346
|
+
extraData: "0x"
|
|
1347
|
+
};
|
|
1348
|
+
const criteriaResolvers = [
|
|
1349
|
+
{
|
|
1350
|
+
orderIndex: BigInt(0),
|
|
1351
|
+
side: 1,
|
|
1352
|
+
// Consideration side
|
|
1353
|
+
index: BigInt(0),
|
|
1354
|
+
// First consideration item (the NFT)
|
|
1355
|
+
identifier: tokenId,
|
|
1356
|
+
criteriaProof: []
|
|
1357
|
+
}
|
|
1358
|
+
];
|
|
1359
|
+
return {
|
|
1360
|
+
to: seaportAddress,
|
|
1361
|
+
functionName: "fulfillAdvancedOrder",
|
|
1362
|
+
args: [advancedOrder, criteriaResolvers, ZERO_BYTES32, recipient],
|
|
1363
|
+
abi: SEAPORT_FULFILL_ADVANCED_ORDER_ABI,
|
|
1364
|
+
value: BigInt(0)
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
function buildFulfillErc20OfferTx(submission, seaportAddress) {
|
|
1368
|
+
const order = {
|
|
1369
|
+
parameters: formatOrderParameters(submission.parameters),
|
|
1370
|
+
signature: submission.signature
|
|
1371
|
+
};
|
|
1372
|
+
return {
|
|
1373
|
+
to: seaportAddress,
|
|
1374
|
+
functionName: "fulfillOrder",
|
|
1375
|
+
args: [order, ZERO_BYTES32],
|
|
1376
|
+
abi: SEAPORT_FULFILL_ORDER_ABI,
|
|
1377
|
+
value: BigInt(0)
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
function buildFulfillErc20ListingTx(submission, recipient, seaportAddress) {
|
|
1381
|
+
const advancedOrder = {
|
|
1382
|
+
parameters: formatOrderParameters(submission.parameters),
|
|
1383
|
+
numerator: BigInt(1),
|
|
1384
|
+
denominator: BigInt(1),
|
|
1385
|
+
signature: submission.signature,
|
|
1386
|
+
extraData: "0x"
|
|
1387
|
+
};
|
|
1388
|
+
return {
|
|
1389
|
+
to: seaportAddress,
|
|
1390
|
+
functionName: "fulfillAdvancedOrder",
|
|
1391
|
+
args: [advancedOrder, [], ZERO_BYTES32, recipient],
|
|
1392
|
+
abi: SEAPORT_FULFILL_ADVANCED_ORDER_ABI,
|
|
1393
|
+
value: getNativeConsiderationValue(submission.parameters)
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1396
|
+
var SEAPORT_EIP712_DOMAIN_NAME = "Seaport";
|
|
1397
|
+
var SEAPORT_EIP712_DOMAIN_VERSION = "1.6";
|
|
1398
|
+
var ZERO_BYTES322 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
1399
|
+
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
1400
|
+
var SEAPORT_ORDER_EIP712_TYPES = {
|
|
1401
|
+
OrderComponents: [
|
|
1402
|
+
{ name: "offerer", type: "address" },
|
|
1403
|
+
{ name: "zone", type: "address" },
|
|
1404
|
+
{ name: "offer", type: "OfferItem[]" },
|
|
1405
|
+
{ name: "consideration", type: "ConsiderationItem[]" },
|
|
1406
|
+
{ name: "orderType", type: "uint8" },
|
|
1407
|
+
{ name: "startTime", type: "uint256" },
|
|
1408
|
+
{ name: "endTime", type: "uint256" },
|
|
1409
|
+
{ name: "zoneHash", type: "bytes32" },
|
|
1410
|
+
{ name: "salt", type: "uint256" },
|
|
1411
|
+
{ name: "conduitKey", type: "bytes32" },
|
|
1412
|
+
{ name: "counter", type: "uint256" }
|
|
1413
|
+
],
|
|
1414
|
+
OfferItem: [
|
|
1415
|
+
{ name: "itemType", type: "uint8" },
|
|
1416
|
+
{ name: "token", type: "address" },
|
|
1417
|
+
{ name: "identifierOrCriteria", type: "uint256" },
|
|
1418
|
+
{ name: "startAmount", type: "uint256" },
|
|
1419
|
+
{ name: "endAmount", type: "uint256" }
|
|
1420
|
+
],
|
|
1421
|
+
ConsiderationItem: [
|
|
1422
|
+
{ name: "itemType", type: "uint8" },
|
|
1423
|
+
{ name: "token", type: "address" },
|
|
1424
|
+
{ name: "identifierOrCriteria", type: "uint256" },
|
|
1425
|
+
{ name: "startAmount", type: "uint256" },
|
|
1426
|
+
{ name: "endAmount", type: "uint256" },
|
|
1427
|
+
{ name: "recipient", type: "address" }
|
|
1428
|
+
]
|
|
1429
|
+
};
|
|
1430
|
+
function calculateFee(price, feeBps, useCeilingDivision) {
|
|
1431
|
+
if (feeBps === 0) return BigInt(0);
|
|
1432
|
+
const fee = price * BigInt(feeBps);
|
|
1433
|
+
if (useCeilingDivision) {
|
|
1434
|
+
return (fee + BigInt(9999)) / BigInt(1e4);
|
|
1435
|
+
}
|
|
1436
|
+
return fee / BigInt(1e4);
|
|
1437
|
+
}
|
|
1438
|
+
function generateSalt() {
|
|
1439
|
+
const bytes = new Uint8Array(32);
|
|
1440
|
+
if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.getRandomValues) {
|
|
1441
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
1442
|
+
} else {
|
|
1443
|
+
for (let i = 0; i < 32; i++) {
|
|
1444
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
let hex = "0x";
|
|
1448
|
+
for (const b of bytes) {
|
|
1449
|
+
hex += b.toString(16).padStart(2, "0");
|
|
1450
|
+
}
|
|
1451
|
+
return BigInt(hex);
|
|
1452
|
+
}
|
|
1453
|
+
function getDefaultExpiration() {
|
|
1454
|
+
return Math.floor(Date.now() / 1e3) + 86400;
|
|
1455
|
+
}
|
|
1456
|
+
function buildListingOrderComponents(params, chainId, counter) {
|
|
1457
|
+
const feeBps = getNftFeeBps(chainId);
|
|
1458
|
+
const feeAmount = calculateFee(params.priceWei, feeBps, false);
|
|
1459
|
+
const sellerAmount = params.priceWei - feeAmount;
|
|
1460
|
+
const endTime = BigInt(params.expirationDate ?? getDefaultExpiration());
|
|
1461
|
+
const feeCollector = getFeeCollectorAddress(chainId);
|
|
1462
|
+
const consideration = [
|
|
1463
|
+
{
|
|
1464
|
+
itemType: 0 /* NATIVE */,
|
|
1465
|
+
token: ZERO_ADDRESS,
|
|
1466
|
+
identifierOrCriteria: BigInt(0),
|
|
1467
|
+
startAmount: sellerAmount,
|
|
1468
|
+
endAmount: sellerAmount,
|
|
1469
|
+
recipient: params.offerer
|
|
1470
|
+
}
|
|
1471
|
+
];
|
|
1472
|
+
if (feeAmount > BigInt(0)) {
|
|
1473
|
+
consideration.push({
|
|
1474
|
+
itemType: 0 /* NATIVE */,
|
|
1475
|
+
token: ZERO_ADDRESS,
|
|
1476
|
+
identifierOrCriteria: BigInt(0),
|
|
1477
|
+
startAmount: feeAmount,
|
|
1478
|
+
endAmount: feeAmount,
|
|
1479
|
+
recipient: feeCollector
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
let zone;
|
|
1483
|
+
let zoneHash;
|
|
1484
|
+
if (params.targetFulfiller) {
|
|
1485
|
+
zone = NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS;
|
|
1486
|
+
zoneHash = viem.keccak256(viem.toBytes(params.targetFulfiller));
|
|
1487
|
+
} else {
|
|
1488
|
+
zone = NET_SEAPORT_ZONE_ADDRESS;
|
|
1489
|
+
zoneHash = ZERO_BYTES322;
|
|
1490
|
+
}
|
|
1491
|
+
const orderParameters = {
|
|
1492
|
+
offerer: params.offerer,
|
|
1493
|
+
zone,
|
|
1494
|
+
offer: [
|
|
1495
|
+
{
|
|
1496
|
+
itemType: 2 /* ERC721 */,
|
|
1497
|
+
token: params.nftAddress,
|
|
1498
|
+
identifierOrCriteria: BigInt(params.tokenId),
|
|
1499
|
+
startAmount: BigInt(1),
|
|
1500
|
+
endAmount: BigInt(1)
|
|
1501
|
+
}
|
|
1502
|
+
],
|
|
1503
|
+
consideration,
|
|
1504
|
+
orderType: 2 /* FULL_RESTRICTED */,
|
|
1505
|
+
startTime: BigInt(0),
|
|
1506
|
+
endTime,
|
|
1507
|
+
zoneHash,
|
|
1508
|
+
salt: generateSalt(),
|
|
1509
|
+
conduitKey: ZERO_BYTES322,
|
|
1510
|
+
totalOriginalConsiderationItems: BigInt(consideration.length)
|
|
1511
|
+
};
|
|
1512
|
+
return { orderParameters, counter };
|
|
1513
|
+
}
|
|
1514
|
+
function buildCollectionOfferOrderComponents(params, chainId, counter) {
|
|
1515
|
+
const weth = getWrappedNativeCurrency(chainId);
|
|
1516
|
+
if (!weth) {
|
|
1517
|
+
throw new Error(`No wrapped native currency configured for chain ${chainId}`);
|
|
1518
|
+
}
|
|
1519
|
+
const feeBps = getNftFeeBps(chainId);
|
|
1520
|
+
const feeAmount = calculateFee(params.priceWei, feeBps, false);
|
|
1521
|
+
const endTime = BigInt(params.expirationDate ?? getDefaultExpiration());
|
|
1522
|
+
const feeCollector = getFeeCollectorAddress(chainId);
|
|
1523
|
+
const consideration = [
|
|
1524
|
+
{
|
|
1525
|
+
itemType: 4 /* ERC721_WITH_CRITERIA */,
|
|
1526
|
+
token: params.nftAddress,
|
|
1527
|
+
identifierOrCriteria: BigInt(0),
|
|
1528
|
+
// Any token in the collection
|
|
1529
|
+
startAmount: BigInt(1),
|
|
1530
|
+
endAmount: BigInt(1),
|
|
1531
|
+
recipient: params.offerer
|
|
1532
|
+
}
|
|
1533
|
+
];
|
|
1534
|
+
if (feeAmount > BigInt(0)) {
|
|
1535
|
+
consideration.push({
|
|
1536
|
+
itemType: 1 /* ERC20 */,
|
|
1537
|
+
token: weth.address,
|
|
1538
|
+
identifierOrCriteria: BigInt(0),
|
|
1539
|
+
startAmount: feeAmount,
|
|
1540
|
+
endAmount: feeAmount,
|
|
1541
|
+
recipient: feeCollector
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
const orderParameters = {
|
|
1545
|
+
offerer: params.offerer,
|
|
1546
|
+
zone: NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS,
|
|
1547
|
+
offer: [
|
|
1548
|
+
{
|
|
1549
|
+
itemType: 1 /* ERC20 */,
|
|
1550
|
+
token: weth.address,
|
|
1551
|
+
identifierOrCriteria: BigInt(0),
|
|
1552
|
+
startAmount: params.priceWei,
|
|
1553
|
+
endAmount: params.priceWei
|
|
1554
|
+
}
|
|
1555
|
+
],
|
|
1556
|
+
consideration,
|
|
1557
|
+
orderType: 2 /* FULL_RESTRICTED */,
|
|
1558
|
+
startTime: BigInt(0),
|
|
1559
|
+
endTime,
|
|
1560
|
+
zoneHash: ZERO_BYTES322,
|
|
1561
|
+
salt: generateSalt(),
|
|
1562
|
+
conduitKey: ZERO_BYTES322,
|
|
1563
|
+
totalOriginalConsiderationItems: BigInt(consideration.length)
|
|
1564
|
+
};
|
|
1565
|
+
return { orderParameters, counter };
|
|
1566
|
+
}
|
|
1567
|
+
function buildErc20OfferOrderComponents(params, chainId, counter) {
|
|
1568
|
+
const weth = getWrappedNativeCurrency(chainId);
|
|
1569
|
+
if (!weth) {
|
|
1570
|
+
throw new Error(`No wrapped native currency configured for chain ${chainId}`);
|
|
1571
|
+
}
|
|
1572
|
+
const feeBps = getNftFeeBps(chainId);
|
|
1573
|
+
const feeAmount = calculateFee(params.priceWei, feeBps, true);
|
|
1574
|
+
const endTime = BigInt(params.expirationDate ?? getDefaultExpiration());
|
|
1575
|
+
const feeCollector = getFeeCollectorAddress(chainId);
|
|
1576
|
+
const consideration = [
|
|
1577
|
+
{
|
|
1578
|
+
itemType: 1 /* ERC20 */,
|
|
1579
|
+
token: params.tokenAddress,
|
|
1580
|
+
identifierOrCriteria: BigInt(0),
|
|
1581
|
+
startAmount: params.tokenAmount,
|
|
1582
|
+
endAmount: params.tokenAmount,
|
|
1583
|
+
recipient: params.offerer
|
|
1584
|
+
}
|
|
1585
|
+
];
|
|
1586
|
+
if (feeAmount > BigInt(0)) {
|
|
1587
|
+
consideration.push({
|
|
1588
|
+
itemType: 1 /* ERC20 */,
|
|
1589
|
+
token: weth.address,
|
|
1590
|
+
identifierOrCriteria: BigInt(0),
|
|
1591
|
+
startAmount: feeAmount,
|
|
1592
|
+
endAmount: feeAmount,
|
|
1593
|
+
recipient: feeCollector
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
const orderParameters = {
|
|
1597
|
+
offerer: params.offerer,
|
|
1598
|
+
zone: NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS,
|
|
1599
|
+
offer: [
|
|
1600
|
+
{
|
|
1601
|
+
itemType: 1 /* ERC20 */,
|
|
1602
|
+
token: weth.address,
|
|
1603
|
+
identifierOrCriteria: BigInt(0),
|
|
1604
|
+
startAmount: params.priceWei,
|
|
1605
|
+
endAmount: params.priceWei
|
|
1606
|
+
}
|
|
1607
|
+
],
|
|
1608
|
+
consideration,
|
|
1609
|
+
orderType: 2 /* FULL_RESTRICTED */,
|
|
1610
|
+
startTime: BigInt(0),
|
|
1611
|
+
endTime,
|
|
1612
|
+
zoneHash: ZERO_BYTES322,
|
|
1613
|
+
salt: generateSalt(),
|
|
1614
|
+
conduitKey: ZERO_BYTES322,
|
|
1615
|
+
totalOriginalConsiderationItems: BigInt(consideration.length)
|
|
1616
|
+
};
|
|
1617
|
+
return { orderParameters, counter };
|
|
1618
|
+
}
|
|
1619
|
+
function buildErc20ListingOrderComponents(params, chainId, counter) {
|
|
1620
|
+
const feeBps = getNftFeeBps(chainId);
|
|
1621
|
+
const feeAmount = calculateFee(params.priceWei, feeBps, true);
|
|
1622
|
+
const sellerAmount = params.priceWei - feeAmount;
|
|
1623
|
+
const endTime = BigInt(params.expirationDate ?? getDefaultExpiration());
|
|
1624
|
+
const feeCollector = getFeeCollectorAddress(chainId);
|
|
1625
|
+
const consideration = [
|
|
1626
|
+
{
|
|
1627
|
+
itemType: 0 /* NATIVE */,
|
|
1628
|
+
token: ZERO_ADDRESS,
|
|
1629
|
+
identifierOrCriteria: BigInt(0),
|
|
1630
|
+
startAmount: sellerAmount,
|
|
1631
|
+
endAmount: sellerAmount,
|
|
1632
|
+
recipient: params.offerer
|
|
1633
|
+
}
|
|
1634
|
+
];
|
|
1635
|
+
if (feeAmount > BigInt(0)) {
|
|
1636
|
+
consideration.push({
|
|
1637
|
+
itemType: 0 /* NATIVE */,
|
|
1638
|
+
token: ZERO_ADDRESS,
|
|
1639
|
+
identifierOrCriteria: BigInt(0),
|
|
1640
|
+
startAmount: feeAmount,
|
|
1641
|
+
endAmount: feeAmount,
|
|
1642
|
+
recipient: feeCollector
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
let zone;
|
|
1646
|
+
let zoneHash;
|
|
1647
|
+
if (params.targetFulfiller) {
|
|
1648
|
+
zone = NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS;
|
|
1649
|
+
zoneHash = viem.keccak256(viem.toBytes(params.targetFulfiller));
|
|
1650
|
+
} else {
|
|
1651
|
+
zone = NET_SEAPORT_ZONE_ADDRESS;
|
|
1652
|
+
zoneHash = ZERO_BYTES322;
|
|
1653
|
+
}
|
|
1654
|
+
const orderParameters = {
|
|
1655
|
+
offerer: params.offerer,
|
|
1656
|
+
zone,
|
|
1657
|
+
offer: [
|
|
1658
|
+
{
|
|
1659
|
+
itemType: 1 /* ERC20 */,
|
|
1660
|
+
token: params.tokenAddress,
|
|
1661
|
+
identifierOrCriteria: BigInt(0),
|
|
1662
|
+
startAmount: params.tokenAmount,
|
|
1663
|
+
endAmount: params.tokenAmount
|
|
1664
|
+
}
|
|
1665
|
+
],
|
|
1666
|
+
consideration,
|
|
1667
|
+
orderType: 2 /* FULL_RESTRICTED */,
|
|
1668
|
+
startTime: BigInt(0),
|
|
1669
|
+
endTime,
|
|
1670
|
+
zoneHash,
|
|
1671
|
+
salt: generateSalt(),
|
|
1672
|
+
conduitKey: ZERO_BYTES322,
|
|
1673
|
+
totalOriginalConsiderationItems: BigInt(consideration.length)
|
|
1674
|
+
};
|
|
1675
|
+
return { orderParameters, counter };
|
|
1676
|
+
}
|
|
1677
|
+
function buildEIP712OrderData(orderParameters, counter, chainId, seaportAddress) {
|
|
1678
|
+
const message = {
|
|
1679
|
+
offerer: orderParameters.offerer,
|
|
1680
|
+
zone: orderParameters.zone,
|
|
1681
|
+
offer: orderParameters.offer.map((item) => ({
|
|
1682
|
+
itemType: item.itemType,
|
|
1683
|
+
token: item.token,
|
|
1684
|
+
identifierOrCriteria: item.identifierOrCriteria,
|
|
1685
|
+
startAmount: item.startAmount,
|
|
1686
|
+
endAmount: item.endAmount
|
|
1687
|
+
})),
|
|
1688
|
+
consideration: orderParameters.consideration.map((item) => ({
|
|
1689
|
+
itemType: item.itemType,
|
|
1690
|
+
token: item.token,
|
|
1691
|
+
identifierOrCriteria: item.identifierOrCriteria,
|
|
1692
|
+
startAmount: item.startAmount,
|
|
1693
|
+
endAmount: item.endAmount,
|
|
1694
|
+
recipient: item.recipient
|
|
1695
|
+
})),
|
|
1696
|
+
orderType: orderParameters.orderType,
|
|
1697
|
+
startTime: orderParameters.startTime,
|
|
1698
|
+
endTime: orderParameters.endTime,
|
|
1699
|
+
zoneHash: orderParameters.zoneHash,
|
|
1700
|
+
salt: orderParameters.salt,
|
|
1701
|
+
conduitKey: orderParameters.conduitKey,
|
|
1702
|
+
counter
|
|
1703
|
+
};
|
|
1704
|
+
return {
|
|
1705
|
+
domain: {
|
|
1706
|
+
name: SEAPORT_EIP712_DOMAIN_NAME,
|
|
1707
|
+
version: SEAPORT_EIP712_DOMAIN_VERSION,
|
|
1708
|
+
chainId,
|
|
1709
|
+
verifyingContract: seaportAddress
|
|
1710
|
+
},
|
|
1711
|
+
types: SEAPORT_ORDER_EIP712_TYPES,
|
|
1712
|
+
primaryType: "OrderComponents",
|
|
1713
|
+
message,
|
|
1714
|
+
orderParameters,
|
|
1715
|
+
counter
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
function buildSubmitOrderTx(contractAddress, abi, orderParameters, counter, signature) {
|
|
1719
|
+
const submission = {
|
|
1720
|
+
parameters: {
|
|
1721
|
+
offerer: orderParameters.offerer,
|
|
1722
|
+
zone: orderParameters.zone,
|
|
1723
|
+
offer: orderParameters.offer.map((item) => ({
|
|
1724
|
+
itemType: item.itemType,
|
|
1725
|
+
token: item.token,
|
|
1726
|
+
identifierOrCriteria: item.identifierOrCriteria,
|
|
1727
|
+
startAmount: item.startAmount,
|
|
1728
|
+
endAmount: item.endAmount
|
|
1729
|
+
})),
|
|
1730
|
+
consideration: orderParameters.consideration.map((item) => ({
|
|
1731
|
+
itemType: item.itemType,
|
|
1732
|
+
token: item.token,
|
|
1733
|
+
identifierOrCriteria: item.identifierOrCriteria,
|
|
1734
|
+
startAmount: item.startAmount,
|
|
1735
|
+
endAmount: item.endAmount,
|
|
1736
|
+
recipient: item.recipient
|
|
1737
|
+
})),
|
|
1738
|
+
orderType: orderParameters.orderType,
|
|
1739
|
+
startTime: orderParameters.startTime,
|
|
1740
|
+
endTime: orderParameters.endTime,
|
|
1741
|
+
zoneHash: orderParameters.zoneHash,
|
|
1742
|
+
salt: orderParameters.salt,
|
|
1743
|
+
conduitKey: orderParameters.conduitKey,
|
|
1744
|
+
totalOriginalConsiderationItems: orderParameters.totalOriginalConsiderationItems
|
|
1745
|
+
},
|
|
1746
|
+
counter,
|
|
1747
|
+
signature
|
|
1748
|
+
};
|
|
1749
|
+
return {
|
|
1750
|
+
to: contractAddress,
|
|
1751
|
+
functionName: "submit",
|
|
1752
|
+
args: [submission],
|
|
1753
|
+
abi
|
|
1754
|
+
};
|
|
1755
|
+
}
|
|
1756
|
+
var ERC721_TOKEN_OWNER_RANGE_HELPER_ADDRESS = "0x00000000f4ec2016d6e856b0cb14d635949bfd3f";
|
|
1757
|
+
var ERC721_TOKEN_OWNER_RANGE_HELPER_ABI = [
|
|
1758
|
+
{
|
|
1759
|
+
inputs: [
|
|
1760
|
+
{ name: "nftContract", type: "address" },
|
|
1761
|
+
{ name: "user", type: "address" },
|
|
1762
|
+
{ name: "startTokenId", type: "uint256" },
|
|
1763
|
+
{ name: "endTokenId", type: "uint256" }
|
|
1764
|
+
],
|
|
1765
|
+
name: "getOwnedTokensInRange",
|
|
1766
|
+
outputs: [{ name: "", type: "uint256[]" }],
|
|
1767
|
+
stateMutability: "view",
|
|
1768
|
+
type: "function"
|
|
1769
|
+
}
|
|
1770
|
+
];
|
|
1771
|
+
var OWNED_TOKENS_BATCH_SIZE = 5000n;
|
|
875
1772
|
var CHAIN_RPC_URLS = {
|
|
876
1773
|
8453: ["https://base-mainnet.public.blastapi.io", "https://mainnet.base.org"],
|
|
877
1774
|
84532: ["https://sepolia.base.org"],
|
|
@@ -934,7 +1831,7 @@ var BazaarClient = class {
|
|
|
934
1831
|
const bazaarAddress = getBazaarAddress(this.chainId);
|
|
935
1832
|
const filter = {
|
|
936
1833
|
appAddress: bazaarAddress,
|
|
937
|
-
topic: nftAddress
|
|
1834
|
+
topic: nftAddress?.toLowerCase(),
|
|
938
1835
|
maker
|
|
939
1836
|
};
|
|
940
1837
|
let startIndex;
|
|
@@ -1007,18 +1904,57 @@ var BazaarClient = class {
|
|
|
1007
1904
|
}
|
|
1008
1905
|
const openListings = listings.filter((l) => l.orderStatus === 2 /* OPEN */);
|
|
1009
1906
|
const expiredListings = includeExpired ? listings.filter((l) => l.orderStatus === 1 /* EXPIRED */) : [];
|
|
1010
|
-
|
|
1011
|
-
const owners = await bulkFetchNftOwners(this.client, nftAddress, tokenIds);
|
|
1907
|
+
let validOpenListings;
|
|
1012
1908
|
const beforeOwnership = openListings.length;
|
|
1013
|
-
|
|
1014
|
-
const
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1909
|
+
if (nftAddress) {
|
|
1910
|
+
const tokenIds = openListings.map((l) => l.tokenId);
|
|
1911
|
+
const owners = await bulkFetchNftOwners(this.client, nftAddress, tokenIds);
|
|
1912
|
+
validOpenListings = openListings.filter((listing, index) => {
|
|
1913
|
+
const owner = owners[index];
|
|
1914
|
+
return isListingValid(
|
|
1915
|
+
listing.orderStatus,
|
|
1916
|
+
listing.expirationDate,
|
|
1917
|
+
listing.maker,
|
|
1918
|
+
owner
|
|
1919
|
+
);
|
|
1920
|
+
});
|
|
1921
|
+
} else {
|
|
1922
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1923
|
+
for (const listing of openListings) {
|
|
1924
|
+
const key = listing.nftAddress.toLowerCase();
|
|
1925
|
+
const group = groups.get(key);
|
|
1926
|
+
if (group) {
|
|
1927
|
+
group.push(listing);
|
|
1928
|
+
} else {
|
|
1929
|
+
groups.set(key, [listing]);
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
const groupEntries = Array.from(groups.entries());
|
|
1933
|
+
const ownerResults = await Promise.all(
|
|
1934
|
+
groupEntries.map(
|
|
1935
|
+
([addr, groupListings]) => bulkFetchNftOwners(
|
|
1936
|
+
this.client,
|
|
1937
|
+
addr,
|
|
1938
|
+
groupListings.map((l) => l.tokenId)
|
|
1939
|
+
)
|
|
1940
|
+
)
|
|
1020
1941
|
);
|
|
1021
|
-
|
|
1942
|
+
validOpenListings = [];
|
|
1943
|
+
groupEntries.forEach(([, groupListings], groupIndex) => {
|
|
1944
|
+
const owners = ownerResults[groupIndex];
|
|
1945
|
+
for (let i = 0; i < groupListings.length; i++) {
|
|
1946
|
+
const listing = groupListings[i];
|
|
1947
|
+
if (isListingValid(
|
|
1948
|
+
listing.orderStatus,
|
|
1949
|
+
listing.expirationDate,
|
|
1950
|
+
listing.maker,
|
|
1951
|
+
owners[i]
|
|
1952
|
+
)) {
|
|
1953
|
+
validOpenListings.push(listing);
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
});
|
|
1957
|
+
}
|
|
1022
1958
|
console.log(tag, `after ownership filter: ${validOpenListings.length}/${beforeOwnership} (${beforeOwnership - validOpenListings.length} dropped)`);
|
|
1023
1959
|
const dedupedOpen = sortListingsByPrice(getBestListingPerToken(validOpenListings));
|
|
1024
1960
|
const activeTokenKeys = new Set(dedupedOpen.map((l) => `${l.nftAddress.toLowerCase()}-${l.tokenId}`));
|
|
@@ -1530,6 +2466,290 @@ var BazaarClient = class {
|
|
|
1530
2466
|
abi: SEAPORT_CANCEL_ABI
|
|
1531
2467
|
};
|
|
1532
2468
|
}
|
|
2469
|
+
// ─── Fulfillment Methods ───────────────────────────────────────────
|
|
2470
|
+
/**
|
|
2471
|
+
* Prepare a fulfillment for an NFT listing (buy an NFT).
|
|
2472
|
+
*
|
|
2473
|
+
* Returns approval transactions (if the listing requires ERC20 payment) and
|
|
2474
|
+
* the Seaport `fulfillAdvancedOrder` transaction with the correct native currency value.
|
|
2475
|
+
*/
|
|
2476
|
+
async prepareFulfillListing(listing, fulfillerAddress) {
|
|
2477
|
+
const submission = decodeSeaportSubmission(listing.messageData);
|
|
2478
|
+
const seaportAddress = getSeaportAddress(this.chainId);
|
|
2479
|
+
const fulfillment = buildFulfillListingTx(submission, fulfillerAddress, seaportAddress);
|
|
2480
|
+
return { approvals: [], fulfillment };
|
|
2481
|
+
}
|
|
2482
|
+
/**
|
|
2483
|
+
* Prepare a fulfillment for a collection offer (sell your NFT into an offer).
|
|
2484
|
+
*
|
|
2485
|
+
* Returns ERC721 approval transaction (if the NFT isn't approved for Seaport)
|
|
2486
|
+
* and the Seaport `fulfillAdvancedOrder` transaction.
|
|
2487
|
+
*/
|
|
2488
|
+
async prepareFulfillCollectionOffer(offer, tokenId, fulfillerAddress) {
|
|
2489
|
+
const submission = decodeSeaportSubmission(offer.messageData);
|
|
2490
|
+
const seaportAddress = getSeaportAddress(this.chainId);
|
|
2491
|
+
const approvals = [];
|
|
2492
|
+
const nftApproval = await checkErc721Approval(
|
|
2493
|
+
this.client,
|
|
2494
|
+
offer.nftAddress,
|
|
2495
|
+
fulfillerAddress,
|
|
2496
|
+
seaportAddress
|
|
2497
|
+
);
|
|
2498
|
+
if (nftApproval) {
|
|
2499
|
+
approvals.push(nftApproval);
|
|
2500
|
+
}
|
|
2501
|
+
const fulfillment = buildFulfillCollectionOfferTx(
|
|
2502
|
+
submission,
|
|
2503
|
+
BigInt(tokenId),
|
|
2504
|
+
fulfillerAddress,
|
|
2505
|
+
seaportAddress
|
|
2506
|
+
);
|
|
2507
|
+
return { approvals, fulfillment };
|
|
2508
|
+
}
|
|
2509
|
+
/**
|
|
2510
|
+
* Prepare a fulfillment for an ERC20 offer (sell your ERC20 tokens into an offer).
|
|
2511
|
+
*
|
|
2512
|
+
* Returns ERC20 approval transaction (if the token isn't approved for Seaport)
|
|
2513
|
+
* and the Seaport `fulfillOrder` transaction.
|
|
2514
|
+
*/
|
|
2515
|
+
async prepareFulfillErc20Offer(offer, fulfillerAddress) {
|
|
2516
|
+
const submission = decodeSeaportSubmission(offer.messageData);
|
|
2517
|
+
const seaportAddress = getSeaportAddress(this.chainId);
|
|
2518
|
+
const approvals = [];
|
|
2519
|
+
const tokenApproval = await checkErc20Approval(
|
|
2520
|
+
this.client,
|
|
2521
|
+
offer.tokenAddress,
|
|
2522
|
+
fulfillerAddress,
|
|
2523
|
+
seaportAddress,
|
|
2524
|
+
offer.tokenAmount
|
|
2525
|
+
);
|
|
2526
|
+
if (tokenApproval) {
|
|
2527
|
+
approvals.push(tokenApproval);
|
|
2528
|
+
}
|
|
2529
|
+
const fulfillment = buildFulfillErc20OfferTx(submission, seaportAddress);
|
|
2530
|
+
return { approvals, fulfillment };
|
|
2531
|
+
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Prepare a fulfillment for an ERC20 listing (buy ERC20 tokens with native currency).
|
|
2534
|
+
*
|
|
2535
|
+
* Returns the Seaport `fulfillAdvancedOrder` transaction with the correct native currency value.
|
|
2536
|
+
* No approvals needed since the buyer pays in native currency.
|
|
2537
|
+
*/
|
|
2538
|
+
async prepareFulfillErc20Listing(listing, fulfillerAddress) {
|
|
2539
|
+
const submission = decodeSeaportSubmission(listing.messageData);
|
|
2540
|
+
const seaportAddress = getSeaportAddress(this.chainId);
|
|
2541
|
+
const fulfillment = buildFulfillErc20ListingTx(submission, fulfillerAddress, seaportAddress);
|
|
2542
|
+
return { approvals: [], fulfillment };
|
|
2543
|
+
}
|
|
2544
|
+
// ─── Order Creation Methods (Step 1: Build EIP-712 data) ──────────
|
|
2545
|
+
/**
|
|
2546
|
+
* Fetch the Seaport counter for an address
|
|
2547
|
+
*/
|
|
2548
|
+
async getSeaportCounter(offerer) {
|
|
2549
|
+
const seaportAddress = getSeaportAddress(this.chainId);
|
|
2550
|
+
const counter = await actions.readContract(this.client, {
|
|
2551
|
+
address: seaportAddress,
|
|
2552
|
+
abi: SEAPORT_GET_COUNTER_ABI,
|
|
2553
|
+
functionName: "getCounter",
|
|
2554
|
+
args: [offerer]
|
|
2555
|
+
});
|
|
2556
|
+
return BigInt(counter);
|
|
2557
|
+
}
|
|
2558
|
+
/**
|
|
2559
|
+
* Prepare an NFT listing order for signing.
|
|
2560
|
+
*
|
|
2561
|
+
* Returns EIP-712 typed data for the caller to sign, plus any maker approvals needed
|
|
2562
|
+
* (ERC721 `setApprovalForAll` for Seaport).
|
|
2563
|
+
*/
|
|
2564
|
+
async prepareCreateListing(params) {
|
|
2565
|
+
const seaportAddress = getSeaportAddress(this.chainId);
|
|
2566
|
+
const counter = await this.getSeaportCounter(params.offerer);
|
|
2567
|
+
const { orderParameters } = buildListingOrderComponents(params, this.chainId, counter);
|
|
2568
|
+
const eip712 = buildEIP712OrderData(orderParameters, counter, this.chainId, seaportAddress);
|
|
2569
|
+
const approvals = [];
|
|
2570
|
+
const nftApproval = await checkErc721Approval(
|
|
2571
|
+
this.client,
|
|
2572
|
+
params.nftAddress,
|
|
2573
|
+
params.offerer,
|
|
2574
|
+
seaportAddress
|
|
2575
|
+
);
|
|
2576
|
+
if (nftApproval) {
|
|
2577
|
+
approvals.push(nftApproval);
|
|
2578
|
+
}
|
|
2579
|
+
return { eip712, approvals };
|
|
2580
|
+
}
|
|
2581
|
+
/**
|
|
2582
|
+
* Prepare a collection offer order for signing.
|
|
2583
|
+
*
|
|
2584
|
+
* Returns EIP-712 typed data for the caller to sign, plus any maker approvals needed
|
|
2585
|
+
* (WETH `approve` for Seaport).
|
|
2586
|
+
*/
|
|
2587
|
+
async prepareCreateCollectionOffer(params) {
|
|
2588
|
+
const seaportAddress = getSeaportAddress(this.chainId);
|
|
2589
|
+
const weth = getWrappedNativeCurrency(this.chainId);
|
|
2590
|
+
if (!weth) {
|
|
2591
|
+
throw new Error(`No wrapped native currency configured for chain ${this.chainId}`);
|
|
2592
|
+
}
|
|
2593
|
+
const counter = await this.getSeaportCounter(params.offerer);
|
|
2594
|
+
const { orderParameters } = buildCollectionOfferOrderComponents(params, this.chainId, counter);
|
|
2595
|
+
const eip712 = buildEIP712OrderData(orderParameters, counter, this.chainId, seaportAddress);
|
|
2596
|
+
const approvals = [];
|
|
2597
|
+
const wethApproval = await checkErc20Approval(
|
|
2598
|
+
this.client,
|
|
2599
|
+
weth.address,
|
|
2600
|
+
params.offerer,
|
|
2601
|
+
seaportAddress,
|
|
2602
|
+
params.priceWei
|
|
2603
|
+
);
|
|
2604
|
+
if (wethApproval) {
|
|
2605
|
+
approvals.push(wethApproval);
|
|
2606
|
+
}
|
|
2607
|
+
return { eip712, approvals };
|
|
2608
|
+
}
|
|
2609
|
+
/**
|
|
2610
|
+
* Prepare an ERC20 offer order for signing.
|
|
2611
|
+
*
|
|
2612
|
+
* Returns EIP-712 typed data for the caller to sign, plus any maker approvals needed
|
|
2613
|
+
* (WETH `approve` for Seaport).
|
|
2614
|
+
*/
|
|
2615
|
+
async prepareCreateErc20Offer(params) {
|
|
2616
|
+
const seaportAddress = getSeaportAddress(this.chainId);
|
|
2617
|
+
const weth = getWrappedNativeCurrency(this.chainId);
|
|
2618
|
+
if (!weth) {
|
|
2619
|
+
throw new Error(`No wrapped native currency configured for chain ${this.chainId}`);
|
|
2620
|
+
}
|
|
2621
|
+
const counter = await this.getSeaportCounter(params.offerer);
|
|
2622
|
+
const { orderParameters } = buildErc20OfferOrderComponents(params, this.chainId, counter);
|
|
2623
|
+
const eip712 = buildEIP712OrderData(orderParameters, counter, this.chainId, seaportAddress);
|
|
2624
|
+
const approvals = [];
|
|
2625
|
+
const wethApproval = await checkErc20Approval(
|
|
2626
|
+
this.client,
|
|
2627
|
+
weth.address,
|
|
2628
|
+
params.offerer,
|
|
2629
|
+
seaportAddress,
|
|
2630
|
+
params.priceWei
|
|
2631
|
+
);
|
|
2632
|
+
if (wethApproval) {
|
|
2633
|
+
approvals.push(wethApproval);
|
|
2634
|
+
}
|
|
2635
|
+
return { eip712, approvals };
|
|
2636
|
+
}
|
|
2637
|
+
/**
|
|
2638
|
+
* Prepare an ERC20 listing order for signing.
|
|
2639
|
+
*
|
|
2640
|
+
* Returns EIP-712 typed data for the caller to sign, plus any maker approvals needed
|
|
2641
|
+
* (ERC20 `approve` for Seaport).
|
|
2642
|
+
*/
|
|
2643
|
+
async prepareCreateErc20Listing(params) {
|
|
2644
|
+
const seaportAddress = getSeaportAddress(this.chainId);
|
|
2645
|
+
const counter = await this.getSeaportCounter(params.offerer);
|
|
2646
|
+
const { orderParameters } = buildErc20ListingOrderComponents(params, this.chainId, counter);
|
|
2647
|
+
const eip712 = buildEIP712OrderData(orderParameters, counter, this.chainId, seaportAddress);
|
|
2648
|
+
const approvals = [];
|
|
2649
|
+
const tokenApproval = await checkErc20Approval(
|
|
2650
|
+
this.client,
|
|
2651
|
+
params.tokenAddress,
|
|
2652
|
+
params.offerer,
|
|
2653
|
+
seaportAddress,
|
|
2654
|
+
params.tokenAmount
|
|
2655
|
+
);
|
|
2656
|
+
if (tokenApproval) {
|
|
2657
|
+
approvals.push(tokenApproval);
|
|
2658
|
+
}
|
|
2659
|
+
return { eip712, approvals };
|
|
2660
|
+
}
|
|
2661
|
+
// ─── Order Creation Methods (Step 2: Submit signed order) ─────────
|
|
2662
|
+
/**
|
|
2663
|
+
* Prepare a submit transaction for an NFT listing.
|
|
2664
|
+
*
|
|
2665
|
+
* Call this after the user has signed the EIP-712 data from prepareCreateListing().
|
|
2666
|
+
*/
|
|
2667
|
+
prepareSubmitListing(orderParameters, counter, signature) {
|
|
2668
|
+
return buildSubmitOrderTx(
|
|
2669
|
+
getBazaarAddress(this.chainId),
|
|
2670
|
+
BAZAAR_V2_ABI,
|
|
2671
|
+
orderParameters,
|
|
2672
|
+
counter,
|
|
2673
|
+
signature
|
|
2674
|
+
);
|
|
2675
|
+
}
|
|
2676
|
+
/**
|
|
2677
|
+
* Prepare a submit transaction for a collection offer.
|
|
2678
|
+
*
|
|
2679
|
+
* Call this after the user has signed the EIP-712 data from prepareCreateCollectionOffer().
|
|
2680
|
+
*/
|
|
2681
|
+
prepareSubmitCollectionOffer(orderParameters, counter, signature) {
|
|
2682
|
+
return buildSubmitOrderTx(
|
|
2683
|
+
getCollectionOffersAddress(this.chainId),
|
|
2684
|
+
BAZAAR_COLLECTION_OFFERS_ABI,
|
|
2685
|
+
orderParameters,
|
|
2686
|
+
counter,
|
|
2687
|
+
signature
|
|
2688
|
+
);
|
|
2689
|
+
}
|
|
2690
|
+
/**
|
|
2691
|
+
* Prepare a submit transaction for an ERC20 offer.
|
|
2692
|
+
*
|
|
2693
|
+
* Call this after the user has signed the EIP-712 data from prepareCreateErc20Offer().
|
|
2694
|
+
*/
|
|
2695
|
+
prepareSubmitErc20Offer(orderParameters, counter, signature) {
|
|
2696
|
+
const erc20OffersAddress = getErc20OffersAddress(this.chainId);
|
|
2697
|
+
if (!erc20OffersAddress) {
|
|
2698
|
+
throw new Error(`ERC20 offers not available on chain ${this.chainId}`);
|
|
2699
|
+
}
|
|
2700
|
+
return buildSubmitOrderTx(
|
|
2701
|
+
erc20OffersAddress,
|
|
2702
|
+
BAZAAR_ERC20_OFFERS_ABI,
|
|
2703
|
+
orderParameters,
|
|
2704
|
+
counter,
|
|
2705
|
+
signature
|
|
2706
|
+
);
|
|
2707
|
+
}
|
|
2708
|
+
/**
|
|
2709
|
+
* Prepare a submit transaction for an ERC20 listing.
|
|
2710
|
+
*
|
|
2711
|
+
* Call this after the user has signed the EIP-712 data from prepareCreateErc20Listing().
|
|
2712
|
+
*/
|
|
2713
|
+
prepareSubmitErc20Listing(orderParameters, counter, signature) {
|
|
2714
|
+
return buildSubmitOrderTx(
|
|
2715
|
+
getErc20BazaarAddress(this.chainId),
|
|
2716
|
+
BAZAAR_V2_ABI,
|
|
2717
|
+
orderParameters,
|
|
2718
|
+
counter,
|
|
2719
|
+
signature
|
|
2720
|
+
);
|
|
2721
|
+
}
|
|
2722
|
+
// ─── Owned Tokens Query ─────────────────────────────────────────────
|
|
2723
|
+
/**
|
|
2724
|
+
* Get token IDs owned by an address for an ERC721 collection.
|
|
2725
|
+
*
|
|
2726
|
+
* Uses the on-chain ERC721TokenOwnerRangeHelper contract, batching
|
|
2727
|
+
* large ranges into 5000-token chunks to avoid RPC limits.
|
|
2728
|
+
*/
|
|
2729
|
+
async getOwnedTokens(params) {
|
|
2730
|
+
const { nftAddress, ownerAddress } = params;
|
|
2731
|
+
const startTokenId = params.startTokenId ?? 0n;
|
|
2732
|
+
const endTokenId = params.endTokenId ?? 10000n;
|
|
2733
|
+
const ownedTokens = [];
|
|
2734
|
+
let current = startTokenId;
|
|
2735
|
+
while (current < endTokenId) {
|
|
2736
|
+
const batchEnd = current + OWNED_TOKENS_BATCH_SIZE < endTokenId ? current + OWNED_TOKENS_BATCH_SIZE : endTokenId;
|
|
2737
|
+
try {
|
|
2738
|
+
const result = await actions.readContract(this.client, {
|
|
2739
|
+
address: ERC721_TOKEN_OWNER_RANGE_HELPER_ADDRESS,
|
|
2740
|
+
abi: ERC721_TOKEN_OWNER_RANGE_HELPER_ABI,
|
|
2741
|
+
functionName: "getOwnedTokensInRange",
|
|
2742
|
+
args: [nftAddress, ownerAddress, current, batchEnd]
|
|
2743
|
+
});
|
|
2744
|
+
for (const tokenId of result) {
|
|
2745
|
+
ownedTokens.push(tokenId);
|
|
2746
|
+
}
|
|
2747
|
+
} catch {
|
|
2748
|
+
}
|
|
2749
|
+
current = batchEnd;
|
|
2750
|
+
}
|
|
2751
|
+
return ownedTokens;
|
|
2752
|
+
}
|
|
1533
2753
|
};
|
|
1534
2754
|
|
|
1535
2755
|
// src/hooks/useBazaarListings.ts
|
|
@@ -1563,7 +2783,7 @@ function useBazaarListings({
|
|
|
1563
2783
|
const filter = react.useMemo(
|
|
1564
2784
|
() => ({
|
|
1565
2785
|
appAddress: bazaarAddress,
|
|
1566
|
-
topic: nftAddress
|
|
2786
|
+
topic: nftAddress?.toLowerCase(),
|
|
1567
2787
|
maker
|
|
1568
2788
|
}),
|
|
1569
2789
|
[bazaarAddress, nftAddress, maker]
|
|
@@ -1587,7 +2807,7 @@ function useBazaarListings({
|
|
|
1587
2807
|
endIndex,
|
|
1588
2808
|
enabled: enabled && isSupported && (hasRangeOverride || totalCount > 0)
|
|
1589
2809
|
});
|
|
1590
|
-
const TAG = `[useBazaarListings chain=${chainId} nft=${nftAddress
|
|
2810
|
+
const TAG = `[useBazaarListings chain=${chainId} nft=${nftAddress?.slice(0, 10) ?? "all"}]`;
|
|
1591
2811
|
react.useEffect(() => {
|
|
1592
2812
|
console.log(TAG, {
|
|
1593
2813
|
enabled,
|