@net-protocol/bazaar 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +198 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +197 -16
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +63 -5
- package/dist/react.d.ts +63 -5
- package/dist/react.js +306 -17
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +306 -18
- package/dist/react.mjs.map +1 -1
- package/dist/{types-CfGfQTJL.d.mts → types-5kMf461x.d.mts} +39 -3
- package/dist/{types-CfGfQTJL.d.ts → types-5kMf461x.d.ts} +39 -3
- package/package.json +2 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PublicClient } from 'viem';
|
|
2
2
|
import { NetMessage } from '@net-protocol/core';
|
|
3
|
-
import { G as GetListingsOptions, L as Listing, a as GetCollectionOffersOptions, C as CollectionOffer, b as GetErc20OffersOptions, E as Erc20Offer, c as GetErc20ListingsOptions, d as Erc20Listing, W as WriteTransactionConfig,
|
|
4
|
-
export {
|
|
3
|
+
import { G as GetListingsOptions, L as Listing, a as GetCollectionOffersOptions, C as CollectionOffer, b as GetErc20OffersOptions, E as Erc20Offer, c as GetErc20ListingsOptions, d as Erc20Listing, e as GetSalesOptions, S as Sale, W as WriteTransactionConfig, f as SeaportOrderComponents, g as SeaportSubmission, h as SeaportOrderParameters, i as SeaportOrderStatusInfo, j as SeaportOrderStatus } from './types-5kMf461x.mjs';
|
|
4
|
+
export { l as ConsiderationItem, n as CreateCollectionOfferParams, m as CreateListingParams, I as ItemType, k as OfferItem, O as OrderType } from './types-5kMf461x.mjs';
|
|
5
5
|
import { Seaport } from '@opensea/seaport-js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -97,6 +97,22 @@ declare class BazaarClient {
|
|
|
97
97
|
* to avoid redundant RPC calls.
|
|
98
98
|
*/
|
|
99
99
|
processErc20ListingsFromMessages(messages: NetMessage[], options: Pick<GetErc20ListingsOptions, "tokenAddress" | "excludeMaker">): Promise<Erc20Listing[]>;
|
|
100
|
+
/**
|
|
101
|
+
* Get recent sales for a collection
|
|
102
|
+
*
|
|
103
|
+
* Sales are stored differently from listings: Net messages contain order hashes,
|
|
104
|
+
* and the actual sale data is fetched from the bulk storage contract.
|
|
105
|
+
*
|
|
106
|
+
* Results are sorted by timestamp (most recent first)
|
|
107
|
+
*/
|
|
108
|
+
getSales(options: GetSalesOptions): Promise<Sale[]>;
|
|
109
|
+
/**
|
|
110
|
+
* Process pre-fetched messages into sales.
|
|
111
|
+
*
|
|
112
|
+
* Each message's data field contains an order hash. The actual sale data
|
|
113
|
+
* is fetched from the bulk storage contract using these order hashes.
|
|
114
|
+
*/
|
|
115
|
+
processSalesFromMessages(messages: NetMessage[], options: Pick<GetSalesOptions, "nftAddress">): Promise<Sale[]>;
|
|
100
116
|
/**
|
|
101
117
|
* Get the chain ID this client is configured for
|
|
102
118
|
*/
|
|
@@ -995,5 +1011,16 @@ declare function parseErc20ListingFromMessage(message: NetMessage, chainId: numb
|
|
|
995
1011
|
* Sort ERC20 listings by price per token (lowest first)
|
|
996
1012
|
*/
|
|
997
1013
|
declare function sortErc20ListingsByPricePerToken(listings: Erc20Listing[]): Erc20Listing[];
|
|
1014
|
+
/**
|
|
1015
|
+
* Parse a sale from bulk storage data (zone-stored sale details).
|
|
1016
|
+
*
|
|
1017
|
+
* The storage contract stores the full ZoneParameters struct for each sale,
|
|
1018
|
+
* keyed by order hash with operator = NET_SEAPORT_ZONE_ADDRESS.
|
|
1019
|
+
*/
|
|
1020
|
+
declare function parseSaleFromStoredData(storedData: string, chainId: number): Sale | null;
|
|
1021
|
+
/**
|
|
1022
|
+
* Sort sales by timestamp (most recent first)
|
|
1023
|
+
*/
|
|
1024
|
+
declare function sortSalesByTimestamp(sales: Sale[]): Sale[];
|
|
998
1025
|
|
|
999
|
-
export { BAZAAR_COLLECTION_OFFERS_ABI, BAZAAR_SUBMISSION_ABI, BAZAAR_V2_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS, type BazaarChainConfig, BazaarClient, CollectionOffer, ERC20_BULK_BALANCE_CHECKER_ABI, ERC20_BULK_BALANCE_CHECKER_ADDRESS, ERC721_OWNER_OF_HELPER_ABI, ERC721_OWNER_OF_HELPER_ADDRESS, Erc20Listing, Erc20Offer, GetCollectionOffersOptions, GetErc20ListingsOptions, GetErc20OffersOptions, GetListingsOptions, Listing, NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS, NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS, NET_SEAPORT_ZONE_ADDRESS, SEAPORT_CANCEL_ABI, SeaportOrderComponents, SeaportOrderParameters, SeaportOrderStatus, SeaportOrderStatusInfo, SeaportSubmission, type WrappedNativeCurrency, WriteTransactionConfig, 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 };
|
|
1026
|
+
export { BAZAAR_COLLECTION_OFFERS_ABI, BAZAAR_SUBMISSION_ABI, BAZAAR_V2_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS, type BazaarChainConfig, BazaarClient, CollectionOffer, ERC20_BULK_BALANCE_CHECKER_ABI, ERC20_BULK_BALANCE_CHECKER_ADDRESS, ERC721_OWNER_OF_HELPER_ABI, ERC721_OWNER_OF_HELPER_ADDRESS, Erc20Listing, Erc20Offer, GetCollectionOffersOptions, GetErc20ListingsOptions, GetErc20OffersOptions, GetListingsOptions, GetSalesOptions, Listing, NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS, NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS, NET_SEAPORT_ZONE_ADDRESS, SEAPORT_CANCEL_ABI, Sale, SeaportOrderComponents, SeaportOrderParameters, SeaportOrderStatus, SeaportOrderStatusInfo, SeaportSubmission, type WrappedNativeCurrency, WriteTransactionConfig, 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, parseSaleFromStoredData, sortErc20ListingsByPricePerToken, sortErc20OffersByPricePerToken, sortListingsByPrice, sortOffersByPrice, sortSalesByTimestamp };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PublicClient } from 'viem';
|
|
2
2
|
import { NetMessage } from '@net-protocol/core';
|
|
3
|
-
import { G as GetListingsOptions, L as Listing, a as GetCollectionOffersOptions, C as CollectionOffer, b as GetErc20OffersOptions, E as Erc20Offer, c as GetErc20ListingsOptions, d as Erc20Listing, W as WriteTransactionConfig,
|
|
4
|
-
export {
|
|
3
|
+
import { G as GetListingsOptions, L as Listing, a as GetCollectionOffersOptions, C as CollectionOffer, b as GetErc20OffersOptions, E as Erc20Offer, c as GetErc20ListingsOptions, d as Erc20Listing, e as GetSalesOptions, S as Sale, W as WriteTransactionConfig, f as SeaportOrderComponents, g as SeaportSubmission, h as SeaportOrderParameters, i as SeaportOrderStatusInfo, j as SeaportOrderStatus } from './types-5kMf461x.js';
|
|
4
|
+
export { l as ConsiderationItem, n as CreateCollectionOfferParams, m as CreateListingParams, I as ItemType, k as OfferItem, O as OrderType } from './types-5kMf461x.js';
|
|
5
5
|
import { Seaport } from '@opensea/seaport-js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -97,6 +97,22 @@ declare class BazaarClient {
|
|
|
97
97
|
* to avoid redundant RPC calls.
|
|
98
98
|
*/
|
|
99
99
|
processErc20ListingsFromMessages(messages: NetMessage[], options: Pick<GetErc20ListingsOptions, "tokenAddress" | "excludeMaker">): Promise<Erc20Listing[]>;
|
|
100
|
+
/**
|
|
101
|
+
* Get recent sales for a collection
|
|
102
|
+
*
|
|
103
|
+
* Sales are stored differently from listings: Net messages contain order hashes,
|
|
104
|
+
* and the actual sale data is fetched from the bulk storage contract.
|
|
105
|
+
*
|
|
106
|
+
* Results are sorted by timestamp (most recent first)
|
|
107
|
+
*/
|
|
108
|
+
getSales(options: GetSalesOptions): Promise<Sale[]>;
|
|
109
|
+
/**
|
|
110
|
+
* Process pre-fetched messages into sales.
|
|
111
|
+
*
|
|
112
|
+
* Each message's data field contains an order hash. The actual sale data
|
|
113
|
+
* is fetched from the bulk storage contract using these order hashes.
|
|
114
|
+
*/
|
|
115
|
+
processSalesFromMessages(messages: NetMessage[], options: Pick<GetSalesOptions, "nftAddress">): Promise<Sale[]>;
|
|
100
116
|
/**
|
|
101
117
|
* Get the chain ID this client is configured for
|
|
102
118
|
*/
|
|
@@ -995,5 +1011,16 @@ declare function parseErc20ListingFromMessage(message: NetMessage, chainId: numb
|
|
|
995
1011
|
* Sort ERC20 listings by price per token (lowest first)
|
|
996
1012
|
*/
|
|
997
1013
|
declare function sortErc20ListingsByPricePerToken(listings: Erc20Listing[]): Erc20Listing[];
|
|
1014
|
+
/**
|
|
1015
|
+
* Parse a sale from bulk storage data (zone-stored sale details).
|
|
1016
|
+
*
|
|
1017
|
+
* The storage contract stores the full ZoneParameters struct for each sale,
|
|
1018
|
+
* keyed by order hash with operator = NET_SEAPORT_ZONE_ADDRESS.
|
|
1019
|
+
*/
|
|
1020
|
+
declare function parseSaleFromStoredData(storedData: string, chainId: number): Sale | null;
|
|
1021
|
+
/**
|
|
1022
|
+
* Sort sales by timestamp (most recent first)
|
|
1023
|
+
*/
|
|
1024
|
+
declare function sortSalesByTimestamp(sales: Sale[]): Sale[];
|
|
998
1025
|
|
|
999
|
-
export { BAZAAR_COLLECTION_OFFERS_ABI, BAZAAR_SUBMISSION_ABI, BAZAAR_V2_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS, type BazaarChainConfig, BazaarClient, CollectionOffer, ERC20_BULK_BALANCE_CHECKER_ABI, ERC20_BULK_BALANCE_CHECKER_ADDRESS, ERC721_OWNER_OF_HELPER_ABI, ERC721_OWNER_OF_HELPER_ADDRESS, Erc20Listing, Erc20Offer, GetCollectionOffersOptions, GetErc20ListingsOptions, GetErc20OffersOptions, GetListingsOptions, Listing, NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS, NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS, NET_SEAPORT_ZONE_ADDRESS, SEAPORT_CANCEL_ABI, SeaportOrderComponents, SeaportOrderParameters, SeaportOrderStatus, SeaportOrderStatusInfo, SeaportSubmission, type WrappedNativeCurrency, WriteTransactionConfig, 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 };
|
|
1026
|
+
export { BAZAAR_COLLECTION_OFFERS_ABI, BAZAAR_SUBMISSION_ABI, BAZAAR_V2_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ABI, BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS, type BazaarChainConfig, BazaarClient, CollectionOffer, ERC20_BULK_BALANCE_CHECKER_ABI, ERC20_BULK_BALANCE_CHECKER_ADDRESS, ERC721_OWNER_OF_HELPER_ABI, ERC721_OWNER_OF_HELPER_ADDRESS, Erc20Listing, Erc20Offer, GetCollectionOffersOptions, GetErc20ListingsOptions, GetErc20OffersOptions, GetListingsOptions, GetSalesOptions, Listing, NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS, NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS, NET_SEAPORT_ZONE_ADDRESS, SEAPORT_CANCEL_ABI, Sale, SeaportOrderComponents, SeaportOrderParameters, SeaportOrderStatus, SeaportOrderStatusInfo, SeaportSubmission, type WrappedNativeCurrency, WriteTransactionConfig, 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, parseSaleFromStoredData, sortErc20ListingsByPricePerToken, sortErc20OffersByPricePerToken, sortListingsByPrice, sortOffersByPrice, sortSalesByTimestamp };
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ var core = require('@net-protocol/core');
|
|
|
5
5
|
var seaportJs = require('@opensea/seaport-js');
|
|
6
6
|
var ethers = require('ethers');
|
|
7
7
|
var actions = require('viem/actions');
|
|
8
|
+
var storage = require('@net-protocol/storage');
|
|
8
9
|
|
|
9
10
|
// src/client/BazaarClient.ts
|
|
10
11
|
|
|
@@ -791,8 +792,6 @@ function isErc20ListingValid(orderStatus, expirationDate, tokenAmount, sellerTok
|
|
|
791
792
|
}
|
|
792
793
|
return true;
|
|
793
794
|
}
|
|
794
|
-
|
|
795
|
-
// src/utils/parsing.ts
|
|
796
795
|
function parseListingFromMessage(message, chainId) {
|
|
797
796
|
try {
|
|
798
797
|
const submission = decodeSeaportSubmission(message.data);
|
|
@@ -1014,8 +1013,85 @@ function sortErc20ListingsByPricePerToken(listings) {
|
|
|
1014
1013
|
return 0;
|
|
1015
1014
|
});
|
|
1016
1015
|
}
|
|
1017
|
-
|
|
1018
|
-
|
|
1016
|
+
var ZONE_STORED_SALE_ABI = [
|
|
1017
|
+
{ type: "uint256" },
|
|
1018
|
+
// timestamp
|
|
1019
|
+
{ type: "uint256" },
|
|
1020
|
+
// netTotalMessageLength
|
|
1021
|
+
{ type: "uint256" },
|
|
1022
|
+
// netTotalMessageForAppTopicLength
|
|
1023
|
+
{
|
|
1024
|
+
name: "zoneParameters",
|
|
1025
|
+
type: "tuple",
|
|
1026
|
+
internalType: "struct ZoneParameters",
|
|
1027
|
+
components: [
|
|
1028
|
+
{ name: "orderHash", type: "bytes32", internalType: "bytes32" },
|
|
1029
|
+
{ name: "fulfiller", type: "address", internalType: "address" },
|
|
1030
|
+
{ name: "offerer", type: "address", internalType: "address" },
|
|
1031
|
+
{
|
|
1032
|
+
name: "offer",
|
|
1033
|
+
type: "tuple[]",
|
|
1034
|
+
internalType: "struct SpentItem[]",
|
|
1035
|
+
components: [
|
|
1036
|
+
{ name: "itemType", type: "uint8", internalType: "enum ItemType" },
|
|
1037
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
1038
|
+
{ name: "identifier", type: "uint256", internalType: "uint256" },
|
|
1039
|
+
{ name: "amount", type: "uint256", internalType: "uint256" }
|
|
1040
|
+
]
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
name: "consideration",
|
|
1044
|
+
type: "tuple[]",
|
|
1045
|
+
internalType: "struct ReceivedItem[]",
|
|
1046
|
+
components: [
|
|
1047
|
+
{ name: "itemType", type: "uint8", internalType: "enum ItemType" },
|
|
1048
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
1049
|
+
{ name: "identifier", type: "uint256", internalType: "uint256" },
|
|
1050
|
+
{ name: "amount", type: "uint256", internalType: "uint256" },
|
|
1051
|
+
{ name: "recipient", type: "address", internalType: "address payable" }
|
|
1052
|
+
]
|
|
1053
|
+
},
|
|
1054
|
+
{ name: "extraData", type: "bytes", internalType: "bytes" },
|
|
1055
|
+
{ name: "orderHashes", type: "bytes32[]", internalType: "bytes32[]" },
|
|
1056
|
+
{ name: "startTime", type: "uint256", internalType: "uint256" },
|
|
1057
|
+
{ name: "endTime", type: "uint256", internalType: "uint256" },
|
|
1058
|
+
{ name: "zoneHash", type: "bytes32", internalType: "bytes32" }
|
|
1059
|
+
]
|
|
1060
|
+
}
|
|
1061
|
+
];
|
|
1062
|
+
function parseSaleFromStoredData(storedData, chainId) {
|
|
1063
|
+
try {
|
|
1064
|
+
const cleanedData = "0x" + (storedData.startsWith("0x") ? storedData.slice(2) : storedData);
|
|
1065
|
+
const [timestamp, , , zoneParameters] = viem.decodeAbiParameters(
|
|
1066
|
+
ZONE_STORED_SALE_ABI,
|
|
1067
|
+
cleanedData
|
|
1068
|
+
);
|
|
1069
|
+
const offerItem = zoneParameters.offer[0];
|
|
1070
|
+
if (!offerItem) return null;
|
|
1071
|
+
const totalConsideration = zoneParameters.consideration.reduce(
|
|
1072
|
+
(acc, item) => acc + item.amount,
|
|
1073
|
+
BigInt(0)
|
|
1074
|
+
);
|
|
1075
|
+
return {
|
|
1076
|
+
seller: zoneParameters.offerer,
|
|
1077
|
+
buyer: zoneParameters.fulfiller,
|
|
1078
|
+
tokenAddress: offerItem.token,
|
|
1079
|
+
tokenId: offerItem.identifier.toString(),
|
|
1080
|
+
amount: offerItem.amount,
|
|
1081
|
+
itemType: offerItem.itemType,
|
|
1082
|
+
priceWei: totalConsideration,
|
|
1083
|
+
price: parseFloat(viem.formatEther(totalConsideration)),
|
|
1084
|
+
currency: getCurrencySymbol(chainId),
|
|
1085
|
+
timestamp: Number(timestamp),
|
|
1086
|
+
orderHash: zoneParameters.orderHash
|
|
1087
|
+
};
|
|
1088
|
+
} catch {
|
|
1089
|
+
return null;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
function sortSalesByTimestamp(sales) {
|
|
1093
|
+
return [...sales].sort((a, b) => b.timestamp - a.timestamp);
|
|
1094
|
+
}
|
|
1019
1095
|
var CHAIN_RPC_URLS = {
|
|
1020
1096
|
8453: ["https://base-mainnet.public.blastapi.io", "https://mainnet.base.org"],
|
|
1021
1097
|
84532: ["https://sepolia.base.org"],
|
|
@@ -1078,7 +1154,7 @@ var BazaarClient = class {
|
|
|
1078
1154
|
const bazaarAddress = getBazaarAddress(this.chainId);
|
|
1079
1155
|
const filter = {
|
|
1080
1156
|
appAddress: bazaarAddress,
|
|
1081
|
-
topic: nftAddress
|
|
1157
|
+
topic: nftAddress?.toLowerCase(),
|
|
1082
1158
|
maker
|
|
1083
1159
|
};
|
|
1084
1160
|
let startIndex;
|
|
@@ -1151,18 +1227,57 @@ var BazaarClient = class {
|
|
|
1151
1227
|
}
|
|
1152
1228
|
const openListings = listings.filter((l) => l.orderStatus === 2 /* OPEN */);
|
|
1153
1229
|
const expiredListings = includeExpired ? listings.filter((l) => l.orderStatus === 1 /* EXPIRED */) : [];
|
|
1154
|
-
|
|
1155
|
-
const owners = await bulkFetchNftOwners(this.client, nftAddress, tokenIds);
|
|
1230
|
+
let validOpenListings;
|
|
1156
1231
|
const beforeOwnership = openListings.length;
|
|
1157
|
-
|
|
1158
|
-
const
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1232
|
+
if (nftAddress) {
|
|
1233
|
+
const tokenIds = openListings.map((l) => l.tokenId);
|
|
1234
|
+
const owners = await bulkFetchNftOwners(this.client, nftAddress, tokenIds);
|
|
1235
|
+
validOpenListings = openListings.filter((listing, index) => {
|
|
1236
|
+
const owner = owners[index];
|
|
1237
|
+
return isListingValid(
|
|
1238
|
+
listing.orderStatus,
|
|
1239
|
+
listing.expirationDate,
|
|
1240
|
+
listing.maker,
|
|
1241
|
+
owner
|
|
1242
|
+
);
|
|
1243
|
+
});
|
|
1244
|
+
} else {
|
|
1245
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1246
|
+
for (const listing of openListings) {
|
|
1247
|
+
const key = listing.nftAddress.toLowerCase();
|
|
1248
|
+
const group = groups.get(key);
|
|
1249
|
+
if (group) {
|
|
1250
|
+
group.push(listing);
|
|
1251
|
+
} else {
|
|
1252
|
+
groups.set(key, [listing]);
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
const groupEntries = Array.from(groups.entries());
|
|
1256
|
+
const ownerResults = await Promise.all(
|
|
1257
|
+
groupEntries.map(
|
|
1258
|
+
([addr, groupListings]) => bulkFetchNftOwners(
|
|
1259
|
+
this.client,
|
|
1260
|
+
addr,
|
|
1261
|
+
groupListings.map((l) => l.tokenId)
|
|
1262
|
+
)
|
|
1263
|
+
)
|
|
1164
1264
|
);
|
|
1165
|
-
|
|
1265
|
+
validOpenListings = [];
|
|
1266
|
+
groupEntries.forEach(([, groupListings], groupIndex) => {
|
|
1267
|
+
const owners = ownerResults[groupIndex];
|
|
1268
|
+
for (let i = 0; i < groupListings.length; i++) {
|
|
1269
|
+
const listing = groupListings[i];
|
|
1270
|
+
if (isListingValid(
|
|
1271
|
+
listing.orderStatus,
|
|
1272
|
+
listing.expirationDate,
|
|
1273
|
+
listing.maker,
|
|
1274
|
+
owners[i]
|
|
1275
|
+
)) {
|
|
1276
|
+
validOpenListings.push(listing);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1166
1281
|
console.log(tag, `after ownership filter: ${validOpenListings.length}/${beforeOwnership} (${beforeOwnership - validOpenListings.length} dropped)`);
|
|
1167
1282
|
const dedupedOpen = sortListingsByPrice(getBestListingPerToken(validOpenListings));
|
|
1168
1283
|
const activeTokenKeys = new Set(dedupedOpen.map((l) => `${l.nftAddress.toLowerCase()}-${l.tokenId}`));
|
|
@@ -1495,6 +1610,72 @@ var BazaarClient = class {
|
|
|
1495
1610
|
console.log(tag, `after balance filter: ${listings.length}/${beforeBalance} (${beforeBalance - listings.length} dropped)`);
|
|
1496
1611
|
return sortErc20ListingsByPricePerToken(listings);
|
|
1497
1612
|
}
|
|
1613
|
+
/**
|
|
1614
|
+
* Get recent sales for a collection
|
|
1615
|
+
*
|
|
1616
|
+
* Sales are stored differently from listings: Net messages contain order hashes,
|
|
1617
|
+
* and the actual sale data is fetched from the bulk storage contract.
|
|
1618
|
+
*
|
|
1619
|
+
* Results are sorted by timestamp (most recent first)
|
|
1620
|
+
*/
|
|
1621
|
+
async getSales(options) {
|
|
1622
|
+
const { nftAddress, maxMessages = 100 } = options;
|
|
1623
|
+
const filter = {
|
|
1624
|
+
appAddress: NET_SEAPORT_ZONE_ADDRESS,
|
|
1625
|
+
topic: nftAddress.toLowerCase()
|
|
1626
|
+
};
|
|
1627
|
+
const count = await this.netClient.getMessageCount({ filter });
|
|
1628
|
+
if (count === 0) {
|
|
1629
|
+
return [];
|
|
1630
|
+
}
|
|
1631
|
+
const startIndex = Math.max(0, count - maxMessages);
|
|
1632
|
+
const messages = await this.netClient.getMessages({
|
|
1633
|
+
filter,
|
|
1634
|
+
startIndex,
|
|
1635
|
+
endIndex: count
|
|
1636
|
+
});
|
|
1637
|
+
return this.processSalesFromMessages(messages, options);
|
|
1638
|
+
}
|
|
1639
|
+
/**
|
|
1640
|
+
* Process pre-fetched messages into sales.
|
|
1641
|
+
*
|
|
1642
|
+
* Each message's data field contains an order hash. The actual sale data
|
|
1643
|
+
* is fetched from the bulk storage contract using these order hashes.
|
|
1644
|
+
*/
|
|
1645
|
+
async processSalesFromMessages(messages, options) {
|
|
1646
|
+
const tag = `[BazaarClient.processSales chain=${this.chainId}]`;
|
|
1647
|
+
if (messages.length === 0) {
|
|
1648
|
+
return [];
|
|
1649
|
+
}
|
|
1650
|
+
const orderHashes = messages.map((m) => m.data);
|
|
1651
|
+
console.log(tag, `fetching ${orderHashes.length} sale details from storage...`);
|
|
1652
|
+
const bulkKeys = orderHashes.map((hash) => ({
|
|
1653
|
+
key: hash,
|
|
1654
|
+
operator: NET_SEAPORT_ZONE_ADDRESS
|
|
1655
|
+
}));
|
|
1656
|
+
let storedResults;
|
|
1657
|
+
try {
|
|
1658
|
+
storedResults = await this.client.readContract({
|
|
1659
|
+
abi: storage.STORAGE_CONTRACT.abi,
|
|
1660
|
+
address: storage.STORAGE_CONTRACT.address,
|
|
1661
|
+
functionName: "bulkGet",
|
|
1662
|
+
args: [bulkKeys]
|
|
1663
|
+
});
|
|
1664
|
+
} catch (err) {
|
|
1665
|
+
console.error(tag, "bulk storage fetch failed:", err);
|
|
1666
|
+
return [];
|
|
1667
|
+
}
|
|
1668
|
+
const sales = [];
|
|
1669
|
+
for (const result of storedResults) {
|
|
1670
|
+
if (!result.value || result.value === "0x") continue;
|
|
1671
|
+
const sale = parseSaleFromStoredData(result.value, this.chainId);
|
|
1672
|
+
if (sale) {
|
|
1673
|
+
sales.push(sale);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
console.log(tag, `parsed ${sales.length}/${storedResults.length} sales`);
|
|
1677
|
+
return sales;
|
|
1678
|
+
}
|
|
1498
1679
|
/**
|
|
1499
1680
|
* Get the chain ID this client is configured for
|
|
1500
1681
|
*/
|
|
@@ -1663,9 +1844,11 @@ exports.parseCollectionOfferFromMessage = parseCollectionOfferFromMessage;
|
|
|
1663
1844
|
exports.parseErc20ListingFromMessage = parseErc20ListingFromMessage;
|
|
1664
1845
|
exports.parseErc20OfferFromMessage = parseErc20OfferFromMessage;
|
|
1665
1846
|
exports.parseListingFromMessage = parseListingFromMessage;
|
|
1847
|
+
exports.parseSaleFromStoredData = parseSaleFromStoredData;
|
|
1666
1848
|
exports.sortErc20ListingsByPricePerToken = sortErc20ListingsByPricePerToken;
|
|
1667
1849
|
exports.sortErc20OffersByPricePerToken = sortErc20OffersByPricePerToken;
|
|
1668
1850
|
exports.sortListingsByPrice = sortListingsByPrice;
|
|
1669
1851
|
exports.sortOffersByPrice = sortOffersByPrice;
|
|
1852
|
+
exports.sortSalesByTimestamp = sortSalesByTimestamp;
|
|
1670
1853
|
//# sourceMappingURL=index.js.map
|
|
1671
1854
|
//# sourceMappingURL=index.js.map
|