@0xsequence/marketplace-sdk 0.5.6 → 0.6.0

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 (240) hide show
  1. package/dist/chunk-2J7JIOW5.js +2 -0
  2. package/dist/chunk-2J7JIOW5.js.map +1 -0
  3. package/dist/{chunk-Y75XGZOB.js → chunk-5O3ZAEEX.js} +4 -2
  4. package/dist/chunk-5O3ZAEEX.js.map +1 -0
  5. package/dist/{chunk-J6F5QOW5.js → chunk-6MYDUGVO.js} +28 -77
  6. package/dist/chunk-6MYDUGVO.js.map +1 -0
  7. package/dist/chunk-6WMO5YM5.js +94 -0
  8. package/dist/chunk-6WMO5YM5.js.map +1 -0
  9. package/dist/{chunk-AIGFG26L.js → chunk-A5ICXOCZ.js} +183 -250
  10. package/dist/chunk-A5ICXOCZ.js.map +1 -0
  11. package/dist/{chunk-4YR6AIXG.js → chunk-C42WHQRT.js} +6 -8
  12. package/dist/chunk-C42WHQRT.js.map +1 -0
  13. package/dist/{chunk-ZBLU3Q22.js → chunk-DLB2EQRX.js} +2 -2
  14. package/dist/{chunk-ZBLU3Q22.js.map → chunk-DLB2EQRX.js.map} +1 -1
  15. package/dist/{chunk-YOKGP2EQ.js → chunk-FG2BBP3P.js} +1 -1
  16. package/dist/{chunk-YOKGP2EQ.js.map → chunk-FG2BBP3P.js.map} +1 -1
  17. package/dist/{chunk-UZIAX32Y.js → chunk-GMWUIMX4.js} +10 -8
  18. package/dist/{chunk-UZIAX32Y.js.map → chunk-GMWUIMX4.js.map} +1 -1
  19. package/dist/{chunk-7C7ADZ2H.js → chunk-NKHM2AIS.js} +28 -44
  20. package/dist/chunk-NKHM2AIS.js.map +1 -0
  21. package/dist/{chunk-RIGIV5XT.js → chunk-NXORBVUS.js} +10 -4
  22. package/dist/chunk-NXORBVUS.js.map +1 -0
  23. package/dist/{chunk-7FN62HOP.js → chunk-UMYRZJVY.js} +11 -3
  24. package/dist/chunk-UMYRZJVY.js.map +1 -0
  25. package/dist/{chunk-E2V2BMF6.js → chunk-UZ3GJXBR.js} +2979 -3037
  26. package/dist/chunk-UZ3GJXBR.js.map +1 -0
  27. package/dist/{chunk-6YHHCGGY.js → chunk-VPJHNXZ2.js} +50 -74
  28. package/dist/chunk-VPJHNXZ2.js.map +1 -0
  29. package/dist/{create-config-CtFGrwXc.d.ts → create-config-CILyA_Hy.d.ts} +1 -1
  30. package/dist/index-BwDj_3at.d.ts +72 -0
  31. package/dist/index.css +12 -6
  32. package/dist/index.d.ts +7 -6
  33. package/dist/index.js +175 -85
  34. package/dist/react/_internal/api/index.d.ts +2 -2
  35. package/dist/react/_internal/databeat/index.css.map +1 -1
  36. package/dist/react/_internal/databeat/index.js +9 -8
  37. package/dist/react/_internal/index.d.ts +5 -5
  38. package/dist/react/_internal/index.js +2 -2
  39. package/dist/react/_internal/wagmi/index.d.ts +2 -2
  40. package/dist/react/_internal/wagmi/index.js +1 -1
  41. package/dist/react/hooks/index.css.map +1 -1
  42. package/dist/react/hooks/index.d.ts +10 -79
  43. package/dist/react/hooks/index.js +10 -10
  44. package/dist/react/hooks/options/index.d.ts +8 -0
  45. package/dist/react/hooks/options/index.js +17 -0
  46. package/dist/react/hooks/options/index.js.map +1 -0
  47. package/dist/react/index.css +52 -35
  48. package/dist/react/index.css.map +1 -1
  49. package/dist/react/index.d.ts +6 -5
  50. package/dist/react/index.js +19 -14
  51. package/dist/react/ssr/index.d.ts +1 -0
  52. package/dist/react/ssr/index.js +10 -2
  53. package/dist/react/ssr/index.js.map +1 -1
  54. package/dist/react/ui/components/collectible-card/index.css +52 -35
  55. package/dist/react/ui/components/collectible-card/index.css.map +1 -1
  56. package/dist/react/ui/components/collectible-card/index.d.ts +4 -3
  57. package/dist/react/ui/components/collectible-card/index.js +14 -12
  58. package/dist/react/ui/components/marketplace-logos/index.d.ts +1 -1
  59. package/dist/react/ui/components/marketplace-logos/index.js +1 -1
  60. package/dist/react/ui/icons/index.css.map +1 -1
  61. package/dist/react/ui/icons/index.js +1 -1
  62. package/dist/react/ui/index.css +52 -35
  63. package/dist/react/ui/index.css.map +1 -1
  64. package/dist/react/ui/index.d.ts +2 -2
  65. package/dist/react/ui/index.js +14 -12
  66. package/dist/react/ui/modals/_internal/components/actionModal/index.css +48 -48
  67. package/dist/react/ui/modals/_internal/components/actionModal/index.css.map +1 -1
  68. package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +2 -2
  69. package/dist/react/ui/modals/_internal/components/actionModal/index.js +9 -8
  70. package/dist/react/ui/styles/index.css.map +1 -1
  71. package/dist/{sdk-config-xWkdBdrL.d.ts → sdk-config-Bs3H_le_.d.ts} +1 -0
  72. package/dist/{services-Cled3TJr.d.ts → services-C3lzi1sL.d.ts} +1 -1
  73. package/dist/styles/index.css +12 -6
  74. package/dist/styles/index.css.map +1 -1
  75. package/dist/styles/index.d.ts +3 -2
  76. package/dist/styles/index.js +3 -1
  77. package/dist/types/index.d.ts +1 -1
  78. package/dist/types/index.js +2 -2
  79. package/dist/{types-C4oGsbnK.d.ts → types-CPl0DH-A.d.ts} +2 -2
  80. package/dist/utils/abi/index.js +5 -5
  81. package/dist/utils/index.d.ts +10 -9
  82. package/dist/utils/index.js +13 -11
  83. package/package.json +19 -15
  84. package/src/consts.ts +2 -0
  85. package/src/react/__tests__/provider.test.tsx +4 -4
  86. package/src/react/_internal/api/__mocks__/indexer.msw.ts +5 -5
  87. package/src/react/_internal/api/__mocks__/metadata.msw.ts +2 -2
  88. package/src/react/_internal/api/zod-schema.ts +2 -2
  89. package/src/react/_internal/databeat/index.ts +11 -3
  90. package/src/react/_internal/types.ts +2 -2
  91. package/src/react/_internal/wagmi/__tests__/create-config.test.ts +6 -6
  92. package/src/react/_internal/wagmi/create-config.ts +11 -2
  93. package/src/react/_internal/wallet/__tests__/wallet.test.ts +343 -0
  94. package/src/react/_internal/wallet/useWallet.ts +22 -15
  95. package/src/react/_internal/wallet/wallet.ts +17 -11
  96. package/src/react/hooks/__tests__/useAutoSelectFeeOption.test.tsx +8 -12
  97. package/src/react/hooks/__tests__/useBalanceOfCollectible.test.tsx +6 -13
  98. package/src/react/hooks/__tests__/useCancelOrder.test.tsx +59 -155
  99. package/src/react/hooks/__tests__/useCancelTransactionSteps.test.tsx +21 -20
  100. package/src/react/hooks/__tests__/useCollectible.test.tsx +6 -7
  101. package/src/react/hooks/__tests__/useCollection.test.tsx +5 -6
  102. package/src/react/hooks/__tests__/useCollectionBalanceDetails.test.tsx +8 -16
  103. package/src/react/hooks/__tests__/useCollectionDetails.test.tsx +7 -6
  104. package/src/react/hooks/__tests__/useCollectionDetailsPolling.test.tsx +8 -12
  105. package/src/react/hooks/__tests__/useComparePrices.test.tsx +1 -2
  106. package/src/react/hooks/__tests__/useConvertPriceToUSD.test.tsx +2 -3
  107. package/src/react/hooks/__tests__/useCountListingsForCollectible.test.tsx +4 -5
  108. package/src/react/hooks/__tests__/useCountOfCollectables.test.tsx +6 -7
  109. package/src/react/hooks/__tests__/useCountOffersForCollectible.test.tsx +4 -5
  110. package/src/react/hooks/__tests__/useCurrencies.test.tsx +3 -4
  111. package/src/react/hooks/__tests__/useCurrency.test.tsx +4 -6
  112. package/src/react/hooks/__tests__/useCurrencyBalance.test.tsx +78 -84
  113. package/src/react/hooks/__tests__/useFilters.test.tsx +5 -6
  114. package/src/react/hooks/__tests__/useFloorOrder.test.tsx +5 -6
  115. package/src/react/hooks/__tests__/useGenerateBuyTransaction.test.tsx +6 -7
  116. package/src/react/hooks/__tests__/useGenerateCancelTransaction.test.tsx +11 -67
  117. package/src/react/hooks/__tests__/useGenerateListingTransaction.test.tsx +6 -17
  118. package/src/react/hooks/__tests__/useGenerateOfferTransaction.test.tsx +6 -16
  119. package/src/react/hooks/__tests__/useGenerateSellTransaction.test.tsx +7 -17
  120. package/src/react/hooks/__tests__/useHighestOffer.test.tsx +6 -7
  121. package/src/react/hooks/__tests__/useListBalances.test.tsx +4 -9
  122. package/src/react/hooks/__tests__/useListCollectibleActivities.test.tsx +5 -11
  123. package/src/react/hooks/__tests__/useListCollectibles.test.tsx +6 -7
  124. package/src/react/hooks/__tests__/useListCollectiblesPaginated.test.tsx +2 -3
  125. package/src/react/hooks/__tests__/useListCollectionActivities.test.tsx +6 -12
  126. package/src/react/hooks/__tests__/useListCollections.test.tsx +5 -14
  127. package/src/react/hooks/__tests__/useListListingsForCollectible.test.tsx +6 -7
  128. package/src/react/hooks/__tests__/useListOffersForCollectible.test.tsx +6 -7
  129. package/src/react/hooks/__tests__/useLowestListing.test.tsx +6 -7
  130. package/src/react/hooks/__tests__/useMarketplaceConfig.test.tsx +5 -14
  131. package/src/react/hooks/__tests__/useRoyaltyPercentage.test.tsx +46 -78
  132. package/src/react/hooks/options/__mocks__/marketplaceConfig.msw.ts +9 -4
  133. package/src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx +3 -4
  134. package/src/react/hooks/options/collectionOptions.ts +42 -0
  135. package/src/react/hooks/options/index.ts +2 -0
  136. package/src/react/hooks/useCancelOrder.tsx +3 -3
  137. package/src/react/hooks/useCancelTransactionSteps.tsx +11 -11
  138. package/src/react/hooks/useCollection.tsx +6 -37
  139. package/src/react/hooks/useCollectionBalanceDetails.tsx +3 -3
  140. package/src/react/hooks/useCollectionDetailsPolling.tsx +1 -1
  141. package/src/react/hooks/useCurrencies.tsx +1 -1
  142. package/src/react/hooks/useCurrencyBalance.tsx +4 -5
  143. package/src/react/hooks/useGenerateListingTransaction.tsx +1 -1
  144. package/src/react/hooks/useGenerateOfferTransaction.tsx +1 -1
  145. package/src/react/hooks/useGetReceiptFromHash.tsx +1 -1
  146. package/src/react/hooks/useListCollectibleActivities.tsx +1 -1
  147. package/src/react/hooks/useListCollectionActivities.tsx +1 -1
  148. package/src/react/hooks/useRoyaltyPercentage.tsx +16 -8
  149. package/src/react/index.ts +1 -0
  150. package/src/react/provider.tsx +2 -2
  151. package/src/react/ssr/__tests__/create-ssr-client.test.ts +97 -0
  152. package/src/react/ssr/create-ssr-client.ts +1 -1
  153. package/src/react/ui/components/_internals/action-button/ActionButton.tsx +3 -3
  154. package/src/react/ui/components/_internals/action-button/components/ActionButtonBody.tsx +2 -2
  155. package/src/react/ui/components/_internals/action-button/components/NonOwnerActions.tsx +4 -4
  156. package/src/react/ui/components/_internals/action-button/components/OwnerActions.tsx +2 -2
  157. package/src/react/ui/components/_internals/action-button/hooks/useActionButtonLogic.ts +1 -1
  158. package/src/react/ui/components/_internals/custom-select/__tests__/CustomSelect.test.tsx +2 -7
  159. package/src/react/ui/components/collectible-card/CollectibleCard.tsx +33 -7
  160. package/src/react/ui/components/collectible-card/Footer.tsx +47 -8
  161. package/src/react/ui/components/collectible-card/styles.css.ts +26 -2
  162. package/src/react/ui/components/marketplace-logos/marketplace-logos.tsx +1 -1
  163. package/src/react/ui/icons/index.ts +2 -5
  164. package/src/react/ui/{icons/DiamondEye.tsx → images/marketplaces/LooksRare.tsx} +1 -1
  165. package/src/react/ui/modals/BuyModal/__tests__/Modal.test.tsx +10 -11
  166. package/src/react/ui/modals/BuyModal/hooks/__tests__/useBuyCollectable.test.tsx +343 -0
  167. package/src/react/ui/modals/BuyModal/hooks/__tests__/useCheckoutOptions.test.tsx +8 -31
  168. package/src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx +4 -4
  169. package/src/react/ui/modals/BuyModal/hooks/__tests__/useLoadData.test.tsx +9 -36
  170. package/src/react/ui/modals/BuyModal/hooks/useCheckoutOptions.ts +3 -3
  171. package/src/react/ui/modals/BuyModal/hooks/useLoadData.ts +1 -1
  172. package/src/react/ui/modals/BuyModal/modals/Modal1155.tsx +25 -15
  173. package/src/react/ui/modals/BuyModal/modals/__tests__/CheckoutModal.test.tsx +2 -2
  174. package/src/react/ui/modals/BuyModal/modals/__tests__/Modal1155.test.tsx +209 -242
  175. package/src/react/ui/modals/CreateListingModal/Modal.tsx +3 -2
  176. package/src/react/ui/modals/CreateListingModal/__tests__/Modal.test.tsx +5 -11
  177. package/src/react/ui/modals/CreateListingModal/hooks/useGetTokenApproval.ts +1 -1
  178. package/src/react/ui/modals/CreateListingModal/index.tsx +1 -1
  179. package/src/react/ui/modals/MakeOfferModal/Modal.tsx +1 -1
  180. package/src/react/ui/modals/MakeOfferModal/__tests__/Modal.test.tsx +46 -49
  181. package/src/react/ui/modals/SellModal/Modal.tsx +1 -0
  182. package/src/react/ui/modals/SellModal/__tests__/Modal.test.tsx +9 -28
  183. package/src/react/ui/modals/SellModal/hooks/useGetTokenApproval.tsx +2 -2
  184. package/src/react/ui/modals/SuccessfulPurchaseModal/__tests__/Modal.test.tsx +3 -3
  185. package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +4 -4
  186. package/src/react/ui/modals/_internal/components/actionModal/store.ts +1 -1
  187. package/src/react/ui/modals/_internal/components/alertMessage/index.tsx +2 -3
  188. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/__tests__/index.test.tsx +4 -4
  189. package/src/react/ui/modals/_internal/components/expirationDateSelect/index.tsx +1 -1
  190. package/src/react/ui/modals/_internal/components/priceInput/__tests__/index.test.tsx +1 -8
  191. package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +9 -5
  192. package/src/react/ui/modals/_internal/components/switchChainModal/__tests__/SwitchChainModal.test.tsx +4 -10
  193. package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +2 -2
  194. package/src/react/ui/modals/_internal/components/switchChainModal/store.ts +1 -1
  195. package/src/react/ui/modals/_internal/components/transaction-footer/index.tsx +9 -3
  196. package/src/react/ui/modals/_internal/components/transaction-footer/transactionFooter.css.ts +11 -0
  197. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +8 -7
  198. package/src/react/ui/modals/_internal/components/transactionStatusModal/__tests__/TransactionStatusModal.test.tsx +4 -9
  199. package/src/react/ui/modals/_internal/components/transactionStatusModal/__tests__/utils.test.ts +3 -3
  200. package/src/react/ui/modals/_internal/components/transactionStatusModal/hooks/useTransactionStatus.ts +4 -4
  201. package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +1 -1
  202. package/src/react/ui/modals/modal-provider.tsx +2 -2
  203. package/src/types/sdk-config.ts +1 -0
  204. package/src/utils/__tests__/address.test.ts +1 -1
  205. package/src/utils/__tests__/getMarketplaceDetails.test.ts +4 -4
  206. package/src/utils/getMarketplaceDetails.ts +7 -7
  207. package/src/utils/index.ts +1 -1
  208. package/src/utils/networkconfigToWagmiChain.ts +17 -0
  209. package/src/utils/price.ts +8 -0
  210. package/test/const.ts +35 -0
  211. package/test/globalSetup.ts +15 -0
  212. package/test/index.ts +1 -0
  213. package/{src/react/_internal/test → test}/mocks/wallet.ts +5 -5
  214. package/test/setup.ts +20 -0
  215. package/test/test-utils.tsx +157 -0
  216. package/tsconfig.json +7 -1
  217. package/tsconfig.tsbuildinfo +1 -1
  218. package/vitest.config.js +5 -3
  219. package/dist/chunk-4YR6AIXG.js.map +0 -1
  220. package/dist/chunk-6YHHCGGY.js.map +0 -1
  221. package/dist/chunk-7C7ADZ2H.js.map +0 -1
  222. package/dist/chunk-7FN62HOP.js.map +0 -1
  223. package/dist/chunk-AIGFG26L.js.map +0 -1
  224. package/dist/chunk-E2V2BMF6.js.map +0 -1
  225. package/dist/chunk-J6F5QOW5.js.map +0 -1
  226. package/dist/chunk-RIGIV5XT.js.map +0 -1
  227. package/dist/chunk-Y75XGZOB.js.map +0 -1
  228. package/src/react/_internal/test/mocks/publicClient.ts +0 -39
  229. package/src/react/_internal/test/mocks/wagmi.ts +0 -61
  230. package/src/react/_internal/test/setup.ts +0 -28
  231. package/src/react/_internal/test-utils.tsx +0 -97
  232. package/src/react/ui/icons/ArrowUp.tsx +0 -32
  233. package/src/react/ui/icons/InventoryIcon.tsx +0 -44
  234. package/src/react/ui/icons/MinusIcon.tsx +0 -34
  235. package/src/react/ui/icons/PlusIcon.tsx +0 -32
  236. package/src/react/ui/icons/PositiveCircleIcon.tsx +0 -38
  237. package/src/react/ui/modals/BuyModal/hooks/__tests__/useBuyCollectable.test.tsx.bak +0 -379
  238. package/src/utils/__tests__/get-public-rpc-client.test.ts +0 -111
  239. package/src/utils/get-public-rpc-client.ts +0 -41
  240. /package/src/react/ui/icons/{Bell.tsx → BellIcon.tsx} +0 -0
@@ -1,9 +1,9 @@
1
- import { queryOptions, useQuery } from '@tanstack/react-query';
2
- import type { Hex } from 'viem';
1
+ import { queryOptions, skipToken, useQuery } from '@tanstack/react-query';
2
+ import type { Hex, PublicClient } from 'viem';
3
3
  import { getContract } from 'viem';
4
+ import { usePublicClient } from 'wagmi';
4
5
  import { z } from 'zod';
5
6
  import { EIP2981_ABI } from '../../utils';
6
- import { getPublicRpcClient } from '../../utils/get-public-rpc-client';
7
7
  import {
8
8
  AddressSchema,
9
9
  ChainIdSchema,
@@ -20,9 +20,11 @@ const UseRoyaletyPercentageSchema = z.object({
20
20
 
21
21
  type UseRoyaletyPercentageArgs = z.infer<typeof UseRoyaletyPercentageSchema>;
22
22
 
23
- const fetchRoyaletyPercentage = async (args: UseRoyaletyPercentageArgs) => {
23
+ const fetchRoyaletyPercentage = async (
24
+ args: UseRoyaletyPercentageArgs,
25
+ publicClient: PublicClient,
26
+ ) => {
24
27
  const parsedArgs = UseRoyaletyPercentageSchema.parse(args);
25
- const publicClient = getPublicRpcClient(parsedArgs.chainId);
26
28
 
27
29
  const contract = getContract({
28
30
  address: parsedArgs.collectionAddress as Hex,
@@ -43,13 +45,19 @@ const fetchRoyaletyPercentage = async (args: UseRoyaletyPercentageArgs) => {
43
45
  }
44
46
  };
45
47
 
46
- export const royaletyPercentageOptions = (args: UseRoyaletyPercentageArgs) =>
48
+ export const royaletyPercentageOptions = (
49
+ args: UseRoyaletyPercentageArgs,
50
+ publicClient?: PublicClient,
51
+ ) =>
47
52
  queryOptions({
48
53
  ...args.query,
49
54
  queryKey: [...collectableKeys.royaltyPercentage, args],
50
- queryFn: () => fetchRoyaletyPercentage(args),
55
+ queryFn: publicClient
56
+ ? () => fetchRoyaletyPercentage(args, publicClient)
57
+ : skipToken,
51
58
  });
52
59
 
53
60
  export const useRoyaltyPercentage = (args: UseRoyaletyPercentageArgs) => {
54
- return useQuery(royaletyPercentageOptions(args));
61
+ const publicClient = usePublicClient({ chainId: Number(args.chainId) });
62
+ return useQuery(royaletyPercentageOptions(args, publicClient));
55
63
  };
@@ -1,5 +1,6 @@
1
1
  export * from './provider';
2
2
  export * from './hooks';
3
+ export * from './hooks/options';
3
4
  export * from './_internal/api/get-query-client';
4
5
  export * from './_internal/wagmi/create-config';
5
6
  export * from './ui/index';
@@ -4,9 +4,9 @@ import { QueryClientProvider } from '@tanstack/react-query';
4
4
  import { createContext } from 'react';
5
5
  import '@0xsequence/design-system/styles.css';
6
6
  import type { SdkConfig } from '../types';
7
- import { PROVIDER_ID } from './_internal/get-provider';
8
- import { getQueryClient } from './_internal/api/get-query-client';
9
7
  import { InvalidProjectAccessKeyError } from '../utils/_internal/error/config';
8
+ import { getQueryClient } from './_internal/api/get-query-client';
9
+ import { PROVIDER_ID } from './_internal/get-provider';
10
10
 
11
11
  export const MarketplaceSdkContext = createContext({} as SdkConfig);
12
12
 
@@ -0,0 +1,97 @@
1
+ import { QueryClient } from '@tanstack/react-query';
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
3
+ import type { SdkConfig } from '../../../types';
4
+ import { mockConfig } from '../../hooks/options/__mocks__/marketplaceConfig.msw';
5
+ import { createSSRClient } from '../create-ssr-client';
6
+
7
+ vi.mock('wagmi', () => ({
8
+ cookieToInitialState: vi.fn().mockReturnValue({
9
+ data: { account: { address: '0x123' } },
10
+ }),
11
+ }));
12
+
13
+ describe('createSSRClient', () => {
14
+ let queryClient: QueryClient;
15
+ let config: SdkConfig;
16
+
17
+ beforeEach(() => {
18
+ // Reset QueryClient
19
+ queryClient = new QueryClient({
20
+ defaultOptions: {
21
+ queries: {
22
+ retry: false,
23
+ },
24
+ },
25
+ });
26
+
27
+ // Setup basic config
28
+ config = {
29
+ projectId: 'test-project',
30
+ projectAccessKey: 'test-key',
31
+ _internal: {
32
+ builderEnv: 'production',
33
+ },
34
+ };
35
+ });
36
+
37
+ it('should create SSR client with proper methods', () => {
38
+ const client = createSSRClient({
39
+ cookie: 'test-cookie',
40
+ config,
41
+ queryClient,
42
+ });
43
+
44
+ expect(client).toHaveProperty('getInitialState');
45
+ expect(client).toHaveProperty('getMarketplaceConfig');
46
+ expect(client).toHaveProperty('config');
47
+ expect(typeof client.getInitialState).toBe('function');
48
+ expect(typeof client.getMarketplaceConfig).toBe('function');
49
+ });
50
+
51
+ it('should fetch marketplace config successfully', async () => {
52
+ const client = createSSRClient({
53
+ cookie: 'test-cookie',
54
+ config,
55
+ queryClient,
56
+ });
57
+
58
+ const marketplaceConfig = await client.getMarketplaceConfig();
59
+
60
+ expect(marketplaceConfig).toBeDefined();
61
+ expect(marketplaceConfig).toMatchObject({
62
+ publisherId: mockConfig.publisherId,
63
+ title: mockConfig.title,
64
+ collections: expect.arrayContaining([
65
+ expect.objectContaining({
66
+ address: expect.any(String),
67
+ chainId: expect.any(Number),
68
+ }),
69
+ ]),
70
+ });
71
+ });
72
+
73
+ it('should get initial state with wagmi configuration', async () => {
74
+ const client = createSSRClient({
75
+ cookie: 'test-cookie',
76
+ config,
77
+ queryClient,
78
+ });
79
+
80
+ const state = await client.getInitialState();
81
+
82
+ expect(state).toHaveProperty('wagmi');
83
+ expect(state.wagmi).toEqual({
84
+ data: { account: { address: '0x123' } },
85
+ });
86
+ });
87
+
88
+ it('should preserve provided config in the client', () => {
89
+ const client = createSSRClient({
90
+ cookie: 'test-cookie',
91
+ config,
92
+ queryClient,
93
+ });
94
+
95
+ expect(client.config).toEqual(config);
96
+ });
97
+ });
@@ -1,8 +1,8 @@
1
+ import type { QueryClient } from '@tanstack/react-query';
1
2
  import { type State, cookieToInitialState } from 'wagmi';
2
3
  import type { SdkConfig } from '../../types/sdk-config';
3
4
  import { createWagmiConfig } from '../_internal/wagmi/create-config';
4
5
  import { marketplaceConfigOptions } from '../hooks/options/marketplaceConfigOptions';
5
- import type { QueryClient } from '@tanstack/react-query';
6
6
 
7
7
  type InitSSRClientArgs = {
8
8
  cookie: string;
@@ -3,10 +3,10 @@
3
3
  import { observer } from '@legendapp/state/react';
4
4
  import type { Hex } from 'viem';
5
5
  import type { Order, OrderbookKind } from '../../../../_internal';
6
- import type { CollectibleCardAction } from './types';
7
- import { useActionButtonLogic } from './hooks/useActionButtonLogic';
8
- import { OwnerActions } from './components/OwnerActions';
9
6
  import { NonOwnerActions } from './components/NonOwnerActions';
7
+ import { OwnerActions } from './components/OwnerActions';
8
+ import { useActionButtonLogic } from './hooks/useActionButtonLogic';
9
+ import type { CollectibleCardAction } from './types';
10
10
 
11
11
  type ActionButtonProps = {
12
12
  chainId: string;
@@ -1,9 +1,9 @@
1
1
  import { Button } from '@0xsequence/design-system';
2
- import { useAccount } from 'wagmi';
3
2
  import { useOpenConnectModal } from '@0xsequence/kit';
4
- import type { CollectibleCardAction } from '../types';
3
+ import { useAccount } from 'wagmi';
5
4
  import { setPendingAction } from '../store';
6
5
  import { actionButton } from '../styles.css';
6
+ import type { CollectibleCardAction } from '../types';
7
7
 
8
8
  type ActionButtonBodyProps = {
9
9
  label: 'Buy now' | 'Sell' | 'Make an offer' | 'Create listing' | 'Transfer';
@@ -1,11 +1,11 @@
1
1
  import type { Hex } from 'viem';
2
+ import { InvalidStepError } from '../../../../../../utils/_internal/error/transaction';
2
3
  import type { Order, OrderbookKind } from '../../../../../_internal';
3
- import { CollectibleCardAction } from '../types';
4
- import { ActionButtonBody } from './ActionButtonBody';
4
+ import SvgCartIcon from '../../../../icons/CartIcon';
5
5
  import { useBuyModal } from '../../../../modals/BuyModal';
6
6
  import { useMakeOfferModal } from '../../../../modals/MakeOfferModal';
7
- import { InvalidStepError } from '../../../../../../utils/_internal/error/transaction';
8
- import SvgCartIcon from '../../../../icons/CartIcon';
7
+ import { CollectibleCardAction } from '../types';
8
+ import { ActionButtonBody } from './ActionButtonBody';
9
9
 
10
10
  type NonOwnerActionsProps = {
11
11
  action: CollectibleCardAction;
@@ -1,10 +1,10 @@
1
1
  import type { Hex } from 'viem';
2
2
  import type { Order, OrderbookKind } from '../../../../../_internal';
3
- import { CollectibleCardAction } from '../types';
4
- import { ActionButtonBody } from './ActionButtonBody';
5
3
  import { useCreateListingModal } from '../../../../modals/CreateListingModal';
6
4
  import { useSellModal } from '../../../../modals/SellModal';
7
5
  import { useTransferModal } from '../../../../modals/TransferModal';
6
+ import { CollectibleCardAction } from '../types';
7
+ import { ActionButtonBody } from './ActionButtonBody';
8
8
 
9
9
  type OwnerActionsProps = {
10
10
  action: CollectibleCardAction;
@@ -1,11 +1,11 @@
1
1
  import { useEffect } from 'react';
2
2
  import { useAccount } from 'wagmi';
3
- import { CollectibleCardAction } from '../types';
4
3
  import {
5
4
  actionButtonStore,
6
5
  clearPendingAction,
7
6
  executePendingActionIfExists,
8
7
  } from '../store';
8
+ import { CollectibleCardAction } from '../types';
9
9
 
10
10
  type UseActionButtonLogicProps = {
11
11
  tokenId: string;
@@ -1,11 +1,6 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
1
+ import { cleanup, fireEvent, render, screen } from '@test';
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
3
  import { CustomSelect, type SelectItem } from '../CustomSelect';
3
- import {
4
- cleanup,
5
- render,
6
- screen,
7
- fireEvent,
8
- } from '../../../../../_internal/test-utils';
9
4
 
10
5
  describe('CustomSelect', () => {
11
6
  const mockItems: SelectItem[] = [
@@ -10,8 +10,8 @@ import type {
10
10
  OrderbookKind,
11
11
  } from '../../../_internal';
12
12
  import { useCurrency } from '../../../hooks';
13
- import SvgDiamondEyeIcon from '../../icons/DiamondEye';
14
13
  import ChessTileImage from '../../images/chess-tile.png';
14
+ import SvgDiamondEyeIcon from '../../images/marketplaces/LooksRare';
15
15
  import { ActionButton } from '../_internals/action-button/ActionButton';
16
16
  import { CollectibleCardAction } from '../_internals/action-button/types';
17
17
  import { Footer } from './Footer';
@@ -60,6 +60,7 @@ type CollectibleCardProps = {
60
60
  lowestListing: CollectibleOrder | undefined;
61
61
  onCollectibleClick?: (tokenId: string) => void;
62
62
  onOfferClick?: ({ order }: { order?: Order }) => void;
63
+ imageSrcPrefixUrl?: string;
63
64
  balance?: string;
64
65
  cardLoading?: boolean;
65
66
  /**
@@ -93,10 +94,12 @@ export function CollectibleCard({
93
94
  balance,
94
95
  cardLoading,
95
96
  onCannotPerformAction,
97
+ imageSrcPrefixUrl,
96
98
  }: CollectibleCardProps) {
97
99
  const collectibleMetadata = lowestListing?.metadata;
98
100
  const highestOffer = lowestListing?.offer;
99
101
  const [imageLoadingError, setImageLoadingError] = useState(false);
102
+ const [imageLoading, setImageLoading] = useState(true);
100
103
 
101
104
  const { data: lowestListingCurrency } = useCurrency({
102
105
  chainId,
@@ -122,6 +125,7 @@ export function CollectibleCard({
122
125
  const name = collectibleMetadata?.name;
123
126
  const image = collectibleMetadata?.image;
124
127
  const externalUrl = collectibleMetadata?.external_url;
128
+ const proxiedImage = `${imageSrcPrefixUrl}/${image}`;
125
129
 
126
130
  return (
127
131
  <Box
@@ -169,12 +173,34 @@ export function CollectibleCard({
169
173
  />
170
174
  )}
171
175
 
172
- <img
173
- src={imageLoadingError ? ChessTileImage : image || ChessTileImage}
174
- alt={name}
175
- className={collectibleImage}
176
- onError={() => setImageLoadingError(true)}
177
- />
176
+ <Box position="relative">
177
+ {imageLoading && (
178
+ <Skeleton
179
+ position="absolute"
180
+ top="0"
181
+ left="0"
182
+ width="full"
183
+ height="full"
184
+ zIndex="10"
185
+ style={{ borderRadius: 0 }}
186
+ />
187
+ )}
188
+ <img
189
+ src={
190
+ imageLoadingError
191
+ ? ChessTileImage
192
+ : (imageSrcPrefixUrl ? proxiedImage : image) || ChessTileImage
193
+ }
194
+ alt={name}
195
+ className={
196
+ imageLoading
197
+ ? collectibleImage.loading
198
+ : collectibleImage.loaded
199
+ }
200
+ onError={() => setImageLoadingError(true)}
201
+ onLoad={() => setImageLoading(false)}
202
+ />
203
+ </Box>
178
204
 
179
205
  <Footer
180
206
  name={name || ''}
@@ -1,15 +1,41 @@
1
- import { Box, IconButton, Image, Text } from '@0xsequence/design-system';
1
+ import {
2
+ Box,
3
+ ChevronLeftIcon,
4
+ ChevronRightIcon,
5
+ IconButton,
6
+ Image,
7
+ Text,
8
+ } from '@0xsequence/design-system';
2
9
  import { formatUnits } from 'viem';
3
10
  import { ContractType, type Currency, type Order } from '../../../_internal';
4
- import SvgBellIcon from '../../icons/Bell';
5
- import { footer, offerBellButton } from './styles.css';
11
+ import SvgBellIcon from '../../icons/BellIcon';
12
+ import { footer, footerPriceChevron, offerBellButton } from './styles.css';
6
13
 
7
- const formatPrice = (amount: string, currency: Currency): string => {
14
+ const OVERFLOW_PRICE = 100000000;
15
+ const UNDERFLOW_PRICE = 0.0001;
16
+
17
+ const formatPrice = (amount: string, currency: Currency): React.ReactNode => {
8
18
  const formattedPrice = formatUnits(BigInt(amount), currency.decimals);
9
19
  const numericPrice = Number.parseFloat(formattedPrice);
10
20
 
11
- if (numericPrice < 0.0001) {
12
- return `< 0.0001 ${currency.symbol}`;
21
+ if (numericPrice < UNDERFLOW_PRICE) {
22
+ return (
23
+ <Box display="flex" alignItems="center">
24
+ <ChevronLeftIcon className={footerPriceChevron} />
25
+ <Text>{`${UNDERFLOW_PRICE} ${currency.symbol}`}</Text>
26
+ </Box>
27
+ );
28
+ }
29
+
30
+ if (numericPrice > OVERFLOW_PRICE) {
31
+ return (
32
+ <Box display="flex" alignItems="center">
33
+ <ChevronRightIcon className={footerPriceChevron} />
34
+ <Text>{`${OVERFLOW_PRICE.toLocaleString('en-US', {
35
+ maximumFractionDigits: 2,
36
+ })} ${currency.symbol}`}</Text>
37
+ </Box>
38
+ );
13
39
  }
14
40
 
15
41
  const maxDecimals = numericPrice < 0.01 ? 6 : 4;
@@ -19,7 +45,13 @@ const formatPrice = (amount: string, currency: Currency): string => {
19
45
  maximumFractionDigits: maxDecimals,
20
46
  });
21
47
 
22
- return `${formattedNumber} ${currency.symbol}`;
48
+ return (
49
+ <Box display="flex" alignItems="center" gap="1">
50
+ <Text>
51
+ {formattedNumber} {currency.symbol}
52
+ </Text>
53
+ </Box>
54
+ );
23
55
  };
24
56
 
25
57
  type FooterProps = {
@@ -100,7 +132,14 @@ export const Footer = ({
100
132
 
101
133
  <Box display="flex" alignItems="center" gap="1">
102
134
  {listed && lowestListingCurrency.imageUrl && (
103
- <Image src={lowestListingCurrency.imageUrl} width="3" height="3" />
135
+ <Image
136
+ src={lowestListingCurrency.imageUrl}
137
+ width="3"
138
+ height="3"
139
+ onError={(e) => {
140
+ e.currentTarget.style.display = 'none';
141
+ }}
142
+ />
104
143
  )}
105
144
 
106
145
  <Text
@@ -1,5 +1,5 @@
1
1
  import { atoms } from '@0xsequence/design-system';
2
- import { style } from '@vanilla-extract/css';
2
+ import { style, styleVariants } from '@vanilla-extract/css';
3
3
 
4
4
  export const collectibleCard = style([
5
5
  {
@@ -37,7 +37,7 @@ export const collectibleTileWrapper = style({
37
37
  },
38
38
  });
39
39
 
40
- export const collectibleImage = style({
40
+ const collectibleImageBase = style({
41
41
  width: '175px',
42
42
  height: '175px',
43
43
  objectFit: 'cover',
@@ -49,6 +49,22 @@ export const collectibleImage = style({
49
49
  },
50
50
  });
51
51
 
52
+ export const collectibleImage = styleVariants({
53
+ default: [collectibleImageBase],
54
+ loading: [
55
+ collectibleImageBase,
56
+ {
57
+ visibility: 'hidden',
58
+ },
59
+ ],
60
+ loaded: [
61
+ collectibleImageBase,
62
+ {
63
+ visibility: 'visible',
64
+ },
65
+ ],
66
+ });
67
+
52
68
  export const offerBellButton = style({
53
69
  width: '22px',
54
70
  height: '22px',
@@ -56,6 +72,14 @@ export const offerBellButton = style({
56
72
 
57
73
  export const footer = style([atoms({ background: 'backgroundPrimary' })]);
58
74
 
75
+ export const footerPriceChevron = style([
76
+ atoms({
77
+ width: '3',
78
+ height: '3',
79
+ color: 'text100',
80
+ }),
81
+ ]);
82
+
59
83
  export const actionWrapper = style([
60
84
  atoms({
61
85
  backdropFilter: 'blur',
@@ -1,5 +1,5 @@
1
- import { type ComponentProps, lazy, Suspense } from 'react';
2
1
  import { Image } from '@0xsequence/design-system';
2
+ import { type ComponentProps, Suspense, lazy } from 'react';
3
3
 
4
4
  /* @__PURE__ */
5
5
  const createMarketplaceLogo = (
@@ -1,7 +1,4 @@
1
+ export * from './BellIcon';
1
2
  export * from './CalendarIcon';
2
- export * from './InventoryIcon';
3
- export * from './MinusIcon';
4
- export * from './PlusIcon';
5
- export * from './ArrowUp';
3
+ export * from './CartIcon';
6
4
  export * from './InfoIcon';
7
- export * from './PositiveCircleIcon';
@@ -1,5 +1,5 @@
1
1
  import { Box, type IconProps } from '@0xsequence/design-system';
2
- import { iconVariants } from './styles.css';
2
+ import { iconVariants } from '../../icons/styles.css';
3
3
 
4
4
  const Svg = () => (
5
5
  <svg
@@ -1,18 +1,13 @@
1
- import {
2
- render,
3
- screen,
4
- cleanup,
5
- waitFor,
6
- } from '../../../../_internal/test-utils';
7
- import { describe, it, expect, vi, beforeEach } from 'vitest';
8
- import { BuyModal } from '../Modal';
9
- import { buyModal$ } from '../store';
10
- import { useLoadData } from '../hooks/useLoadData';
11
- import { useBuyCollectable } from '../hooks/useBuyCollectable';
1
+ import { cleanup, render, screen, waitFor } from '@test';
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
12
3
  import type { Mock } from 'vitest';
13
4
  import type { Order } from '../../../../_internal';
14
5
  import { MarketplaceKind } from '../../../../_internal';
15
6
  import { ContractType } from '../../../../_internal';
7
+ import { BuyModal } from '../Modal';
8
+ import { useBuyCollectable } from '../hooks/useBuyCollectable';
9
+ import { useLoadData } from '../hooks/useLoadData';
10
+ import { buyModal$ } from '../store';
16
11
 
17
12
  const mockOrder = {
18
13
  orderId: '1',
@@ -31,6 +26,10 @@ vi.mock('../hooks/useBuyCollectable', () => ({
31
26
  useBuyCollectable: vi.fn(),
32
27
  }));
33
28
 
29
+ vi.mock('@0xsequence/kit', () => ({
30
+ useWaasFeeOptions: vi.fn().mockReturnValue([]),
31
+ }));
32
+
34
33
  describe('BuyModal', () => {
35
34
  beforeEach(() => {
36
35
  vi.clearAllMocks();