@net-protocol/bazaar 0.1.2 → 0.1.4
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/README.md +3 -3
- package/dist/index.d.mts +35 -6
- package/dist/index.d.ts +35 -6
- package/dist/index.js +164 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -52
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +10 -3
- package/dist/react.d.ts +10 -3
- package/dist/react.js +270 -88
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +270 -88
- package/dist/react.mjs.map +1 -1
- package/dist/{types-KQgBECzI.d.mts → types-DDHh9yJB.d.mts} +2 -0
- package/dist/{types-KQgBECzI.d.ts → types-DDHh9yJB.d.ts} +2 -0
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -357,8 +357,8 @@ var DEFAULT_FEE_COLLECTOR_ADDRESS = "0x32D16C15410248bef498D7aF50D10Db1a546b9E5"
|
|
|
357
357
|
var DEFAULT_ERC20_BAZAAR_ADDRESS = "0x00000000a2d173a4610c85c7471a25b6bc216a70";
|
|
358
358
|
var DEFAULT_NFT_FEE_BPS = 500;
|
|
359
359
|
var BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS = "0x0000009112ABCE652674b4fE3eD9C765B22d11A7";
|
|
360
|
-
var ERC721_OWNER_OF_HELPER_ADDRESS = "
|
|
361
|
-
var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "
|
|
360
|
+
var ERC721_OWNER_OF_HELPER_ADDRESS = "0x00000012E3eb0700925947fAF9cd1440319b4F37";
|
|
361
|
+
var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "0x000000B50A9f2923F2DB931391824F6D1278f712";
|
|
362
362
|
var NET_SEAPORT_ZONE_ADDRESS = "0x000000007F8c58fbf215bF91Bda7421A806cf3ae";
|
|
363
363
|
var NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS = "0x000000B799ec6D7aCC1B578f62bFc324c25DFC5A";
|
|
364
364
|
var NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS = "0x000000bC63761cbb05305632212e2f3AE2BE7a9B";
|
|
@@ -649,18 +649,26 @@ async function bulkFetchOrderStatuses(client, chainId, orderHashes) {
|
|
|
649
649
|
return [];
|
|
650
650
|
}
|
|
651
651
|
const seaportAddress = getSeaportAddress(chainId);
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
652
|
+
try {
|
|
653
|
+
console.log(`[bulkFetchOrderStatuses] fetching ${orderHashes.length} statuses via ${BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS}`);
|
|
654
|
+
const results = await readContract(client, {
|
|
655
|
+
address: BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS,
|
|
656
|
+
abi: BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI,
|
|
657
|
+
functionName: "getOrderStatuses",
|
|
658
|
+
args: [seaportAddress, orderHashes]
|
|
659
|
+
});
|
|
660
|
+
const statuses = results.map((r) => ({
|
|
661
|
+
isValidated: r.isValidated,
|
|
662
|
+
isCancelled: r.isCancelled,
|
|
663
|
+
totalFilled: BigInt(r.totalFilled),
|
|
664
|
+
totalSize: BigInt(r.totalSize)
|
|
665
|
+
}));
|
|
666
|
+
console.log(`[bulkFetchOrderStatuses] success: ${statuses.length} statuses`);
|
|
667
|
+
return statuses;
|
|
668
|
+
} catch (err) {
|
|
669
|
+
console.error(`[bulkFetchOrderStatuses] FAILED for ${orderHashes.length} hashes:`, err);
|
|
670
|
+
throw err;
|
|
671
|
+
}
|
|
664
672
|
}
|
|
665
673
|
async function createOrderStatusMap(client, chainId, orderHashes) {
|
|
666
674
|
const statuses = await bulkFetchOrderStatuses(client, chainId, orderHashes);
|
|
@@ -675,16 +683,21 @@ async function bulkFetchNftOwners(client, nftAddress, tokenIds) {
|
|
|
675
683
|
return [];
|
|
676
684
|
}
|
|
677
685
|
try {
|
|
686
|
+
console.log(`[bulkFetchNftOwners] fetching ${tokenIds.length} owners for ${nftAddress.slice(0, 10)} via ${ERC721_OWNER_OF_HELPER_ADDRESS}`);
|
|
678
687
|
const owners = await readContract(client, {
|
|
679
688
|
address: ERC721_OWNER_OF_HELPER_ADDRESS,
|
|
680
689
|
abi: ERC721_OWNER_OF_HELPER_ABI,
|
|
681
690
|
functionName: "getTokenOwners",
|
|
682
691
|
args: [nftAddress, tokenIds.map((id) => BigInt(id))]
|
|
683
692
|
});
|
|
684
|
-
|
|
693
|
+
const result = owners.map(
|
|
685
694
|
(owner) => owner === "0x0000000000000000000000000000000000000000" ? null : owner
|
|
686
695
|
);
|
|
687
|
-
|
|
696
|
+
const validCount = result.filter((o) => o !== null).length;
|
|
697
|
+
console.log(`[bulkFetchNftOwners] success: ${validCount}/${tokenIds.length} have owners`);
|
|
698
|
+
return result;
|
|
699
|
+
} catch (err) {
|
|
700
|
+
console.error(`[bulkFetchNftOwners] FAILED for ${tokenIds.length} tokens \u2014 returning all null:`, err);
|
|
688
701
|
return tokenIds.map(() => null);
|
|
689
702
|
}
|
|
690
703
|
}
|
|
@@ -701,14 +714,18 @@ async function bulkFetchErc20Balances(client, tokenAddress, addresses) {
|
|
|
701
714
|
return [];
|
|
702
715
|
}
|
|
703
716
|
try {
|
|
717
|
+
console.log(`[bulkFetchErc20Balances] fetching ${addresses.length} balances for ${tokenAddress.slice(0, 10)}`);
|
|
704
718
|
const balances = await readContract(client, {
|
|
705
719
|
address: ERC20_BULK_BALANCE_CHECKER_ADDRESS,
|
|
706
720
|
abi: ERC20_BULK_BALANCE_CHECKER_ABI,
|
|
707
721
|
functionName: "getBalances",
|
|
708
722
|
args: [tokenAddress, addresses]
|
|
709
723
|
});
|
|
710
|
-
|
|
711
|
-
|
|
724
|
+
const result = balances.map((b) => BigInt(b));
|
|
725
|
+
console.log(`[bulkFetchErc20Balances] success: ${result.length} balances`);
|
|
726
|
+
return result;
|
|
727
|
+
} catch (err) {
|
|
728
|
+
console.error(`[bulkFetchErc20Balances] FAILED for ${addresses.length} addresses \u2014 returning all zero:`, err);
|
|
712
729
|
return addresses.map(() => BigInt(0));
|
|
713
730
|
}
|
|
714
731
|
}
|
|
@@ -1015,26 +1032,30 @@ var BazaarClient = class {
|
|
|
1015
1032
|
}
|
|
1016
1033
|
this.chainId = params.chainId;
|
|
1017
1034
|
this.rpcUrl = params.rpcUrl || CHAIN_RPC_URLS[params.chainId]?.[0] || "";
|
|
1018
|
-
if (
|
|
1019
|
-
|
|
1035
|
+
if (params.publicClient) {
|
|
1036
|
+
this.client = params.publicClient;
|
|
1037
|
+
} else {
|
|
1038
|
+
if (!this.rpcUrl) {
|
|
1039
|
+
throw new Error(`No RPC URL available for chain ${params.chainId}`);
|
|
1040
|
+
}
|
|
1041
|
+
const config = getBazaarChainConfig(params.chainId);
|
|
1042
|
+
this.client = createPublicClient({
|
|
1043
|
+
chain: defineChain({
|
|
1044
|
+
id: params.chainId,
|
|
1045
|
+
name: `Chain ${params.chainId}`,
|
|
1046
|
+
nativeCurrency: {
|
|
1047
|
+
name: config.wrappedNativeCurrency.name.replace("Wrapped ", ""),
|
|
1048
|
+
symbol: config.currencySymbol.toUpperCase(),
|
|
1049
|
+
decimals: 18
|
|
1050
|
+
},
|
|
1051
|
+
rpcUrls: {
|
|
1052
|
+
default: { http: [this.rpcUrl] }
|
|
1053
|
+
}
|
|
1054
|
+
}),
|
|
1055
|
+
transport: http(this.rpcUrl),
|
|
1056
|
+
batch: { multicall: true }
|
|
1057
|
+
});
|
|
1020
1058
|
}
|
|
1021
|
-
const config = getBazaarChainConfig(params.chainId);
|
|
1022
|
-
this.client = createPublicClient({
|
|
1023
|
-
chain: defineChain({
|
|
1024
|
-
id: params.chainId,
|
|
1025
|
-
name: `Chain ${params.chainId}`,
|
|
1026
|
-
nativeCurrency: {
|
|
1027
|
-
name: config.wrappedNativeCurrency.name.replace("Wrapped ", ""),
|
|
1028
|
-
symbol: config.currencySymbol.toUpperCase(),
|
|
1029
|
-
decimals: 18
|
|
1030
|
-
},
|
|
1031
|
-
rpcUrls: {
|
|
1032
|
-
default: { http: [this.rpcUrl] }
|
|
1033
|
-
}
|
|
1034
|
-
}),
|
|
1035
|
-
transport: http(this.rpcUrl),
|
|
1036
|
-
batch: { multicall: true }
|
|
1037
|
-
});
|
|
1038
1059
|
this.netClient = new NetClient({
|
|
1039
1060
|
chainId: params.chainId,
|
|
1040
1061
|
overrides: params.rpcUrl ? { rpcUrls: [params.rpcUrl] } : void 0
|
|
@@ -1076,6 +1097,17 @@ var BazaarClient = class {
|
|
|
1076
1097
|
startIndex,
|
|
1077
1098
|
endIndex
|
|
1078
1099
|
});
|
|
1100
|
+
return this.processListingsFromMessages(messages, options);
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Process pre-fetched messages into valid NFT listings.
|
|
1104
|
+
*
|
|
1105
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1106
|
+
* to avoid redundant RPC calls.
|
|
1107
|
+
*/
|
|
1108
|
+
async processListingsFromMessages(messages, options) {
|
|
1109
|
+
const { nftAddress, excludeMaker, includeExpired = false } = options;
|
|
1110
|
+
const tag = `[BazaarClient.processListings chain=${this.chainId}]`;
|
|
1079
1111
|
let listings = [];
|
|
1080
1112
|
for (const message of messages) {
|
|
1081
1113
|
const listing = parseListingFromMessage(message, this.chainId);
|
|
@@ -1085,6 +1117,7 @@ var BazaarClient = class {
|
|
|
1085
1117
|
}
|
|
1086
1118
|
listings.push(listing);
|
|
1087
1119
|
}
|
|
1120
|
+
console.log(tag, `parsed ${listings.length}/${messages.length} messages into listings`);
|
|
1088
1121
|
if (listings.length === 0) {
|
|
1089
1122
|
return [];
|
|
1090
1123
|
}
|
|
@@ -1099,15 +1132,27 @@ var BazaarClient = class {
|
|
|
1099
1132
|
const statusInfo = statusInfos[index];
|
|
1100
1133
|
listing.orderStatus = getOrderStatusFromInfo(listing.orderComponents, statusInfo);
|
|
1101
1134
|
});
|
|
1135
|
+
const statusCounts = {};
|
|
1136
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1137
|
+
let expiredCount = 0;
|
|
1138
|
+
for (const l of listings) {
|
|
1139
|
+
statusCounts[l.orderStatus] = (statusCounts[l.orderStatus] || 0) + 1;
|
|
1140
|
+
if (l.expirationDate <= now) expiredCount++;
|
|
1141
|
+
}
|
|
1142
|
+
console.log(tag, `order statuses:`, statusCounts, `expired: ${expiredCount}`);
|
|
1102
1143
|
listings = listings.filter(
|
|
1103
|
-
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate >
|
|
1144
|
+
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > now || includeExpired && l.orderStatus === 1 /* EXPIRED */
|
|
1104
1145
|
);
|
|
1146
|
+
console.log(tag, `after status filter: ${listings.length} (OPEN${includeExpired ? " + EXPIRED" : ""})`);
|
|
1105
1147
|
if (listings.length === 0) {
|
|
1106
1148
|
return [];
|
|
1107
1149
|
}
|
|
1108
|
-
const
|
|
1150
|
+
const openListings = listings.filter((l) => l.orderStatus === 2 /* OPEN */);
|
|
1151
|
+
const expiredListings = includeExpired ? listings.filter((l) => l.orderStatus === 1 /* EXPIRED */) : [];
|
|
1152
|
+
const tokenIds = openListings.map((l) => l.tokenId);
|
|
1109
1153
|
const owners = await bulkFetchNftOwners(this.client, nftAddress, tokenIds);
|
|
1110
|
-
|
|
1154
|
+
const beforeOwnership = openListings.length;
|
|
1155
|
+
const validOpenListings = openListings.filter((listing, index) => {
|
|
1111
1156
|
const owner = owners[index];
|
|
1112
1157
|
return isListingValid(
|
|
1113
1158
|
listing.orderStatus,
|
|
@@ -1116,7 +1161,16 @@ var BazaarClient = class {
|
|
|
1116
1161
|
owner
|
|
1117
1162
|
);
|
|
1118
1163
|
});
|
|
1119
|
-
|
|
1164
|
+
console.log(tag, `after ownership filter: ${validOpenListings.length}/${beforeOwnership} (${beforeOwnership - validOpenListings.length} dropped)`);
|
|
1165
|
+
const dedupedOpen = sortListingsByPrice(getBestListingPerToken(validOpenListings));
|
|
1166
|
+
const activeTokenKeys = new Set(dedupedOpen.map((l) => `${l.nftAddress.toLowerCase()}-${l.tokenId}`));
|
|
1167
|
+
const uniqueExpired = getBestListingPerToken(
|
|
1168
|
+
expiredListings.filter((l) => !activeTokenKeys.has(`${l.nftAddress.toLowerCase()}-${l.tokenId}`))
|
|
1169
|
+
);
|
|
1170
|
+
const sortedExpired = sortListingsByPrice(uniqueExpired);
|
|
1171
|
+
const result = [...dedupedOpen, ...sortedExpired];
|
|
1172
|
+
console.log(tag, `final: ${result.length} listings (${dedupedOpen.length} open, ${sortedExpired.length} expired)`);
|
|
1173
|
+
return result;
|
|
1120
1174
|
}
|
|
1121
1175
|
/**
|
|
1122
1176
|
* Get valid collection offers for a collection
|
|
@@ -1131,10 +1185,6 @@ var BazaarClient = class {
|
|
|
1131
1185
|
async getCollectionOffers(options) {
|
|
1132
1186
|
const { nftAddress, excludeMaker, maxMessages = 100 } = options;
|
|
1133
1187
|
const collectionOffersAddress = getCollectionOffersAddress(this.chainId);
|
|
1134
|
-
const weth = getWrappedNativeCurrency(this.chainId);
|
|
1135
|
-
if (!weth) {
|
|
1136
|
-
return [];
|
|
1137
|
-
}
|
|
1138
1188
|
const count = await this.netClient.getMessageCount({
|
|
1139
1189
|
filter: {
|
|
1140
1190
|
appAddress: collectionOffersAddress,
|
|
@@ -1153,6 +1203,21 @@ var BazaarClient = class {
|
|
|
1153
1203
|
startIndex,
|
|
1154
1204
|
endIndex: count
|
|
1155
1205
|
});
|
|
1206
|
+
return this.processCollectionOffersFromMessages(messages, options);
|
|
1207
|
+
}
|
|
1208
|
+
/**
|
|
1209
|
+
* Process pre-fetched messages into valid collection offers.
|
|
1210
|
+
*
|
|
1211
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1212
|
+
* to avoid redundant RPC calls.
|
|
1213
|
+
*/
|
|
1214
|
+
async processCollectionOffersFromMessages(messages, options) {
|
|
1215
|
+
const { nftAddress, excludeMaker } = options;
|
|
1216
|
+
const tag = `[BazaarClient.processCollectionOffers chain=${this.chainId}]`;
|
|
1217
|
+
const weth = getWrappedNativeCurrency(this.chainId);
|
|
1218
|
+
if (!weth) {
|
|
1219
|
+
return [];
|
|
1220
|
+
}
|
|
1156
1221
|
let offers = [];
|
|
1157
1222
|
for (const message of messages) {
|
|
1158
1223
|
const offer = parseCollectionOfferFromMessage(message, this.chainId);
|
|
@@ -1167,6 +1232,7 @@ var BazaarClient = class {
|
|
|
1167
1232
|
}
|
|
1168
1233
|
offers.push(offer);
|
|
1169
1234
|
}
|
|
1235
|
+
console.log(tag, `parsed ${offers.length}/${messages.length} messages into offers`);
|
|
1170
1236
|
if (offers.length === 0) {
|
|
1171
1237
|
return [];
|
|
1172
1238
|
}
|
|
@@ -1181,9 +1247,11 @@ var BazaarClient = class {
|
|
|
1181
1247
|
const statusInfo = statusInfos[index];
|
|
1182
1248
|
offer.orderStatus = getOrderStatusFromInfo(offer.orderComponents, statusInfo);
|
|
1183
1249
|
});
|
|
1250
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1184
1251
|
offers = offers.filter(
|
|
1185
|
-
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate >
|
|
1252
|
+
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > now
|
|
1186
1253
|
);
|
|
1254
|
+
console.log(tag, `after status filter: ${offers.length} OPEN & not expired`);
|
|
1187
1255
|
if (offers.length === 0) {
|
|
1188
1256
|
return [];
|
|
1189
1257
|
}
|
|
@@ -1193,6 +1261,7 @@ var BazaarClient = class {
|
|
|
1193
1261
|
uniqueMakers.forEach((maker, index) => {
|
|
1194
1262
|
balanceMap.set(maker.toLowerCase(), balances[index]);
|
|
1195
1263
|
});
|
|
1264
|
+
const beforeBalance = offers.length;
|
|
1196
1265
|
offers = offers.filter((offer) => {
|
|
1197
1266
|
const balance = balanceMap.get(offer.maker.toLowerCase()) || BigInt(0);
|
|
1198
1267
|
return isCollectionOfferValid(
|
|
@@ -1202,6 +1271,7 @@ var BazaarClient = class {
|
|
|
1202
1271
|
balance
|
|
1203
1272
|
);
|
|
1204
1273
|
});
|
|
1274
|
+
console.log(tag, `after balance filter: ${offers.length}/${beforeBalance} (${beforeBalance - offers.length} dropped)`);
|
|
1205
1275
|
return sortOffersByPrice(offers);
|
|
1206
1276
|
}
|
|
1207
1277
|
/**
|
|
@@ -1219,8 +1289,7 @@ var BazaarClient = class {
|
|
|
1219
1289
|
async getErc20Offers(options) {
|
|
1220
1290
|
const { tokenAddress, excludeMaker, maxMessages = 200 } = options;
|
|
1221
1291
|
const erc20OffersAddress = getErc20OffersAddress(this.chainId);
|
|
1222
|
-
|
|
1223
|
-
if (!erc20OffersAddress || !weth) {
|
|
1292
|
+
if (!erc20OffersAddress) {
|
|
1224
1293
|
return [];
|
|
1225
1294
|
}
|
|
1226
1295
|
const count = await this.netClient.getMessageCount({
|
|
@@ -1241,6 +1310,21 @@ var BazaarClient = class {
|
|
|
1241
1310
|
startIndex,
|
|
1242
1311
|
endIndex: count
|
|
1243
1312
|
});
|
|
1313
|
+
return this.processErc20OffersFromMessages(messages, options);
|
|
1314
|
+
}
|
|
1315
|
+
/**
|
|
1316
|
+
* Process pre-fetched messages into valid ERC20 offers.
|
|
1317
|
+
*
|
|
1318
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1319
|
+
* to avoid redundant RPC calls.
|
|
1320
|
+
*/
|
|
1321
|
+
async processErc20OffersFromMessages(messages, options) {
|
|
1322
|
+
const { tokenAddress, excludeMaker } = options;
|
|
1323
|
+
const tag = `[BazaarClient.processErc20Offers chain=${this.chainId}]`;
|
|
1324
|
+
const weth = getWrappedNativeCurrency(this.chainId);
|
|
1325
|
+
if (!weth) {
|
|
1326
|
+
return [];
|
|
1327
|
+
}
|
|
1244
1328
|
let offers = [];
|
|
1245
1329
|
for (const message of messages) {
|
|
1246
1330
|
const offer = parseErc20OfferFromMessage(message, this.chainId);
|
|
@@ -1258,6 +1342,7 @@ var BazaarClient = class {
|
|
|
1258
1342
|
}
|
|
1259
1343
|
offers.push(offer);
|
|
1260
1344
|
}
|
|
1345
|
+
console.log(tag, `parsed ${offers.length}/${messages.length} messages into offers`);
|
|
1261
1346
|
if (offers.length === 0) {
|
|
1262
1347
|
return [];
|
|
1263
1348
|
}
|
|
@@ -1272,9 +1357,11 @@ var BazaarClient = class {
|
|
|
1272
1357
|
const statusInfo = statusInfos[index];
|
|
1273
1358
|
offer.orderStatus = getOrderStatusFromInfo(offer.orderComponents, statusInfo);
|
|
1274
1359
|
});
|
|
1360
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1275
1361
|
offers = offers.filter(
|
|
1276
|
-
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate >
|
|
1362
|
+
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > now
|
|
1277
1363
|
);
|
|
1364
|
+
console.log(tag, `after status filter: ${offers.length} OPEN & not expired`);
|
|
1278
1365
|
if (offers.length === 0) {
|
|
1279
1366
|
return [];
|
|
1280
1367
|
}
|
|
@@ -1284,6 +1371,7 @@ var BazaarClient = class {
|
|
|
1284
1371
|
uniqueMakers.forEach((maker, index) => {
|
|
1285
1372
|
balanceMap.set(maker.toLowerCase(), balances[index]);
|
|
1286
1373
|
});
|
|
1374
|
+
const beforeBalance = offers.length;
|
|
1287
1375
|
offers = offers.filter((offer) => {
|
|
1288
1376
|
const balance = balanceMap.get(offer.maker.toLowerCase()) || BigInt(0);
|
|
1289
1377
|
return isErc20OfferValid(
|
|
@@ -1293,6 +1381,7 @@ var BazaarClient = class {
|
|
|
1293
1381
|
balance
|
|
1294
1382
|
);
|
|
1295
1383
|
});
|
|
1384
|
+
console.log(tag, `after balance filter: ${offers.length}/${beforeBalance} (${beforeBalance - offers.length} dropped)`);
|
|
1296
1385
|
return sortErc20OffersByPricePerToken(offers);
|
|
1297
1386
|
}
|
|
1298
1387
|
/**
|
|
@@ -1332,6 +1421,17 @@ var BazaarClient = class {
|
|
|
1332
1421
|
startIndex,
|
|
1333
1422
|
endIndex
|
|
1334
1423
|
});
|
|
1424
|
+
return this.processErc20ListingsFromMessages(messages, options);
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Process pre-fetched messages into valid ERC20 listings.
|
|
1428
|
+
*
|
|
1429
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1430
|
+
* to avoid redundant RPC calls.
|
|
1431
|
+
*/
|
|
1432
|
+
async processErc20ListingsFromMessages(messages, options) {
|
|
1433
|
+
const { tokenAddress, excludeMaker } = options;
|
|
1434
|
+
const tag = `[BazaarClient.processErc20Listings chain=${this.chainId}]`;
|
|
1335
1435
|
let listings = [];
|
|
1336
1436
|
for (const message of messages) {
|
|
1337
1437
|
const listing = parseErc20ListingFromMessage(message, this.chainId);
|
|
@@ -1344,6 +1444,7 @@ var BazaarClient = class {
|
|
|
1344
1444
|
}
|
|
1345
1445
|
listings.push(listing);
|
|
1346
1446
|
}
|
|
1447
|
+
console.log(tag, `parsed ${listings.length}/${messages.length} messages into listings`);
|
|
1347
1448
|
if (listings.length === 0) {
|
|
1348
1449
|
return [];
|
|
1349
1450
|
}
|
|
@@ -1358,18 +1459,28 @@ var BazaarClient = class {
|
|
|
1358
1459
|
const statusInfo = statusInfos[index];
|
|
1359
1460
|
listing.orderStatus = getOrderStatusFromInfo(listing.orderComponents, statusInfo);
|
|
1360
1461
|
});
|
|
1462
|
+
const statusCounts = {};
|
|
1463
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1464
|
+
let expiredCount = 0;
|
|
1465
|
+
for (const l of listings) {
|
|
1466
|
+
statusCounts[l.orderStatus] = (statusCounts[l.orderStatus] || 0) + 1;
|
|
1467
|
+
if (l.expirationDate <= now) expiredCount++;
|
|
1468
|
+
}
|
|
1469
|
+
console.log(tag, `order statuses:`, statusCounts, `expired: ${expiredCount}`);
|
|
1361
1470
|
listings = listings.filter(
|
|
1362
|
-
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate >
|
|
1471
|
+
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > now
|
|
1363
1472
|
);
|
|
1473
|
+
console.log(tag, `after status filter: ${listings.length} OPEN & not expired`);
|
|
1364
1474
|
if (listings.length === 0) {
|
|
1365
1475
|
return [];
|
|
1366
1476
|
}
|
|
1367
1477
|
const uniqueMakers = [...new Set(listings.map((l) => l.maker))];
|
|
1368
1478
|
const balances = await bulkFetchErc20Balances(this.client, tokenAddress, uniqueMakers);
|
|
1369
1479
|
const balanceMap = /* @__PURE__ */ new Map();
|
|
1370
|
-
uniqueMakers.forEach((
|
|
1371
|
-
balanceMap.set(
|
|
1480
|
+
uniqueMakers.forEach((maker, index) => {
|
|
1481
|
+
balanceMap.set(maker.toLowerCase(), balances[index]);
|
|
1372
1482
|
});
|
|
1483
|
+
const beforeBalance = listings.length;
|
|
1373
1484
|
listings = listings.filter((listing) => {
|
|
1374
1485
|
const balance = balanceMap.get(listing.maker.toLowerCase()) || BigInt(0);
|
|
1375
1486
|
return isErc20ListingValid(
|
|
@@ -1379,6 +1490,7 @@ var BazaarClient = class {
|
|
|
1379
1490
|
balance
|
|
1380
1491
|
);
|
|
1381
1492
|
});
|
|
1493
|
+
console.log(tag, `after balance filter: ${listings.length}/${beforeBalance} (${beforeBalance - listings.length} dropped)`);
|
|
1382
1494
|
return sortErc20ListingsByPricePerToken(listings);
|
|
1383
1495
|
}
|
|
1384
1496
|
/**
|