@net-protocol/bazaar 0.1.1 → 0.1.3

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.mjs CHANGED
@@ -357,10 +357,11 @@ 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 = "0x000000aa4eFa2e5A4a6002C7F08B6e8Ec8cf1dDa";
361
- var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "0x000000b50a9f2923f2db931391824f6d1278f712";
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
+ var NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS = "0x000000bC63761cbb05305632212e2f3AE2BE7a9B";
364
365
  var BAZAAR_CHAIN_CONFIGS = {
365
366
  // Base Mainnet
366
367
  8453: {
@@ -648,18 +649,26 @@ async function bulkFetchOrderStatuses(client, chainId, orderHashes) {
648
649
  return [];
649
650
  }
650
651
  const seaportAddress = getSeaportAddress(chainId);
651
- const results = await readContract(client, {
652
- address: BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS,
653
- abi: BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI,
654
- functionName: "getOrderStatuses",
655
- args: [seaportAddress, orderHashes]
656
- });
657
- return results.map((r) => ({
658
- isValidated: r.isValidated,
659
- isCancelled: r.isCancelled,
660
- totalFilled: BigInt(r.totalFilled),
661
- totalSize: BigInt(r.totalSize)
662
- }));
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
+ }
663
672
  }
664
673
  async function createOrderStatusMap(client, chainId, orderHashes) {
665
674
  const statuses = await bulkFetchOrderStatuses(client, chainId, orderHashes);
@@ -674,16 +683,21 @@ async function bulkFetchNftOwners(client, nftAddress, tokenIds) {
674
683
  return [];
675
684
  }
676
685
  try {
686
+ console.log(`[bulkFetchNftOwners] fetching ${tokenIds.length} owners for ${nftAddress.slice(0, 10)} via ${ERC721_OWNER_OF_HELPER_ADDRESS}`);
677
687
  const owners = await readContract(client, {
678
688
  address: ERC721_OWNER_OF_HELPER_ADDRESS,
679
689
  abi: ERC721_OWNER_OF_HELPER_ABI,
680
690
  functionName: "getTokenOwners",
681
691
  args: [nftAddress, tokenIds.map((id) => BigInt(id))]
682
692
  });
683
- return owners.map(
693
+ const result = owners.map(
684
694
  (owner) => owner === "0x0000000000000000000000000000000000000000" ? null : owner
685
695
  );
686
- } catch {
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);
687
701
  return tokenIds.map(() => null);
688
702
  }
689
703
  }
@@ -700,14 +714,18 @@ async function bulkFetchErc20Balances(client, tokenAddress, addresses) {
700
714
  return [];
701
715
  }
702
716
  try {
717
+ console.log(`[bulkFetchErc20Balances] fetching ${addresses.length} balances for ${tokenAddress.slice(0, 10)}`);
703
718
  const balances = await readContract(client, {
704
719
  address: ERC20_BULK_BALANCE_CHECKER_ADDRESS,
705
720
  abi: ERC20_BULK_BALANCE_CHECKER_ABI,
706
721
  functionName: "getBalances",
707
722
  args: [tokenAddress, addresses]
708
723
  });
709
- return balances.map((b) => BigInt(b));
710
- } catch {
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);
711
729
  return addresses.map(() => BigInt(0));
712
730
  }
713
731
  }
@@ -786,6 +804,7 @@ function parseListingFromMessage(message, chainId) {
786
804
  }
787
805
  const priceWei = getTotalConsiderationAmount(parameters);
788
806
  const tokenId = offerItem.identifierOrCriteria.toString();
807
+ const targetFulfiller = parameters.zone.toLowerCase() === NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS.toLowerCase() && parameters.zoneHash !== "0x0000000000000000000000000000000000000000000000000000000000000000" ? parameters.zoneHash : void 0;
789
808
  return {
790
809
  maker: parameters.offerer,
791
810
  nftAddress: offerItem.token,
@@ -802,7 +821,8 @@ function parseListingFromMessage(message, chainId) {
802
821
  orderComponents: {
803
822
  ...parameters,
804
823
  counter: submission.counter
805
- }
824
+ },
825
+ targetFulfiller
806
826
  };
807
827
  } catch {
808
828
  return null;
@@ -1012,26 +1032,30 @@ var BazaarClient = class {
1012
1032
  }
1013
1033
  this.chainId = params.chainId;
1014
1034
  this.rpcUrl = params.rpcUrl || CHAIN_RPC_URLS[params.chainId]?.[0] || "";
1015
- if (!this.rpcUrl) {
1016
- throw new Error(`No RPC URL available for chain ${params.chainId}`);
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
+ });
1017
1058
  }
1018
- const config = getBazaarChainConfig(params.chainId);
1019
- this.client = createPublicClient({
1020
- chain: defineChain({
1021
- id: params.chainId,
1022
- name: `Chain ${params.chainId}`,
1023
- nativeCurrency: {
1024
- name: config.wrappedNativeCurrency.name.replace("Wrapped ", ""),
1025
- symbol: config.currencySymbol.toUpperCase(),
1026
- decimals: 18
1027
- },
1028
- rpcUrls: {
1029
- default: { http: [this.rpcUrl] }
1030
- }
1031
- }),
1032
- transport: http(this.rpcUrl),
1033
- batch: { multicall: true }
1034
- });
1035
1059
  this.netClient = new NetClient({
1036
1060
  chainId: params.chainId,
1037
1061
  overrides: params.rpcUrl ? { rpcUrls: [params.rpcUrl] } : void 0
@@ -1048,26 +1072,42 @@ var BazaarClient = class {
1048
1072
  * Results are deduplicated (one per token) and sorted by price (lowest first)
1049
1073
  */
1050
1074
  async getListings(options) {
1051
- const { nftAddress, excludeMaker, maxMessages = 200 } = options;
1075
+ const { nftAddress, excludeMaker, maker, maxMessages = 200 } = options;
1052
1076
  const bazaarAddress = getBazaarAddress(this.chainId);
1053
- const count = await this.netClient.getMessageCount({
1054
- filter: {
1055
- appAddress: bazaarAddress,
1056
- topic: nftAddress.toLowerCase()
1077
+ const filter = {
1078
+ appAddress: bazaarAddress,
1079
+ topic: nftAddress.toLowerCase(),
1080
+ maker
1081
+ };
1082
+ let startIndex;
1083
+ let endIndex;
1084
+ if (options.startIndex != null && options.endIndex != null) {
1085
+ startIndex = options.startIndex;
1086
+ endIndex = options.endIndex;
1087
+ } else {
1088
+ const count = await this.netClient.getMessageCount({ filter });
1089
+ if (count === 0) {
1090
+ return [];
1057
1091
  }
1058
- });
1059
- if (count === 0) {
1060
- return [];
1092
+ startIndex = Math.max(0, count - maxMessages);
1093
+ endIndex = count;
1061
1094
  }
1062
- const startIndex = Math.max(0, count - maxMessages);
1063
1095
  const messages = await this.netClient.getMessages({
1064
- filter: {
1065
- appAddress: bazaarAddress,
1066
- topic: nftAddress.toLowerCase()
1067
- },
1096
+ filter,
1068
1097
  startIndex,
1069
- endIndex: count
1098
+ endIndex
1070
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}]`;
1071
1111
  let listings = [];
1072
1112
  for (const message of messages) {
1073
1113
  const listing = parseListingFromMessage(message, this.chainId);
@@ -1077,6 +1117,7 @@ var BazaarClient = class {
1077
1117
  }
1078
1118
  listings.push(listing);
1079
1119
  }
1120
+ console.log(tag, `parsed ${listings.length}/${messages.length} messages into listings`);
1080
1121
  if (listings.length === 0) {
1081
1122
  return [];
1082
1123
  }
@@ -1091,15 +1132,27 @@ var BazaarClient = class {
1091
1132
  const statusInfo = statusInfos[index];
1092
1133
  listing.orderStatus = getOrderStatusFromInfo(listing.orderComponents, statusInfo);
1093
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}`);
1094
1143
  listings = listings.filter(
1095
- (l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > Math.floor(Date.now() / 1e3)
1144
+ (l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > now || includeExpired && l.orderStatus === 1 /* EXPIRED */
1096
1145
  );
1146
+ console.log(tag, `after status filter: ${listings.length} (OPEN${includeExpired ? " + EXPIRED" : ""})`);
1097
1147
  if (listings.length === 0) {
1098
1148
  return [];
1099
1149
  }
1100
- const tokenIds = listings.map((l) => l.tokenId);
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);
1101
1153
  const owners = await bulkFetchNftOwners(this.client, nftAddress, tokenIds);
1102
- listings = listings.filter((listing, index) => {
1154
+ const beforeOwnership = openListings.length;
1155
+ const validOpenListings = openListings.filter((listing, index) => {
1103
1156
  const owner = owners[index];
1104
1157
  return isListingValid(
1105
1158
  listing.orderStatus,
@@ -1108,7 +1161,16 @@ var BazaarClient = class {
1108
1161
  owner
1109
1162
  );
1110
1163
  });
1111
- return sortListingsByPrice(getBestListingPerToken(listings));
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;
1112
1174
  }
1113
1175
  /**
1114
1176
  * Get valid collection offers for a collection
@@ -1123,10 +1185,6 @@ var BazaarClient = class {
1123
1185
  async getCollectionOffers(options) {
1124
1186
  const { nftAddress, excludeMaker, maxMessages = 100 } = options;
1125
1187
  const collectionOffersAddress = getCollectionOffersAddress(this.chainId);
1126
- const weth = getWrappedNativeCurrency(this.chainId);
1127
- if (!weth) {
1128
- return [];
1129
- }
1130
1188
  const count = await this.netClient.getMessageCount({
1131
1189
  filter: {
1132
1190
  appAddress: collectionOffersAddress,
@@ -1145,6 +1203,21 @@ var BazaarClient = class {
1145
1203
  startIndex,
1146
1204
  endIndex: count
1147
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
+ }
1148
1221
  let offers = [];
1149
1222
  for (const message of messages) {
1150
1223
  const offer = parseCollectionOfferFromMessage(message, this.chainId);
@@ -1159,6 +1232,7 @@ var BazaarClient = class {
1159
1232
  }
1160
1233
  offers.push(offer);
1161
1234
  }
1235
+ console.log(tag, `parsed ${offers.length}/${messages.length} messages into offers`);
1162
1236
  if (offers.length === 0) {
1163
1237
  return [];
1164
1238
  }
@@ -1173,9 +1247,11 @@ var BazaarClient = class {
1173
1247
  const statusInfo = statusInfos[index];
1174
1248
  offer.orderStatus = getOrderStatusFromInfo(offer.orderComponents, statusInfo);
1175
1249
  });
1250
+ const now = Math.floor(Date.now() / 1e3);
1176
1251
  offers = offers.filter(
1177
- (o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > Math.floor(Date.now() / 1e3)
1252
+ (o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > now
1178
1253
  );
1254
+ console.log(tag, `after status filter: ${offers.length} OPEN & not expired`);
1179
1255
  if (offers.length === 0) {
1180
1256
  return [];
1181
1257
  }
@@ -1185,6 +1261,7 @@ var BazaarClient = class {
1185
1261
  uniqueMakers.forEach((maker, index) => {
1186
1262
  balanceMap.set(maker.toLowerCase(), balances[index]);
1187
1263
  });
1264
+ const beforeBalance = offers.length;
1188
1265
  offers = offers.filter((offer) => {
1189
1266
  const balance = balanceMap.get(offer.maker.toLowerCase()) || BigInt(0);
1190
1267
  return isCollectionOfferValid(
@@ -1194,6 +1271,7 @@ var BazaarClient = class {
1194
1271
  balance
1195
1272
  );
1196
1273
  });
1274
+ console.log(tag, `after balance filter: ${offers.length}/${beforeBalance} (${beforeBalance - offers.length} dropped)`);
1197
1275
  return sortOffersByPrice(offers);
1198
1276
  }
1199
1277
  /**
@@ -1211,8 +1289,7 @@ var BazaarClient = class {
1211
1289
  async getErc20Offers(options) {
1212
1290
  const { tokenAddress, excludeMaker, maxMessages = 200 } = options;
1213
1291
  const erc20OffersAddress = getErc20OffersAddress(this.chainId);
1214
- const weth = getWrappedNativeCurrency(this.chainId);
1215
- if (!erc20OffersAddress || !weth) {
1292
+ if (!erc20OffersAddress) {
1216
1293
  return [];
1217
1294
  }
1218
1295
  const count = await this.netClient.getMessageCount({
@@ -1233,6 +1310,21 @@ var BazaarClient = class {
1233
1310
  startIndex,
1234
1311
  endIndex: count
1235
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
+ }
1236
1328
  let offers = [];
1237
1329
  for (const message of messages) {
1238
1330
  const offer = parseErc20OfferFromMessage(message, this.chainId);
@@ -1250,6 +1342,7 @@ var BazaarClient = class {
1250
1342
  }
1251
1343
  offers.push(offer);
1252
1344
  }
1345
+ console.log(tag, `parsed ${offers.length}/${messages.length} messages into offers`);
1253
1346
  if (offers.length === 0) {
1254
1347
  return [];
1255
1348
  }
@@ -1264,9 +1357,11 @@ var BazaarClient = class {
1264
1357
  const statusInfo = statusInfos[index];
1265
1358
  offer.orderStatus = getOrderStatusFromInfo(offer.orderComponents, statusInfo);
1266
1359
  });
1360
+ const now = Math.floor(Date.now() / 1e3);
1267
1361
  offers = offers.filter(
1268
- (o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > Math.floor(Date.now() / 1e3)
1362
+ (o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > now
1269
1363
  );
1364
+ console.log(tag, `after status filter: ${offers.length} OPEN & not expired`);
1270
1365
  if (offers.length === 0) {
1271
1366
  return [];
1272
1367
  }
@@ -1276,6 +1371,7 @@ var BazaarClient = class {
1276
1371
  uniqueMakers.forEach((maker, index) => {
1277
1372
  balanceMap.set(maker.toLowerCase(), balances[index]);
1278
1373
  });
1374
+ const beforeBalance = offers.length;
1279
1375
  offers = offers.filter((offer) => {
1280
1376
  const balance = balanceMap.get(offer.maker.toLowerCase()) || BigInt(0);
1281
1377
  return isErc20OfferValid(
@@ -1285,6 +1381,7 @@ var BazaarClient = class {
1285
1381
  balance
1286
1382
  );
1287
1383
  });
1384
+ console.log(tag, `after balance filter: ${offers.length}/${beforeBalance} (${beforeBalance - offers.length} dropped)`);
1288
1385
  return sortErc20OffersByPricePerToken(offers);
1289
1386
  }
1290
1387
  /**
@@ -1299,26 +1396,42 @@ var BazaarClient = class {
1299
1396
  * all valid listings are returned (grouped by maker in the UI).
1300
1397
  */
1301
1398
  async getErc20Listings(options) {
1302
- const { tokenAddress, excludeMaker, maxMessages = 200 } = options;
1399
+ const { tokenAddress, excludeMaker, maker, maxMessages = 200 } = options;
1303
1400
  const erc20BazaarAddress = getErc20BazaarAddress(this.chainId);
1304
- const count = await this.netClient.getMessageCount({
1305
- filter: {
1306
- appAddress: erc20BazaarAddress,
1307
- topic: tokenAddress.toLowerCase()
1401
+ const filter = {
1402
+ appAddress: erc20BazaarAddress,
1403
+ topic: tokenAddress.toLowerCase(),
1404
+ maker
1405
+ };
1406
+ let startIndex;
1407
+ let endIndex;
1408
+ if (options.startIndex != null && options.endIndex != null) {
1409
+ startIndex = options.startIndex;
1410
+ endIndex = options.endIndex;
1411
+ } else {
1412
+ const count = await this.netClient.getMessageCount({ filter });
1413
+ if (count === 0) {
1414
+ return [];
1308
1415
  }
1309
- });
1310
- if (count === 0) {
1311
- return [];
1416
+ startIndex = Math.max(0, count - maxMessages);
1417
+ endIndex = count;
1312
1418
  }
1313
- const startIndex = Math.max(0, count - maxMessages);
1314
1419
  const messages = await this.netClient.getMessages({
1315
- filter: {
1316
- appAddress: erc20BazaarAddress,
1317
- topic: tokenAddress.toLowerCase()
1318
- },
1420
+ filter,
1319
1421
  startIndex,
1320
- endIndex: count
1422
+ endIndex
1321
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}]`;
1322
1435
  let listings = [];
1323
1436
  for (const message of messages) {
1324
1437
  const listing = parseErc20ListingFromMessage(message, this.chainId);
@@ -1331,6 +1444,7 @@ var BazaarClient = class {
1331
1444
  }
1332
1445
  listings.push(listing);
1333
1446
  }
1447
+ console.log(tag, `parsed ${listings.length}/${messages.length} messages into listings`);
1334
1448
  if (listings.length === 0) {
1335
1449
  return [];
1336
1450
  }
@@ -1345,9 +1459,18 @@ var BazaarClient = class {
1345
1459
  const statusInfo = statusInfos[index];
1346
1460
  listing.orderStatus = getOrderStatusFromInfo(listing.orderComponents, statusInfo);
1347
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}`);
1348
1470
  listings = listings.filter(
1349
- (l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > Math.floor(Date.now() / 1e3)
1471
+ (l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > now
1350
1472
  );
1473
+ console.log(tag, `after status filter: ${listings.length} OPEN & not expired`);
1351
1474
  if (listings.length === 0) {
1352
1475
  return [];
1353
1476
  }
@@ -1357,6 +1480,7 @@ var BazaarClient = class {
1357
1480
  uniqueMakers.forEach((maker, index) => {
1358
1481
  balanceMap.set(maker.toLowerCase(), balances[index]);
1359
1482
  });
1483
+ const beforeBalance = listings.length;
1360
1484
  listings = listings.filter((listing) => {
1361
1485
  const balance = balanceMap.get(listing.maker.toLowerCase()) || BigInt(0);
1362
1486
  return isErc20ListingValid(
@@ -1366,6 +1490,7 @@ var BazaarClient = class {
1366
1490
  balance
1367
1491
  );
1368
1492
  });
1493
+ console.log(tag, `after balance filter: ${listings.length}/${beforeBalance} (${beforeBalance - listings.length} dropped)`);
1369
1494
  return sortErc20ListingsByPricePerToken(listings);
1370
1495
  }
1371
1496
  /**
@@ -1483,6 +1608,6 @@ var BazaarClient = class {
1483
1608
  }
1484
1609
  };
1485
1610
 
1486
- export { BAZAAR_COLLECTION_OFFERS_ABI, BAZAAR_SUBMISSION_ABI, BAZAAR_V2_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS, BazaarClient, ERC20_BULK_BALANCE_CHECKER_ABI, ERC20_BULK_BALANCE_CHECKER_ADDRESS, ERC721_OWNER_OF_HELPER_ABI, ERC721_OWNER_OF_HELPER_ADDRESS, ItemType, NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS, NET_SEAPORT_ZONE_ADDRESS, OrderType, SEAPORT_CANCEL_ABI, SeaportOrderStatus, bulkFetchErc20Balances, bulkFetchNftOwners, bulkFetchOrderStatuses, computeOrderHash, createBalanceMap, createOrderStatusMap, createOwnershipMap, createSeaportInstance, decodeSeaportSubmission, formatPrice, getBazaarAddress, getBazaarChainConfig, getBazaarSupportedChainIds, getBestCollectionOffer, getBestListingPerToken, getCollectionOffersAddress, getCurrencySymbol, getErc20BazaarAddress, getErc20OffersAddress, getFeeCollectorAddress, getHighEthAddress, getNftFeeBps, getOrderStatusFromInfo, getSeaportAddress, getSeaportOrderFromMessageData, getTotalConsiderationAmount, getWrappedNativeCurrency, isBazaarSupportedOnChain, isCollectionOfferValid, isErc20ListingValid, isErc20OfferValid, isListingValid, parseCollectionOfferFromMessage, parseErc20ListingFromMessage, parseErc20OfferFromMessage, parseListingFromMessage, sortErc20ListingsByPricePerToken, sortErc20OffersByPricePerToken, sortListingsByPrice, sortOffersByPrice };
1611
+ export { BAZAAR_COLLECTION_OFFERS_ABI, BAZAAR_SUBMISSION_ABI, BAZAAR_V2_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS, BazaarClient, ERC20_BULK_BALANCE_CHECKER_ABI, ERC20_BULK_BALANCE_CHECKER_ADDRESS, ERC721_OWNER_OF_HELPER_ABI, ERC721_OWNER_OF_HELPER_ADDRESS, ItemType, NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS, NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS, NET_SEAPORT_ZONE_ADDRESS, OrderType, SEAPORT_CANCEL_ABI, SeaportOrderStatus, bulkFetchErc20Balances, bulkFetchNftOwners, bulkFetchOrderStatuses, computeOrderHash, createBalanceMap, createOrderStatusMap, createOwnershipMap, createSeaportInstance, decodeSeaportSubmission, formatPrice, getBazaarAddress, getBazaarChainConfig, getBazaarSupportedChainIds, getBestCollectionOffer, getBestListingPerToken, getCollectionOffersAddress, getCurrencySymbol, getErc20BazaarAddress, getErc20OffersAddress, getFeeCollectorAddress, getHighEthAddress, getNftFeeBps, getOrderStatusFromInfo, getSeaportAddress, getSeaportOrderFromMessageData, getTotalConsiderationAmount, getWrappedNativeCurrency, isBazaarSupportedOnChain, isCollectionOfferValid, isErc20ListingValid, isErc20OfferValid, isListingValid, parseCollectionOfferFromMessage, parseErc20ListingFromMessage, parseErc20OfferFromMessage, parseListingFromMessage, sortErc20ListingsByPricePerToken, sortErc20OffersByPricePerToken, sortListingsByPrice, sortOffersByPrice };
1487
1612
  //# sourceMappingURL=index.mjs.map
1488
1613
  //# sourceMappingURL=index.mjs.map