@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/README.md +1 -1
- package/dist/index.d.mts +36 -6
- package/dist/index.d.ts +36 -6
- package/dist/index.js +205 -79
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +205 -80
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +22 -3
- package/dist/react.d.ts +22 -3
- package/dist/react.js +336 -129
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +336 -129
- package/dist/react.mjs.map +1 -1
- package/dist/{types--4_RIuQ5.d.mts → types-DDHh9yJB.d.mts} +16 -0
- package/dist/{types--4_RIuQ5.d.ts → types-DDHh9yJB.d.ts} +16 -0
- package/package.json +1 -1
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 = "
|
|
361
|
-
var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "
|
|
360
|
+
var ERC721_OWNER_OF_HELPER_ADDRESS = "0x00000012E3eb0700925947fAF9cd1440319b4F37";
|
|
361
|
+
var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "0x000000B50A9f2923F2DB931391824F6D1278f712";
|
|
362
362
|
var NET_SEAPORT_ZONE_ADDRESS = "0x000000007F8c58fbf215bF91Bda7421A806cf3ae";
|
|
363
363
|
var NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS = "0x000000B799ec6D7aCC1B578f62bFc324c25DFC5A";
|
|
364
|
+
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
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
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
|
-
|
|
693
|
+
const result = owners.map(
|
|
684
694
|
(owner) => owner === "0x0000000000000000000000000000000000000000" ? null : owner
|
|
685
695
|
);
|
|
686
|
-
|
|
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
|
-
|
|
710
|
-
|
|
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 (
|
|
1016
|
-
|
|
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
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
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
|
-
|
|
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
|
|
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 >
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 >
|
|
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
|
-
|
|
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 >
|
|
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
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
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
|
-
|
|
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
|
|
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 >
|
|
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
|