@net-protocol/bazaar 0.1.2 → 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/README.md +1 -1
- package/dist/index.d.mts +34 -5
- package/dist/index.d.ts +34 -5
- 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 +1 -1
package/dist/react.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useState, useMemo, useEffect } from 'react';
|
|
2
|
+
import { usePublicClient } from 'wagmi';
|
|
2
3
|
import { useNetMessageCount, useNetMessages } from '@net-protocol/core/react';
|
|
3
4
|
import { createPublicClient, http, defineChain, decodeAbiParameters, formatEther } from 'viem';
|
|
4
5
|
import { NetClient } from '@net-protocol/core';
|
|
@@ -180,8 +181,8 @@ var DEFAULT_FEE_COLLECTOR_ADDRESS = "0x32D16C15410248bef498D7aF50D10Db1a546b9E5"
|
|
|
180
181
|
var DEFAULT_ERC20_BAZAAR_ADDRESS = "0x00000000a2d173a4610c85c7471a25b6bc216a70";
|
|
181
182
|
var DEFAULT_NFT_FEE_BPS = 500;
|
|
182
183
|
var BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS = "0x0000009112ABCE652674b4fE3eD9C765B22d11A7";
|
|
183
|
-
var ERC721_OWNER_OF_HELPER_ADDRESS = "
|
|
184
|
-
var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "
|
|
184
|
+
var ERC721_OWNER_OF_HELPER_ADDRESS = "0x00000012E3eb0700925947fAF9cd1440319b4F37";
|
|
185
|
+
var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "0x000000B50A9f2923F2DB931391824F6D1278f712";
|
|
185
186
|
var NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS = "0x000000B799ec6D7aCC1B578f62bFc324c25DFC5A";
|
|
186
187
|
var NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS = "0x000000bC63761cbb05305632212e2f3AE2BE7a9B";
|
|
187
188
|
var BAZAAR_CHAIN_CONFIGS = {
|
|
@@ -462,34 +463,47 @@ async function bulkFetchOrderStatuses(client, chainId, orderHashes) {
|
|
|
462
463
|
return [];
|
|
463
464
|
}
|
|
464
465
|
const seaportAddress = getSeaportAddress(chainId);
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
466
|
+
try {
|
|
467
|
+
console.log(`[bulkFetchOrderStatuses] fetching ${orderHashes.length} statuses via ${BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS}`);
|
|
468
|
+
const results = await readContract(client, {
|
|
469
|
+
address: BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS,
|
|
470
|
+
abi: BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI,
|
|
471
|
+
functionName: "getOrderStatuses",
|
|
472
|
+
args: [seaportAddress, orderHashes]
|
|
473
|
+
});
|
|
474
|
+
const statuses = results.map((r) => ({
|
|
475
|
+
isValidated: r.isValidated,
|
|
476
|
+
isCancelled: r.isCancelled,
|
|
477
|
+
totalFilled: BigInt(r.totalFilled),
|
|
478
|
+
totalSize: BigInt(r.totalSize)
|
|
479
|
+
}));
|
|
480
|
+
console.log(`[bulkFetchOrderStatuses] success: ${statuses.length} statuses`);
|
|
481
|
+
return statuses;
|
|
482
|
+
} catch (err) {
|
|
483
|
+
console.error(`[bulkFetchOrderStatuses] FAILED for ${orderHashes.length} hashes:`, err);
|
|
484
|
+
throw err;
|
|
485
|
+
}
|
|
477
486
|
}
|
|
478
487
|
async function bulkFetchNftOwners(client, nftAddress, tokenIds) {
|
|
479
488
|
if (tokenIds.length === 0) {
|
|
480
489
|
return [];
|
|
481
490
|
}
|
|
482
491
|
try {
|
|
492
|
+
console.log(`[bulkFetchNftOwners] fetching ${tokenIds.length} owners for ${nftAddress.slice(0, 10)} via ${ERC721_OWNER_OF_HELPER_ADDRESS}`);
|
|
483
493
|
const owners = await readContract(client, {
|
|
484
494
|
address: ERC721_OWNER_OF_HELPER_ADDRESS,
|
|
485
495
|
abi: ERC721_OWNER_OF_HELPER_ABI,
|
|
486
496
|
functionName: "getTokenOwners",
|
|
487
497
|
args: [nftAddress, tokenIds.map((id) => BigInt(id))]
|
|
488
498
|
});
|
|
489
|
-
|
|
499
|
+
const result = owners.map(
|
|
490
500
|
(owner) => owner === "0x0000000000000000000000000000000000000000" ? null : owner
|
|
491
501
|
);
|
|
492
|
-
|
|
502
|
+
const validCount = result.filter((o) => o !== null).length;
|
|
503
|
+
console.log(`[bulkFetchNftOwners] success: ${validCount}/${tokenIds.length} have owners`);
|
|
504
|
+
return result;
|
|
505
|
+
} catch (err) {
|
|
506
|
+
console.error(`[bulkFetchNftOwners] FAILED for ${tokenIds.length} tokens \u2014 returning all null:`, err);
|
|
493
507
|
return tokenIds.map(() => null);
|
|
494
508
|
}
|
|
495
509
|
}
|
|
@@ -498,14 +512,18 @@ async function bulkFetchErc20Balances(client, tokenAddress, addresses) {
|
|
|
498
512
|
return [];
|
|
499
513
|
}
|
|
500
514
|
try {
|
|
515
|
+
console.log(`[bulkFetchErc20Balances] fetching ${addresses.length} balances for ${tokenAddress.slice(0, 10)}`);
|
|
501
516
|
const balances = await readContract(client, {
|
|
502
517
|
address: ERC20_BULK_BALANCE_CHECKER_ADDRESS,
|
|
503
518
|
abi: ERC20_BULK_BALANCE_CHECKER_ABI,
|
|
504
519
|
functionName: "getBalances",
|
|
505
520
|
args: [tokenAddress, addresses]
|
|
506
521
|
});
|
|
507
|
-
|
|
508
|
-
|
|
522
|
+
const result = balances.map((b) => BigInt(b));
|
|
523
|
+
console.log(`[bulkFetchErc20Balances] success: ${result.length} balances`);
|
|
524
|
+
return result;
|
|
525
|
+
} catch (err) {
|
|
526
|
+
console.error(`[bulkFetchErc20Balances] FAILED for ${addresses.length} addresses \u2014 returning all zero:`, err);
|
|
509
527
|
return addresses.map(() => BigInt(0));
|
|
510
528
|
}
|
|
511
529
|
}
|
|
@@ -796,26 +814,30 @@ var BazaarClient = class {
|
|
|
796
814
|
}
|
|
797
815
|
this.chainId = params.chainId;
|
|
798
816
|
this.rpcUrl = params.rpcUrl || CHAIN_RPC_URLS[params.chainId]?.[0] || "";
|
|
799
|
-
if (
|
|
800
|
-
|
|
817
|
+
if (params.publicClient) {
|
|
818
|
+
this.client = params.publicClient;
|
|
819
|
+
} else {
|
|
820
|
+
if (!this.rpcUrl) {
|
|
821
|
+
throw new Error(`No RPC URL available for chain ${params.chainId}`);
|
|
822
|
+
}
|
|
823
|
+
const config = getBazaarChainConfig(params.chainId);
|
|
824
|
+
this.client = createPublicClient({
|
|
825
|
+
chain: defineChain({
|
|
826
|
+
id: params.chainId,
|
|
827
|
+
name: `Chain ${params.chainId}`,
|
|
828
|
+
nativeCurrency: {
|
|
829
|
+
name: config.wrappedNativeCurrency.name.replace("Wrapped ", ""),
|
|
830
|
+
symbol: config.currencySymbol.toUpperCase(),
|
|
831
|
+
decimals: 18
|
|
832
|
+
},
|
|
833
|
+
rpcUrls: {
|
|
834
|
+
default: { http: [this.rpcUrl] }
|
|
835
|
+
}
|
|
836
|
+
}),
|
|
837
|
+
transport: http(this.rpcUrl),
|
|
838
|
+
batch: { multicall: true }
|
|
839
|
+
});
|
|
801
840
|
}
|
|
802
|
-
const config = getBazaarChainConfig(params.chainId);
|
|
803
|
-
this.client = createPublicClient({
|
|
804
|
-
chain: defineChain({
|
|
805
|
-
id: params.chainId,
|
|
806
|
-
name: `Chain ${params.chainId}`,
|
|
807
|
-
nativeCurrency: {
|
|
808
|
-
name: config.wrappedNativeCurrency.name.replace("Wrapped ", ""),
|
|
809
|
-
symbol: config.currencySymbol.toUpperCase(),
|
|
810
|
-
decimals: 18
|
|
811
|
-
},
|
|
812
|
-
rpcUrls: {
|
|
813
|
-
default: { http: [this.rpcUrl] }
|
|
814
|
-
}
|
|
815
|
-
}),
|
|
816
|
-
transport: http(this.rpcUrl),
|
|
817
|
-
batch: { multicall: true }
|
|
818
|
-
});
|
|
819
841
|
this.netClient = new NetClient({
|
|
820
842
|
chainId: params.chainId,
|
|
821
843
|
overrides: params.rpcUrl ? { rpcUrls: [params.rpcUrl] } : void 0
|
|
@@ -857,6 +879,17 @@ var BazaarClient = class {
|
|
|
857
879
|
startIndex,
|
|
858
880
|
endIndex
|
|
859
881
|
});
|
|
882
|
+
return this.processListingsFromMessages(messages, options);
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Process pre-fetched messages into valid NFT listings.
|
|
886
|
+
*
|
|
887
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
888
|
+
* to avoid redundant RPC calls.
|
|
889
|
+
*/
|
|
890
|
+
async processListingsFromMessages(messages, options) {
|
|
891
|
+
const { nftAddress, excludeMaker, includeExpired = false } = options;
|
|
892
|
+
const tag = `[BazaarClient.processListings chain=${this.chainId}]`;
|
|
860
893
|
let listings = [];
|
|
861
894
|
for (const message of messages) {
|
|
862
895
|
const listing = parseListingFromMessage(message, this.chainId);
|
|
@@ -866,6 +899,7 @@ var BazaarClient = class {
|
|
|
866
899
|
}
|
|
867
900
|
listings.push(listing);
|
|
868
901
|
}
|
|
902
|
+
console.log(tag, `parsed ${listings.length}/${messages.length} messages into listings`);
|
|
869
903
|
if (listings.length === 0) {
|
|
870
904
|
return [];
|
|
871
905
|
}
|
|
@@ -880,15 +914,27 @@ var BazaarClient = class {
|
|
|
880
914
|
const statusInfo = statusInfos[index];
|
|
881
915
|
listing.orderStatus = getOrderStatusFromInfo(listing.orderComponents, statusInfo);
|
|
882
916
|
});
|
|
917
|
+
const statusCounts = {};
|
|
918
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
919
|
+
let expiredCount = 0;
|
|
920
|
+
for (const l of listings) {
|
|
921
|
+
statusCounts[l.orderStatus] = (statusCounts[l.orderStatus] || 0) + 1;
|
|
922
|
+
if (l.expirationDate <= now) expiredCount++;
|
|
923
|
+
}
|
|
924
|
+
console.log(tag, `order statuses:`, statusCounts, `expired: ${expiredCount}`);
|
|
883
925
|
listings = listings.filter(
|
|
884
|
-
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate >
|
|
926
|
+
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > now || includeExpired && l.orderStatus === 1 /* EXPIRED */
|
|
885
927
|
);
|
|
928
|
+
console.log(tag, `after status filter: ${listings.length} (OPEN${includeExpired ? " + EXPIRED" : ""})`);
|
|
886
929
|
if (listings.length === 0) {
|
|
887
930
|
return [];
|
|
888
931
|
}
|
|
889
|
-
const
|
|
932
|
+
const openListings = listings.filter((l) => l.orderStatus === 2 /* OPEN */);
|
|
933
|
+
const expiredListings = includeExpired ? listings.filter((l) => l.orderStatus === 1 /* EXPIRED */) : [];
|
|
934
|
+
const tokenIds = openListings.map((l) => l.tokenId);
|
|
890
935
|
const owners = await bulkFetchNftOwners(this.client, nftAddress, tokenIds);
|
|
891
|
-
|
|
936
|
+
const beforeOwnership = openListings.length;
|
|
937
|
+
const validOpenListings = openListings.filter((listing, index) => {
|
|
892
938
|
const owner = owners[index];
|
|
893
939
|
return isListingValid(
|
|
894
940
|
listing.orderStatus,
|
|
@@ -897,7 +943,16 @@ var BazaarClient = class {
|
|
|
897
943
|
owner
|
|
898
944
|
);
|
|
899
945
|
});
|
|
900
|
-
|
|
946
|
+
console.log(tag, `after ownership filter: ${validOpenListings.length}/${beforeOwnership} (${beforeOwnership - validOpenListings.length} dropped)`);
|
|
947
|
+
const dedupedOpen = sortListingsByPrice(getBestListingPerToken(validOpenListings));
|
|
948
|
+
const activeTokenKeys = new Set(dedupedOpen.map((l) => `${l.nftAddress.toLowerCase()}-${l.tokenId}`));
|
|
949
|
+
const uniqueExpired = getBestListingPerToken(
|
|
950
|
+
expiredListings.filter((l) => !activeTokenKeys.has(`${l.nftAddress.toLowerCase()}-${l.tokenId}`))
|
|
951
|
+
);
|
|
952
|
+
const sortedExpired = sortListingsByPrice(uniqueExpired);
|
|
953
|
+
const result = [...dedupedOpen, ...sortedExpired];
|
|
954
|
+
console.log(tag, `final: ${result.length} listings (${dedupedOpen.length} open, ${sortedExpired.length} expired)`);
|
|
955
|
+
return result;
|
|
901
956
|
}
|
|
902
957
|
/**
|
|
903
958
|
* Get valid collection offers for a collection
|
|
@@ -912,10 +967,6 @@ var BazaarClient = class {
|
|
|
912
967
|
async getCollectionOffers(options) {
|
|
913
968
|
const { nftAddress, excludeMaker, maxMessages = 100 } = options;
|
|
914
969
|
const collectionOffersAddress = getCollectionOffersAddress(this.chainId);
|
|
915
|
-
const weth = getWrappedNativeCurrency(this.chainId);
|
|
916
|
-
if (!weth) {
|
|
917
|
-
return [];
|
|
918
|
-
}
|
|
919
970
|
const count = await this.netClient.getMessageCount({
|
|
920
971
|
filter: {
|
|
921
972
|
appAddress: collectionOffersAddress,
|
|
@@ -934,6 +985,21 @@ var BazaarClient = class {
|
|
|
934
985
|
startIndex,
|
|
935
986
|
endIndex: count
|
|
936
987
|
});
|
|
988
|
+
return this.processCollectionOffersFromMessages(messages, options);
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* Process pre-fetched messages into valid collection offers.
|
|
992
|
+
*
|
|
993
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
994
|
+
* to avoid redundant RPC calls.
|
|
995
|
+
*/
|
|
996
|
+
async processCollectionOffersFromMessages(messages, options) {
|
|
997
|
+
const { nftAddress, excludeMaker } = options;
|
|
998
|
+
const tag = `[BazaarClient.processCollectionOffers chain=${this.chainId}]`;
|
|
999
|
+
const weth = getWrappedNativeCurrency(this.chainId);
|
|
1000
|
+
if (!weth) {
|
|
1001
|
+
return [];
|
|
1002
|
+
}
|
|
937
1003
|
let offers = [];
|
|
938
1004
|
for (const message of messages) {
|
|
939
1005
|
const offer = parseCollectionOfferFromMessage(message, this.chainId);
|
|
@@ -948,6 +1014,7 @@ var BazaarClient = class {
|
|
|
948
1014
|
}
|
|
949
1015
|
offers.push(offer);
|
|
950
1016
|
}
|
|
1017
|
+
console.log(tag, `parsed ${offers.length}/${messages.length} messages into offers`);
|
|
951
1018
|
if (offers.length === 0) {
|
|
952
1019
|
return [];
|
|
953
1020
|
}
|
|
@@ -962,9 +1029,11 @@ var BazaarClient = class {
|
|
|
962
1029
|
const statusInfo = statusInfos[index];
|
|
963
1030
|
offer.orderStatus = getOrderStatusFromInfo(offer.orderComponents, statusInfo);
|
|
964
1031
|
});
|
|
1032
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
965
1033
|
offers = offers.filter(
|
|
966
|
-
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate >
|
|
1034
|
+
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > now
|
|
967
1035
|
);
|
|
1036
|
+
console.log(tag, `after status filter: ${offers.length} OPEN & not expired`);
|
|
968
1037
|
if (offers.length === 0) {
|
|
969
1038
|
return [];
|
|
970
1039
|
}
|
|
@@ -974,6 +1043,7 @@ var BazaarClient = class {
|
|
|
974
1043
|
uniqueMakers.forEach((maker, index) => {
|
|
975
1044
|
balanceMap.set(maker.toLowerCase(), balances[index]);
|
|
976
1045
|
});
|
|
1046
|
+
const beforeBalance = offers.length;
|
|
977
1047
|
offers = offers.filter((offer) => {
|
|
978
1048
|
const balance = balanceMap.get(offer.maker.toLowerCase()) || BigInt(0);
|
|
979
1049
|
return isCollectionOfferValid(
|
|
@@ -983,6 +1053,7 @@ var BazaarClient = class {
|
|
|
983
1053
|
balance
|
|
984
1054
|
);
|
|
985
1055
|
});
|
|
1056
|
+
console.log(tag, `after balance filter: ${offers.length}/${beforeBalance} (${beforeBalance - offers.length} dropped)`);
|
|
986
1057
|
return sortOffersByPrice(offers);
|
|
987
1058
|
}
|
|
988
1059
|
/**
|
|
@@ -1000,8 +1071,7 @@ var BazaarClient = class {
|
|
|
1000
1071
|
async getErc20Offers(options) {
|
|
1001
1072
|
const { tokenAddress, excludeMaker, maxMessages = 200 } = options;
|
|
1002
1073
|
const erc20OffersAddress = getErc20OffersAddress(this.chainId);
|
|
1003
|
-
|
|
1004
|
-
if (!erc20OffersAddress || !weth) {
|
|
1074
|
+
if (!erc20OffersAddress) {
|
|
1005
1075
|
return [];
|
|
1006
1076
|
}
|
|
1007
1077
|
const count = await this.netClient.getMessageCount({
|
|
@@ -1022,6 +1092,21 @@ var BazaarClient = class {
|
|
|
1022
1092
|
startIndex,
|
|
1023
1093
|
endIndex: count
|
|
1024
1094
|
});
|
|
1095
|
+
return this.processErc20OffersFromMessages(messages, options);
|
|
1096
|
+
}
|
|
1097
|
+
/**
|
|
1098
|
+
* Process pre-fetched messages into valid ERC20 offers.
|
|
1099
|
+
*
|
|
1100
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1101
|
+
* to avoid redundant RPC calls.
|
|
1102
|
+
*/
|
|
1103
|
+
async processErc20OffersFromMessages(messages, options) {
|
|
1104
|
+
const { tokenAddress, excludeMaker } = options;
|
|
1105
|
+
const tag = `[BazaarClient.processErc20Offers chain=${this.chainId}]`;
|
|
1106
|
+
const weth = getWrappedNativeCurrency(this.chainId);
|
|
1107
|
+
if (!weth) {
|
|
1108
|
+
return [];
|
|
1109
|
+
}
|
|
1025
1110
|
let offers = [];
|
|
1026
1111
|
for (const message of messages) {
|
|
1027
1112
|
const offer = parseErc20OfferFromMessage(message, this.chainId);
|
|
@@ -1039,6 +1124,7 @@ var BazaarClient = class {
|
|
|
1039
1124
|
}
|
|
1040
1125
|
offers.push(offer);
|
|
1041
1126
|
}
|
|
1127
|
+
console.log(tag, `parsed ${offers.length}/${messages.length} messages into offers`);
|
|
1042
1128
|
if (offers.length === 0) {
|
|
1043
1129
|
return [];
|
|
1044
1130
|
}
|
|
@@ -1053,9 +1139,11 @@ var BazaarClient = class {
|
|
|
1053
1139
|
const statusInfo = statusInfos[index];
|
|
1054
1140
|
offer.orderStatus = getOrderStatusFromInfo(offer.orderComponents, statusInfo);
|
|
1055
1141
|
});
|
|
1142
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1056
1143
|
offers = offers.filter(
|
|
1057
|
-
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate >
|
|
1144
|
+
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > now
|
|
1058
1145
|
);
|
|
1146
|
+
console.log(tag, `after status filter: ${offers.length} OPEN & not expired`);
|
|
1059
1147
|
if (offers.length === 0) {
|
|
1060
1148
|
return [];
|
|
1061
1149
|
}
|
|
@@ -1065,6 +1153,7 @@ var BazaarClient = class {
|
|
|
1065
1153
|
uniqueMakers.forEach((maker, index) => {
|
|
1066
1154
|
balanceMap.set(maker.toLowerCase(), balances[index]);
|
|
1067
1155
|
});
|
|
1156
|
+
const beforeBalance = offers.length;
|
|
1068
1157
|
offers = offers.filter((offer) => {
|
|
1069
1158
|
const balance = balanceMap.get(offer.maker.toLowerCase()) || BigInt(0);
|
|
1070
1159
|
return isErc20OfferValid(
|
|
@@ -1074,6 +1163,7 @@ var BazaarClient = class {
|
|
|
1074
1163
|
balance
|
|
1075
1164
|
);
|
|
1076
1165
|
});
|
|
1166
|
+
console.log(tag, `after balance filter: ${offers.length}/${beforeBalance} (${beforeBalance - offers.length} dropped)`);
|
|
1077
1167
|
return sortErc20OffersByPricePerToken(offers);
|
|
1078
1168
|
}
|
|
1079
1169
|
/**
|
|
@@ -1113,6 +1203,17 @@ var BazaarClient = class {
|
|
|
1113
1203
|
startIndex,
|
|
1114
1204
|
endIndex
|
|
1115
1205
|
});
|
|
1206
|
+
return this.processErc20ListingsFromMessages(messages, options);
|
|
1207
|
+
}
|
|
1208
|
+
/**
|
|
1209
|
+
* Process pre-fetched messages into valid ERC20 listings.
|
|
1210
|
+
*
|
|
1211
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1212
|
+
* to avoid redundant RPC calls.
|
|
1213
|
+
*/
|
|
1214
|
+
async processErc20ListingsFromMessages(messages, options) {
|
|
1215
|
+
const { tokenAddress, excludeMaker } = options;
|
|
1216
|
+
const tag = `[BazaarClient.processErc20Listings chain=${this.chainId}]`;
|
|
1116
1217
|
let listings = [];
|
|
1117
1218
|
for (const message of messages) {
|
|
1118
1219
|
const listing = parseErc20ListingFromMessage(message, this.chainId);
|
|
@@ -1125,6 +1226,7 @@ var BazaarClient = class {
|
|
|
1125
1226
|
}
|
|
1126
1227
|
listings.push(listing);
|
|
1127
1228
|
}
|
|
1229
|
+
console.log(tag, `parsed ${listings.length}/${messages.length} messages into listings`);
|
|
1128
1230
|
if (listings.length === 0) {
|
|
1129
1231
|
return [];
|
|
1130
1232
|
}
|
|
@@ -1139,18 +1241,28 @@ var BazaarClient = class {
|
|
|
1139
1241
|
const statusInfo = statusInfos[index];
|
|
1140
1242
|
listing.orderStatus = getOrderStatusFromInfo(listing.orderComponents, statusInfo);
|
|
1141
1243
|
});
|
|
1244
|
+
const statusCounts = {};
|
|
1245
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1246
|
+
let expiredCount = 0;
|
|
1247
|
+
for (const l of listings) {
|
|
1248
|
+
statusCounts[l.orderStatus] = (statusCounts[l.orderStatus] || 0) + 1;
|
|
1249
|
+
if (l.expirationDate <= now) expiredCount++;
|
|
1250
|
+
}
|
|
1251
|
+
console.log(tag, `order statuses:`, statusCounts, `expired: ${expiredCount}`);
|
|
1142
1252
|
listings = listings.filter(
|
|
1143
|
-
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate >
|
|
1253
|
+
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > now
|
|
1144
1254
|
);
|
|
1255
|
+
console.log(tag, `after status filter: ${listings.length} OPEN & not expired`);
|
|
1145
1256
|
if (listings.length === 0) {
|
|
1146
1257
|
return [];
|
|
1147
1258
|
}
|
|
1148
1259
|
const uniqueMakers = [...new Set(listings.map((l) => l.maker))];
|
|
1149
1260
|
const balances = await bulkFetchErc20Balances(this.client, tokenAddress, uniqueMakers);
|
|
1150
1261
|
const balanceMap = /* @__PURE__ */ new Map();
|
|
1151
|
-
uniqueMakers.forEach((
|
|
1152
|
-
balanceMap.set(
|
|
1262
|
+
uniqueMakers.forEach((maker, index) => {
|
|
1263
|
+
balanceMap.set(maker.toLowerCase(), balances[index]);
|
|
1153
1264
|
});
|
|
1265
|
+
const beforeBalance = listings.length;
|
|
1154
1266
|
listings = listings.filter((listing) => {
|
|
1155
1267
|
const balance = balanceMap.get(listing.maker.toLowerCase()) || BigInt(0);
|
|
1156
1268
|
return isErc20ListingValid(
|
|
@@ -1160,6 +1272,7 @@ var BazaarClient = class {
|
|
|
1160
1272
|
balance
|
|
1161
1273
|
);
|
|
1162
1274
|
});
|
|
1275
|
+
console.log(tag, `after balance filter: ${listings.length}/${beforeBalance} (${beforeBalance - listings.length} dropped)`);
|
|
1163
1276
|
return sortErc20ListingsByPricePerToken(listings);
|
|
1164
1277
|
}
|
|
1165
1278
|
/**
|
|
@@ -1286,8 +1399,12 @@ function useBazaarListings({
|
|
|
1286
1399
|
maxMessages = 200,
|
|
1287
1400
|
startIndex: startIndexOverride,
|
|
1288
1401
|
endIndex: endIndexOverride,
|
|
1289
|
-
|
|
1402
|
+
includeExpired = false,
|
|
1403
|
+
enabled = true,
|
|
1404
|
+
publicClient
|
|
1290
1405
|
}) {
|
|
1406
|
+
const wagmiClient = usePublicClient({ chainId });
|
|
1407
|
+
const resolvedClient = publicClient ?? wagmiClient;
|
|
1291
1408
|
const [listings, setListings] = useState([]);
|
|
1292
1409
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
1293
1410
|
const [processingError, setProcessingError] = useState();
|
|
@@ -1328,6 +1445,21 @@ function useBazaarListings({
|
|
|
1328
1445
|
endIndex,
|
|
1329
1446
|
enabled: enabled && isSupported && (hasRangeOverride || totalCount > 0)
|
|
1330
1447
|
});
|
|
1448
|
+
const TAG = `[useBazaarListings chain=${chainId} nft=${nftAddress.slice(0, 10)}]`;
|
|
1449
|
+
useEffect(() => {
|
|
1450
|
+
console.log(TAG, {
|
|
1451
|
+
enabled,
|
|
1452
|
+
isSupported,
|
|
1453
|
+
hasRangeOverride,
|
|
1454
|
+
totalCount,
|
|
1455
|
+
isLoadingCount,
|
|
1456
|
+
startIndex,
|
|
1457
|
+
endIndex,
|
|
1458
|
+
messagesLength: messages?.length ?? 0,
|
|
1459
|
+
isLoadingMessages,
|
|
1460
|
+
messagesError: messagesError?.message
|
|
1461
|
+
});
|
|
1462
|
+
}, [enabled, isSupported, hasRangeOverride, totalCount, isLoadingCount, startIndex, endIndex, messages?.length, isLoadingMessages, messagesError]);
|
|
1331
1463
|
useEffect(() => {
|
|
1332
1464
|
if (!isSupported || !enabled) {
|
|
1333
1465
|
setListings([]);
|
|
@@ -1341,20 +1473,19 @@ function useBazaarListings({
|
|
|
1341
1473
|
async function processListings() {
|
|
1342
1474
|
setIsProcessing(true);
|
|
1343
1475
|
setProcessingError(void 0);
|
|
1476
|
+
console.log(TAG, `processing ${messages.length} messages...`);
|
|
1344
1477
|
try {
|
|
1345
|
-
const client = new BazaarClient({ chainId });
|
|
1346
|
-
const validListings = await client.
|
|
1347
|
-
|
|
1348
|
-
excludeMaker,
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
startIndex: hasRangeOverride ? startIndexOverride : void 0,
|
|
1352
|
-
endIndex: hasRangeOverride ? endIndexOverride : void 0
|
|
1353
|
-
});
|
|
1478
|
+
const client = new BazaarClient({ chainId, publicClient: resolvedClient });
|
|
1479
|
+
const validListings = await client.processListingsFromMessages(
|
|
1480
|
+
messages,
|
|
1481
|
+
{ nftAddress, excludeMaker, includeExpired }
|
|
1482
|
+
);
|
|
1483
|
+
console.log(TAG, `processed \u2192 ${validListings.length} valid listings`);
|
|
1354
1484
|
if (!cancelled) {
|
|
1355
1485
|
setListings(validListings);
|
|
1356
1486
|
}
|
|
1357
1487
|
} catch (err) {
|
|
1488
|
+
console.error(TAG, "processing error:", err);
|
|
1358
1489
|
if (!cancelled) {
|
|
1359
1490
|
setProcessingError(err instanceof Error ? err : new Error(String(err)));
|
|
1360
1491
|
setListings([]);
|
|
@@ -1369,7 +1500,7 @@ function useBazaarListings({
|
|
|
1369
1500
|
return () => {
|
|
1370
1501
|
cancelled = true;
|
|
1371
1502
|
};
|
|
1372
|
-
}, [chainId, nftAddress, excludeMaker,
|
|
1503
|
+
}, [chainId, nftAddress, excludeMaker, includeExpired, messages, isSupported, enabled, refetchTrigger]);
|
|
1373
1504
|
const refetch = () => {
|
|
1374
1505
|
refetchMessages();
|
|
1375
1506
|
setRefetchTrigger((t) => t + 1);
|
|
@@ -1388,6 +1519,7 @@ function useBazaarCollectionOffers({
|
|
|
1388
1519
|
maxMessages = 100,
|
|
1389
1520
|
enabled = true
|
|
1390
1521
|
}) {
|
|
1522
|
+
const wagmiClient = usePublicClient({ chainId });
|
|
1391
1523
|
const [offers, setOffers] = useState([]);
|
|
1392
1524
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
1393
1525
|
const [processingError, setProcessingError] = useState();
|
|
@@ -1428,6 +1560,20 @@ function useBazaarCollectionOffers({
|
|
|
1428
1560
|
endIndex: totalCount,
|
|
1429
1561
|
enabled: enabled && isSupported && totalCount > 0
|
|
1430
1562
|
});
|
|
1563
|
+
const TAG = `[useBazaarCollectionOffers chain=${chainId} nft=${nftAddress.slice(0, 10)}]`;
|
|
1564
|
+
useEffect(() => {
|
|
1565
|
+
console.log(TAG, {
|
|
1566
|
+
enabled,
|
|
1567
|
+
isSupported,
|
|
1568
|
+
totalCount,
|
|
1569
|
+
isLoadingCount,
|
|
1570
|
+
startIndex,
|
|
1571
|
+
endIndex: totalCount,
|
|
1572
|
+
messagesLength: messages?.length ?? 0,
|
|
1573
|
+
isLoadingMessages,
|
|
1574
|
+
messagesError: messagesError?.message
|
|
1575
|
+
});
|
|
1576
|
+
}, [enabled, isSupported, totalCount, isLoadingCount, startIndex, messages?.length, isLoadingMessages, messagesError]);
|
|
1431
1577
|
useEffect(() => {
|
|
1432
1578
|
if (!isSupported || !enabled) {
|
|
1433
1579
|
setOffers([]);
|
|
@@ -1441,17 +1587,19 @@ function useBazaarCollectionOffers({
|
|
|
1441
1587
|
async function processOffers() {
|
|
1442
1588
|
setIsProcessing(true);
|
|
1443
1589
|
setProcessingError(void 0);
|
|
1590
|
+
console.log(TAG, `processing ${messages.length} messages...`);
|
|
1444
1591
|
try {
|
|
1445
|
-
const client = new BazaarClient({ chainId });
|
|
1446
|
-
const validOffers = await client.
|
|
1447
|
-
|
|
1448
|
-
excludeMaker
|
|
1449
|
-
|
|
1450
|
-
});
|
|
1592
|
+
const client = new BazaarClient({ chainId, publicClient: wagmiClient });
|
|
1593
|
+
const validOffers = await client.processCollectionOffersFromMessages(
|
|
1594
|
+
messages,
|
|
1595
|
+
{ nftAddress, excludeMaker }
|
|
1596
|
+
);
|
|
1597
|
+
console.log(TAG, `processed \u2192 ${validOffers.length} valid offers`);
|
|
1451
1598
|
if (!cancelled) {
|
|
1452
1599
|
setOffers(validOffers);
|
|
1453
1600
|
}
|
|
1454
1601
|
} catch (err) {
|
|
1602
|
+
console.error(TAG, "processing error:", err);
|
|
1455
1603
|
if (!cancelled) {
|
|
1456
1604
|
setProcessingError(err instanceof Error ? err : new Error(String(err)));
|
|
1457
1605
|
setOffers([]);
|
|
@@ -1466,7 +1614,7 @@ function useBazaarCollectionOffers({
|
|
|
1466
1614
|
return () => {
|
|
1467
1615
|
cancelled = true;
|
|
1468
1616
|
};
|
|
1469
|
-
}, [chainId, nftAddress, excludeMaker,
|
|
1617
|
+
}, [chainId, nftAddress, excludeMaker, messages, isSupported, enabled, refetchTrigger]);
|
|
1470
1618
|
const refetch = () => {
|
|
1471
1619
|
refetchMessages();
|
|
1472
1620
|
setRefetchTrigger((t) => t + 1);
|
|
@@ -1485,6 +1633,7 @@ function useBazaarErc20Offers({
|
|
|
1485
1633
|
maxMessages = 200,
|
|
1486
1634
|
enabled = true
|
|
1487
1635
|
}) {
|
|
1636
|
+
const wagmiClient = usePublicClient({ chainId });
|
|
1488
1637
|
const [offers, setOffers] = useState([]);
|
|
1489
1638
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
1490
1639
|
const [processingError, setProcessingError] = useState();
|
|
@@ -1526,6 +1675,20 @@ function useBazaarErc20Offers({
|
|
|
1526
1675
|
endIndex: totalCount,
|
|
1527
1676
|
enabled: enabled && hasErc20Offers && totalCount > 0
|
|
1528
1677
|
});
|
|
1678
|
+
const TAG = `[useBazaarErc20Offers chain=${chainId} token=${tokenAddress.slice(0, 10)}]`;
|
|
1679
|
+
useEffect(() => {
|
|
1680
|
+
console.log(TAG, {
|
|
1681
|
+
enabled,
|
|
1682
|
+
hasErc20Offers,
|
|
1683
|
+
totalCount,
|
|
1684
|
+
isLoadingCount,
|
|
1685
|
+
startIndex,
|
|
1686
|
+
endIndex: totalCount,
|
|
1687
|
+
messagesLength: messages?.length ?? 0,
|
|
1688
|
+
isLoadingMessages,
|
|
1689
|
+
messagesError: messagesError?.message
|
|
1690
|
+
});
|
|
1691
|
+
}, [enabled, hasErc20Offers, totalCount, isLoadingCount, startIndex, messages?.length, isLoadingMessages, messagesError]);
|
|
1529
1692
|
useEffect(() => {
|
|
1530
1693
|
if (!hasErc20Offers || !enabled) {
|
|
1531
1694
|
setOffers([]);
|
|
@@ -1539,17 +1702,19 @@ function useBazaarErc20Offers({
|
|
|
1539
1702
|
async function processOffers() {
|
|
1540
1703
|
setIsProcessing(true);
|
|
1541
1704
|
setProcessingError(void 0);
|
|
1705
|
+
console.log(TAG, `processing ${messages.length} messages...`);
|
|
1542
1706
|
try {
|
|
1543
|
-
const client = new BazaarClient({ chainId });
|
|
1544
|
-
const validOffers = await client.
|
|
1545
|
-
|
|
1546
|
-
excludeMaker
|
|
1547
|
-
|
|
1548
|
-
});
|
|
1707
|
+
const client = new BazaarClient({ chainId, publicClient: wagmiClient });
|
|
1708
|
+
const validOffers = await client.processErc20OffersFromMessages(
|
|
1709
|
+
messages,
|
|
1710
|
+
{ tokenAddress, excludeMaker }
|
|
1711
|
+
);
|
|
1712
|
+
console.log(TAG, `processed \u2192 ${validOffers.length} valid offers`);
|
|
1549
1713
|
if (!cancelled) {
|
|
1550
1714
|
setOffers(validOffers);
|
|
1551
1715
|
}
|
|
1552
1716
|
} catch (err) {
|
|
1717
|
+
console.error(TAG, "processing error:", err);
|
|
1553
1718
|
if (!cancelled) {
|
|
1554
1719
|
setProcessingError(err instanceof Error ? err : new Error(String(err)));
|
|
1555
1720
|
setOffers([]);
|
|
@@ -1564,7 +1729,7 @@ function useBazaarErc20Offers({
|
|
|
1564
1729
|
return () => {
|
|
1565
1730
|
cancelled = true;
|
|
1566
1731
|
};
|
|
1567
|
-
}, [chainId, tokenAddress, excludeMaker,
|
|
1732
|
+
}, [chainId, tokenAddress, excludeMaker, messages, hasErc20Offers, enabled, refetchTrigger]);
|
|
1568
1733
|
const refetch = () => {
|
|
1569
1734
|
refetchMessages();
|
|
1570
1735
|
setRefetchTrigger((t) => t + 1);
|
|
@@ -1584,8 +1749,11 @@ function useBazaarErc20Listings({
|
|
|
1584
1749
|
maxMessages = 200,
|
|
1585
1750
|
startIndex: startIndexOverride,
|
|
1586
1751
|
endIndex: endIndexOverride,
|
|
1587
|
-
enabled = true
|
|
1752
|
+
enabled = true,
|
|
1753
|
+
publicClient
|
|
1588
1754
|
}) {
|
|
1755
|
+
const wagmiClient = usePublicClient({ chainId });
|
|
1756
|
+
const resolvedClient = publicClient ?? wagmiClient;
|
|
1589
1757
|
const [listings, setListings] = useState([]);
|
|
1590
1758
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
1591
1759
|
const [processingError, setProcessingError] = useState();
|
|
@@ -1626,6 +1794,21 @@ function useBazaarErc20Listings({
|
|
|
1626
1794
|
endIndex,
|
|
1627
1795
|
enabled: enabled && isSupported && (hasRangeOverride || totalCount > 0)
|
|
1628
1796
|
});
|
|
1797
|
+
const TAG = `[useBazaarErc20Listings chain=${chainId} token=${tokenAddress.slice(0, 10)}]`;
|
|
1798
|
+
useEffect(() => {
|
|
1799
|
+
console.log(TAG, {
|
|
1800
|
+
enabled,
|
|
1801
|
+
isSupported,
|
|
1802
|
+
hasRangeOverride,
|
|
1803
|
+
totalCount,
|
|
1804
|
+
isLoadingCount,
|
|
1805
|
+
startIndex,
|
|
1806
|
+
endIndex,
|
|
1807
|
+
messagesLength: messages?.length ?? 0,
|
|
1808
|
+
isLoadingMessages,
|
|
1809
|
+
messagesError: messagesError?.message
|
|
1810
|
+
});
|
|
1811
|
+
}, [enabled, isSupported, hasRangeOverride, totalCount, isLoadingCount, startIndex, endIndex, messages?.length, isLoadingMessages, messagesError]);
|
|
1629
1812
|
useEffect(() => {
|
|
1630
1813
|
if (!isSupported || !enabled) {
|
|
1631
1814
|
setListings([]);
|
|
@@ -1639,20 +1822,19 @@ function useBazaarErc20Listings({
|
|
|
1639
1822
|
async function processListings() {
|
|
1640
1823
|
setIsProcessing(true);
|
|
1641
1824
|
setProcessingError(void 0);
|
|
1825
|
+
console.log(TAG, `processing ${messages.length} messages...`);
|
|
1642
1826
|
try {
|
|
1643
|
-
const client = new BazaarClient({ chainId });
|
|
1644
|
-
const validListings = await client.
|
|
1645
|
-
|
|
1646
|
-
excludeMaker
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
startIndex: hasRangeOverride ? startIndexOverride : void 0,
|
|
1650
|
-
endIndex: hasRangeOverride ? endIndexOverride : void 0
|
|
1651
|
-
});
|
|
1827
|
+
const client = new BazaarClient({ chainId, publicClient: resolvedClient });
|
|
1828
|
+
const validListings = await client.processErc20ListingsFromMessages(
|
|
1829
|
+
messages,
|
|
1830
|
+
{ tokenAddress, excludeMaker }
|
|
1831
|
+
);
|
|
1832
|
+
console.log(TAG, `processed \u2192 ${validListings.length} valid listings`);
|
|
1652
1833
|
if (!cancelled) {
|
|
1653
1834
|
setListings(validListings);
|
|
1654
1835
|
}
|
|
1655
1836
|
} catch (err) {
|
|
1837
|
+
console.error(TAG, "processing error:", err);
|
|
1656
1838
|
if (!cancelled) {
|
|
1657
1839
|
setProcessingError(err instanceof Error ? err : new Error(String(err)));
|
|
1658
1840
|
setListings([]);
|
|
@@ -1667,7 +1849,7 @@ function useBazaarErc20Listings({
|
|
|
1667
1849
|
return () => {
|
|
1668
1850
|
cancelled = true;
|
|
1669
1851
|
};
|
|
1670
|
-
}, [chainId, tokenAddress, excludeMaker,
|
|
1852
|
+
}, [chainId, tokenAddress, excludeMaker, messages, isSupported, enabled, refetchTrigger]);
|
|
1671
1853
|
const refetch = () => {
|
|
1672
1854
|
refetchMessages();
|
|
1673
1855
|
setRefetchTrigger((t) => t + 1);
|