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