@0xsequence/marketplace-sdk 2.0.0 → 2.0.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.
Files changed (136) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/BellIcon.js +1 -1
  3. package/dist/Card.js +1 -1
  4. package/dist/ShopCard.d.ts +4 -4
  5. package/dist/builder-api.js +1 -1
  6. package/dist/collectible.js +2 -2
  7. package/dist/collectible.js.map +1 -1
  8. package/dist/collection.js +1 -1
  9. package/dist/create-config.d.ts +589 -193
  10. package/dist/create-config.js +1 -1
  11. package/dist/currency.js +3 -3
  12. package/dist/currency.js.map +1 -1
  13. package/dist/dist.js +167 -148
  14. package/dist/dist.js.map +1 -1
  15. package/dist/expirationDateSelect.js +1 -1
  16. package/dist/filter-state.d.ts +1 -1
  17. package/dist/filters.d.ts +1 -1
  18. package/dist/index.d.ts +3 -3
  19. package/dist/index.js +3 -3
  20. package/dist/index10.d.ts +1 -1
  21. package/dist/index11.d.ts +17 -17
  22. package/dist/index12.d.ts +21 -21
  23. package/dist/index14.d.ts +3 -3
  24. package/dist/index15.d.ts +3 -3
  25. package/dist/index16.d.ts +2 -2
  26. package/dist/index17.d.ts +75 -75
  27. package/dist/index18.d.ts +40 -40
  28. package/dist/index19.d.ts +5 -5
  29. package/dist/index2.d.ts +4 -1
  30. package/dist/index21.d.ts +15 -15
  31. package/dist/index22.d.ts +8 -65
  32. package/dist/index23.d.ts +21 -13
  33. package/dist/index26.d.ts +4 -4
  34. package/dist/index27.d.ts +4 -4
  35. package/dist/index28.d.ts +10 -10
  36. package/dist/index3.d.ts +2 -2194
  37. package/dist/index31.d.ts +5 -5
  38. package/dist/index33.d.ts +3 -3
  39. package/dist/index34.d.ts +1 -1
  40. package/dist/index35.d.ts +1 -1
  41. package/dist/index36.d.ts +5 -5
  42. package/dist/index37.d.ts +8 -6
  43. package/dist/index38.d.ts +5 -5
  44. package/dist/index39.d.ts +1 -1
  45. package/dist/index4.d.ts +1356 -1356
  46. package/dist/index40.d.ts +2 -2
  47. package/dist/index8.d.ts +11 -3
  48. package/dist/index9.d.ts +2811 -3
  49. package/dist/inventory.d.ts +4 -4
  50. package/dist/inventory.js +3 -3
  51. package/dist/inventory.js.map +1 -1
  52. package/dist/marketplace2.js +3 -3
  53. package/dist/marketplace2.js.map +1 -1
  54. package/dist/metadata.d.ts +41 -41
  55. package/dist/primary-sale-checkout-options.d.ts +4 -4
  56. package/dist/quantityInput.js +1 -1
  57. package/dist/ranges.d.ts +12 -12
  58. package/dist/react/_internal/index.d.ts +1 -1
  59. package/dist/react/_internal/index.js +1 -1
  60. package/dist/react/index.d.ts +1 -1
  61. package/dist/react/queries/collectible/index.d.ts +1 -1
  62. package/dist/react/queries/index.d.ts +1 -1
  63. package/dist/react/ssr/index.d.ts +3 -3
  64. package/dist/react/ssr/index.js +3 -3
  65. package/dist/react/ui/components/marketplace-collectible-card/index.d.ts +1 -1
  66. package/dist/react/ui/modals/CreateListingModal/internal/hooks/index.d.ts +1 -1
  67. package/dist/react/ui/modals/MakeOfferModal/internal/hooks/index.d.ts +1 -1
  68. package/dist/react/ui/modals/_internal/components/alertMessage/index.d.ts +2 -2
  69. package/dist/react/ui/modals/_internal/components/baseModal/index.d.ts +6 -6
  70. package/dist/react/ui/modals/_internal/components/calendar/index.d.ts +2 -2
  71. package/dist/react/ui/modals/_internal/components/currencyImage/index.d.ts +2 -2
  72. package/dist/react/ui/modals/_internal/components/currencyOptionsSelect/index.d.ts +3 -3
  73. package/dist/react/ui/modals/_internal/components/floorPriceText/index.d.ts +2 -2
  74. package/dist/react/ui/modals/_internal/components/priceInput/index.d.ts +3 -5
  75. package/dist/react/ui/modals/_internal/components/quantityInput/index.d.ts +2 -2
  76. package/dist/react/ui/modals/_internal/components/selectWaasFeeOptions/index.d.ts +2 -2
  77. package/dist/react/ui/modals/_internal/components/switchChainErrorModal/index.d.ts +2 -2
  78. package/dist/react/ui/modals/_internal/components/timeAgo/index.d.ts +2 -2
  79. package/dist/react/ui/modals/_internal/components/tokenPreview/index.d.ts +3 -3
  80. package/dist/react/ui/modals/_internal/components/transaction-footer/index.d.ts +3 -3
  81. package/dist/react/ui/modals/_internal/components/transactionDetails/index.d.ts +3 -3
  82. package/dist/react/ui/modals/_internal/components/transactionPreview/index.d.ts +3 -3
  83. package/dist/react/ui/modals/_internal/components/transactionStatusModal/index.d.ts +3 -3
  84. package/dist/react.js +2279 -1919
  85. package/dist/react.js.map +1 -1
  86. package/dist/styles/index.css +15 -0
  87. package/dist/token-balances.d.ts +28 -28
  88. package/dist/transaction-footer.js +1 -1
  89. package/dist/types/index.d.ts +1 -1
  90. package/dist/types/index.js +1 -1
  91. package/dist/types.d.ts +1 -1
  92. package/dist/url-state.js +1 -1
  93. package/dist/utils/index.d.ts +2 -2
  94. package/dist/utils/index.js +2 -2
  95. package/dist/utils.js +31 -4
  96. package/dist/utils.js.map +1 -1
  97. package/package.json +7 -5
  98. package/src/react/hooks/config/useMarketplaceConfig.test.tsx +1 -0
  99. package/src/react/hooks/currency/list.test.tsx +23 -2
  100. package/src/react/hooks/transactions/useCancelTransactionSteps.tsx +4 -1
  101. package/src/react/hooks/transactions/useMarketTransactionSteps.tsx +55 -15
  102. package/src/react/hooks/utils/useEnsureCorrectChain.ts +10 -5
  103. package/src/react/queries/collectible/market-list.ts +5 -3
  104. package/src/react/queries/currency/list.ts +8 -5
  105. package/src/react/queries/inventory/inventory.ts +5 -3
  106. package/src/react/queries/marketplace/filters.ts +5 -3
  107. package/src/react/ui/modals/BuyModal/components/BuyModalContent.tsx +74 -37
  108. package/src/react/ui/modals/BuyModal/components/CryptoPaymentModal.tsx +74 -11
  109. package/src/react/ui/modals/BuyModal/components/Modal.tsx +62 -1
  110. package/src/react/ui/modals/BuyModal/hooks/useExecuteBundledTransactions.ts +13 -26
  111. package/src/react/ui/modals/BuyModal/hooks/useMarketPlatformFee.ts +5 -5
  112. package/src/react/ui/modals/BuyModal/internal/__tests__/buildTrailsMarketBuyActions.test.ts +213 -0
  113. package/src/react/ui/modals/BuyModal/internal/buildTrailsMarketBuyActions.ts +259 -0
  114. package/src/react/ui/modals/BuyModal/internal/buyModalContext.ts +79 -10
  115. package/src/react/ui/modals/BuyModal/internal/cryptoPaymentModalContext.tsx +44 -17
  116. package/src/react/ui/modals/CreateListingModal/internal/store.ts +5 -2
  117. package/src/react/ui/modals/MakeOfferModal/internal/context.ts +21 -1
  118. package/src/react/ui/modals/MakeOfferModal/internal/helpers/validation.ts +16 -1
  119. package/src/react/ui/modals/MakeOfferModal/internal/store.ts +5 -2
  120. package/src/react/ui/modals/SellModal/internal/store.ts +5 -2
  121. package/src/react/ui/modals/_internal/components/baseModal/errors/ModalInitializationError.tsx +8 -6
  122. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +2 -1
  123. package/src/react/ui/modals/_internal/components/priceInput/index.tsx +13 -19
  124. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +5 -2
  125. package/src/react/ui/modals/_internal/helpers/currency.test.ts +27 -0
  126. package/src/react/ui/modals/_internal/helpers/currency.ts +4 -2
  127. package/src/styles/styles.ts +18 -0
  128. package/src/utils/__tests__/getMarketplaceDetails.test.ts +10 -0
  129. package/src/utils/__tests__/getWebRPCErrorMessage.test.ts +28 -0
  130. package/src/utils/__tests__/marketplaceNormalization.test.ts +38 -0
  131. package/src/utils/collection.ts +19 -0
  132. package/src/utils/getConduitAddressForOrderbook.ts +2 -10
  133. package/src/utils/getMarketplaceDetails.ts +11 -4
  134. package/src/utils/getWebRPCErrorMessage.ts +21 -0
  135. package/src/utils/index.ts +1 -0
  136. package/src/utils/normalizeMarketplace.ts +31 -0
@@ -1855,6 +1855,17 @@
1855
1855
  --tw-tracking: var(--tracking-normal);
1856
1856
  letter-spacing: var(--tracking-normal);
1857
1857
  }
1858
+ .text-small {
1859
+ font-family: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
1860
+ font-size: var(--text-xs);
1861
+ line-height: var(--tw-leading, var(--text-xs--line-height));
1862
+ --tw-leading: calc(var(--spacing) * 4);
1863
+ line-height: calc(var(--spacing) * 4);
1864
+ --tw-font-weight: var(--font-weight-medium);
1865
+ font-weight: var(--font-weight-medium);
1866
+ --tw-tracking: var(--tracking-wide);
1867
+ letter-spacing: var(--tracking-wide);
1868
+ }
1858
1869
  .font-body {
1859
1870
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
1860
1871
  }
@@ -2316,6 +2327,10 @@
2316
2327
  --tw-duration: 100ms;
2317
2328
  transition-duration: 100ms;
2318
2329
  }
2330
+ .duration-150 {
2331
+ --tw-duration: 150ms;
2332
+ transition-duration: 150ms;
2333
+ }
2319
2334
  .duration-200 {
2320
2335
  --tw-duration: 200ms;
2321
2336
  transition-duration: 200ms;
@@ -1,6 +1,6 @@
1
- import { A as ListCollectibleOffersResponse, B as ListPrimarySaleItemsRequest, C as GetHighestPriceOfferForCollectibleRequest, D as GetPrimarySaleItemResponse, E as GetPrimarySaleItemRequest, Gt as CollectiblesFilter, I as ListOffersForCollectibleRequest, M as ListCollectiblesResponse, Mt as TokenBalance$1, P as ListListingsForCollectibleRequest, V as ListPrimarySaleItemsResponse, Z as Order, _ as GetCountOfFilteredCollectiblesRequest, b as GetCountOfOffersForCollectibleRequest, bt as GetBalanceOfCollectibleRequest, cn as OrderSide, fn as Page, h as GetCountOfAllCollectiblesRequest, hn as PrimarySaleItemsFilter, ht as GetSingleTokenMetadataArgs, j as ListCollectiblesRequest, k as ListCollectibleListingsResponse, kt as GetUserCollectionBalancesRequest, sn as OrderFilter, vn as SortBy, w as GetLowestPriceListingForCollectibleRequest, y as GetCountOfListingsForCollectibleRequest, yt as TokenMetadata$1, zt as TokenId } from "./index2.js";
1
+ import { A as ListCollectibleListingsResponse, At as GetUserCollectionBalancesRequest, Bt as TokenId, D as GetPrimarySaleItemRequest, F as ListListingsForCollectibleRequest, H as ListPrimarySaleItemsResponse, Kt as CollectiblesFilter, L as ListOffersForCollectibleRequest, M as ListCollectiblesRequest, N as ListCollectiblesResponse, Nt as TokenBalance$1, O as GetPrimarySaleItemResponse, Q as Order, T as GetLowestPriceListingForCollectibleRequest, V as ListPrimarySaleItemsRequest, b as GetCountOfListingsForCollectibleRequest, bt as TokenMetadata$1, cn as OrderFilter, g as GetCountOfAllCollectiblesRequest, gn as PrimarySaleItemsFilter, gt as GetSingleTokenMetadataArgs, j as ListCollectibleOffersResponse, ln as OrderSide, pn as Page, v as GetCountOfFilteredCollectiblesRequest, w as GetHighestPriceOfferForCollectibleRequest, x as GetCountOfOffersForCollectibleRequest, xt as GetBalanceOfCollectibleRequest, yn as SortBy } from "./index2.js";
2
2
  import { U as SdkInfiniteQueryParams, W as SdkQueryParams, X as WithRequired, it as WithOptionalParams, l as CardType, ot as buildQueryOptions } from "./create-config.js";
3
- import * as _tanstack_react_query128 from "@tanstack/react-query";
3
+ import * as _tanstack_react_query80 from "@tanstack/react-query";
4
4
 
5
5
  //#region src/react/queries/collectible/balance.d.ts
6
6
  type FetchBalanceOfCollectibleParams = GetBalanceOfCollectibleRequest;
@@ -32,8 +32,8 @@ declare function getBalanceOfCollectibleQueryKey(params: BalanceOfCollectibleQue
32
32
  * @param params - The query parameters
33
33
  * @returns Query options configuration
34
34
  */
35
- declare function balanceOfCollectibleOptions(params: WithOptionalParams<WithRequired<BalanceOfCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'userAddress' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<TokenBalance$1, Error, TokenBalance$1, readonly unknown[]>, "queryFn"> & {
36
- queryFn?: _tanstack_react_query128.QueryFunction<TokenBalance$1, readonly unknown[], never> | undefined;
35
+ declare function balanceOfCollectibleOptions(params: WithOptionalParams<WithRequired<BalanceOfCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'userAddress' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<TokenBalance$1, Error, TokenBalance$1, readonly unknown[]>, "queryFn"> & {
36
+ queryFn?: _tanstack_react_query80.QueryFunction<TokenBalance$1, readonly unknown[], never> | undefined;
37
37
  } & {
38
38
  queryKey: readonly unknown[] & {
39
39
  [dataTagSymbol]: TokenBalance$1;
@@ -58,8 +58,8 @@ declare function getCountOfCollectablesQueryKey(params: CountOfCollectablesQuery
58
58
  readonly filter: CollectiblesFilter | undefined;
59
59
  readonly side: OrderSide | undefined;
60
60
  }];
61
- declare function countOfCollectablesQueryOptions(params: WithOptionalParams<WithRequired<CountOfCollectablesQueryOptions, 'chainId' | 'collectionAddress' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<number, Error, number, readonly unknown[]>, "queryFn"> & {
62
- queryFn?: _tanstack_react_query128.QueryFunction<number, readonly unknown[], never> | undefined;
61
+ declare function countOfCollectablesQueryOptions(params: WithOptionalParams<WithRequired<CountOfCollectablesQueryOptions, 'chainId' | 'collectionAddress' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<number, Error, number, readonly unknown[]>, "queryFn"> & {
62
+ queryFn?: _tanstack_react_query80.QueryFunction<number, readonly unknown[], never> | undefined;
63
63
  } & {
64
64
  queryKey: readonly unknown[] & {
65
65
  [dataTagSymbol]: number;
@@ -97,11 +97,11 @@ declare function getListCollectiblesQueryKey(params: ListCollectiblesQueryOption
97
97
  readonly side: OrderSide | undefined;
98
98
  readonly filter: CollectiblesFilter | undefined;
99
99
  }];
100
- declare function listCollectiblesQueryOptions(params: WithOptionalParams<WithRequired<ListCollectiblesQueryOptions, 'chainId' | 'collectionAddress' | 'side' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseInfiniteQueryOptions<ListCollectiblesResponse, Error, _tanstack_react_query128.InfiniteData<ListCollectiblesResponse, unknown>, readonly unknown[], Page>, "queryFn"> & {
101
- queryFn?: _tanstack_react_query128.QueryFunction<ListCollectiblesResponse, readonly unknown[], Page> | undefined;
100
+ declare function listCollectiblesQueryOptions(params: WithOptionalParams<WithRequired<ListCollectiblesQueryOptions, 'chainId' | 'collectionAddress' | 'side' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseInfiniteQueryOptions<ListCollectiblesResponse, Error, _tanstack_react_query80.InfiniteData<ListCollectiblesResponse, unknown>, readonly unknown[], Page>, "queryFn"> & {
101
+ queryFn?: _tanstack_react_query80.QueryFunction<ListCollectiblesResponse, readonly unknown[], Page> | undefined;
102
102
  } & {
103
103
  queryKey: readonly unknown[] & {
104
- [dataTagSymbol]: _tanstack_react_query128.InfiniteData<ListCollectiblesResponse, unknown>;
104
+ [dataTagSymbol]: _tanstack_react_query80.InfiniteData<ListCollectiblesResponse, unknown>;
105
105
  [dataTagErrorSymbol]: Error;
106
106
  };
107
107
  };
@@ -128,8 +128,8 @@ declare function getListCollectiblesPaginatedQueryKey(params: ListCollectiblesPa
128
128
  readonly page: number | undefined;
129
129
  readonly pageSize: number | undefined;
130
130
  }];
131
- declare function listCollectiblesPaginatedQueryOptions(params: WithOptionalParams<WithRequired<ListCollectiblesPaginatedQueryOptions, 'collectionAddress' | 'chainId' | 'side' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<ListCollectiblesResponse, Error, ListCollectiblesResponse, readonly unknown[]>, "queryFn"> & {
132
- queryFn?: _tanstack_react_query128.QueryFunction<ListCollectiblesResponse, readonly unknown[], never> | undefined;
131
+ declare function listCollectiblesPaginatedQueryOptions(params: WithOptionalParams<WithRequired<ListCollectiblesPaginatedQueryOptions, 'collectionAddress' | 'chainId' | 'side' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<ListCollectiblesResponse, Error, ListCollectiblesResponse, readonly unknown[]>, "queryFn"> & {
132
+ queryFn?: _tanstack_react_query80.QueryFunction<ListCollectiblesResponse, readonly unknown[], never> | undefined;
133
133
  } & {
134
134
  queryKey: readonly unknown[] & {
135
135
  [dataTagSymbol]: ListCollectiblesResponse;
@@ -150,8 +150,8 @@ declare function getListListingsForCollectibleQueryKey(params: ListListingsForCo
150
150
  readonly filter: OrderFilter | undefined;
151
151
  readonly page: Page | undefined;
152
152
  }];
153
- declare function listListingsForCollectibleQueryOptions(params: WithOptionalParams<WithRequired<ListListingsForCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<ListCollectibleListingsResponse, Error, ListCollectibleListingsResponse, readonly unknown[]>, "queryFn"> & {
154
- queryFn?: _tanstack_react_query128.QueryFunction<ListCollectibleListingsResponse, readonly unknown[], never> | undefined;
153
+ declare function listListingsForCollectibleQueryOptions(params: WithOptionalParams<WithRequired<ListListingsForCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<ListCollectibleListingsResponse, Error, ListCollectibleListingsResponse, readonly unknown[]>, "queryFn"> & {
154
+ queryFn?: _tanstack_react_query80.QueryFunction<ListCollectibleListingsResponse, readonly unknown[], never> | undefined;
155
155
  } & {
156
156
  queryKey: readonly unknown[] & {
157
157
  [dataTagSymbol]: ListCollectibleListingsResponse;
@@ -172,8 +172,8 @@ declare function getCountListingsForCollectibleQueryKey(params: CountListingsFor
172
172
  readonly tokenId: bigint;
173
173
  readonly filter: OrderFilter | undefined;
174
174
  }];
175
- declare function countListingsForCollectibleQueryOptions(params: WithOptionalParams<WithRequired<CountListingsForCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<number, Error, number, readonly unknown[]>, "queryFn"> & {
176
- queryFn?: _tanstack_react_query128.QueryFunction<number, readonly unknown[], never> | undefined;
175
+ declare function countListingsForCollectibleQueryOptions(params: WithOptionalParams<WithRequired<CountListingsForCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<number, Error, number, readonly unknown[]>, "queryFn"> & {
176
+ queryFn?: _tanstack_react_query80.QueryFunction<number, readonly unknown[], never> | undefined;
177
177
  } & {
178
178
  queryKey: readonly unknown[] & {
179
179
  [dataTagSymbol]: number;
@@ -207,8 +207,8 @@ declare function getListOffersForCollectibleQueryKey(params: ListOffersForCollec
207
207
  readonly filter: OrderFilter | undefined;
208
208
  readonly page: Page | undefined;
209
209
  }];
210
- declare function listOffersForCollectibleQueryOptions(params: WithOptionalParams<WithRequired<ListOffersForCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<ListCollectibleOffersResponse, Error, ListCollectibleOffersResponse, readonly unknown[]>, "queryFn"> & {
211
- queryFn?: _tanstack_react_query128.QueryFunction<ListCollectibleOffersResponse, readonly unknown[], never> | undefined;
210
+ declare function listOffersForCollectibleQueryOptions(params: WithOptionalParams<WithRequired<ListOffersForCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<ListCollectibleOffersResponse, Error, ListCollectibleOffersResponse, readonly unknown[]>, "queryFn"> & {
211
+ queryFn?: _tanstack_react_query80.QueryFunction<ListCollectibleOffersResponse, readonly unknown[], never> | undefined;
212
212
  } & {
213
213
  queryKey: readonly unknown[] & {
214
214
  [dataTagSymbol]: ListCollectibleOffersResponse;
@@ -229,8 +229,8 @@ declare function getCountOffersForCollectibleQueryKey(params: CountOffersForColl
229
229
  readonly tokenId: bigint;
230
230
  readonly filter: OrderFilter | undefined;
231
231
  }];
232
- declare function countOffersForCollectibleQueryOptions(params: WithOptionalParams<WithRequired<CountOffersForCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<number, Error, number, readonly unknown[]>, "queryFn"> & {
233
- queryFn?: _tanstack_react_query128.QueryFunction<number, readonly unknown[], never> | undefined;
232
+ declare function countOffersForCollectibleQueryOptions(params: WithOptionalParams<WithRequired<CountOffersForCollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<number, Error, number, readonly unknown[]>, "queryFn"> & {
233
+ queryFn?: _tanstack_react_query80.QueryFunction<number, readonly unknown[], never> | undefined;
234
234
  } & {
235
235
  queryKey: readonly unknown[] & {
236
236
  [dataTagSymbol]: number;
@@ -254,8 +254,8 @@ declare function getCollectibleQueryKey(params: CollectibleQueryOptions): readon
254
254
  contractAddress: `0x${string}` | undefined;
255
255
  tokenIds: bigint[];
256
256
  }];
257
- declare function collectibleQueryOptions(params: WithOptionalParams<WithRequired<CollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<TokenMetadata$1 | undefined, Error, TokenMetadata$1 | undefined, readonly unknown[]>, "queryFn"> & {
258
- queryFn?: _tanstack_react_query128.QueryFunction<TokenMetadata$1 | undefined, readonly unknown[], never> | undefined;
257
+ declare function collectibleQueryOptions(params: WithOptionalParams<WithRequired<CollectibleQueryOptions, 'chainId' | 'collectionAddress' | 'tokenId' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<TokenMetadata$1 | undefined, Error, TokenMetadata$1 | undefined, readonly unknown[]>, "queryFn"> & {
258
+ queryFn?: _tanstack_react_query80.QueryFunction<TokenMetadata$1 | undefined, readonly unknown[], never> | undefined;
259
259
  } & {
260
260
  queryKey: readonly unknown[] & {
261
261
  [dataTagSymbol]: TokenMetadata$1 | undefined;
@@ -277,8 +277,8 @@ declare function getPrimarySaleItemQueryKey(params: PrimarySaleItemQueryOptions)
277
277
  primarySaleContractAddress: string;
278
278
  tokenId: string;
279
279
  }];
280
- declare function primarySaleItemQueryOptions(params: WithOptionalParams<WithRequired<PrimarySaleItemQueryOptions, 'chainId' | 'primarySaleContractAddress' | 'tokenId' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<GetPrimarySaleItemResponse, Error, GetPrimarySaleItemResponse, readonly unknown[]>, "queryFn"> & {
281
- queryFn?: _tanstack_react_query128.QueryFunction<GetPrimarySaleItemResponse, readonly unknown[], never> | undefined;
280
+ declare function primarySaleItemQueryOptions(params: WithOptionalParams<WithRequired<PrimarySaleItemQueryOptions, 'chainId' | 'primarySaleContractAddress' | 'tokenId' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<GetPrimarySaleItemResponse, Error, GetPrimarySaleItemResponse, readonly unknown[]>, "queryFn"> & {
281
+ queryFn?: _tanstack_react_query80.QueryFunction<GetPrimarySaleItemResponse, readonly unknown[], never> | undefined;
282
282
  } & {
283
283
  queryKey: readonly unknown[] & {
284
284
  [dataTagSymbol]: GetPrimarySaleItemResponse;
@@ -298,7 +298,7 @@ declare function getPrimarySaleItemsQueryKey(params: ListPrimarySaleItemsQueryOp
298
298
  readonly primarySaleContractAddress: string;
299
299
  readonly filter: PrimarySaleItemsFilter | undefined;
300
300
  }];
301
- declare const primarySaleItemsQueryOptions: (params: ListPrimarySaleItemsQueryOptions) => _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseInfiniteQueryOptions<ListPrimarySaleItemsResponse, Error, _tanstack_react_query128.InfiniteData<ListPrimarySaleItemsResponse, unknown>, readonly ["collectible", "primary-sale-items", {
301
+ declare const primarySaleItemsQueryOptions: (params: ListPrimarySaleItemsQueryOptions) => _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseInfiniteQueryOptions<ListPrimarySaleItemsResponse, Error, _tanstack_react_query80.InfiniteData<ListPrimarySaleItemsResponse, unknown>, readonly ["collectible", "primary-sale-items", {
302
302
  readonly chainId: number;
303
303
  readonly primarySaleContractAddress: string;
304
304
  readonly filter: PrimarySaleItemsFilter | undefined;
@@ -306,7 +306,7 @@ declare const primarySaleItemsQueryOptions: (params: ListPrimarySaleItemsQueryOp
306
306
  page: number;
307
307
  pageSize: number;
308
308
  }>, "queryFn"> & {
309
- queryFn?: _tanstack_react_query128.QueryFunction<ListPrimarySaleItemsResponse, readonly ["collectible", "primary-sale-items", {
309
+ queryFn?: _tanstack_react_query80.QueryFunction<ListPrimarySaleItemsResponse, readonly ["collectible", "primary-sale-items", {
310
310
  readonly chainId: number;
311
311
  readonly primarySaleContractAddress: string;
312
312
  readonly filter: PrimarySaleItemsFilter | undefined;
@@ -320,7 +320,7 @@ declare const primarySaleItemsQueryOptions: (params: ListPrimarySaleItemsQueryOp
320
320
  readonly primarySaleContractAddress: string;
321
321
  readonly filter: PrimarySaleItemsFilter | undefined;
322
322
  }] & {
323
- [dataTagSymbol]: _tanstack_react_query128.InfiniteData<ListPrimarySaleItemsResponse, unknown>;
323
+ [dataTagSymbol]: _tanstack_react_query80.InfiniteData<ListPrimarySaleItemsResponse, unknown>;
324
324
  [dataTagErrorSymbol]: Error;
325
325
  };
326
326
  };
@@ -346,8 +346,8 @@ declare function getTokenBalancesQueryKey(params: TokenBalancesQueryOptions): re
346
346
  * @param params - The query parameters
347
347
  * @returns Query options configuration
348
348
  */
349
- declare function tokenBalancesOptions(params: WithOptionalParams<WithRequired<TokenBalancesQueryOptions, 'chainId' | 'collectionAddress' | 'userAddress' | 'config'>>): _tanstack_react_query128.OmitKeyof<_tanstack_react_query128.UseQueryOptions<TokenBalance$1[], Error, TokenBalance$1[], readonly unknown[]>, "queryFn"> & {
350
- queryFn?: _tanstack_react_query128.QueryFunction<TokenBalance$1[], readonly unknown[], never> | undefined;
349
+ declare function tokenBalancesOptions(params: WithOptionalParams<WithRequired<TokenBalancesQueryOptions, 'chainId' | 'collectionAddress' | 'userAddress' | 'config'>>): _tanstack_react_query80.OmitKeyof<_tanstack_react_query80.UseQueryOptions<TokenBalance$1[], Error, TokenBalance$1[], readonly unknown[]>, "queryFn"> & {
350
+ queryFn?: _tanstack_react_query80.QueryFunction<TokenBalance$1[], readonly unknown[], never> | undefined;
351
351
  } & {
352
352
  queryKey: readonly unknown[] & {
353
353
  [dataTagSymbol]: TokenBalance$1[];
@@ -1,4 +1,4 @@
1
- import { d as truncateMiddle } from "./utils.js";
1
+ import { h as truncateMiddle } from "./utils.js";
2
2
  import { networks } from "@0xsequence/network";
3
3
  import { CheckmarkIcon, Spinner, Text } from "@0xsequence/design-system";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,4 +1,4 @@
1
- import { Bt as AdditionalFee, Gt as CollectiblesFilter, Ht as CheckoutOptions, J as MarketplaceWallet, K as MarketplaceCollection, Kt as Collection, Mt as TokenBalance$1, Q as OrderData, Sn as TransactionCrypto, Tn as FilterCondition, U as MarketCollection, W as MarketPage, Wt as Collectible, Z as Order, _n as PropertyType, bn as StepType, c as CreateReq, cn as OrderSide, et as ShopCollection, fn as Page, ft as Filter, gn as PropertyFilter, i as CollectibleOrder, in as MarketplaceKind, it as Step, l as Currency, ln as OrderStatus, mn as PriceFilter, n as CheckoutOptionsItem, nt as Signature, pn as PostRequest, qt as CollectionStatus, s as ContractType, sn as OrderFilter, tt as ShopPage, un as OrderbookKind, ut as ContractInfo$1, vn as SortBy, wn as WalletKind, yn as SortOrder, yt as TokenMetadata$1 } from "../index2.js";
1
+ import { $ as OrderData, Cn as TransactionCrypto, En as FilterCondition, G as MarketPage, Gt as Collectible, Jt as CollectionStatus, Kt as CollectiblesFilter, Nt as TokenBalance$1, Q as Order, Tn as WalletKind, Ut as CheckoutOptions, Vt as AdditionalFee, W as MarketCollection, Y as MarketplaceWallet, _n as PropertyFilter, a as CollectibleOrder, an as MarketplaceKind, at as Step, bn as SortOrder, bt as TokenMetadata$1, c as ContractType, cn as OrderFilter, dn as OrderbookKind, dt as ContractInfo$1, hn as PriceFilter, l as CreateReq, ln as OrderSide, mn as PostRequest, nt as ShopPage, pn as Page, pt as Filter, q as MarketplaceCollection, qt as Collection, r as CheckoutOptionsItem, rt as Signature, tt as ShopCollection, u as Currency, un as OrderStatus, vn as PropertyType, xn as StepType, yn as SortBy } from "../index2.js";
2
2
  import { Dt as fetchMarketplaceConfig, Ot as marketplaceConfigOptions, _ as Price, a as CheckoutMode, c as SdkConfig, d as CollectionFilterSettings, f as EcosystemWalletSettings, g as MetadataFilterRule, h as MarketplaceWalletWaasSettings, i as ApiConfig, l as CardType, m as MarketplaceWalletOptions, o as Env, p as MarketplaceConfig, r as TransactionType, s as MarketplaceSdkContext, u as CollectibleCardAction, v as isMarketCollection, y as isShopCollection } from "../create-config.js";
3
3
  import "../xstate-store.cjs.js";
4
4
  import "../index3.js";
@@ -1,4 +1,4 @@
1
- import { C as FilterCondition, S as WalletKind, _ as PropertyType, b as TransactionCrypto, c as CollectionStatus, d as MarketplaceKind, g as OrderbookKind, h as OrderStatus, m as OrderSide, t as ContractType, v as SortOrder, y as StepType } from "../dist.js";
1
+ import { S as TransactionCrypto, T as FilterCondition, _ as OrderStatus, b as SortOrder, g as OrderSide, p as MarketplaceKind, t as ContractType, u as CollectionStatus, v as OrderbookKind, w as WalletKind, x as StepType, y as PropertyType } from "../dist.js";
2
2
  import { i as TransactionType, n as isMarketCollection, r as isShopCollection, t as CollectibleCardAction } from "../types.js";
3
3
 
4
4
  export { CollectibleCardAction, CollectionStatus, ContractType, FilterCondition, MarketplaceKind, OrderSide, OrderStatus, OrderbookKind, PropertyType, SortOrder, StepType, TransactionCrypto, TransactionType, WalletKind, isMarketCollection, isShopCollection };
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Ft as Address$1, Z as Order, i as CollectibleOrder, s as ContractType, xn as TokenMetadata } from "./index2.js";
1
+ import { It as Address$1, Q as Order, Sn as TokenMetadata, a as CollectibleOrder, c as ContractType } from "./index2.js";
2
2
  import { l as CardType, u as CollectibleCardAction } from "./create-config.js";
3
3
 
4
4
  //#region src/react/ui/components/marketplace-collectible-card/types.d.ts
package/dist/url-state.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as PropertyType } from "./dist.js";
1
+ import { y as PropertyType } from "./dist.js";
2
2
  import { useMemo } from "react";
3
3
  import { createSerializer, parseAsBoolean, parseAsJson, parseAsString, useQueryState } from "nuqs";
4
4
 
@@ -4,6 +4,6 @@ import { n as getMarketplaceABI, r as getSaleContractABI, t as MAIN_MODULE_ABI }
4
4
  import { n as SequenceMarketplaceV1_ABI, r as EIP2981_ABI, t as SequenceMarketplaceV2_ABI } from "../index5.js";
5
5
  import { i as ERC721_SALE_ABI_V0, n as ERC1155_SALES_CONTRACT_ABI_V0, r as ERC721_SALE_ABI_V1, t as ERC1155_SALES_CONTRACT_ABI_V1 } from "../index6.js";
6
6
  import { i as ERC20_ABI, n as ERC1155_ABI, r as ERC721_ABI, t as SEQUENCE_1155_ITEMS_ABI } from "../index7.js";
7
- import { a as formatPriceWithFee, c as getNetwork, d as cn, f as compareAddress, i as formatPrice, l as getPresentableChainName, m as truncateMiddle, n as calculatePriceDifferencePercentage, o as validateOpenseaOfferDecimals, p as truncateEnd, r as calculateTotalOfferCost, s as networkToWagmiChain, t as calculateEarningsAfterFees, u as getMarketplaceDetails } from "../index8.js";
7
+ import { a as formatPriceWithFee, c as getNetwork, d as findMarketCollection, f as cn, h as truncateMiddle, i as formatPrice, l as getPresentableChainName, m as truncateEnd, n as calculatePriceDifferencePercentage, o as validateOpenseaOfferDecimals, p as compareAddress, r as calculateTotalOfferCost, s as networkToWagmiChain, t as calculateEarningsAfterFees, u as getMarketplaceDetails } from "../index8.js";
8
8
  import "../index9.js";
9
- export { EIP2981_ABI, ERC1155_ABI, ERC1155_SALES_CONTRACT_ABI_V0, ERC1155_SALES_CONTRACT_ABI_V1, ERC20_ABI, ERC721_ABI, ERC721_SALE_ABI_V0, ERC721_SALE_ABI_V1, MAIN_MODULE_ABI, SEQUENCE_1155_ITEMS_ABI, SequenceMarketplaceV1_ABI, SequenceMarketplaceV2_ABI, calculateEarningsAfterFees, calculatePriceDifferencePercentage, calculateTotalOfferCost, cn, compareAddress, formatPrice, formatPriceWithFee, getMarketplaceABI, getMarketplaceDetails, getNetwork, getPresentableChainName, getSaleContractABI, networkToWagmiChain, truncateEnd, truncateMiddle, validateOpenseaOfferDecimals };
9
+ export { EIP2981_ABI, ERC1155_ABI, ERC1155_SALES_CONTRACT_ABI_V0, ERC1155_SALES_CONTRACT_ABI_V1, ERC20_ABI, ERC721_ABI, ERC721_SALE_ABI_V0, ERC721_SALE_ABI_V1, MAIN_MODULE_ABI, SEQUENCE_1155_ITEMS_ABI, SequenceMarketplaceV1_ABI, SequenceMarketplaceV2_ABI, calculateEarningsAfterFees, calculatePriceDifferencePercentage, calculateTotalOfferCost, cn, compareAddress, findMarketCollection, formatPrice, formatPriceWithFee, getMarketplaceABI, getMarketplaceDetails, getNetwork, getPresentableChainName, getSaleContractABI, networkToWagmiChain, truncateEnd, truncateMiddle, validateOpenseaOfferDecimals };
@@ -4,7 +4,7 @@ import { n as SequenceMarketplaceV1_ABI, r as EIP2981_ABI, t as SequenceMarketpl
4
4
  import { i as ERC721_SALE_ABI_V0, n as ERC1155_SALES_CONTRACT_ABI_V0, r as ERC721_SALE_ABI_V1, t as ERC1155_SALES_CONTRACT_ABI_V1 } from "../primary-sale.js";
5
5
  import { n as getMarketplaceABI, r as getSaleContractABI, t as MAIN_MODULE_ABI } from "../abi.js";
6
6
  import { i as ERC20_ABI, n as ERC1155_ABI, r as ERC721_ABI, t as SEQUENCE_1155_ITEMS_ABI } from "../token.js";
7
- import { a as formatPriceWithFee, c as cn, d as truncateMiddle, i as formatPrice, l as compareAddress, n as calculatePriceDifferencePercentage, o as validateOpenseaOfferDecimals, r as calculateTotalOfferCost, s as getMarketplaceDetails, t as calculateEarningsAfterFees, u as truncateEnd } from "../utils.js";
7
+ import { a as formatPriceWithFee, d as findMarketCollection, f as cn, h as truncateMiddle, i as formatPrice, m as truncateEnd, n as calculatePriceDifferencePercentage, o as validateOpenseaOfferDecimals, p as compareAddress, r as calculateTotalOfferCost, s as getMarketplaceDetails, t as calculateEarningsAfterFees } from "../utils.js";
8
8
  import { n as getPresentableChainName, t as getNetwork } from "../network.js";
9
9
 
10
- export { EIP2981_ABI, ERC1155_ABI, ERC1155_SALES_CONTRACT_ABI_V0, ERC1155_SALES_CONTRACT_ABI_V1, ERC20_ABI, ERC721_ABI, ERC721_SALE_ABI_V0, ERC721_SALE_ABI_V1, MAIN_MODULE_ABI, SEQUENCE_1155_ITEMS_ABI, SequenceMarketplaceV1_ABI, SequenceMarketplaceV2_ABI, calculateEarningsAfterFees, calculatePriceDifferencePercentage, calculateTotalOfferCost, cn, compareAddress, formatPrice, formatPriceWithFee, getMarketplaceABI, getMarketplaceDetails, getNetwork, getPresentableChainName, getSaleContractABI, networkToWagmiChain, truncateEnd, truncateMiddle, validateOpenseaOfferDecimals };
10
+ export { EIP2981_ABI, ERC1155_ABI, ERC1155_SALES_CONTRACT_ABI_V0, ERC1155_SALES_CONTRACT_ABI_V1, ERC20_ABI, ERC721_ABI, ERC721_SALE_ABI_V0, ERC721_SALE_ABI_V1, MAIN_MODULE_ABI, SEQUENCE_1155_ITEMS_ABI, SequenceMarketplaceV1_ABI, SequenceMarketplaceV2_ABI, calculateEarningsAfterFees, calculatePriceDifferencePercentage, calculateTotalOfferCost, cn, compareAddress, findMarketCollection, formatPrice, formatPriceWithFee, getMarketplaceABI, getMarketplaceDetails, getNetwork, getPresentableChainName, getSaleContractABI, networkToWagmiChain, truncateEnd, truncateMiddle, validateOpenseaOfferDecimals };
package/dist/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { d as MarketplaceKind } from "./dist.js";
1
+ import { p as MarketplaceKind, v as OrderbookKind } from "./dist.js";
2
2
  import { c as LooksRareLogo, d as MintifyLogo, g as SequenceLogo, i as BlurLogo, l as MagicEdenLogo, m as OpenSeaLogo, t as AlienSwapLogo, y as X2y2Logo } from "./marketplace-logos.js";
3
3
  import { clsx } from "clsx";
4
4
  import { twMerge } from "tailwind-merge";
@@ -26,6 +26,31 @@ function cn(...inputs) {
26
26
  return twMerge(clsx(inputs));
27
27
  }
28
28
 
29
+ //#endregion
30
+ //#region src/utils/collection.ts
31
+ /**
32
+ * Finds a market collection matching both the collection address and chain ID.
33
+ * Always use this instead of manually searching market.collections to avoid
34
+ * multi-chain bugs where the same collection address exists on different chains.
35
+ */
36
+ const findMarketCollection = (collections, collectionAddress, chainId) => {
37
+ return collections.find((collection) => compareAddress(collection.itemsAddress, collectionAddress) && Number(collection.chainId) === Number(chainId));
38
+ };
39
+
40
+ //#endregion
41
+ //#region src/utils/normalizeMarketplace.ts
42
+ function normalizeMarketplaceKind(kind) {
43
+ if (!kind) return kind;
44
+ return kind === MarketplaceKind.magic_eden ? MarketplaceKind.opensea : kind;
45
+ }
46
+ function normalizeOrderbookKind(kind) {
47
+ if (!kind) return kind;
48
+ return kind === OrderbookKind.magic_eden ? OrderbookKind.opensea : kind;
49
+ }
50
+ function isOpenSeaOrderbook(kind) {
51
+ return normalizeOrderbookKind(kind) === OrderbookKind.opensea;
52
+ }
53
+
29
54
  //#endregion
30
55
  //#region src/utils/getMarketplaceDetails.ts
31
56
  const MARKETPLACES = {
@@ -73,7 +98,9 @@ const KIND_TO_MARKETPLACE = {
73
98
  [MarketplaceKind.magic_eden]: "magiceden"
74
99
  };
75
100
  function getMarketplaceDetails({ originName, kind }) {
76
- if (kind === MarketplaceKind.sequence_marketplace_v1 || kind === MarketplaceKind.sequence_marketplace_v2) return MARKETPLACES.sequence;
101
+ const normalizedKind = normalizeMarketplaceKind(kind);
102
+ if (normalizedKind === MarketplaceKind.sequence_marketplace_v1 || normalizedKind === MarketplaceKind.sequence_marketplace_v2) return MARKETPLACES.sequence;
103
+ if (normalizedKind === MarketplaceKind.opensea) return MARKETPLACES.opensea;
77
104
  let name = originName.toLowerCase();
78
105
  try {
79
106
  new URL(name);
@@ -82,7 +109,7 @@ function getMarketplaceDetails({ originName, kind }) {
82
109
  name = name.replace(/ /g, "");
83
110
  const details = MARKETPLACES[name];
84
111
  if (details) return details;
85
- if (KIND_TO_MARKETPLACE[kind]) return MARKETPLACES[KIND_TO_MARKETPLACE[kind]];
112
+ if (normalizedKind && KIND_TO_MARKETPLACE[normalizedKind]) return MARKETPLACES[KIND_TO_MARKETPLACE[normalizedKind]];
86
113
  }
87
114
  function getRootDomain(url) {
88
115
  const parts = url.replace(/^(https?:\/\/)?(www\.)?/, "").split(".");
@@ -226,5 +253,5 @@ const validateOpenseaOfferDecimals = (value) => {
226
253
  };
227
254
 
228
255
  //#endregion
229
- export { formatPriceWithFee as a, cn as c, truncateMiddle as d, formatPrice as i, compareAddress as l, calculatePriceDifferencePercentage as n, validateOpenseaOfferDecimals as o, calculateTotalOfferCost as r, getMarketplaceDetails as s, calculateEarningsAfterFees as t, truncateEnd as u };
256
+ export { formatPriceWithFee as a, isOpenSeaOrderbook as c, findMarketCollection as d, cn as f, truncateMiddle as h, formatPrice as i, normalizeMarketplaceKind as l, truncateEnd as m, calculatePriceDifferencePercentage as n, validateOpenseaOfferDecimals as o, compareAddress as p, calculateTotalOfferCost as r, getMarketplaceDetails as s, calculateEarningsAfterFees as t, normalizeOrderbookKind as u };
230
257
  //# sourceMappingURL=utils.js.map
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["MARKETPLACES: Record<string, Marketplace>","KIND_TO_MARKETPLACE: Partial<\n\tRecord<MarketplaceKind, keyof typeof MARKETPLACES>\n>"],"sources":["../src/utils/address.ts","../src/utils/cn.ts","../src/utils/getMarketplaceDetails.ts","../src/utils/price.ts"],"sourcesContent":["export const truncateMiddle = (\n\taddress: string,\n\tminPrefix = 20,\n\tminSuffix = 3,\n): string => {\n\tif (minPrefix + minSuffix >= 40) {\n\t\treturn address;\n\t}\n\treturn `${address.substring(0, 2 + minPrefix)}…${address.substring(address.length - minSuffix)}`;\n};\n\nexport const truncateEnd = (text: string | undefined, truncateAt: number) => {\n\tif (!text) return '';\n\n\tlet finalText = text;\n\n\tif (text.length >= truncateAt) {\n\t\tfinalText = `${text.slice(0, truncateAt)}...`;\n\t}\n\n\treturn finalText;\n};\n\nexport const compareAddress = (a = '', b = '') => {\n\treturn a.toLowerCase() === b.toLowerCase();\n};\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import { MarketplaceKind } from '@0xsequence/api-client';\nimport type { Image } from '@0xsequence/design-system';\nimport type { ComponentType } from 'react';\nimport {\n\tAlienSwapLogo,\n\tBlurLogo,\n\tLooksRareLogo,\n\tMagicEdenLogo,\n\tMintifyLogo,\n\tOpenSeaLogo,\n\tSequenceLogo,\n\tX2y2Logo,\n} from '../react/ui/components/marketplace-logos';\n\ninterface Marketplace {\n\tlogo: ComponentType<React.ComponentProps<typeof Image>>;\n\tdisplayName: string;\n}\n\nconst MARKETPLACES: Record<string, Marketplace> = {\n\tsequence: {\n\t\tlogo: SequenceLogo,\n\t\tdisplayName: 'Sequence',\n\t},\n\topensea: {\n\t\tlogo: OpenSeaLogo,\n\t\tdisplayName: 'OpenSea',\n\t},\n\tmagiceden: {\n\t\tlogo: MagicEdenLogo,\n\t\tdisplayName: 'Magic Eden',\n\t},\n\tmintify: {\n\t\tlogo: MintifyLogo,\n\t\tdisplayName: 'Mintify',\n\t},\n\tlooksrare: {\n\t\tlogo: LooksRareLogo,\n\t\tdisplayName: 'Looks Rare',\n\t},\n\tx2y2: {\n\t\tlogo: X2y2Logo,\n\t\tdisplayName: 'X2Y2',\n\t},\n\tblur: {\n\t\tlogo: BlurLogo,\n\t\tdisplayName: 'Blur',\n\t},\n\talienswap: {\n\t\tlogo: AlienSwapLogo,\n\t\tdisplayName: 'AlienSwap',\n\t},\n} as const;\n\nconst KIND_TO_MARKETPLACE: Partial<\n\tRecord<MarketplaceKind, keyof typeof MARKETPLACES>\n> = {\n\t[MarketplaceKind.sequence_marketplace_v1]: 'sequence',\n\t[MarketplaceKind.sequence_marketplace_v2]: 'sequence',\n\t[MarketplaceKind.opensea]: 'opensea',\n\t[MarketplaceKind.mintify]: 'mintify',\n\t[MarketplaceKind.looks_rare]: 'looksrare',\n\t[MarketplaceKind.x2y2]: 'x2y2',\n\t[MarketplaceKind.blur]: 'blur',\n\t[MarketplaceKind.magic_eden]: 'magiceden',\n};\n\ntype MarketplaceDetailsProp = {\n\toriginName: string;\n\tkind: MarketplaceKind;\n};\n\n// TODO: add support for more marketplaces and improve detection of marketplace\nexport function getMarketplaceDetails({\n\toriginName,\n\tkind,\n}: MarketplaceDetailsProp) {\n\tif (\n\t\tkind === MarketplaceKind.sequence_marketplace_v1 ||\n\t\tkind === MarketplaceKind.sequence_marketplace_v2\n\t) {\n\t\treturn MARKETPLACES.sequence;\n\t}\n\n\tlet name = originName.toLowerCase();\n\n\ttry {\n\t\t//Check if the name can be parsed as a url\n\t\tnew URL(name);\n\t\t// if it can we are naively trying to extract the root domain\n\t\tname = getRootDomain(name) || name;\n\t} catch {}\n\n\tname = name.replace(/ /g, '');\n\n\tconst details = MARKETPLACES[name];\n\n\tif (details) {\n\t\treturn details;\n\t}\n\n\tif (KIND_TO_MARKETPLACE[kind]) {\n\t\treturn MARKETPLACES[KIND_TO_MARKETPLACE[kind]];\n\t}\n}\n\nfunction getRootDomain(url: string) {\n\tconst domain = url.replace(/^(https?:\\/\\/)?(www\\.)?/, '');\n\tconst parts = domain.split('.');\n\treturn parts[parts.length - 2] || parts[0];\n}\n","import * as dn from 'dnum';\nimport { formatUnits } from 'viem';\n\ntype CalculatePriceDifferencePercentageArgs = {\n\tinputPriceRaw: bigint;\n\tbasePriceRaw: bigint;\n\tdecimals: number;\n};\n\n/**\n * Calculates the percentage difference between two prices\n * @param args - Object containing input price, base price, and decimals\n * @returns The percentage difference as a string with 2 decimal places\n * @example\n * ```ts\n * const diff = calculatePriceDifferencePercentage({\n * inputPriceRaw: 1000000n,\n * basePriceRaw: 900000n,\n * decimals: 6\n * }); // Returns \"11.11\"\n * ```\n */\nexport const calculatePriceDifferencePercentage = ({\n\tinputPriceRaw,\n\tbasePriceRaw,\n\tdecimals,\n}: CalculatePriceDifferencePercentageArgs) => {\n\tconst inputPrice = Number(formatUnits(inputPriceRaw, decimals));\n\tconst basePrice = Number(formatUnits(basePriceRaw, decimals));\n\tconst difference = inputPrice - basePrice;\n\tconst percentageDifference = (difference / basePrice) * 100;\n\n\treturn percentageDifference.toFixed(2);\n};\n\n/**\n * Formats a raw price amount with the specified number of decimal places\n * @param amount - The raw price amount as a bigint\n * @param decimals - Number of decimal places to format to\n * @returns Formatted price string with proper decimal and thousands separators\n * @example\n * ```ts\n * const formatted = formatPrice(1000000n, 6); // Returns \"1.000000\"\n * ```\n */\nexport const formatPrice = (amount: bigint, decimals: number): string => {\n\tconst formattedUnits = Number(formatUnits(amount, decimals));\n\treturn formattedUnits.toLocaleString('en-US', {\n\t\tminimumFractionDigits: 0,\n\t\tmaximumFractionDigits: decimals,\n\t});\n};\n\n/**\n * Calculates the final earnings amount after applying multiple fee percentages\n * @param amount - The raw amount as a bigint (e.g., from a blockchain transaction)\n * @param decimals - The number of decimal places for the currency (e.g., 18 for ETH, 6 for USDC)\n * @param fees - Array of fee percentages to apply (e.g., [2.5, 1.0] for 2.5% and 1% fees)\n * @returns Formatted string representing the final earnings after all fees are applied\n * @throws Will return '0' if there's an error in calculation\n * @example\n * ```ts\n * const earnings = calculateEarningsAfterFees(\n * 1000000000000000000n, // 1 ETH\n * 18, // ETH decimals\n * [2.5, 1.0] // 2.5% and 1% fees\n * ); // Returns \"0.96525\" (1 ETH after 2.5% and 1% fees)\n * ```\n */\nexport const calculateEarningsAfterFees = (\n\tamount: bigint,\n\tdecimals: number,\n\tfees: number[],\n): string => {\n\ttry {\n\t\t// formatUnits already returns a string, no need for Number conversion\n\t\tconst decimalAmount = formatUnits(amount, decimals);\n\t\tlet earnings = dn.from(decimalAmount, decimals);\n\n\t\tfor (const fee of fees) {\n\t\t\tif (fee > 0) {\n\t\t\t\t// dnum accepts numbers directly via Numberish type\n\t\t\t\tconst feeMultiplier = dn.from(1 - fee / 100, decimals);\n\t\t\t\tearnings = dn.multiply(earnings, feeMultiplier);\n\t\t\t}\n\t\t}\n\n\t\treturn dn.format(earnings, {\n\t\t\tdigits: decimals,\n\t\t\ttrailingZeros: false,\n\t\t\tlocale: 'en-US',\n\t\t});\n\t} catch (error) {\n\t\tconsole.error('Error calculating earnings after fees:', error);\n\t\treturn '0';\n\t}\n};\n\n/**\n * Formats a price amount with fee applied\n * @param amount - The raw price amount as a bigint\n * @param decimals - Number of decimal places for the currency\n * @param feePercentage - Fee percentage to apply (e.g., 3.5 for 3.5%)\n * @returns Formatted price string with fee applied and proper decimal/thousands separators\n * @example\n * ```ts\n * const priceWithFee = formatPriceWithFee(1000000n, 6, 3.5); // Returns \"1.035\"\n * ```\n */\nexport const formatPriceWithFee = (\n\tamount: bigint,\n\tdecimals: number,\n\tfeePercentage: number,\n): string => {\n\ttry {\n\t\t// formatUnits already returns a string, no need for Number conversion\n\t\tconst decimalAmount = formatUnits(amount, decimals);\n\t\tconst price = dn.from(decimalAmount, decimals);\n\t\t// dnum accepts numbers directly via Numberish type\n\t\tconst feeMultiplier = dn.from(1 + feePercentage / 100, decimals);\n\t\tconst totalPrice = dn.multiply(price, feeMultiplier);\n\n\t\treturn dn.format(totalPrice, {\n\t\t\tdigits: decimals,\n\t\t\ttrailingZeros: false,\n\t\t\tlocale: 'en-US',\n\t\t});\n\t} catch (error) {\n\t\tconsole.error('Error formatting price with fee:', error);\n\t\treturn '0';\n\t}\n};\n\nexport const calculateTotalOfferCost = (\n\tofferAmountRaw: bigint,\n\tdecimals: number,\n\troyaltyPercentage = 0,\n): bigint => {\n\ttry {\n\t\tconst dnumAmount = [offerAmountRaw, decimals] as dn.Dnum;\n\t\tlet totalCost = dn.from(dnumAmount);\n\n\t\tif (royaltyPercentage > 0) {\n\t\t\t// dnum accepts numbers directly via Numberish type\n\t\t\tconst royaltyFee = dn.multiply(\n\t\t\t\ttotalCost,\n\t\t\t\tdn.from(royaltyPercentage / 100, decimals),\n\t\t\t);\n\t\t\ttotalCost = dn.add(totalCost, royaltyFee);\n\t\t}\n\n\t\tconst totalCostString = dn.format(totalCost, {\n\t\t\tdigits: decimals,\n\t\t\ttrailingZeros: true,\n\t\t});\n\n\t\tconst cleanAmount = totalCostString.replace(/,/g, '');\n\n\t\treturn BigInt(Math.round(Number(cleanAmount) * 10 ** decimals));\n\t} catch (error) {\n\t\tconsole.error('Error calculating total offer cost:', error);\n\t\treturn offerAmountRaw;\n\t}\n};\n\n/**\n * Validates if a price value meets OpenSea's decimal constraints for offers\n * OpenSea allows maximum 4 decimal places for offers and minimum 0.0001\n * @param value - The price value as a string\n * @returns Object containing validation result and error message\n * @example\n * ```ts\n * const result = validateOpenseaOfferDecimals('0.12345');\n * // Returns { isValid: false, errorMessage: \"Offer amount must be at least 0.0001\" }\n * ```\n */\nexport const validateOpenseaOfferDecimals = (\n\tvalue: string,\n): { isValid: boolean; errorMessage?: string } => {\n\tif (!value || value === '0') return { isValid: true };\n\n\tconst [_, decimals = ''] = value.split('.');\n\tif (decimals.length > 4) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terrorMessage: 'Offer amount must be at least 0.0001',\n\t\t};\n\t}\n\n\treturn { isValid: true };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","names":["MARKETPLACES: Record<string, Marketplace>","KIND_TO_MARKETPLACE: Partial<\n\tRecord<MarketplaceKind, keyof typeof MARKETPLACES>\n>"],"sources":["../src/utils/address.ts","../src/utils/cn.ts","../src/utils/collection.ts","../src/utils/normalizeMarketplace.ts","../src/utils/getMarketplaceDetails.ts","../src/utils/price.ts"],"sourcesContent":["export const truncateMiddle = (\n\taddress: string,\n\tminPrefix = 20,\n\tminSuffix = 3,\n): string => {\n\tif (minPrefix + minSuffix >= 40) {\n\t\treturn address;\n\t}\n\treturn `${address.substring(0, 2 + minPrefix)}…${address.substring(address.length - minSuffix)}`;\n};\n\nexport const truncateEnd = (text: string | undefined, truncateAt: number) => {\n\tif (!text) return '';\n\n\tlet finalText = text;\n\n\tif (text.length >= truncateAt) {\n\t\tfinalText = `${text.slice(0, truncateAt)}...`;\n\t}\n\n\treturn finalText;\n};\n\nexport const compareAddress = (a = '', b = '') => {\n\treturn a.toLowerCase() === b.toLowerCase();\n};\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import type { MarketCollection } from '@0xsequence/api-client';\nimport { compareAddress } from './address';\n\n/**\n * Finds a market collection matching both the collection address and chain ID.\n * Always use this instead of manually searching market.collections to avoid\n * multi-chain bugs where the same collection address exists on different chains.\n */\nexport const findMarketCollection = (\n\tcollections: MarketCollection[],\n\tcollectionAddress: string,\n\tchainId: string | number,\n): MarketCollection | undefined => {\n\treturn collections.find(\n\t\t(collection) =>\n\t\t\tcompareAddress(collection.itemsAddress, collectionAddress) &&\n\t\t\tNumber(collection.chainId) === Number(chainId),\n\t);\n};\n","import { MarketplaceKind, OrderbookKind } from '@0xsequence/api-client';\n\nexport function normalizeMarketplaceKind(\n\tkind: MarketplaceKind | undefined,\n): MarketplaceKind | undefined {\n\tif (!kind) {\n\t\treturn kind;\n\t}\n\n\treturn kind === MarketplaceKind.magic_eden\n\t\t? MarketplaceKind.opensea\n\t\t: kind;\n}\n\nexport function normalizeOrderbookKind(\n\tkind: OrderbookKind | undefined,\n): OrderbookKind | undefined {\n\tif (!kind) {\n\t\treturn kind;\n\t}\n\n\treturn kind === OrderbookKind.magic_eden\n\t\t? OrderbookKind.opensea\n\t\t: kind;\n}\n\nexport function isOpenSeaOrderbook(\n\tkind: OrderbookKind | undefined,\n): boolean {\n\treturn normalizeOrderbookKind(kind) === OrderbookKind.opensea;\n}\n","import { MarketplaceKind } from '@0xsequence/api-client';\nimport type { Image } from '@0xsequence/design-system';\nimport type { ComponentType } from 'react';\nimport {\n\tAlienSwapLogo,\n\tBlurLogo,\n\tLooksRareLogo,\n\tMagicEdenLogo,\n\tMintifyLogo,\n\tOpenSeaLogo,\n\tSequenceLogo,\n\tX2y2Logo,\n} from '../react/ui/components/marketplace-logos';\nimport { normalizeMarketplaceKind } from './normalizeMarketplace';\n\ninterface Marketplace {\n\tlogo: ComponentType<React.ComponentProps<typeof Image>>;\n\tdisplayName: string;\n}\n\nconst MARKETPLACES: Record<string, Marketplace> = {\n\tsequence: {\n\t\tlogo: SequenceLogo,\n\t\tdisplayName: 'Sequence',\n\t},\n\topensea: {\n\t\tlogo: OpenSeaLogo,\n\t\tdisplayName: 'OpenSea',\n\t},\n\tmagiceden: {\n\t\tlogo: MagicEdenLogo,\n\t\tdisplayName: 'Magic Eden',\n\t},\n\tmintify: {\n\t\tlogo: MintifyLogo,\n\t\tdisplayName: 'Mintify',\n\t},\n\tlooksrare: {\n\t\tlogo: LooksRareLogo,\n\t\tdisplayName: 'Looks Rare',\n\t},\n\tx2y2: {\n\t\tlogo: X2y2Logo,\n\t\tdisplayName: 'X2Y2',\n\t},\n\tblur: {\n\t\tlogo: BlurLogo,\n\t\tdisplayName: 'Blur',\n\t},\n\talienswap: {\n\t\tlogo: AlienSwapLogo,\n\t\tdisplayName: 'AlienSwap',\n\t},\n} as const;\n\nconst KIND_TO_MARKETPLACE: Partial<\n\tRecord<MarketplaceKind, keyof typeof MARKETPLACES>\n> = {\n\t[MarketplaceKind.sequence_marketplace_v1]: 'sequence',\n\t[MarketplaceKind.sequence_marketplace_v2]: 'sequence',\n\t[MarketplaceKind.opensea]: 'opensea',\n\t[MarketplaceKind.mintify]: 'mintify',\n\t[MarketplaceKind.looks_rare]: 'looksrare',\n\t[MarketplaceKind.x2y2]: 'x2y2',\n\t[MarketplaceKind.blur]: 'blur',\n\t[MarketplaceKind.magic_eden]: 'magiceden',\n};\n\ntype MarketplaceDetailsProp = {\n\toriginName: string;\n\tkind: MarketplaceKind;\n};\n\n// TODO: add support for more marketplaces and improve detection of marketplace\nexport function getMarketplaceDetails({\n\toriginName,\n\tkind,\n}: MarketplaceDetailsProp) {\n\tconst normalizedKind = normalizeMarketplaceKind(kind);\n\n\tif (\n\t\tnormalizedKind === MarketplaceKind.sequence_marketplace_v1 ||\n\t\tnormalizedKind === MarketplaceKind.sequence_marketplace_v2\n\t) {\n\t\treturn MARKETPLACES.sequence;\n\t}\n\n\tif (normalizedKind === MarketplaceKind.opensea) {\n\t\treturn MARKETPLACES.opensea;\n\t}\n\n\tlet name = originName.toLowerCase();\n\n\ttry {\n\t\t//Check if the name can be parsed as a url\n\t\tnew URL(name);\n\t\t// if it can we are naively trying to extract the root domain\n\t\tname = getRootDomain(name) || name;\n\t} catch {}\n\n\tname = name.replace(/ /g, '');\n\n\tconst details = MARKETPLACES[name];\n\n\tif (details) {\n\t\treturn details;\n\t}\n\n\tif (normalizedKind && KIND_TO_MARKETPLACE[normalizedKind]) {\n\t\treturn MARKETPLACES[KIND_TO_MARKETPLACE[normalizedKind]];\n\t}\n}\n\nfunction getRootDomain(url: string) {\n\tconst domain = url.replace(/^(https?:\\/\\/)?(www\\.)?/, '');\n\tconst parts = domain.split('.');\n\treturn parts[parts.length - 2] || parts[0];\n}\n","import * as dn from 'dnum';\nimport { formatUnits } from 'viem';\n\ntype CalculatePriceDifferencePercentageArgs = {\n\tinputPriceRaw: bigint;\n\tbasePriceRaw: bigint;\n\tdecimals: number;\n};\n\n/**\n * Calculates the percentage difference between two prices\n * @param args - Object containing input price, base price, and decimals\n * @returns The percentage difference as a string with 2 decimal places\n * @example\n * ```ts\n * const diff = calculatePriceDifferencePercentage({\n * inputPriceRaw: 1000000n,\n * basePriceRaw: 900000n,\n * decimals: 6\n * }); // Returns \"11.11\"\n * ```\n */\nexport const calculatePriceDifferencePercentage = ({\n\tinputPriceRaw,\n\tbasePriceRaw,\n\tdecimals,\n}: CalculatePriceDifferencePercentageArgs) => {\n\tconst inputPrice = Number(formatUnits(inputPriceRaw, decimals));\n\tconst basePrice = Number(formatUnits(basePriceRaw, decimals));\n\tconst difference = inputPrice - basePrice;\n\tconst percentageDifference = (difference / basePrice) * 100;\n\n\treturn percentageDifference.toFixed(2);\n};\n\n/**\n * Formats a raw price amount with the specified number of decimal places\n * @param amount - The raw price amount as a bigint\n * @param decimals - Number of decimal places to format to\n * @returns Formatted price string with proper decimal and thousands separators\n * @example\n * ```ts\n * const formatted = formatPrice(1000000n, 6); // Returns \"1.000000\"\n * ```\n */\nexport const formatPrice = (amount: bigint, decimals: number): string => {\n\tconst formattedUnits = Number(formatUnits(amount, decimals));\n\treturn formattedUnits.toLocaleString('en-US', {\n\t\tminimumFractionDigits: 0,\n\t\tmaximumFractionDigits: decimals,\n\t});\n};\n\n/**\n * Calculates the final earnings amount after applying multiple fee percentages\n * @param amount - The raw amount as a bigint (e.g., from a blockchain transaction)\n * @param decimals - The number of decimal places for the currency (e.g., 18 for ETH, 6 for USDC)\n * @param fees - Array of fee percentages to apply (e.g., [2.5, 1.0] for 2.5% and 1% fees)\n * @returns Formatted string representing the final earnings after all fees are applied\n * @throws Will return '0' if there's an error in calculation\n * @example\n * ```ts\n * const earnings = calculateEarningsAfterFees(\n * 1000000000000000000n, // 1 ETH\n * 18, // ETH decimals\n * [2.5, 1.0] // 2.5% and 1% fees\n * ); // Returns \"0.96525\" (1 ETH after 2.5% and 1% fees)\n * ```\n */\nexport const calculateEarningsAfterFees = (\n\tamount: bigint,\n\tdecimals: number,\n\tfees: number[],\n): string => {\n\ttry {\n\t\t// formatUnits already returns a string, no need for Number conversion\n\t\tconst decimalAmount = formatUnits(amount, decimals);\n\t\tlet earnings = dn.from(decimalAmount, decimals);\n\n\t\tfor (const fee of fees) {\n\t\t\tif (fee > 0) {\n\t\t\t\t// dnum accepts numbers directly via Numberish type\n\t\t\t\tconst feeMultiplier = dn.from(1 - fee / 100, decimals);\n\t\t\t\tearnings = dn.multiply(earnings, feeMultiplier);\n\t\t\t}\n\t\t}\n\n\t\treturn dn.format(earnings, {\n\t\t\tdigits: decimals,\n\t\t\ttrailingZeros: false,\n\t\t\tlocale: 'en-US',\n\t\t});\n\t} catch (error) {\n\t\tconsole.error('Error calculating earnings after fees:', error);\n\t\treturn '0';\n\t}\n};\n\n/**\n * Formats a price amount with fee applied\n * @param amount - The raw price amount as a bigint\n * @param decimals - Number of decimal places for the currency\n * @param feePercentage - Fee percentage to apply (e.g., 3.5 for 3.5%)\n * @returns Formatted price string with fee applied and proper decimal/thousands separators\n * @example\n * ```ts\n * const priceWithFee = formatPriceWithFee(1000000n, 6, 3.5); // Returns \"1.035\"\n * ```\n */\nexport const formatPriceWithFee = (\n\tamount: bigint,\n\tdecimals: number,\n\tfeePercentage: number,\n): string => {\n\ttry {\n\t\t// formatUnits already returns a string, no need for Number conversion\n\t\tconst decimalAmount = formatUnits(amount, decimals);\n\t\tconst price = dn.from(decimalAmount, decimals);\n\t\t// dnum accepts numbers directly via Numberish type\n\t\tconst feeMultiplier = dn.from(1 + feePercentage / 100, decimals);\n\t\tconst totalPrice = dn.multiply(price, feeMultiplier);\n\n\t\treturn dn.format(totalPrice, {\n\t\t\tdigits: decimals,\n\t\t\ttrailingZeros: false,\n\t\t\tlocale: 'en-US',\n\t\t});\n\t} catch (error) {\n\t\tconsole.error('Error formatting price with fee:', error);\n\t\treturn '0';\n\t}\n};\n\nexport const calculateTotalOfferCost = (\n\tofferAmountRaw: bigint,\n\tdecimals: number,\n\troyaltyPercentage = 0,\n): bigint => {\n\ttry {\n\t\tconst dnumAmount = [offerAmountRaw, decimals] as dn.Dnum;\n\t\tlet totalCost = dn.from(dnumAmount);\n\n\t\tif (royaltyPercentage > 0) {\n\t\t\t// dnum accepts numbers directly via Numberish type\n\t\t\tconst royaltyFee = dn.multiply(\n\t\t\t\ttotalCost,\n\t\t\t\tdn.from(royaltyPercentage / 100, decimals),\n\t\t\t);\n\t\t\ttotalCost = dn.add(totalCost, royaltyFee);\n\t\t}\n\n\t\tconst totalCostString = dn.format(totalCost, {\n\t\t\tdigits: decimals,\n\t\t\ttrailingZeros: true,\n\t\t});\n\n\t\tconst cleanAmount = totalCostString.replace(/,/g, '');\n\n\t\treturn BigInt(Math.round(Number(cleanAmount) * 10 ** decimals));\n\t} catch (error) {\n\t\tconsole.error('Error calculating total offer cost:', error);\n\t\treturn offerAmountRaw;\n\t}\n};\n\n/**\n * Validates if a price value meets OpenSea's decimal constraints for offers\n * OpenSea allows maximum 4 decimal places for offers and minimum 0.0001\n * @param value - The price value as a string\n * @returns Object containing validation result and error message\n * @example\n * ```ts\n * const result = validateOpenseaOfferDecimals('0.12345');\n * // Returns { isValid: false, errorMessage: \"Offer amount must be at least 0.0001\" }\n * ```\n */\nexport const validateOpenseaOfferDecimals = (\n\tvalue: string,\n): { isValid: boolean; errorMessage?: string } => {\n\tif (!value || value === '0') return { isValid: true };\n\n\tconst [_, decimals = ''] = value.split('.');\n\tif (decimals.length > 4) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terrorMessage: 'Offer amount must be at least 0.0001',\n\t\t};\n\t}\n\n\treturn { isValid: true };\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@0xsequence/marketplace-sdk",
3
3
  "private": false,
4
- "version": "2.0.0",
4
+ "version": "2.0.2",
5
5
  "type": "module",
6
6
  "sideEffects": [
7
7
  "**/*.css"
@@ -39,7 +39,8 @@
39
39
  }
40
40
  },
41
41
  "dependencies": {
42
- "0xtrails": "^0.9.6",
42
+ "0xtrails": "^0.16.2",
43
+ "@0xtrails/adapter-wagmi": "^0.16.2",
43
44
  "@databeat/tracker": "^0.9.3",
44
45
  "@tailwindcss/cli": "^4.1.18",
45
46
  "@xstate/store": "^3.14.1",
@@ -62,12 +63,12 @@
62
63
  "@0xsequence/network": "2.3.39",
63
64
  "@0xsequence/waas": "2.3.39",
64
65
  "@google/model-viewer": "^4.1.0",
65
- "@tanstack/react-query": "5.90.16",
66
+ "@tanstack/react-query": "5.90.20",
66
67
  "nuqs": "^2.8.6",
67
68
  "react": "^19.2.3",
68
69
  "react-dom": "^19.2.3",
69
- "viem": "2.44.4",
70
- "wagmi": "2.18.0"
70
+ "viem": "2.45.0",
71
+ "wagmi": "2.19.5"
71
72
  },
72
73
  "peerDependenciesMeta": {
73
74
  "nuqs": {
@@ -117,6 +118,7 @@
117
118
  ]
118
119
  },
119
120
  "scripts": {
121
+ "prebuild": "pnpm --filter \"@0xsequence/api-client\" build",
120
122
  "build": "tsdown",
121
123
  "format": "biome format --write .",
122
124
  "format:check": "biome format .",
@@ -38,4 +38,5 @@ describe('useMarketplaceConfig', () => {
38
38
  expect(result.current.error).toBeDefined();
39
39
  expect(result.current.data).toBeUndefined();
40
40
  });
41
+
41
42
  });
@@ -52,9 +52,9 @@ describe('useCurrencyList', () => {
52
52
  );
53
53
  });
54
54
 
55
- it('should filter currencies by collection address', async () => {
55
+ it('should filter currencies by collection address and chain', async () => {
56
56
  const args = {
57
- ...defaultArgs,
57
+ chainId: mockConfig.marketCollections[1].chainId,
58
58
  collectionAddress: mockConfig.marketCollections[1]
59
59
  .itemsAddress as Address,
60
60
  } satisfies Parameters<typeof useCurrencyList>[0];
@@ -73,6 +73,27 @@ describe('useCurrencyList', () => {
73
73
  );
74
74
  });
75
75
 
76
+ it('should not filter currencies when collection address matches a different chain', async () => {
77
+ const args = {
78
+ ...defaultArgs,
79
+ collectionAddress: mockConfig.marketCollections[1]
80
+ .itemsAddress as Address,
81
+ } satisfies Parameters<typeof useCurrencyList>[0];
82
+
83
+ const { result } = renderHook(() => useCurrencyList(args));
84
+
85
+ await waitFor(() => {
86
+ expect(result.current.isLoading).toBe(false);
87
+ });
88
+
89
+ const currencyAddresses = result.current.data?.map(
90
+ (c) => c.contractAddress,
91
+ );
92
+ expect(currencyAddresses).toEqual(
93
+ mockCurrencies.map((currency) => currency.contractAddress),
94
+ );
95
+ });
96
+
76
97
  it('should handle error states', async () => {
77
98
  // Override the handler for this test to return an error
78
99
  server.use(
@@ -84,7 +84,10 @@ export const useCancelTransactionSteps = ({
84
84
  }
85
85
 
86
86
  try {
87
- await ensureCorrectChainAsync(Number(chainId));
87
+ const isOnCorrectChain = await ensureCorrectChainAsync(Number(chainId));
88
+ if (!isOnCorrectChain) {
89
+ return;
90
+ }
88
91
 
89
92
  setSteps((prev) => ({
90
93
  ...prev,
@@ -5,8 +5,8 @@ import {
5
5
  type Step,
6
6
  WalletKind,
7
7
  } from '@0xsequence/api-client';
8
- import { useQuery } from '@tanstack/react-query';
9
- import { useMemo } from 'react';
8
+ import { useQuery, useQueryClient } from '@tanstack/react-query';
9
+ import { useEffect, useMemo } from 'react';
10
10
  import { getMarketplaceClient } from '../../_internal/api';
11
11
  import { useConfig } from '../config';
12
12
 
@@ -38,6 +38,7 @@ export function useMarketTransactionSteps({
38
38
  enabled = true,
39
39
  }: UseMarketTransactionStepsParams) {
40
40
  const config = useConfig();
41
+ const queryClient = useQueryClient();
41
42
  const marketplaceClient = useMemo(
42
43
  () => getMarketplaceClient(config),
43
44
  [config],
@@ -48,19 +49,24 @@ export function useMarketTransactionSteps({
48
49
  const useWithTrails =
49
50
  config.checkoutMode === 'trails' || config.checkoutMode === undefined;
50
51
 
51
- return useQuery<{ steps: Step[]; canBeUsedWithTrails: boolean }, Error>({
52
- queryKey: [
53
- 'market-transaction-steps',
54
- {
55
- chainId,
56
- collectionAddress,
57
- buyer,
58
- orderId,
59
- tokenId,
60
- quantity,
61
- useWithTrails,
62
- },
63
- ],
52
+ const queryKey = [
53
+ 'market-transaction-steps',
54
+ {
55
+ chainId,
56
+ collectionAddress,
57
+ buyer,
58
+ orderId,
59
+ tokenId,
60
+ quantity,
61
+ useWithTrails,
62
+ },
63
+ ];
64
+
65
+ const query = useQuery<
66
+ { steps: Step[]; canBeUsedWithTrails: boolean },
67
+ Error
68
+ >({
69
+ queryKey,
64
70
  queryFn: async () => {
65
71
  const response = await marketplaceClient.generateBuyTransaction({
66
72
  chainId,
@@ -85,5 +91,39 @@ export function useMarketTransactionSteps({
85
91
  };
86
92
  },
87
93
  enabled: enabled && !!buyer,
94
+ retry: false,
88
95
  });
96
+
97
+ // Abort and refetch every 3 seconds until we have data
98
+ useEffect(() => {
99
+ if (
100
+ !query.data &&
101
+ enabled &&
102
+ buyer &&
103
+ query.fetchStatus === 'fetching' &&
104
+ !query.isError
105
+ ) {
106
+ const intervalId = setInterval(() => {
107
+ // Cancel all queries with this key
108
+ queryClient.cancelQueries({ queryKey });
109
+
110
+ query.refetch();
111
+ }, 3000);
112
+
113
+ return () => {
114
+ clearInterval(intervalId);
115
+ };
116
+ }
117
+ }, [
118
+ query.data,
119
+ enabled,
120
+ buyer,
121
+ query.fetchStatus,
122
+ query.isError,
123
+ query,
124
+ queryClient,
125
+ queryKey,
126
+ ]);
127
+
128
+ return query;
89
129
  }