@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.js
CHANGED
|
@@ -359,10 +359,11 @@ var DEFAULT_FEE_COLLECTOR_ADDRESS = "0x32D16C15410248bef498D7aF50D10Db1a546b9E5"
|
|
|
359
359
|
var DEFAULT_ERC20_BAZAAR_ADDRESS = "0x00000000a2d173a4610c85c7471a25b6bc216a70";
|
|
360
360
|
var DEFAULT_NFT_FEE_BPS = 500;
|
|
361
361
|
var BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS = "0x0000009112ABCE652674b4fE3eD9C765B22d11A7";
|
|
362
|
-
var ERC721_OWNER_OF_HELPER_ADDRESS = "
|
|
363
|
-
var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "
|
|
362
|
+
var ERC721_OWNER_OF_HELPER_ADDRESS = "0x00000012E3eb0700925947fAF9cd1440319b4F37";
|
|
363
|
+
var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "0x000000B50A9f2923F2DB931391824F6D1278f712";
|
|
364
364
|
var NET_SEAPORT_ZONE_ADDRESS = "0x000000007F8c58fbf215bF91Bda7421A806cf3ae";
|
|
365
365
|
var NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS = "0x000000B799ec6D7aCC1B578f62bFc324c25DFC5A";
|
|
366
|
+
var NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS = "0x000000bC63761cbb05305632212e2f3AE2BE7a9B";
|
|
366
367
|
var BAZAAR_CHAIN_CONFIGS = {
|
|
367
368
|
// Base Mainnet
|
|
368
369
|
8453: {
|
|
@@ -650,18 +651,26 @@ async function bulkFetchOrderStatuses(client, chainId, orderHashes) {
|
|
|
650
651
|
return [];
|
|
651
652
|
}
|
|
652
653
|
const seaportAddress = getSeaportAddress(chainId);
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
654
|
+
try {
|
|
655
|
+
console.log(`[bulkFetchOrderStatuses] fetching ${orderHashes.length} statuses via ${BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS}`);
|
|
656
|
+
const results = await actions.readContract(client, {
|
|
657
|
+
address: BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS,
|
|
658
|
+
abi: BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI,
|
|
659
|
+
functionName: "getOrderStatuses",
|
|
660
|
+
args: [seaportAddress, orderHashes]
|
|
661
|
+
});
|
|
662
|
+
const statuses = results.map((r) => ({
|
|
663
|
+
isValidated: r.isValidated,
|
|
664
|
+
isCancelled: r.isCancelled,
|
|
665
|
+
totalFilled: BigInt(r.totalFilled),
|
|
666
|
+
totalSize: BigInt(r.totalSize)
|
|
667
|
+
}));
|
|
668
|
+
console.log(`[bulkFetchOrderStatuses] success: ${statuses.length} statuses`);
|
|
669
|
+
return statuses;
|
|
670
|
+
} catch (err) {
|
|
671
|
+
console.error(`[bulkFetchOrderStatuses] FAILED for ${orderHashes.length} hashes:`, err);
|
|
672
|
+
throw err;
|
|
673
|
+
}
|
|
665
674
|
}
|
|
666
675
|
async function createOrderStatusMap(client, chainId, orderHashes) {
|
|
667
676
|
const statuses = await bulkFetchOrderStatuses(client, chainId, orderHashes);
|
|
@@ -676,16 +685,21 @@ async function bulkFetchNftOwners(client, nftAddress, tokenIds) {
|
|
|
676
685
|
return [];
|
|
677
686
|
}
|
|
678
687
|
try {
|
|
688
|
+
console.log(`[bulkFetchNftOwners] fetching ${tokenIds.length} owners for ${nftAddress.slice(0, 10)} via ${ERC721_OWNER_OF_HELPER_ADDRESS}`);
|
|
679
689
|
const owners = await actions.readContract(client, {
|
|
680
690
|
address: ERC721_OWNER_OF_HELPER_ADDRESS,
|
|
681
691
|
abi: ERC721_OWNER_OF_HELPER_ABI,
|
|
682
692
|
functionName: "getTokenOwners",
|
|
683
693
|
args: [nftAddress, tokenIds.map((id) => BigInt(id))]
|
|
684
694
|
});
|
|
685
|
-
|
|
695
|
+
const result = owners.map(
|
|
686
696
|
(owner) => owner === "0x0000000000000000000000000000000000000000" ? null : owner
|
|
687
697
|
);
|
|
688
|
-
|
|
698
|
+
const validCount = result.filter((o) => o !== null).length;
|
|
699
|
+
console.log(`[bulkFetchNftOwners] success: ${validCount}/${tokenIds.length} have owners`);
|
|
700
|
+
return result;
|
|
701
|
+
} catch (err) {
|
|
702
|
+
console.error(`[bulkFetchNftOwners] FAILED for ${tokenIds.length} tokens \u2014 returning all null:`, err);
|
|
689
703
|
return tokenIds.map(() => null);
|
|
690
704
|
}
|
|
691
705
|
}
|
|
@@ -702,14 +716,18 @@ async function bulkFetchErc20Balances(client, tokenAddress, addresses) {
|
|
|
702
716
|
return [];
|
|
703
717
|
}
|
|
704
718
|
try {
|
|
719
|
+
console.log(`[bulkFetchErc20Balances] fetching ${addresses.length} balances for ${tokenAddress.slice(0, 10)}`);
|
|
705
720
|
const balances = await actions.readContract(client, {
|
|
706
721
|
address: ERC20_BULK_BALANCE_CHECKER_ADDRESS,
|
|
707
722
|
abi: ERC20_BULK_BALANCE_CHECKER_ABI,
|
|
708
723
|
functionName: "getBalances",
|
|
709
724
|
args: [tokenAddress, addresses]
|
|
710
725
|
});
|
|
711
|
-
|
|
712
|
-
|
|
726
|
+
const result = balances.map((b) => BigInt(b));
|
|
727
|
+
console.log(`[bulkFetchErc20Balances] success: ${result.length} balances`);
|
|
728
|
+
return result;
|
|
729
|
+
} catch (err) {
|
|
730
|
+
console.error(`[bulkFetchErc20Balances] FAILED for ${addresses.length} addresses \u2014 returning all zero:`, err);
|
|
713
731
|
return addresses.map(() => BigInt(0));
|
|
714
732
|
}
|
|
715
733
|
}
|
|
@@ -788,6 +806,7 @@ function parseListingFromMessage(message, chainId) {
|
|
|
788
806
|
}
|
|
789
807
|
const priceWei = getTotalConsiderationAmount(parameters);
|
|
790
808
|
const tokenId = offerItem.identifierOrCriteria.toString();
|
|
809
|
+
const targetFulfiller = parameters.zone.toLowerCase() === NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS.toLowerCase() && parameters.zoneHash !== "0x0000000000000000000000000000000000000000000000000000000000000000" ? parameters.zoneHash : void 0;
|
|
791
810
|
return {
|
|
792
811
|
maker: parameters.offerer,
|
|
793
812
|
nftAddress: offerItem.token,
|
|
@@ -804,7 +823,8 @@ function parseListingFromMessage(message, chainId) {
|
|
|
804
823
|
orderComponents: {
|
|
805
824
|
...parameters,
|
|
806
825
|
counter: submission.counter
|
|
807
|
-
}
|
|
826
|
+
},
|
|
827
|
+
targetFulfiller
|
|
808
828
|
};
|
|
809
829
|
} catch {
|
|
810
830
|
return null;
|
|
@@ -1014,26 +1034,30 @@ var BazaarClient = class {
|
|
|
1014
1034
|
}
|
|
1015
1035
|
this.chainId = params.chainId;
|
|
1016
1036
|
this.rpcUrl = params.rpcUrl || CHAIN_RPC_URLS[params.chainId]?.[0] || "";
|
|
1017
|
-
if (
|
|
1018
|
-
|
|
1037
|
+
if (params.publicClient) {
|
|
1038
|
+
this.client = params.publicClient;
|
|
1039
|
+
} else {
|
|
1040
|
+
if (!this.rpcUrl) {
|
|
1041
|
+
throw new Error(`No RPC URL available for chain ${params.chainId}`);
|
|
1042
|
+
}
|
|
1043
|
+
const config = getBazaarChainConfig(params.chainId);
|
|
1044
|
+
this.client = viem.createPublicClient({
|
|
1045
|
+
chain: viem.defineChain({
|
|
1046
|
+
id: params.chainId,
|
|
1047
|
+
name: `Chain ${params.chainId}`,
|
|
1048
|
+
nativeCurrency: {
|
|
1049
|
+
name: config.wrappedNativeCurrency.name.replace("Wrapped ", ""),
|
|
1050
|
+
symbol: config.currencySymbol.toUpperCase(),
|
|
1051
|
+
decimals: 18
|
|
1052
|
+
},
|
|
1053
|
+
rpcUrls: {
|
|
1054
|
+
default: { http: [this.rpcUrl] }
|
|
1055
|
+
}
|
|
1056
|
+
}),
|
|
1057
|
+
transport: viem.http(this.rpcUrl),
|
|
1058
|
+
batch: { multicall: true }
|
|
1059
|
+
});
|
|
1019
1060
|
}
|
|
1020
|
-
const config = getBazaarChainConfig(params.chainId);
|
|
1021
|
-
this.client = viem.createPublicClient({
|
|
1022
|
-
chain: viem.defineChain({
|
|
1023
|
-
id: params.chainId,
|
|
1024
|
-
name: `Chain ${params.chainId}`,
|
|
1025
|
-
nativeCurrency: {
|
|
1026
|
-
name: config.wrappedNativeCurrency.name.replace("Wrapped ", ""),
|
|
1027
|
-
symbol: config.currencySymbol.toUpperCase(),
|
|
1028
|
-
decimals: 18
|
|
1029
|
-
},
|
|
1030
|
-
rpcUrls: {
|
|
1031
|
-
default: { http: [this.rpcUrl] }
|
|
1032
|
-
}
|
|
1033
|
-
}),
|
|
1034
|
-
transport: viem.http(this.rpcUrl),
|
|
1035
|
-
batch: { multicall: true }
|
|
1036
|
-
});
|
|
1037
1061
|
this.netClient = new core.NetClient({
|
|
1038
1062
|
chainId: params.chainId,
|
|
1039
1063
|
overrides: params.rpcUrl ? { rpcUrls: [params.rpcUrl] } : void 0
|
|
@@ -1050,26 +1074,42 @@ var BazaarClient = class {
|
|
|
1050
1074
|
* Results are deduplicated (one per token) and sorted by price (lowest first)
|
|
1051
1075
|
*/
|
|
1052
1076
|
async getListings(options) {
|
|
1053
|
-
const { nftAddress, excludeMaker, maxMessages = 200 } = options;
|
|
1077
|
+
const { nftAddress, excludeMaker, maker, maxMessages = 200 } = options;
|
|
1054
1078
|
const bazaarAddress = getBazaarAddress(this.chainId);
|
|
1055
|
-
const
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1079
|
+
const filter = {
|
|
1080
|
+
appAddress: bazaarAddress,
|
|
1081
|
+
topic: nftAddress.toLowerCase(),
|
|
1082
|
+
maker
|
|
1083
|
+
};
|
|
1084
|
+
let startIndex;
|
|
1085
|
+
let endIndex;
|
|
1086
|
+
if (options.startIndex != null && options.endIndex != null) {
|
|
1087
|
+
startIndex = options.startIndex;
|
|
1088
|
+
endIndex = options.endIndex;
|
|
1089
|
+
} else {
|
|
1090
|
+
const count = await this.netClient.getMessageCount({ filter });
|
|
1091
|
+
if (count === 0) {
|
|
1092
|
+
return [];
|
|
1059
1093
|
}
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
return [];
|
|
1094
|
+
startIndex = Math.max(0, count - maxMessages);
|
|
1095
|
+
endIndex = count;
|
|
1063
1096
|
}
|
|
1064
|
-
const startIndex = Math.max(0, count - maxMessages);
|
|
1065
1097
|
const messages = await this.netClient.getMessages({
|
|
1066
|
-
filter
|
|
1067
|
-
appAddress: bazaarAddress,
|
|
1068
|
-
topic: nftAddress.toLowerCase()
|
|
1069
|
-
},
|
|
1098
|
+
filter,
|
|
1070
1099
|
startIndex,
|
|
1071
|
-
endIndex
|
|
1100
|
+
endIndex
|
|
1072
1101
|
});
|
|
1102
|
+
return this.processListingsFromMessages(messages, options);
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Process pre-fetched messages into valid NFT listings.
|
|
1106
|
+
*
|
|
1107
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1108
|
+
* to avoid redundant RPC calls.
|
|
1109
|
+
*/
|
|
1110
|
+
async processListingsFromMessages(messages, options) {
|
|
1111
|
+
const { nftAddress, excludeMaker, includeExpired = false } = options;
|
|
1112
|
+
const tag = `[BazaarClient.processListings chain=${this.chainId}]`;
|
|
1073
1113
|
let listings = [];
|
|
1074
1114
|
for (const message of messages) {
|
|
1075
1115
|
const listing = parseListingFromMessage(message, this.chainId);
|
|
@@ -1079,6 +1119,7 @@ var BazaarClient = class {
|
|
|
1079
1119
|
}
|
|
1080
1120
|
listings.push(listing);
|
|
1081
1121
|
}
|
|
1122
|
+
console.log(tag, `parsed ${listings.length}/${messages.length} messages into listings`);
|
|
1082
1123
|
if (listings.length === 0) {
|
|
1083
1124
|
return [];
|
|
1084
1125
|
}
|
|
@@ -1093,15 +1134,27 @@ var BazaarClient = class {
|
|
|
1093
1134
|
const statusInfo = statusInfos[index];
|
|
1094
1135
|
listing.orderStatus = getOrderStatusFromInfo(listing.orderComponents, statusInfo);
|
|
1095
1136
|
});
|
|
1137
|
+
const statusCounts = {};
|
|
1138
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1139
|
+
let expiredCount = 0;
|
|
1140
|
+
for (const l of listings) {
|
|
1141
|
+
statusCounts[l.orderStatus] = (statusCounts[l.orderStatus] || 0) + 1;
|
|
1142
|
+
if (l.expirationDate <= now) expiredCount++;
|
|
1143
|
+
}
|
|
1144
|
+
console.log(tag, `order statuses:`, statusCounts, `expired: ${expiredCount}`);
|
|
1096
1145
|
listings = listings.filter(
|
|
1097
|
-
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate >
|
|
1146
|
+
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > now || includeExpired && l.orderStatus === 1 /* EXPIRED */
|
|
1098
1147
|
);
|
|
1148
|
+
console.log(tag, `after status filter: ${listings.length} (OPEN${includeExpired ? " + EXPIRED" : ""})`);
|
|
1099
1149
|
if (listings.length === 0) {
|
|
1100
1150
|
return [];
|
|
1101
1151
|
}
|
|
1102
|
-
const
|
|
1152
|
+
const openListings = listings.filter((l) => l.orderStatus === 2 /* OPEN */);
|
|
1153
|
+
const expiredListings = includeExpired ? listings.filter((l) => l.orderStatus === 1 /* EXPIRED */) : [];
|
|
1154
|
+
const tokenIds = openListings.map((l) => l.tokenId);
|
|
1103
1155
|
const owners = await bulkFetchNftOwners(this.client, nftAddress, tokenIds);
|
|
1104
|
-
|
|
1156
|
+
const beforeOwnership = openListings.length;
|
|
1157
|
+
const validOpenListings = openListings.filter((listing, index) => {
|
|
1105
1158
|
const owner = owners[index];
|
|
1106
1159
|
return isListingValid(
|
|
1107
1160
|
listing.orderStatus,
|
|
@@ -1110,7 +1163,16 @@ var BazaarClient = class {
|
|
|
1110
1163
|
owner
|
|
1111
1164
|
);
|
|
1112
1165
|
});
|
|
1113
|
-
|
|
1166
|
+
console.log(tag, `after ownership filter: ${validOpenListings.length}/${beforeOwnership} (${beforeOwnership - validOpenListings.length} dropped)`);
|
|
1167
|
+
const dedupedOpen = sortListingsByPrice(getBestListingPerToken(validOpenListings));
|
|
1168
|
+
const activeTokenKeys = new Set(dedupedOpen.map((l) => `${l.nftAddress.toLowerCase()}-${l.tokenId}`));
|
|
1169
|
+
const uniqueExpired = getBestListingPerToken(
|
|
1170
|
+
expiredListings.filter((l) => !activeTokenKeys.has(`${l.nftAddress.toLowerCase()}-${l.tokenId}`))
|
|
1171
|
+
);
|
|
1172
|
+
const sortedExpired = sortListingsByPrice(uniqueExpired);
|
|
1173
|
+
const result = [...dedupedOpen, ...sortedExpired];
|
|
1174
|
+
console.log(tag, `final: ${result.length} listings (${dedupedOpen.length} open, ${sortedExpired.length} expired)`);
|
|
1175
|
+
return result;
|
|
1114
1176
|
}
|
|
1115
1177
|
/**
|
|
1116
1178
|
* Get valid collection offers for a collection
|
|
@@ -1125,10 +1187,6 @@ var BazaarClient = class {
|
|
|
1125
1187
|
async getCollectionOffers(options) {
|
|
1126
1188
|
const { nftAddress, excludeMaker, maxMessages = 100 } = options;
|
|
1127
1189
|
const collectionOffersAddress = getCollectionOffersAddress(this.chainId);
|
|
1128
|
-
const weth = getWrappedNativeCurrency(this.chainId);
|
|
1129
|
-
if (!weth) {
|
|
1130
|
-
return [];
|
|
1131
|
-
}
|
|
1132
1190
|
const count = await this.netClient.getMessageCount({
|
|
1133
1191
|
filter: {
|
|
1134
1192
|
appAddress: collectionOffersAddress,
|
|
@@ -1147,6 +1205,21 @@ var BazaarClient = class {
|
|
|
1147
1205
|
startIndex,
|
|
1148
1206
|
endIndex: count
|
|
1149
1207
|
});
|
|
1208
|
+
return this.processCollectionOffersFromMessages(messages, options);
|
|
1209
|
+
}
|
|
1210
|
+
/**
|
|
1211
|
+
* Process pre-fetched messages into valid collection offers.
|
|
1212
|
+
*
|
|
1213
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1214
|
+
* to avoid redundant RPC calls.
|
|
1215
|
+
*/
|
|
1216
|
+
async processCollectionOffersFromMessages(messages, options) {
|
|
1217
|
+
const { nftAddress, excludeMaker } = options;
|
|
1218
|
+
const tag = `[BazaarClient.processCollectionOffers chain=${this.chainId}]`;
|
|
1219
|
+
const weth = getWrappedNativeCurrency(this.chainId);
|
|
1220
|
+
if (!weth) {
|
|
1221
|
+
return [];
|
|
1222
|
+
}
|
|
1150
1223
|
let offers = [];
|
|
1151
1224
|
for (const message of messages) {
|
|
1152
1225
|
const offer = parseCollectionOfferFromMessage(message, this.chainId);
|
|
@@ -1161,6 +1234,7 @@ var BazaarClient = class {
|
|
|
1161
1234
|
}
|
|
1162
1235
|
offers.push(offer);
|
|
1163
1236
|
}
|
|
1237
|
+
console.log(tag, `parsed ${offers.length}/${messages.length} messages into offers`);
|
|
1164
1238
|
if (offers.length === 0) {
|
|
1165
1239
|
return [];
|
|
1166
1240
|
}
|
|
@@ -1175,9 +1249,11 @@ var BazaarClient = class {
|
|
|
1175
1249
|
const statusInfo = statusInfos[index];
|
|
1176
1250
|
offer.orderStatus = getOrderStatusFromInfo(offer.orderComponents, statusInfo);
|
|
1177
1251
|
});
|
|
1252
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1178
1253
|
offers = offers.filter(
|
|
1179
|
-
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate >
|
|
1254
|
+
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > now
|
|
1180
1255
|
);
|
|
1256
|
+
console.log(tag, `after status filter: ${offers.length} OPEN & not expired`);
|
|
1181
1257
|
if (offers.length === 0) {
|
|
1182
1258
|
return [];
|
|
1183
1259
|
}
|
|
@@ -1187,6 +1263,7 @@ var BazaarClient = class {
|
|
|
1187
1263
|
uniqueMakers.forEach((maker, index) => {
|
|
1188
1264
|
balanceMap.set(maker.toLowerCase(), balances[index]);
|
|
1189
1265
|
});
|
|
1266
|
+
const beforeBalance = offers.length;
|
|
1190
1267
|
offers = offers.filter((offer) => {
|
|
1191
1268
|
const balance = balanceMap.get(offer.maker.toLowerCase()) || BigInt(0);
|
|
1192
1269
|
return isCollectionOfferValid(
|
|
@@ -1196,6 +1273,7 @@ var BazaarClient = class {
|
|
|
1196
1273
|
balance
|
|
1197
1274
|
);
|
|
1198
1275
|
});
|
|
1276
|
+
console.log(tag, `after balance filter: ${offers.length}/${beforeBalance} (${beforeBalance - offers.length} dropped)`);
|
|
1199
1277
|
return sortOffersByPrice(offers);
|
|
1200
1278
|
}
|
|
1201
1279
|
/**
|
|
@@ -1213,8 +1291,7 @@ var BazaarClient = class {
|
|
|
1213
1291
|
async getErc20Offers(options) {
|
|
1214
1292
|
const { tokenAddress, excludeMaker, maxMessages = 200 } = options;
|
|
1215
1293
|
const erc20OffersAddress = getErc20OffersAddress(this.chainId);
|
|
1216
|
-
|
|
1217
|
-
if (!erc20OffersAddress || !weth) {
|
|
1294
|
+
if (!erc20OffersAddress) {
|
|
1218
1295
|
return [];
|
|
1219
1296
|
}
|
|
1220
1297
|
const count = await this.netClient.getMessageCount({
|
|
@@ -1235,6 +1312,21 @@ var BazaarClient = class {
|
|
|
1235
1312
|
startIndex,
|
|
1236
1313
|
endIndex: count
|
|
1237
1314
|
});
|
|
1315
|
+
return this.processErc20OffersFromMessages(messages, options);
|
|
1316
|
+
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Process pre-fetched messages into valid ERC20 offers.
|
|
1319
|
+
*
|
|
1320
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1321
|
+
* to avoid redundant RPC calls.
|
|
1322
|
+
*/
|
|
1323
|
+
async processErc20OffersFromMessages(messages, options) {
|
|
1324
|
+
const { tokenAddress, excludeMaker } = options;
|
|
1325
|
+
const tag = `[BazaarClient.processErc20Offers chain=${this.chainId}]`;
|
|
1326
|
+
const weth = getWrappedNativeCurrency(this.chainId);
|
|
1327
|
+
if (!weth) {
|
|
1328
|
+
return [];
|
|
1329
|
+
}
|
|
1238
1330
|
let offers = [];
|
|
1239
1331
|
for (const message of messages) {
|
|
1240
1332
|
const offer = parseErc20OfferFromMessage(message, this.chainId);
|
|
@@ -1252,6 +1344,7 @@ var BazaarClient = class {
|
|
|
1252
1344
|
}
|
|
1253
1345
|
offers.push(offer);
|
|
1254
1346
|
}
|
|
1347
|
+
console.log(tag, `parsed ${offers.length}/${messages.length} messages into offers`);
|
|
1255
1348
|
if (offers.length === 0) {
|
|
1256
1349
|
return [];
|
|
1257
1350
|
}
|
|
@@ -1266,9 +1359,11 @@ var BazaarClient = class {
|
|
|
1266
1359
|
const statusInfo = statusInfos[index];
|
|
1267
1360
|
offer.orderStatus = getOrderStatusFromInfo(offer.orderComponents, statusInfo);
|
|
1268
1361
|
});
|
|
1362
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1269
1363
|
offers = offers.filter(
|
|
1270
|
-
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate >
|
|
1364
|
+
(o) => o.orderStatus === 2 /* OPEN */ && o.expirationDate > now
|
|
1271
1365
|
);
|
|
1366
|
+
console.log(tag, `after status filter: ${offers.length} OPEN & not expired`);
|
|
1272
1367
|
if (offers.length === 0) {
|
|
1273
1368
|
return [];
|
|
1274
1369
|
}
|
|
@@ -1278,6 +1373,7 @@ var BazaarClient = class {
|
|
|
1278
1373
|
uniqueMakers.forEach((maker, index) => {
|
|
1279
1374
|
balanceMap.set(maker.toLowerCase(), balances[index]);
|
|
1280
1375
|
});
|
|
1376
|
+
const beforeBalance = offers.length;
|
|
1281
1377
|
offers = offers.filter((offer) => {
|
|
1282
1378
|
const balance = balanceMap.get(offer.maker.toLowerCase()) || BigInt(0);
|
|
1283
1379
|
return isErc20OfferValid(
|
|
@@ -1287,6 +1383,7 @@ var BazaarClient = class {
|
|
|
1287
1383
|
balance
|
|
1288
1384
|
);
|
|
1289
1385
|
});
|
|
1386
|
+
console.log(tag, `after balance filter: ${offers.length}/${beforeBalance} (${beforeBalance - offers.length} dropped)`);
|
|
1290
1387
|
return sortErc20OffersByPricePerToken(offers);
|
|
1291
1388
|
}
|
|
1292
1389
|
/**
|
|
@@ -1301,26 +1398,42 @@ var BazaarClient = class {
|
|
|
1301
1398
|
* all valid listings are returned (grouped by maker in the UI).
|
|
1302
1399
|
*/
|
|
1303
1400
|
async getErc20Listings(options) {
|
|
1304
|
-
const { tokenAddress, excludeMaker, maxMessages = 200 } = options;
|
|
1401
|
+
const { tokenAddress, excludeMaker, maker, maxMessages = 200 } = options;
|
|
1305
1402
|
const erc20BazaarAddress = getErc20BazaarAddress(this.chainId);
|
|
1306
|
-
const
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1403
|
+
const filter = {
|
|
1404
|
+
appAddress: erc20BazaarAddress,
|
|
1405
|
+
topic: tokenAddress.toLowerCase(),
|
|
1406
|
+
maker
|
|
1407
|
+
};
|
|
1408
|
+
let startIndex;
|
|
1409
|
+
let endIndex;
|
|
1410
|
+
if (options.startIndex != null && options.endIndex != null) {
|
|
1411
|
+
startIndex = options.startIndex;
|
|
1412
|
+
endIndex = options.endIndex;
|
|
1413
|
+
} else {
|
|
1414
|
+
const count = await this.netClient.getMessageCount({ filter });
|
|
1415
|
+
if (count === 0) {
|
|
1416
|
+
return [];
|
|
1310
1417
|
}
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
return [];
|
|
1418
|
+
startIndex = Math.max(0, count - maxMessages);
|
|
1419
|
+
endIndex = count;
|
|
1314
1420
|
}
|
|
1315
|
-
const startIndex = Math.max(0, count - maxMessages);
|
|
1316
1421
|
const messages = await this.netClient.getMessages({
|
|
1317
|
-
filter
|
|
1318
|
-
appAddress: erc20BazaarAddress,
|
|
1319
|
-
topic: tokenAddress.toLowerCase()
|
|
1320
|
-
},
|
|
1422
|
+
filter,
|
|
1321
1423
|
startIndex,
|
|
1322
|
-
endIndex
|
|
1424
|
+
endIndex
|
|
1323
1425
|
});
|
|
1426
|
+
return this.processErc20ListingsFromMessages(messages, options);
|
|
1427
|
+
}
|
|
1428
|
+
/**
|
|
1429
|
+
* Process pre-fetched messages into valid ERC20 listings.
|
|
1430
|
+
*
|
|
1431
|
+
* Use this when messages have already been fetched (e.g. via useNetMessages)
|
|
1432
|
+
* to avoid redundant RPC calls.
|
|
1433
|
+
*/
|
|
1434
|
+
async processErc20ListingsFromMessages(messages, options) {
|
|
1435
|
+
const { tokenAddress, excludeMaker } = options;
|
|
1436
|
+
const tag = `[BazaarClient.processErc20Listings chain=${this.chainId}]`;
|
|
1324
1437
|
let listings = [];
|
|
1325
1438
|
for (const message of messages) {
|
|
1326
1439
|
const listing = parseErc20ListingFromMessage(message, this.chainId);
|
|
@@ -1333,6 +1446,7 @@ var BazaarClient = class {
|
|
|
1333
1446
|
}
|
|
1334
1447
|
listings.push(listing);
|
|
1335
1448
|
}
|
|
1449
|
+
console.log(tag, `parsed ${listings.length}/${messages.length} messages into listings`);
|
|
1336
1450
|
if (listings.length === 0) {
|
|
1337
1451
|
return [];
|
|
1338
1452
|
}
|
|
@@ -1347,9 +1461,18 @@ var BazaarClient = class {
|
|
|
1347
1461
|
const statusInfo = statusInfos[index];
|
|
1348
1462
|
listing.orderStatus = getOrderStatusFromInfo(listing.orderComponents, statusInfo);
|
|
1349
1463
|
});
|
|
1464
|
+
const statusCounts = {};
|
|
1465
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1466
|
+
let expiredCount = 0;
|
|
1467
|
+
for (const l of listings) {
|
|
1468
|
+
statusCounts[l.orderStatus] = (statusCounts[l.orderStatus] || 0) + 1;
|
|
1469
|
+
if (l.expirationDate <= now) expiredCount++;
|
|
1470
|
+
}
|
|
1471
|
+
console.log(tag, `order statuses:`, statusCounts, `expired: ${expiredCount}`);
|
|
1350
1472
|
listings = listings.filter(
|
|
1351
|
-
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate >
|
|
1473
|
+
(l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > now
|
|
1352
1474
|
);
|
|
1475
|
+
console.log(tag, `after status filter: ${listings.length} OPEN & not expired`);
|
|
1353
1476
|
if (listings.length === 0) {
|
|
1354
1477
|
return [];
|
|
1355
1478
|
}
|
|
@@ -1359,6 +1482,7 @@ var BazaarClient = class {
|
|
|
1359
1482
|
uniqueMakers.forEach((maker, index) => {
|
|
1360
1483
|
balanceMap.set(maker.toLowerCase(), balances[index]);
|
|
1361
1484
|
});
|
|
1485
|
+
const beforeBalance = listings.length;
|
|
1362
1486
|
listings = listings.filter((listing) => {
|
|
1363
1487
|
const balance = balanceMap.get(listing.maker.toLowerCase()) || BigInt(0);
|
|
1364
1488
|
return isErc20ListingValid(
|
|
@@ -1368,6 +1492,7 @@ var BazaarClient = class {
|
|
|
1368
1492
|
balance
|
|
1369
1493
|
);
|
|
1370
1494
|
});
|
|
1495
|
+
console.log(tag, `after balance filter: ${listings.length}/${beforeBalance} (${beforeBalance - listings.length} dropped)`);
|
|
1371
1496
|
return sortErc20ListingsByPricePerToken(listings);
|
|
1372
1497
|
}
|
|
1373
1498
|
/**
|
|
@@ -1497,6 +1622,7 @@ exports.ERC721_OWNER_OF_HELPER_ABI = ERC721_OWNER_OF_HELPER_ABI;
|
|
|
1497
1622
|
exports.ERC721_OWNER_OF_HELPER_ADDRESS = ERC721_OWNER_OF_HELPER_ADDRESS;
|
|
1498
1623
|
exports.ItemType = ItemType;
|
|
1499
1624
|
exports.NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS = NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS;
|
|
1625
|
+
exports.NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS = NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS;
|
|
1500
1626
|
exports.NET_SEAPORT_ZONE_ADDRESS = NET_SEAPORT_ZONE_ADDRESS;
|
|
1501
1627
|
exports.OrderType = OrderType;
|
|
1502
1628
|
exports.SEAPORT_CANCEL_ABI = SEAPORT_CANCEL_ABI;
|