@net-protocol/bazaar 0.1.0 → 0.1.2

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 CHANGED
@@ -1,5 +1,5 @@
1
- import { G as GetListingsOptions, L as Listing, a as GetCollectionOffersOptions, C as CollectionOffer, b as GetErc20OffersOptions, E as Erc20Offer, W as WriteTransactionConfig, S as SeaportOrderComponents, c as SeaportSubmission, d as SeaportOrderParameters, e as SeaportOrderStatusInfo, f as SeaportOrderStatus } from './types-CY-6M9Ta.mjs';
2
- export { h as ConsiderationItem, j as CreateCollectionOfferParams, i as CreateListingParams, I as ItemType, g as OfferItem, O as OrderType } from './types-CY-6M9Ta.mjs';
1
+ 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, S as SeaportOrderComponents, e as SeaportSubmission, f as SeaportOrderParameters, g as SeaportOrderStatusInfo, h as SeaportOrderStatus } from './types-KQgBECzI.mjs';
2
+ export { j as ConsiderationItem, l as CreateCollectionOfferParams, k as CreateListingParams, I as ItemType, i as OfferItem, O as OrderType } from './types-KQgBECzI.mjs';
3
3
  import { Seaport } from '@opensea/seaport-js';
4
4
  import { PublicClient } from 'viem';
5
5
  import { NetMessage } from '@net-protocol/core';
@@ -56,6 +56,18 @@ declare class BazaarClient {
56
56
  * Results are sorted by price per token (highest first)
57
57
  */
58
58
  getErc20Offers(options: GetErc20OffersOptions): Promise<Erc20Offer[]>;
59
+ /**
60
+ * Get valid ERC20 listings for a token
61
+ *
62
+ * Returns listings that are:
63
+ * - OPEN status (not filled, cancelled, or expired)
64
+ * - Not expired
65
+ * - Seller has sufficient ERC20 token balance
66
+ *
67
+ * Results are sorted by price per token (lowest first). No deduplication —
68
+ * all valid listings are returned (grouped by maker in the UI).
69
+ */
70
+ getErc20Listings(options: GetErc20ListingsOptions): Promise<Erc20Listing[]>;
59
71
  /**
60
72
  * Get the chain ID this client is configured for
61
73
  */
@@ -73,6 +85,10 @@ declare class BazaarClient {
73
85
  * Only available on Base (8453) and HyperEVM (999)
74
86
  */
75
87
  getErc20OffersAddress(): `0x${string}` | undefined;
88
+ /**
89
+ * Get the ERC20 bazaar (listings) contract address for this chain
90
+ */
91
+ getErc20BazaarAddress(): `0x${string}`;
76
92
  /**
77
93
  * Get the Seaport contract address for this chain
78
94
  */
@@ -91,6 +107,13 @@ declare class BazaarClient {
91
107
  * Use the orderComponents from the CollectionOffer object returned by getCollectionOffers().
92
108
  */
93
109
  prepareCancelCollectionOffer(offer: CollectionOffer): WriteTransactionConfig;
110
+ /**
111
+ * Prepare a transaction to cancel an ERC20 listing
112
+ *
113
+ * The listing must have been created by the caller.
114
+ * Use the orderComponents from the Erc20Listing object returned by getErc20Listings().
115
+ */
116
+ prepareCancelErc20Listing(listing: Erc20Listing): WriteTransactionConfig;
94
117
  /**
95
118
  * Prepare a transaction to cancel a Seaport order
96
119
  *
@@ -116,6 +139,8 @@ interface BazaarChainConfig {
116
139
  collectionOffersAddress: `0x${string}`;
117
140
  /** ERC20 offers contract (only on Base and HyperEVM) */
118
141
  erc20OffersAddress?: `0x${string}`;
142
+ /** ERC20 listings contract */
143
+ erc20BazaarAddress?: `0x${string}`;
119
144
  /** Seaport contract address */
120
145
  seaportAddress: `0x${string}`;
121
146
  /** Fee collector address */
@@ -134,6 +159,7 @@ declare const ERC721_OWNER_OF_HELPER_ADDRESS: "0x000000aa4eFa2e5A4a6002C7F08B6e8
134
159
  declare const ERC20_BULK_BALANCE_CHECKER_ADDRESS: "0x000000b50a9f2923f2db931391824f6d1278f712";
135
160
  declare const NET_SEAPORT_ZONE_ADDRESS: "0x000000007F8c58fbf215bF91Bda7421A806cf3ae";
136
161
  declare const NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS: "0x000000B799ec6D7aCC1B578f62bFc324c25DFC5A";
162
+ declare const NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS: "0x000000bC63761cbb05305632212e2f3AE2BE7a9B";
137
163
  /**
138
164
  * Get bazaar configuration for a chain
139
165
  */
@@ -183,6 +209,10 @@ declare function getHighEthAddress(chainId: number): `0x${string}` | undefined;
183
209
  * Only deployed on Base (8453) and HyperEVM (999)
184
210
  */
185
211
  declare function getErc20OffersAddress(chainId: number): `0x${string}` | undefined;
212
+ /**
213
+ * Get ERC20 bazaar (listings) contract address for a chain
214
+ */
215
+ declare function getErc20BazaarAddress(chainId: number): `0x${string}`;
186
216
 
187
217
  declare const BAZAAR_V2_ABI: readonly [{
188
218
  readonly type: "function";
@@ -880,6 +910,13 @@ declare function isCollectionOfferValid(orderStatus: SeaportOrderStatus, expirat
880
910
  * - Buyer has sufficient WETH balance
881
911
  */
882
912
  declare function isErc20OfferValid(orderStatus: SeaportOrderStatus, expirationDate: number, priceWei: bigint, buyerWethBalance: bigint): boolean;
913
+ /**
914
+ * Validate that an ERC20 listing is still valid:
915
+ * - Order is OPEN
916
+ * - Not expired
917
+ * - Seller has sufficient ERC20 token balance
918
+ */
919
+ declare function isErc20ListingValid(orderStatus: SeaportOrderStatus, expirationDate: number, tokenAmount: bigint, sellerTokenBalance: bigint): boolean;
883
920
 
884
921
  /**
885
922
  * Utilities for parsing Net messages into listings and offers
@@ -917,5 +954,17 @@ declare function parseErc20OfferFromMessage(message: NetMessage, chainId: number
917
954
  * Sort ERC20 offers by price per token (highest first)
918
955
  */
919
956
  declare function sortErc20OffersByPricePerToken(offers: Erc20Offer[]): Erc20Offer[];
957
+ /**
958
+ * Parse a Net message into an ERC20 listing
959
+ *
960
+ * ERC20 listings have the ERC20 token in the offer array (seller is offering tokens)
961
+ * and native currency payments in the consideration array.
962
+ * They do NOT use the collection offer zone (that would be an offer, not a listing).
963
+ */
964
+ declare function parseErc20ListingFromMessage(message: NetMessage, chainId: number): Erc20Listing | null;
965
+ /**
966
+ * Sort ERC20 listings by price per token (lowest first)
967
+ */
968
+ declare function sortErc20ListingsByPricePerToken(listings: Erc20Listing[]): Erc20Listing[];
920
969
 
921
- 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, Erc20Offer, GetCollectionOffersOptions, GetErc20OffersOptions, GetListingsOptions, Listing, NET_SEAPORT_COLLECTION_OFFER_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, getErc20OffersAddress, getFeeCollectorAddress, getHighEthAddress, getNftFeeBps, getOrderStatusFromInfo, getSeaportAddress, getSeaportOrderFromMessageData, getTotalConsiderationAmount, getWrappedNativeCurrency, isBazaarSupportedOnChain, isCollectionOfferValid, isErc20OfferValid, isListingValid, parseCollectionOfferFromMessage, parseErc20OfferFromMessage, parseListingFromMessage, sortErc20OffersByPricePerToken, sortListingsByPrice, sortOffersByPrice };
970
+ 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 };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { G as GetListingsOptions, L as Listing, a as GetCollectionOffersOptions, C as CollectionOffer, b as GetErc20OffersOptions, E as Erc20Offer, W as WriteTransactionConfig, S as SeaportOrderComponents, c as SeaportSubmission, d as SeaportOrderParameters, e as SeaportOrderStatusInfo, f as SeaportOrderStatus } from './types-CY-6M9Ta.js';
2
- export { h as ConsiderationItem, j as CreateCollectionOfferParams, i as CreateListingParams, I as ItemType, g as OfferItem, O as OrderType } from './types-CY-6M9Ta.js';
1
+ 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, S as SeaportOrderComponents, e as SeaportSubmission, f as SeaportOrderParameters, g as SeaportOrderStatusInfo, h as SeaportOrderStatus } from './types-KQgBECzI.js';
2
+ export { j as ConsiderationItem, l as CreateCollectionOfferParams, k as CreateListingParams, I as ItemType, i as OfferItem, O as OrderType } from './types-KQgBECzI.js';
3
3
  import { Seaport } from '@opensea/seaport-js';
4
4
  import { PublicClient } from 'viem';
5
5
  import { NetMessage } from '@net-protocol/core';
@@ -56,6 +56,18 @@ declare class BazaarClient {
56
56
  * Results are sorted by price per token (highest first)
57
57
  */
58
58
  getErc20Offers(options: GetErc20OffersOptions): Promise<Erc20Offer[]>;
59
+ /**
60
+ * Get valid ERC20 listings for a token
61
+ *
62
+ * Returns listings that are:
63
+ * - OPEN status (not filled, cancelled, or expired)
64
+ * - Not expired
65
+ * - Seller has sufficient ERC20 token balance
66
+ *
67
+ * Results are sorted by price per token (lowest first). No deduplication —
68
+ * all valid listings are returned (grouped by maker in the UI).
69
+ */
70
+ getErc20Listings(options: GetErc20ListingsOptions): Promise<Erc20Listing[]>;
59
71
  /**
60
72
  * Get the chain ID this client is configured for
61
73
  */
@@ -73,6 +85,10 @@ declare class BazaarClient {
73
85
  * Only available on Base (8453) and HyperEVM (999)
74
86
  */
75
87
  getErc20OffersAddress(): `0x${string}` | undefined;
88
+ /**
89
+ * Get the ERC20 bazaar (listings) contract address for this chain
90
+ */
91
+ getErc20BazaarAddress(): `0x${string}`;
76
92
  /**
77
93
  * Get the Seaport contract address for this chain
78
94
  */
@@ -91,6 +107,13 @@ declare class BazaarClient {
91
107
  * Use the orderComponents from the CollectionOffer object returned by getCollectionOffers().
92
108
  */
93
109
  prepareCancelCollectionOffer(offer: CollectionOffer): WriteTransactionConfig;
110
+ /**
111
+ * Prepare a transaction to cancel an ERC20 listing
112
+ *
113
+ * The listing must have been created by the caller.
114
+ * Use the orderComponents from the Erc20Listing object returned by getErc20Listings().
115
+ */
116
+ prepareCancelErc20Listing(listing: Erc20Listing): WriteTransactionConfig;
94
117
  /**
95
118
  * Prepare a transaction to cancel a Seaport order
96
119
  *
@@ -116,6 +139,8 @@ interface BazaarChainConfig {
116
139
  collectionOffersAddress: `0x${string}`;
117
140
  /** ERC20 offers contract (only on Base and HyperEVM) */
118
141
  erc20OffersAddress?: `0x${string}`;
142
+ /** ERC20 listings contract */
143
+ erc20BazaarAddress?: `0x${string}`;
119
144
  /** Seaport contract address */
120
145
  seaportAddress: `0x${string}`;
121
146
  /** Fee collector address */
@@ -134,6 +159,7 @@ declare const ERC721_OWNER_OF_HELPER_ADDRESS: "0x000000aa4eFa2e5A4a6002C7F08B6e8
134
159
  declare const ERC20_BULK_BALANCE_CHECKER_ADDRESS: "0x000000b50a9f2923f2db931391824f6d1278f712";
135
160
  declare const NET_SEAPORT_ZONE_ADDRESS: "0x000000007F8c58fbf215bF91Bda7421A806cf3ae";
136
161
  declare const NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS: "0x000000B799ec6D7aCC1B578f62bFc324c25DFC5A";
162
+ declare const NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS: "0x000000bC63761cbb05305632212e2f3AE2BE7a9B";
137
163
  /**
138
164
  * Get bazaar configuration for a chain
139
165
  */
@@ -183,6 +209,10 @@ declare function getHighEthAddress(chainId: number): `0x${string}` | undefined;
183
209
  * Only deployed on Base (8453) and HyperEVM (999)
184
210
  */
185
211
  declare function getErc20OffersAddress(chainId: number): `0x${string}` | undefined;
212
+ /**
213
+ * Get ERC20 bazaar (listings) contract address for a chain
214
+ */
215
+ declare function getErc20BazaarAddress(chainId: number): `0x${string}`;
186
216
 
187
217
  declare const BAZAAR_V2_ABI: readonly [{
188
218
  readonly type: "function";
@@ -880,6 +910,13 @@ declare function isCollectionOfferValid(orderStatus: SeaportOrderStatus, expirat
880
910
  * - Buyer has sufficient WETH balance
881
911
  */
882
912
  declare function isErc20OfferValid(orderStatus: SeaportOrderStatus, expirationDate: number, priceWei: bigint, buyerWethBalance: bigint): boolean;
913
+ /**
914
+ * Validate that an ERC20 listing is still valid:
915
+ * - Order is OPEN
916
+ * - Not expired
917
+ * - Seller has sufficient ERC20 token balance
918
+ */
919
+ declare function isErc20ListingValid(orderStatus: SeaportOrderStatus, expirationDate: number, tokenAmount: bigint, sellerTokenBalance: bigint): boolean;
883
920
 
884
921
  /**
885
922
  * Utilities for parsing Net messages into listings and offers
@@ -917,5 +954,17 @@ declare function parseErc20OfferFromMessage(message: NetMessage, chainId: number
917
954
  * Sort ERC20 offers by price per token (highest first)
918
955
  */
919
956
  declare function sortErc20OffersByPricePerToken(offers: Erc20Offer[]): Erc20Offer[];
957
+ /**
958
+ * Parse a Net message into an ERC20 listing
959
+ *
960
+ * ERC20 listings have the ERC20 token in the offer array (seller is offering tokens)
961
+ * and native currency payments in the consideration array.
962
+ * They do NOT use the collection offer zone (that would be an offer, not a listing).
963
+ */
964
+ declare function parseErc20ListingFromMessage(message: NetMessage, chainId: number): Erc20Listing | null;
965
+ /**
966
+ * Sort ERC20 listings by price per token (lowest first)
967
+ */
968
+ declare function sortErc20ListingsByPricePerToken(listings: Erc20Listing[]): Erc20Listing[];
920
969
 
921
- 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, Erc20Offer, GetCollectionOffersOptions, GetErc20OffersOptions, GetListingsOptions, Listing, NET_SEAPORT_COLLECTION_OFFER_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, getErc20OffersAddress, getFeeCollectorAddress, getHighEthAddress, getNftFeeBps, getOrderStatusFromInfo, getSeaportAddress, getSeaportOrderFromMessageData, getTotalConsiderationAmount, getWrappedNativeCurrency, isBazaarSupportedOnChain, isCollectionOfferValid, isErc20OfferValid, isListingValid, parseCollectionOfferFromMessage, parseErc20OfferFromMessage, parseListingFromMessage, sortErc20OffersByPricePerToken, sortListingsByPrice, sortOffersByPrice };
970
+ 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 };
package/dist/index.js CHANGED
@@ -356,18 +356,21 @@ var DEFAULT_SEAPORT_ADDRESS = "0x0000000000000068F116a894984e2DB1123eB395";
356
356
  var DEFAULT_BAZAAR_ADDRESS = "0x00000000E3dA5fC031282A39759bDDA78ae7fAE5";
357
357
  var DEFAULT_COLLECTION_OFFERS_ADDRESS = "0x0000000D43423E0A12CecB307a74591999b32B32";
358
358
  var DEFAULT_FEE_COLLECTOR_ADDRESS = "0x32D16C15410248bef498D7aF50D10Db1a546b9E5";
359
+ var DEFAULT_ERC20_BAZAAR_ADDRESS = "0x00000000a2d173a4610c85c7471a25b6bc216a70";
359
360
  var DEFAULT_NFT_FEE_BPS = 500;
360
361
  var BULK_SEAPORT_ORDER_STATUS_FETCHER_ADDRESS = "0x0000009112ABCE652674b4fE3eD9C765B22d11A7";
361
362
  var ERC721_OWNER_OF_HELPER_ADDRESS = "0x000000aa4eFa2e5A4a6002C7F08B6e8Ec8cf1dDa";
362
363
  var ERC20_BULK_BALANCE_CHECKER_ADDRESS = "0x000000b50a9f2923f2db931391824f6d1278f712";
363
364
  var NET_SEAPORT_ZONE_ADDRESS = "0x000000007F8c58fbf215bF91Bda7421A806cf3ae";
364
365
  var NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS = "0x000000B799ec6D7aCC1B578f62bFc324c25DFC5A";
366
+ var NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS = "0x000000bC63761cbb05305632212e2f3AE2BE7a9B";
365
367
  var BAZAAR_CHAIN_CONFIGS = {
366
368
  // Base Mainnet
367
369
  8453: {
368
370
  bazaarAddress: "0x000000058f3ade587388daf827174d0e6fc97595",
369
371
  collectionOffersAddress: "0x0000000f9c45efcff0f78d8b54aa6a40092d66dc",
370
372
  erc20OffersAddress: "0x0000000e23a89aa06f317306aa1ae231d3503082",
373
+ erc20BazaarAddress: "0x00000006557e3629e2fc50bbad0c002b27cac492",
371
374
  seaportAddress: DEFAULT_SEAPORT_ADDRESS,
372
375
  feeCollectorAddress: "0x66547ff4f7206e291F7BC157b54C026Fc6660961",
373
376
  nftFeeBps: 0,
@@ -457,6 +460,7 @@ var BAZAAR_CHAIN_CONFIGS = {
457
460
  bazaarAddress: "0x000000058f3ade587388daf827174d0e6fc97595",
458
461
  collectionOffersAddress: "0x0000000f9c45efcff0f78d8b54aa6a40092d66dc",
459
462
  erc20OffersAddress: "0x0000000e23a89aa06f317306aa1ae231d3503082",
463
+ erc20BazaarAddress: "0x00000006557e3629e2fc50bbad0c002b27cac492",
460
464
  seaportAddress: DEFAULT_SEAPORT_ADDRESS,
461
465
  feeCollectorAddress: "0x66547ff4f7206e291F7BC157b54C026Fc6660961",
462
466
  nftFeeBps: 0,
@@ -533,6 +537,9 @@ function getHighEthAddress(chainId) {
533
537
  function getErc20OffersAddress(chainId) {
534
538
  return BAZAAR_CHAIN_CONFIGS[chainId]?.erc20OffersAddress;
535
539
  }
540
+ function getErc20BazaarAddress(chainId) {
541
+ return BAZAAR_CHAIN_CONFIGS[chainId]?.erc20BazaarAddress ?? DEFAULT_ERC20_BAZAAR_ADDRESS;
542
+ }
536
543
  function decodeSeaportSubmission(messageData) {
537
544
  const [decoded] = viem.decodeAbiParameters(BAZAAR_SUBMISSION_ABI, messageData);
538
545
  return {
@@ -754,6 +761,19 @@ function isErc20OfferValid(orderStatus, expirationDate, priceWei, buyerWethBalan
754
761
  }
755
762
  return true;
756
763
  }
764
+ function isErc20ListingValid(orderStatus, expirationDate, tokenAmount, sellerTokenBalance) {
765
+ if (orderStatus !== 2 /* OPEN */) {
766
+ return false;
767
+ }
768
+ const now = Math.floor(Date.now() / 1e3);
769
+ if (expirationDate <= now) {
770
+ return false;
771
+ }
772
+ if (sellerTokenBalance < tokenAmount) {
773
+ return false;
774
+ }
775
+ return true;
776
+ }
757
777
 
758
778
  // src/utils/parsing.ts
759
779
  function parseListingFromMessage(message, chainId) {
@@ -769,6 +789,7 @@ function parseListingFromMessage(message, chainId) {
769
789
  }
770
790
  const priceWei = getTotalConsiderationAmount(parameters);
771
791
  const tokenId = offerItem.identifierOrCriteria.toString();
792
+ const targetFulfiller = parameters.zone.toLowerCase() === NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS.toLowerCase() && parameters.zoneHash !== "0x0000000000000000000000000000000000000000000000000000000000000000" ? parameters.zoneHash : void 0;
772
793
  return {
773
794
  maker: parameters.offerer,
774
795
  nftAddress: offerItem.token,
@@ -785,7 +806,8 @@ function parseListingFromMessage(message, chainId) {
785
806
  orderComponents: {
786
807
  ...parameters,
787
808
  counter: submission.counter
788
- }
809
+ },
810
+ targetFulfiller
789
811
  };
790
812
  } catch {
791
813
  return null;
@@ -923,6 +945,58 @@ function sortErc20OffersByPricePerToken(offers) {
923
945
  return 0;
924
946
  });
925
947
  }
948
+ function parseErc20ListingFromMessage(message, chainId) {
949
+ try {
950
+ const submission = decodeSeaportSubmission(message.data);
951
+ const { parameters } = submission;
952
+ if (parameters.zone.toLowerCase() === NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS.toLowerCase()) {
953
+ return null;
954
+ }
955
+ const offerItem = parameters.offer[0];
956
+ if (!offerItem || offerItem.itemType !== 1 /* ERC20 */) {
957
+ return null;
958
+ }
959
+ const tokenAmount = offerItem.startAmount;
960
+ if (tokenAmount === BigInt(0)) {
961
+ return null;
962
+ }
963
+ const priceWei = getTotalConsiderationAmount(parameters);
964
+ if (priceWei === BigInt(0)) {
965
+ return null;
966
+ }
967
+ const pricePerTokenWei = priceWei / tokenAmount;
968
+ return {
969
+ maker: parameters.offerer,
970
+ tokenAddress: offerItem.token,
971
+ tokenAmount,
972
+ priceWei,
973
+ pricePerTokenWei,
974
+ price: formatPrice(priceWei),
975
+ pricePerToken: formatPrice(pricePerTokenWei),
976
+ currency: getCurrencySymbol(chainId),
977
+ expirationDate: Number(parameters.endTime),
978
+ orderHash: "0x",
979
+ // Will be computed later
980
+ orderStatus: 2 /* OPEN */,
981
+ // Will be validated later
982
+ messageData: message.data,
983
+ orderComponents: {
984
+ ...parameters,
985
+ counter: submission.counter
986
+ }
987
+ };
988
+ } catch {
989
+ return null;
990
+ }
991
+ }
992
+ function sortErc20ListingsByPricePerToken(listings) {
993
+ return [...listings].sort((a, b) => {
994
+ const diff = a.pricePerTokenWei - b.pricePerTokenWei;
995
+ if (diff < BigInt(0)) return -1;
996
+ if (diff > BigInt(0)) return 1;
997
+ return 0;
998
+ });
999
+ }
926
1000
 
927
1001
  // src/client/BazaarClient.ts
928
1002
  var CHAIN_RPC_URLS = {
@@ -979,25 +1053,30 @@ var BazaarClient = class {
979
1053
  * Results are deduplicated (one per token) and sorted by price (lowest first)
980
1054
  */
981
1055
  async getListings(options) {
982
- const { nftAddress, excludeMaker, maxMessages = 200 } = options;
1056
+ const { nftAddress, excludeMaker, maker, maxMessages = 200 } = options;
983
1057
  const bazaarAddress = getBazaarAddress(this.chainId);
984
- const count = await this.netClient.getMessageCount({
985
- filter: {
986
- appAddress: bazaarAddress,
987
- topic: nftAddress.toLowerCase()
1058
+ const filter = {
1059
+ appAddress: bazaarAddress,
1060
+ topic: nftAddress.toLowerCase(),
1061
+ maker
1062
+ };
1063
+ let startIndex;
1064
+ let endIndex;
1065
+ if (options.startIndex != null && options.endIndex != null) {
1066
+ startIndex = options.startIndex;
1067
+ endIndex = options.endIndex;
1068
+ } else {
1069
+ const count = await this.netClient.getMessageCount({ filter });
1070
+ if (count === 0) {
1071
+ return [];
988
1072
  }
989
- });
990
- if (count === 0) {
991
- return [];
1073
+ startIndex = Math.max(0, count - maxMessages);
1074
+ endIndex = count;
992
1075
  }
993
- const startIndex = Math.max(0, count - maxMessages);
994
1076
  const messages = await this.netClient.getMessages({
995
- filter: {
996
- appAddress: bazaarAddress,
997
- topic: nftAddress.toLowerCase()
998
- },
1077
+ filter,
999
1078
  startIndex,
1000
- endIndex: count
1079
+ endIndex
1001
1080
  });
1002
1081
  let listings = [];
1003
1082
  for (const message of messages) {
@@ -1218,6 +1297,92 @@ var BazaarClient = class {
1218
1297
  });
1219
1298
  return sortErc20OffersByPricePerToken(offers);
1220
1299
  }
1300
+ /**
1301
+ * Get valid ERC20 listings for a token
1302
+ *
1303
+ * Returns listings that are:
1304
+ * - OPEN status (not filled, cancelled, or expired)
1305
+ * - Not expired
1306
+ * - Seller has sufficient ERC20 token balance
1307
+ *
1308
+ * Results are sorted by price per token (lowest first). No deduplication —
1309
+ * all valid listings are returned (grouped by maker in the UI).
1310
+ */
1311
+ async getErc20Listings(options) {
1312
+ const { tokenAddress, excludeMaker, maker, maxMessages = 200 } = options;
1313
+ const erc20BazaarAddress = getErc20BazaarAddress(this.chainId);
1314
+ const filter = {
1315
+ appAddress: erc20BazaarAddress,
1316
+ topic: tokenAddress.toLowerCase(),
1317
+ maker
1318
+ };
1319
+ let startIndex;
1320
+ let endIndex;
1321
+ if (options.startIndex != null && options.endIndex != null) {
1322
+ startIndex = options.startIndex;
1323
+ endIndex = options.endIndex;
1324
+ } else {
1325
+ const count = await this.netClient.getMessageCount({ filter });
1326
+ if (count === 0) {
1327
+ return [];
1328
+ }
1329
+ startIndex = Math.max(0, count - maxMessages);
1330
+ endIndex = count;
1331
+ }
1332
+ const messages = await this.netClient.getMessages({
1333
+ filter,
1334
+ startIndex,
1335
+ endIndex
1336
+ });
1337
+ let listings = [];
1338
+ for (const message of messages) {
1339
+ const listing = parseErc20ListingFromMessage(message, this.chainId);
1340
+ if (!listing) continue;
1341
+ if (listing.tokenAddress.toLowerCase() !== tokenAddress.toLowerCase()) {
1342
+ continue;
1343
+ }
1344
+ if (excludeMaker && listing.maker.toLowerCase() === excludeMaker.toLowerCase()) {
1345
+ continue;
1346
+ }
1347
+ listings.push(listing);
1348
+ }
1349
+ if (listings.length === 0) {
1350
+ return [];
1351
+ }
1352
+ const seaport = createSeaportInstance(this.chainId, this.rpcUrl);
1353
+ for (const listing of listings) {
1354
+ const order = getSeaportOrderFromMessageData(listing.messageData);
1355
+ listing.orderHash = computeOrderHash(seaport, order.parameters, order.counter);
1356
+ }
1357
+ const orderHashes = listings.map((l) => l.orderHash);
1358
+ const statusInfos = await bulkFetchOrderStatuses(this.client, this.chainId, orderHashes);
1359
+ listings.forEach((listing, index) => {
1360
+ const statusInfo = statusInfos[index];
1361
+ listing.orderStatus = getOrderStatusFromInfo(listing.orderComponents, statusInfo);
1362
+ });
1363
+ listings = listings.filter(
1364
+ (l) => l.orderStatus === 2 /* OPEN */ && l.expirationDate > Math.floor(Date.now() / 1e3)
1365
+ );
1366
+ if (listings.length === 0) {
1367
+ return [];
1368
+ }
1369
+ const uniqueMakers = [...new Set(listings.map((l) => l.maker))];
1370
+ const balances = await bulkFetchErc20Balances(this.client, tokenAddress, uniqueMakers);
1371
+ const balanceMap = /* @__PURE__ */ new Map();
1372
+ uniqueMakers.forEach((maker2, index) => {
1373
+ balanceMap.set(maker2.toLowerCase(), balances[index]);
1374
+ });
1375
+ listings = listings.filter((listing) => {
1376
+ const balance = balanceMap.get(listing.maker.toLowerCase()) || BigInt(0);
1377
+ return isErc20ListingValid(
1378
+ listing.orderStatus,
1379
+ listing.expirationDate,
1380
+ listing.tokenAmount,
1381
+ balance
1382
+ );
1383
+ });
1384
+ return sortErc20ListingsByPricePerToken(listings);
1385
+ }
1221
1386
  /**
1222
1387
  * Get the chain ID this client is configured for
1223
1388
  */
@@ -1243,6 +1408,12 @@ var BazaarClient = class {
1243
1408
  getErc20OffersAddress() {
1244
1409
  return getErc20OffersAddress(this.chainId);
1245
1410
  }
1411
+ /**
1412
+ * Get the ERC20 bazaar (listings) contract address for this chain
1413
+ */
1414
+ getErc20BazaarAddress() {
1415
+ return getErc20BazaarAddress(this.chainId);
1416
+ }
1246
1417
  /**
1247
1418
  * Get the Seaport contract address for this chain
1248
1419
  */
@@ -1273,6 +1444,18 @@ var BazaarClient = class {
1273
1444
  }
1274
1445
  return this.prepareCancelOrder(offer.orderComponents);
1275
1446
  }
1447
+ /**
1448
+ * Prepare a transaction to cancel an ERC20 listing
1449
+ *
1450
+ * The listing must have been created by the caller.
1451
+ * Use the orderComponents from the Erc20Listing object returned by getErc20Listings().
1452
+ */
1453
+ prepareCancelErc20Listing(listing) {
1454
+ if (!listing.orderComponents) {
1455
+ throw new Error("Listing does not have order components");
1456
+ }
1457
+ return this.prepareCancelOrder(listing.orderComponents);
1458
+ }
1276
1459
  /**
1277
1460
  * Prepare a transaction to cancel a Seaport order
1278
1461
  *
@@ -1327,6 +1510,7 @@ exports.ERC721_OWNER_OF_HELPER_ABI = ERC721_OWNER_OF_HELPER_ABI;
1327
1510
  exports.ERC721_OWNER_OF_HELPER_ADDRESS = ERC721_OWNER_OF_HELPER_ADDRESS;
1328
1511
  exports.ItemType = ItemType;
1329
1512
  exports.NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS = NET_SEAPORT_COLLECTION_OFFER_ZONE_ADDRESS;
1513
+ exports.NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS = NET_SEAPORT_PRIVATE_ORDER_ZONE_ADDRESS;
1330
1514
  exports.NET_SEAPORT_ZONE_ADDRESS = NET_SEAPORT_ZONE_ADDRESS;
1331
1515
  exports.OrderType = OrderType;
1332
1516
  exports.SEAPORT_CANCEL_ABI = SEAPORT_CANCEL_ABI;
@@ -1348,6 +1532,7 @@ exports.getBestCollectionOffer = getBestCollectionOffer;
1348
1532
  exports.getBestListingPerToken = getBestListingPerToken;
1349
1533
  exports.getCollectionOffersAddress = getCollectionOffersAddress;
1350
1534
  exports.getCurrencySymbol = getCurrencySymbol;
1535
+ exports.getErc20BazaarAddress = getErc20BazaarAddress;
1351
1536
  exports.getErc20OffersAddress = getErc20OffersAddress;
1352
1537
  exports.getFeeCollectorAddress = getFeeCollectorAddress;
1353
1538
  exports.getHighEthAddress = getHighEthAddress;
@@ -1359,11 +1544,14 @@ exports.getTotalConsiderationAmount = getTotalConsiderationAmount;
1359
1544
  exports.getWrappedNativeCurrency = getWrappedNativeCurrency;
1360
1545
  exports.isBazaarSupportedOnChain = isBazaarSupportedOnChain;
1361
1546
  exports.isCollectionOfferValid = isCollectionOfferValid;
1547
+ exports.isErc20ListingValid = isErc20ListingValid;
1362
1548
  exports.isErc20OfferValid = isErc20OfferValid;
1363
1549
  exports.isListingValid = isListingValid;
1364
1550
  exports.parseCollectionOfferFromMessage = parseCollectionOfferFromMessage;
1551
+ exports.parseErc20ListingFromMessage = parseErc20ListingFromMessage;
1365
1552
  exports.parseErc20OfferFromMessage = parseErc20OfferFromMessage;
1366
1553
  exports.parseListingFromMessage = parseListingFromMessage;
1554
+ exports.sortErc20ListingsByPricePerToken = sortErc20ListingsByPricePerToken;
1367
1555
  exports.sortErc20OffersByPricePerToken = sortErc20OffersByPricePerToken;
1368
1556
  exports.sortListingsByPrice = sortListingsByPrice;
1369
1557
  exports.sortOffersByPrice = sortOffersByPrice;