@0xsequence/marketplace-sdk 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/dist/builder-types-wOwfTJpd.d.ts +73 -0
  2. package/dist/{chunk-FCF57DZI.js → chunk-7FN62HOP.js} +5 -9
  3. package/dist/chunk-7FN62HOP.js.map +1 -0
  4. package/dist/{chunk-MSTTVFVQ.js → chunk-BVXIRVEC.js} +251 -241
  5. package/dist/chunk-BVXIRVEC.js.map +1 -0
  6. package/dist/{chunk-XP3WY5AX.js → chunk-BZD2LDJJ.js} +2 -2
  7. package/dist/{chunk-XP3WY5AX.js.map → chunk-BZD2LDJJ.js.map} +1 -1
  8. package/dist/chunk-DZKPDV63.js +27 -0
  9. package/dist/chunk-DZKPDV63.js.map +1 -0
  10. package/dist/{chunk-I37CRQ4S.js → chunk-H5YWG6WN.js} +128 -88
  11. package/dist/chunk-H5YWG6WN.js.map +1 -0
  12. package/dist/{chunk-ZUEQGPLO.js → chunk-J6F5QOW5.js} +2 -2
  13. package/dist/{chunk-ZUEQGPLO.js.map → chunk-J6F5QOW5.js.map} +1 -1
  14. package/dist/{chunk-LJAB3S6U.js → chunk-TFRAOS7F.js} +22 -13
  15. package/dist/chunk-TFRAOS7F.js.map +1 -0
  16. package/dist/{chunk-5NORRVPM.js → chunk-UZIAX32Y.js} +1 -1
  17. package/dist/{chunk-5NORRVPM.js.map → chunk-UZIAX32Y.js.map} +1 -1
  18. package/dist/{chunk-MKGSGTQC.js → chunk-Y7YTLAO2.js} +3 -3
  19. package/dist/{create-config-BXvwUh55.d.ts → create-config-Bltg8Enl.d.ts} +1 -1
  20. package/dist/index.css +1 -1
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.js +10 -6
  23. package/dist/react/_internal/index.d.ts +3 -3
  24. package/dist/react/_internal/index.js +6 -6
  25. package/dist/react/_internal/wagmi/index.d.ts +2 -3
  26. package/dist/react/_internal/wagmi/index.js +1 -1
  27. package/dist/react/hooks/index.d.ts +72 -20
  28. package/dist/react/hooks/index.js +5 -7
  29. package/dist/react/index.css +1 -1
  30. package/dist/react/index.css.map +1 -1
  31. package/dist/react/index.d.ts +4 -4
  32. package/dist/react/index.js +10 -12
  33. package/dist/react/ssr/index.d.ts +54 -41
  34. package/dist/react/ssr/index.js +5 -9
  35. package/dist/react/ssr/index.js.map +1 -1
  36. package/dist/react/ui/components/collectible-card/index.css +1 -1
  37. package/dist/react/ui/components/collectible-card/index.css.map +1 -1
  38. package/dist/react/ui/components/collectible-card/index.d.ts +2 -2
  39. package/dist/react/ui/components/collectible-card/index.js +8 -8
  40. package/dist/react/ui/index.css +1 -1
  41. package/dist/react/ui/index.css.map +1 -1
  42. package/dist/react/ui/index.d.ts +2 -2
  43. package/dist/react/ui/index.js +8 -8
  44. package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +2 -2
  45. package/dist/react/ui/modals/_internal/components/actionModal/index.js +6 -6
  46. package/dist/react/ui/styles/index.d.ts +1 -1
  47. package/dist/styles/index.css +1 -1
  48. package/dist/styles/index.css.map +1 -1
  49. package/dist/styles/index.d.ts +1 -1
  50. package/dist/styles/index.js +1 -1
  51. package/dist/types/index.d.ts +1 -3
  52. package/dist/types/index.js +9 -5
  53. package/dist/{types-Yto6KrTN.d.ts → types-BY3husBh.d.ts} +1 -1
  54. package/dist/utils/index.d.ts +2 -2
  55. package/dist/utils/index.js +4 -4
  56. package/package.json +11 -10
  57. package/src/react/_internal/api/__mocks__/indexer.msw.ts +197 -0
  58. package/src/react/_internal/api/__mocks__/marketplace.msw.ts +140 -1
  59. package/src/react/_internal/api/__mocks__/metadata.msw.ts +162 -0
  60. package/src/react/_internal/test/mocks/publicClient.ts +39 -0
  61. package/src/react/_internal/test/mocks/wagmi.ts +61 -0
  62. package/src/react/_internal/test/mocks/wallet.ts +61 -0
  63. package/src/react/_internal/test/setup.ts +28 -0
  64. package/src/react/_internal/test-utils.tsx +31 -2
  65. package/src/react/_internal/wagmi/__tests__/create-config.test.ts +53 -20
  66. package/src/react/_internal/wagmi/create-config.ts +3 -4
  67. package/src/react/_internal/wagmi/embedded.ts +1 -4
  68. package/src/react/_internal/wagmi/universal.ts +1 -4
  69. package/src/react/_internal/wallet/wallet.ts +1 -0
  70. package/src/react/hooks/__tests__/useAutoSelectFeeOption.test.tsx +314 -0
  71. package/src/react/hooks/__tests__/useBalanceOfCollectible.test.tsx +148 -0
  72. package/src/react/hooks/__tests__/useCancelOrder.test.tsx +410 -0
  73. package/src/react/hooks/__tests__/useCancelTransactionSteps.test.tsx +269 -0
  74. package/src/react/hooks/__tests__/useCollectible.test.tsx +120 -0
  75. package/src/react/hooks/__tests__/useCollection.test.tsx +101 -0
  76. package/src/react/hooks/__tests__/useCollectionBalanceDetails.test.tsx +175 -0
  77. package/src/react/hooks/__tests__/useCollectionDetails.test.tsx +82 -0
  78. package/src/react/hooks/__tests__/useCollectionDetailsPolling.test.tsx +133 -0
  79. package/src/react/hooks/__tests__/useCountListingsForCollectible.test.tsx +108 -0
  80. package/src/react/hooks/__tests__/useCountOfCollectables.test.tsx +129 -0
  81. package/src/react/hooks/__tests__/useCountOffersForCollectible.test.tsx +108 -0
  82. package/src/react/hooks/__tests__/useCurrencies.test.tsx +176 -0
  83. package/src/react/hooks/__tests__/useCurrency.test.tsx +153 -0
  84. package/src/react/hooks/__tests__/useCurrencyBalance.test.tsx +111 -0
  85. package/src/react/hooks/__tests__/useFilters.test.tsx +127 -0
  86. package/src/react/hooks/__tests__/useFloorOrder.test.tsx +101 -0
  87. package/src/react/hooks/__tests__/useGenerateBuyTransaction.test.tsx +173 -0
  88. package/src/react/hooks/__tests__/useGenerateCancelTransaction.test.tsx +207 -0
  89. package/src/react/hooks/__tests__/useGenerateListingTransaction.test.tsx +207 -0
  90. package/src/react/hooks/__tests__/useGenerateOfferTransaction.test.tsx +205 -0
  91. package/src/react/hooks/__tests__/useGenerateSellTransaction.test.tsx +181 -0
  92. package/src/react/hooks/__tests__/useHighestOffer.test.tsx +118 -0
  93. package/src/react/hooks/__tests__/useListBalances.test.tsx +136 -0
  94. package/src/react/hooks/__tests__/useListCollectibleActivities.test.tsx +200 -0
  95. package/src/react/hooks/__tests__/useListCollectibles.test.tsx +232 -0
  96. package/src/react/hooks/__tests__/useListCollectionActivities.test.tsx +235 -0
  97. package/src/react/hooks/__tests__/useListCollections.test.tsx +296 -0
  98. package/src/react/hooks/__tests__/useListListingsForCollectible.test.tsx +140 -0
  99. package/src/react/hooks/__tests__/useListOffersForCollectible.test.tsx +140 -0
  100. package/src/react/hooks/__tests__/useLowestListing.test.tsx +148 -0
  101. package/src/react/hooks/__tests__/useMarketplaceConfig.test.tsx +106 -0
  102. package/src/react/hooks/__tests__/useRoyaltyPercentage.test.tsx +129 -0
  103. package/src/react/hooks/index.ts +0 -1
  104. package/src/react/hooks/options/__mocks__/marketplaceConfig.msw.ts +66 -10
  105. package/src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx +2 -11
  106. package/src/react/hooks/options/marketplaceConfigOptions.ts +8 -3
  107. package/src/react/hooks/useAutoSelectFeeOption.tsx +4 -3
  108. package/src/react/hooks/useCancelTransactionSteps.tsx +17 -9
  109. package/src/react/hooks/useCollectionDetailsPolling.tsx +1 -1
  110. package/src/react/hooks/useCurrencies.tsx +29 -28
  111. package/src/react/hooks/useFilters.tsx +69 -2
  112. package/src/react/hooks/useGenerateBuyTransaction.tsx +13 -5
  113. package/src/react/hooks/useListCollectibleActivities.tsx +1 -0
  114. package/src/react/hooks/useListCollectibles.tsx +1 -0
  115. package/src/react/hooks/useListCollectionActivities.tsx +1 -0
  116. package/src/react/hooks/useListCollections.tsx +2 -2
  117. package/src/react/ui/components/_internals/custom-select/__tests__/CustomSelect.test.tsx +6 -2
  118. package/src/react/ui/components/collectible-card/CollectibleCard.tsx +1 -1
  119. package/src/react/ui/components/collectible-card/Footer.tsx +9 -5
  120. package/src/react/ui/modals/BuyModal/Modal.tsx +9 -4
  121. package/src/react/ui/modals/BuyModal/__tests__/Modal.test.tsx +0 -1
  122. package/src/react/ui/modals/BuyModal/__tests__/store.test.ts +4 -2
  123. package/src/react/ui/modals/BuyModal/hooks/__tests__/useBuyCollectable.test.tsx +1 -24
  124. package/src/react/ui/modals/BuyModal/hooks/__tests__/useCheckoutOptions.test.tsx +152 -210
  125. package/src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx +19 -49
  126. package/src/react/ui/modals/BuyModal/hooks/useFees.ts +6 -6
  127. package/src/react/ui/modals/BuyModal/modals/Modal1155.tsx +4 -2
  128. package/src/react/ui/modals/BuyModal/modals/__tests__/Modal1155.test.tsx +161 -52
  129. package/src/react/ui/modals/BuyModal/store.ts +7 -0
  130. package/src/react/ui/modals/CreateListingModal/Modal.tsx +1 -3
  131. package/src/react/ui/modals/CreateListingModal/__tests__/Modal.test.tsx +59 -227
  132. package/src/react/ui/modals/CreateListingModal/hooks/useCreateListing.tsx +2 -1
  133. package/src/react/ui/modals/CreateListingModal/hooks/useTransactionSteps.tsx +9 -5
  134. package/src/react/ui/modals/MakeOfferModal/Modal.tsx +1 -8
  135. package/src/react/ui/modals/MakeOfferModal/__tests__/Modal.test.tsx +41 -118
  136. package/src/react/ui/modals/MakeOfferModal/hooks/useMakeOffer.tsx +2 -1
  137. package/src/react/ui/modals/MakeOfferModal/hooks/useTransactionSteps.tsx +9 -5
  138. package/src/react/ui/modals/SellModal/__tests__/Modal.test.tsx +4 -3
  139. package/src/react/ui/modals/SellModal/hooks/useGetTokenApproval.tsx +33 -31
  140. package/src/react/ui/modals/SellModal/hooks/useSell.tsx +1 -0
  141. package/src/react/ui/modals/SellModal/hooks/useTransactionSteps.tsx +9 -5
  142. package/src/react/ui/modals/SuccessfulPurchaseModal/__tests__/Modal.test.tsx +0 -1
  143. package/src/react/ui/modals/_internal/components/actionModal/ErrorModal.tsx +4 -2
  144. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/__tests__/index.test.tsx +129 -57
  145. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +1 -3
  146. package/src/react/ui/modals/_internal/components/priceInput/__tests__/index.test.tsx +1 -3
  147. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +2 -2
  148. package/src/react/ui/modals/_internal/components/transactionStatusModal/__tests__/TransactionStatusModal.test.tsx +8 -8
  149. package/src/react/ui/modals/_internal/components/transactionStatusModal/hooks/useTransactionStatus.ts +1 -0
  150. package/src/types/builder-types.ts +79 -0
  151. package/src/types/index.ts +1 -1
  152. package/src/utils/__tests__/get-public-rpc-client.test.ts +2 -0
  153. package/src/utils/getMarketplaceDetails.ts +2 -2
  154. package/tsconfig.tsbuildinfo +1 -1
  155. package/vitest.config.js +2 -1
  156. package/dist/chunk-FCF57DZI.js.map +0 -1
  157. package/dist/chunk-I37CRQ4S.js.map +0 -1
  158. package/dist/chunk-LJAB3S6U.js.map +0 -1
  159. package/dist/chunk-MSTTVFVQ.js.map +0 -1
  160. package/dist/chunk-RK6KYMZM.js +0 -18
  161. package/dist/chunk-RK6KYMZM.js.map +0 -1
  162. package/dist/marketplace-config-znEu4L0K.d.ts +0 -60
  163. package/src/react/hooks/useCurrencyOptions.tsx +0 -16
  164. package/src/types/marketplace-config.ts +0 -67
  165. /package/dist/{chunk-MKGSGTQC.js.map → chunk-Y7YTLAO2.js.map} +0 -0
@@ -4,21 +4,21 @@ import { z } from 'zod';
4
4
  import type { SdkConfig } from '../../types';
5
5
  import {
6
6
  AddressSchema,
7
- type ChainId,
8
7
  ChainIdSchema,
9
- type Currency,
10
- QueryArgSchema,
11
8
  currencyKeys,
12
9
  getMarketplaceClient,
10
+ getQueryClient,
11
+ QueryArgSchema,
13
12
  } from '../_internal';
14
13
  import { useConfig } from './useConfig';
14
+ import { marketplaceConfigOptions } from './useMarketplaceConfig';
15
15
 
16
16
  const ChainIdCoerce = ChainIdSchema.transform((val) => val.toString());
17
17
 
18
18
  const UseCurrenciesArgsSchema = z.object({
19
19
  chainId: ChainIdCoerce,
20
20
  includeNativeCurrency: z.boolean().optional().default(true),
21
- currencyOptions: z.array(AddressSchema).optional(),
21
+ collectionAddress: AddressSchema.optional(),
22
22
  query: QueryArgSchema,
23
23
  });
24
24
 
@@ -26,37 +26,40 @@ type UseCurrenciesArgs = z.input<typeof UseCurrenciesArgsSchema>;
26
26
 
27
27
  export type UseCurrenciesReturn = Awaited<ReturnType<typeof fetchCurrencies>>;
28
28
 
29
- const fetchCurrencies = async (chainId: ChainId, config: SdkConfig) => {
30
- const parsedChainId = ChainIdCoerce.parse(chainId);
31
- const marketplaceClient = getMarketplaceClient(parsedChainId, config);
32
- return marketplaceClient.listCurrencies().then((resp) =>
29
+ const fetchCurrencies = async (args: UseCurrenciesArgs, config: SdkConfig) => {
30
+ const parsedArgs = UseCurrenciesArgsSchema.parse(args);
31
+ const marketplaceClient = getMarketplaceClient(parsedArgs.chainId, config);
32
+
33
+ let currencies = await marketplaceClient.listCurrencies().then((resp) =>
33
34
  resp.currencies.map((currency) => ({
34
35
  ...currency,
35
- // TODO: remove this, when we are sure of the schema
36
36
  contractAddress: currency.contractAddress || zeroAddress,
37
37
  })),
38
38
  );
39
- };
40
39
 
41
- const selectCurrencies = (data: Currency[], args: UseCurrenciesArgs) => {
42
- const argsParsed = UseCurrenciesArgsSchema.parse(args);
40
+ if (parsedArgs.collectionAddress) {
41
+ const queryClient = getQueryClient();
42
+ const marketplaceConfig = await queryClient.fetchQuery(
43
+ marketplaceConfigOptions(config),
44
+ );
43
45
 
44
- let filteredData = data;
46
+ const currenciesOptions = marketplaceConfig.collections.find(
47
+ (collection) => collection.address === args.collectionAddress,
48
+ )?.currencyOptions;
45
49
 
46
- if (!argsParsed.includeNativeCurrency) {
47
- filteredData = filteredData.filter((currency) => !currency.nativeCurrency);
50
+ // Filter currencies based on collection currency options
51
+ if (currenciesOptions) {
52
+ currencies = currencies.filter((currency) =>
53
+ currenciesOptions.includes(currency.contractAddress),
54
+ );
55
+ }
48
56
  }
49
57
 
50
- if (argsParsed.currencyOptions) {
51
- const lowerCaseCurrencyOptions = argsParsed.currencyOptions.map((option) =>
52
- option.toLowerCase(),
53
- );
54
-
55
- filteredData = filteredData.filter((currency) =>
56
- lowerCaseCurrencyOptions.includes(currency.contractAddress.toLowerCase()),
57
- );
58
+ if (!parsedArgs.includeNativeCurrency) {
59
+ currencies = currencies.filter((currency) => !currency.nativeCurrency);
58
60
  }
59
- return filteredData;
61
+
62
+ return currencies;
60
63
  };
61
64
 
62
65
  export const currenciesOptions = (
@@ -65,15 +68,13 @@ export const currenciesOptions = (
65
68
  ) => {
66
69
  return queryOptions({
67
70
  ...args.query,
68
- queryKey: [...currencyKeys.lists, args.chainId],
69
- queryFn: () => fetchCurrencies(args.chainId, config),
70
- select: (data) => selectCurrencies(data, args),
71
+ queryKey: [...currencyKeys.lists, args],
72
+ queryFn: () => fetchCurrencies(args, config),
71
73
  enabled: args.query?.enabled,
72
74
  });
73
75
  };
74
76
 
75
77
  export const useCurrencies = (args: UseCurrenciesArgs) => {
76
78
  const config = useConfig();
77
-
78
79
  return useQuery(currenciesOptions(args, config));
79
80
  };
@@ -1,18 +1,23 @@
1
1
  import { queryOptions, useQuery } from '@tanstack/react-query';
2
2
  import { z } from 'zod';
3
- import type { SdkConfig } from '../../types';
3
+ import { FilterCondition, type SdkConfig } from '../../types';
4
4
  import {
5
5
  AddressSchema,
6
6
  ChainIdSchema,
7
7
  QueryArgSchema,
8
8
  collectableKeys,
9
9
  getMetadataClient,
10
+ getQueryClient,
10
11
  } from '../_internal';
11
12
  import { useConfig } from './useConfig';
13
+ import { marketplaceConfigOptions } from './useMarketplaceConfig';
14
+ import { compareAddress } from '../../utils';
15
+ import type { PropertyFilter } from '@0xsequence/metadata';
12
16
 
13
17
  const UseFiltersSchema = z.object({
14
18
  chainId: ChainIdSchema.pipe(z.coerce.string()),
15
19
  collectionAddress: AddressSchema,
20
+ showAllFilters: z.boolean().default(false).optional(),
16
21
  query: QueryArgSchema,
17
22
  });
18
23
 
@@ -23,12 +28,74 @@ export type UseFilterReturn = Awaited<ReturnType<typeof fetchFilters>>;
23
28
  export const fetchFilters = async (args: UseFiltersArgs, config: SdkConfig) => {
24
29
  const parsedArgs = UseFiltersSchema.parse(args);
25
30
  const metadataClient = getMetadataClient(config);
26
- return metadataClient
31
+ const filters = await metadataClient
27
32
  .tokenCollectionFilters({
28
33
  chainID: parsedArgs.chainId,
29
34
  contractAddress: parsedArgs.collectionAddress,
30
35
  })
31
36
  .then((resp) => resp.filters);
37
+
38
+ if (args.showAllFilters) return filters;
39
+
40
+ const queryClient = getQueryClient();
41
+ const marketplaceConfig = await queryClient.fetchQuery(
42
+ marketplaceConfigOptions(config),
43
+ );
44
+ const collectionFilters = marketplaceConfig.collections.find((c) =>
45
+ compareAddress(c.address, parsedArgs.collectionAddress),
46
+ )?.filterSettings;
47
+
48
+ if (!collectionFilters) return filters;
49
+
50
+ const { filterOrder, exclusions } = collectionFilters;
51
+
52
+ // Sort the filters based on the filterOrder, the filters that are not in the filterOrder are at the end
53
+ const sortedFilters = filters.toSorted((a, b) => {
54
+ const aIndex =
55
+ filterOrder.indexOf(a.name) > -1
56
+ ? filterOrder.indexOf(a.name)
57
+ : filterOrder.length;
58
+ const bIndex =
59
+ filterOrder.indexOf(b.name) > -1
60
+ ? filterOrder.indexOf(b.name)
61
+ : filterOrder.length;
62
+ return aIndex - bIndex;
63
+ });
64
+
65
+ const filteredResults = sortedFilters.reduce<PropertyFilter[]>(
66
+ (acc, filter) => {
67
+ // Check if this filter should be excluded
68
+ const exclusionRule = exclusions.find((rule) => rule.key === filter.name);
69
+
70
+ if (!exclusionRule) {
71
+ // No exclusion rule, include the filter
72
+ acc.push(filter);
73
+ return acc;
74
+ }
75
+
76
+ if (exclusionRule.condition === FilterCondition.ENTIRE_KEY) {
77
+ // Skip this filter entirely
78
+ return acc;
79
+ }
80
+
81
+ if (
82
+ exclusionRule.condition === FilterCondition.SPECIFIC_VALUE &&
83
+ exclusionRule.value
84
+ ) {
85
+ // Filter out specific values while keeping the filter
86
+ const filteredValues =
87
+ filter.values?.filter((value) => value !== exclusionRule.value) || [];
88
+ if (filteredValues.length > 0) {
89
+ acc.push({ ...filter, values: filteredValues });
90
+ }
91
+ }
92
+
93
+ return acc;
94
+ },
95
+ [],
96
+ );
97
+
98
+ return filteredResults;
32
99
  };
33
100
 
34
101
  export const filtersOptions = (args: UseFiltersArgs, config: SdkConfig) => {
@@ -1,4 +1,4 @@
1
- import { queryOptions, useQuery } from '@tanstack/react-query';
1
+ import { queryOptions, skipToken, useQuery } from '@tanstack/react-query';
2
2
  import type { Hex } from 'viem';
3
3
  import { useAccount } from 'wagmi';
4
4
  import { z } from 'zod';
@@ -64,8 +64,16 @@ export const useGenerateBuyTransaction = (
64
64
  ) => {
65
65
  const { address } = useAccount();
66
66
  const config = useConfig();
67
- return useQuery(
68
- // biome-ignore lint/style/noNonNullAssertion: <explanation>
69
- generateBuyTransactionOptions({ buyer: address!, ...args }, config),
70
- );
67
+
68
+ return useQuery({
69
+ queryKey: ['generateBuyTransaction', args],
70
+ queryFn: address
71
+ ? () => {
72
+ return fetchGenerateBuyTransaction(
73
+ { buyer: address, ...args },
74
+ config,
75
+ );
76
+ }
77
+ : skipToken,
78
+ });
71
79
  };
@@ -46,6 +46,7 @@ export const listCollectibleActivitiesOptions = (
46
46
  return queryOptions({
47
47
  queryKey: [...collectableKeys.collectibleActivities, args, config],
48
48
  queryFn: () => fetchCollectibleActivities(args, config),
49
+ enabled: args.query?.enabled ?? true,
49
50
  });
50
51
  };
51
52
 
@@ -57,6 +57,7 @@ export const listCollectiblesOptions = (
57
57
  initialPageParam: { page: 1, pageSize: 30 },
58
58
  getNextPageParam: (lastPage) =>
59
59
  lastPage.page?.more ? lastPage.page : undefined,
60
+ enabled: args.query?.enabled ?? true,
60
61
  });
61
62
  };
62
63
 
@@ -46,6 +46,7 @@ export const listCollectionActivitiesOptions = (
46
46
  return queryOptions({
47
47
  queryKey: [...collectionKeys.collectionActivities, args, config],
48
48
  queryFn: () => fetchListCollectionActivities(args, config),
49
+ enabled: args.query?.enabled ?? true,
49
50
  });
50
51
  };
51
52
 
@@ -38,11 +38,11 @@ const fetchListCollections = async (
38
38
  const collectionsByChain = marketplaceConfig.collections.reduce<
39
39
  Record<string, string[]>
40
40
  >((acc, curr) => {
41
- const { chainId, collectionAddress } = curr;
41
+ const { chainId, address } = curr;
42
42
  if (!acc[chainId]) {
43
43
  acc[chainId] = [];
44
44
  }
45
- acc[chainId].push(collectionAddress);
45
+ acc[chainId].push(address);
46
46
  return acc;
47
47
  }, {});
48
48
 
@@ -1,7 +1,11 @@
1
- import '@testing-library/jest-dom/vitest';
2
- import { render, screen, cleanup, fireEvent } from '@testing-library/react';
3
1
  import { describe, it, expect, vi, beforeEach } from 'vitest';
4
2
  import { CustomSelect, type SelectItem } from '../CustomSelect';
3
+ import {
4
+ cleanup,
5
+ render,
6
+ screen,
7
+ fireEvent,
8
+ } from '../../../../../_internal/test-utils';
5
9
 
6
10
  describe('CustomSelect', () => {
7
11
  const mockItems: SelectItem[] = [
@@ -95,7 +95,7 @@ export function CollectibleCard({
95
95
  onCannotPerformAction,
96
96
  }: CollectibleCardProps) {
97
97
  const collectibleMetadata = lowestListing?.metadata;
98
- const highestOffer = lowestListing?.offer
98
+ const highestOffer = lowestListing?.offer;
99
99
  const [imageLoadingError, setImageLoadingError] = useState(false);
100
100
 
101
101
  const { data: lowestListingCurrency } = useCurrency({
@@ -4,6 +4,14 @@ import { ContractType, type Currency, type Order } from '../../../_internal';
4
4
  import SvgBellIcon from '../../icons/Bell';
5
5
  import { footer, offerBellButton } from './styles.css';
6
6
 
7
+ const formatPrice = (amount: string, currency: Currency): string => {
8
+ const formattedPrice = formatUnits(BigInt(amount), currency.decimals);
9
+ const numericPrice = Number.parseFloat(formattedPrice);
10
+ return numericPrice < 0.0001
11
+ ? `< 0.0001 ${currency.symbol}`
12
+ : `${formattedPrice} ${currency.symbol}`;
13
+ };
14
+
7
15
  type FooterProps = {
8
16
  name: string;
9
17
  type?: ContractType;
@@ -91,11 +99,7 @@ export const Footer = ({
91
99
  fontFamily="body"
92
100
  >
93
101
  {listed &&
94
- `${formatUnits(
95
- BigInt(lowestListingPriceAmount),
96
- lowestListingCurrency.decimals,
97
- )} ${lowestListingCurrency.symbol}`}
98
-
102
+ formatPrice(lowestListingPriceAmount, lowestListingCurrency)}
99
103
  {!listed && 'Not listed yet'}
100
104
  </Text>
101
105
  </Box>
@@ -1,14 +1,14 @@
1
1
  import { use$ } from '@legendapp/state/react';
2
2
  import type { Hex } from 'viem';
3
3
  import { ContractType, type TokenMetadata } from '../../../_internal';
4
- import { buyModal$ } from './store';
4
+ import { ErrorModal } from '../_internal/components/actionModal/ErrorModal';
5
5
  import { LoadingModal } from '../_internal/components/actionModal/LoadingModal';
6
+ import { useBuyCollectable } from './hooks/useBuyCollectable';
7
+ import { useLoadData } from './hooks/useLoadData';
6
8
  import { CheckoutModal } from './modals/CheckoutModal';
7
9
  import type { BuyInput } from './modals/CheckoutModal';
8
10
  import { ERC1155QuantityModal } from './modals/Modal1155';
9
- import { useLoadData } from './hooks/useLoadData';
10
- import { useBuyCollectable } from './hooks/useBuyCollectable';
11
- import { ErrorModal } from '../_internal/components/actionModal/ErrorModal';
11
+ import { buyModal$ } from './store';
12
12
 
13
13
  export const BuyModal = () => {
14
14
  const isOpen = use$(buyModal$.isOpen);
@@ -57,6 +57,7 @@ const BuyModalContent = () => {
57
57
  const buyAction = (input: BuyInput) => {
58
58
  if (buy && checkoutOptions) {
59
59
  buy({ ...input, checkoutOptions });
60
+ buyModal$.state.purchaseProcessing.set(true);
60
61
  } else {
61
62
  console.error('buy is null or undefined');
62
63
  }
@@ -91,6 +92,10 @@ const BuyModalContent = () => {
91
92
  );
92
93
  }
93
94
 
95
+ if (buyModal$.state.purchaseProcessing.get()) {
96
+ return null;
97
+ }
98
+
94
99
  return collection.type === ContractType.ERC721 ? (
95
100
  <CheckoutModal
96
101
  buy={buyAction}
@@ -1,4 +1,3 @@
1
- import '@testing-library/jest-dom/vitest';
2
1
  import {
3
2
  render,
4
3
  screen,
@@ -1,6 +1,6 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { buyModal$, initialState } from '../store';
1
+ import { beforeEach, describe, expect, it } from 'vitest';
3
2
  import type { Order } from '../../../../_internal';
3
+ import { buyModal$, initialState } from '../store';
4
4
 
5
5
  describe('BuyModal Store', () => {
6
6
  beforeEach(() => {
@@ -15,6 +15,7 @@ describe('BuyModal Store', () => {
15
15
  invalidQuantity: false,
16
16
  checkoutModalIsLoading: false,
17
17
  checkoutModalLoaded: false,
18
+ purchaseProcessing: false,
18
19
  });
19
20
  expect(buyModal$.callbacks.get()).toBeUndefined();
20
21
  });
@@ -44,6 +45,7 @@ describe('BuyModal Store', () => {
44
45
  invalidQuantity: false,
45
46
  checkoutModalIsLoading: false,
46
47
  checkoutModalLoaded: false,
48
+ purchaseProcessing: false,
47
49
  });
48
50
  expect(buyModal$.callbacks.get()).toBe(mockCallbacks);
49
51
  });
@@ -10,7 +10,6 @@ import {
10
10
  TransactionCrypto,
11
11
  WalletKind,
12
12
  getMarketplaceClient,
13
- collectableKeys,
14
13
  } from '../../../../../_internal';
15
14
 
16
15
  // Mock dependencies
@@ -38,18 +37,6 @@ vi.mock('../store', () => ({
38
37
  },
39
38
  }));
40
39
 
41
- // Mock react-query
42
- const mockInvalidateQueries = vi.fn();
43
- vi.mock('@tanstack/react-query', async () => {
44
- const actual = await vi.importActual('@tanstack/react-query');
45
- return {
46
- ...actual,
47
- getQueryClient: () => ({
48
- invalidateQueries: mockInvalidateQueries,
49
- }),
50
- };
51
- });
52
-
53
40
  vi.mock('../../../../../_internal', async () => {
54
41
  const actual = (await vi.importActual('../../../../../_internal')) as Record<
55
42
  string,
@@ -78,9 +65,6 @@ vi.mock('../../../../../_internal', async () => {
78
65
  balanceQueries: {
79
66
  all: ['balances'],
80
67
  },
81
- getQueryClient: () => ({
82
- invalidateQueries: mockInvalidateQueries,
83
- }),
84
68
  };
85
69
  });
86
70
 
@@ -270,7 +254,7 @@ describe('useBuyCollectable', () => {
270
254
  expect(defaultProps.setCheckoutModalLoaded).toHaveBeenCalledWith(true);
271
255
  });
272
256
 
273
- it('should handle success callback and invalidate queries', async () => {
257
+ it('should handle success callback', async () => {
274
258
  (useWallet as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
275
259
  wallet: {
276
260
  kind: WalletKind.sequence,
@@ -338,13 +322,6 @@ describe('useBuyCollectable', () => {
338
322
  const txHash = '0x789';
339
323
  await onSuccessCallback(txHash);
340
324
 
341
- expect(mockInvalidateQueries).toHaveBeenCalledWith({
342
- queryKey: collectableKeys.listings,
343
- });
344
- expect(mockInvalidateQueries).toHaveBeenCalledWith({
345
- queryKey: collectableKeys.listingsCount,
346
- });
347
-
348
325
  expect(onSuccessMock).toHaveBeenCalledWith({ hash: txHash });
349
326
  });
350
327