@0xsequence/marketplace-sdk 0.5.1 → 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 (164) 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-F4E3WJ2K.js → chunk-BVXIRVEC.js} +261 -249
  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 +1 -1
  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 +8 -10
  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/styles/index.css +1 -1
  47. package/dist/styles/index.css.map +1 -1
  48. package/dist/styles/index.js +1 -1
  49. package/dist/types/index.d.ts +1 -3
  50. package/dist/types/index.js +9 -5
  51. package/dist/{types-Yto6KrTN.d.ts → types-BY3husBh.d.ts} +1 -1
  52. package/dist/utils/index.d.ts +2 -2
  53. package/dist/utils/index.js +4 -4
  54. package/package.json +11 -10
  55. package/src/react/_internal/api/__mocks__/indexer.msw.ts +197 -0
  56. package/src/react/_internal/api/__mocks__/marketplace.msw.ts +140 -1
  57. package/src/react/_internal/api/__mocks__/metadata.msw.ts +162 -0
  58. package/src/react/_internal/test/mocks/publicClient.ts +39 -0
  59. package/src/react/_internal/test/mocks/wagmi.ts +61 -0
  60. package/src/react/_internal/test/mocks/wallet.ts +61 -0
  61. package/src/react/_internal/test/setup.ts +28 -0
  62. package/src/react/_internal/test-utils.tsx +31 -2
  63. package/src/react/_internal/wagmi/__tests__/create-config.test.ts +53 -20
  64. package/src/react/_internal/wagmi/create-config.ts +3 -4
  65. package/src/react/_internal/wagmi/embedded.ts +1 -4
  66. package/src/react/_internal/wagmi/universal.ts +1 -4
  67. package/src/react/_internal/wallet/wallet.ts +1 -0
  68. package/src/react/hooks/__tests__/useAutoSelectFeeOption.test.tsx +314 -0
  69. package/src/react/hooks/__tests__/useBalanceOfCollectible.test.tsx +148 -0
  70. package/src/react/hooks/__tests__/useCancelOrder.test.tsx +410 -0
  71. package/src/react/hooks/__tests__/useCancelTransactionSteps.test.tsx +269 -0
  72. package/src/react/hooks/__tests__/useCollectible.test.tsx +120 -0
  73. package/src/react/hooks/__tests__/useCollection.test.tsx +101 -0
  74. package/src/react/hooks/__tests__/useCollectionBalanceDetails.test.tsx +175 -0
  75. package/src/react/hooks/__tests__/useCollectionDetails.test.tsx +82 -0
  76. package/src/react/hooks/__tests__/useCollectionDetailsPolling.test.tsx +133 -0
  77. package/src/react/hooks/__tests__/useCountListingsForCollectible.test.tsx +108 -0
  78. package/src/react/hooks/__tests__/useCountOfCollectables.test.tsx +129 -0
  79. package/src/react/hooks/__tests__/useCountOffersForCollectible.test.tsx +108 -0
  80. package/src/react/hooks/__tests__/useCurrencies.test.tsx +176 -0
  81. package/src/react/hooks/__tests__/useCurrency.test.tsx +153 -0
  82. package/src/react/hooks/__tests__/useCurrencyBalance.test.tsx +111 -0
  83. package/src/react/hooks/__tests__/useFilters.test.tsx +127 -0
  84. package/src/react/hooks/__tests__/useFloorOrder.test.tsx +101 -0
  85. package/src/react/hooks/__tests__/useGenerateBuyTransaction.test.tsx +173 -0
  86. package/src/react/hooks/__tests__/useGenerateCancelTransaction.test.tsx +207 -0
  87. package/src/react/hooks/__tests__/useGenerateListingTransaction.test.tsx +207 -0
  88. package/src/react/hooks/__tests__/useGenerateOfferTransaction.test.tsx +205 -0
  89. package/src/react/hooks/__tests__/useGenerateSellTransaction.test.tsx +181 -0
  90. package/src/react/hooks/__tests__/useHighestOffer.test.tsx +118 -0
  91. package/src/react/hooks/__tests__/useListBalances.test.tsx +136 -0
  92. package/src/react/hooks/__tests__/useListCollectibleActivities.test.tsx +200 -0
  93. package/src/react/hooks/__tests__/useListCollectibles.test.tsx +232 -0
  94. package/src/react/hooks/__tests__/useListCollectionActivities.test.tsx +235 -0
  95. package/src/react/hooks/__tests__/useListCollections.test.tsx +296 -0
  96. package/src/react/hooks/__tests__/useListListingsForCollectible.test.tsx +140 -0
  97. package/src/react/hooks/__tests__/useListOffersForCollectible.test.tsx +140 -0
  98. package/src/react/hooks/__tests__/useLowestListing.test.tsx +148 -0
  99. package/src/react/hooks/__tests__/useMarketplaceConfig.test.tsx +106 -0
  100. package/src/react/hooks/__tests__/useRoyaltyPercentage.test.tsx +129 -0
  101. package/src/react/hooks/index.ts +0 -1
  102. package/src/react/hooks/options/__mocks__/marketplaceConfig.msw.ts +66 -10
  103. package/src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx +2 -11
  104. package/src/react/hooks/options/marketplaceConfigOptions.ts +8 -3
  105. package/src/react/hooks/useAutoSelectFeeOption.tsx +4 -3
  106. package/src/react/hooks/useCancelTransactionSteps.tsx +17 -9
  107. package/src/react/hooks/useCollectionDetailsPolling.tsx +1 -1
  108. package/src/react/hooks/useCurrencies.tsx +29 -28
  109. package/src/react/hooks/useFilters.tsx +69 -2
  110. package/src/react/hooks/useGenerateBuyTransaction.tsx +13 -5
  111. package/src/react/hooks/useListCollectibleActivities.tsx +1 -0
  112. package/src/react/hooks/useListCollectibles.tsx +1 -0
  113. package/src/react/hooks/useListCollectionActivities.tsx +1 -0
  114. package/src/react/hooks/useListCollections.tsx +2 -2
  115. package/src/react/ui/components/_internals/custom-select/__tests__/CustomSelect.test.tsx +6 -2
  116. package/src/react/ui/components/collectible-card/CollectibleCard.tsx +1 -1
  117. package/src/react/ui/components/collectible-card/Footer.tsx +9 -5
  118. package/src/react/ui/modals/BuyModal/Modal.tsx +9 -4
  119. package/src/react/ui/modals/BuyModal/__tests__/Modal.test.tsx +0 -1
  120. package/src/react/ui/modals/BuyModal/__tests__/store.test.ts +4 -2
  121. package/src/react/ui/modals/BuyModal/hooks/__tests__/useBuyCollectable.test.tsx +1 -24
  122. package/src/react/ui/modals/BuyModal/hooks/__tests__/useCheckoutOptions.test.tsx +152 -210
  123. package/src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx +19 -49
  124. package/src/react/ui/modals/BuyModal/hooks/useFees.ts +6 -6
  125. package/src/react/ui/modals/BuyModal/modals/Modal1155.tsx +4 -2
  126. package/src/react/ui/modals/BuyModal/modals/__tests__/Modal1155.test.tsx +161 -52
  127. package/src/react/ui/modals/BuyModal/store.ts +7 -0
  128. package/src/react/ui/modals/CreateListingModal/Modal.tsx +1 -3
  129. package/src/react/ui/modals/CreateListingModal/__tests__/Modal.test.tsx +59 -227
  130. package/src/react/ui/modals/CreateListingModal/hooks/useCreateListing.tsx +2 -1
  131. package/src/react/ui/modals/CreateListingModal/hooks/useGetTokenApproval.ts +8 -2
  132. package/src/react/ui/modals/CreateListingModal/hooks/useTransactionSteps.tsx +9 -5
  133. package/src/react/ui/modals/MakeOfferModal/Modal.tsx +1 -8
  134. package/src/react/ui/modals/MakeOfferModal/__tests__/Modal.test.tsx +41 -118
  135. package/src/react/ui/modals/MakeOfferModal/hooks/useMakeOffer.tsx +2 -1
  136. package/src/react/ui/modals/MakeOfferModal/hooks/useTransactionSteps.tsx +9 -5
  137. package/src/react/ui/modals/SellModal/__tests__/Modal.test.tsx +4 -3
  138. package/src/react/ui/modals/SellModal/hooks/useGetTokenApproval.tsx +33 -31
  139. package/src/react/ui/modals/SellModal/hooks/useSell.tsx +1 -0
  140. package/src/react/ui/modals/SellModal/hooks/useTransactionSteps.tsx +9 -5
  141. package/src/react/ui/modals/SuccessfulPurchaseModal/__tests__/Modal.test.tsx +0 -1
  142. package/src/react/ui/modals/_internal/components/actionModal/ErrorModal.tsx +4 -2
  143. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/__tests__/index.test.tsx +129 -57
  144. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +1 -3
  145. package/src/react/ui/modals/_internal/components/priceInput/__tests__/index.test.tsx +1 -3
  146. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +2 -2
  147. package/src/react/ui/modals/_internal/components/transactionStatusModal/__tests__/TransactionStatusModal.test.tsx +8 -8
  148. package/src/react/ui/modals/_internal/components/transactionStatusModal/hooks/useTransactionStatus.ts +1 -0
  149. package/src/types/builder-types.ts +79 -0
  150. package/src/types/index.ts +1 -1
  151. package/src/utils/__tests__/get-public-rpc-client.test.ts +2 -0
  152. package/src/utils/getMarketplaceDetails.ts +2 -2
  153. package/tsconfig.tsbuildinfo +1 -1
  154. package/vitest.config.js +2 -1
  155. package/dist/chunk-F4E3WJ2K.js.map +0 -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-RK6KYMZM.js +0 -18
  160. package/dist/chunk-RK6KYMZM.js.map +0 -1
  161. package/dist/marketplace-config-znEu4L0K.d.ts +0 -60
  162. package/src/react/hooks/useCurrencyOptions.tsx +0 -16
  163. package/src/types/marketplace-config.ts +0 -67
  164. /package/dist/{chunk-MKGSGTQC.js.map → chunk-Y7YTLAO2.js.map} +0 -0
@@ -0,0 +1,108 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { useCountListingsForCollectible } from '../useCountListingsForCollectible';
3
+ import { renderHook, waitFor } from '../../_internal/test-utils';
4
+ import { zeroAddress } from 'viem';
5
+ import { http, HttpResponse } from 'msw';
6
+ import { server } from '../../_internal/test/setup';
7
+ import { mockMarketplaceEndpoint } from '../../_internal/api/__mocks__/marketplace.msw';
8
+
9
+ describe('useCountListingsForCollectible', () => {
10
+ const defaultArgs = {
11
+ chainId: '1',
12
+ collectionAddress: zeroAddress,
13
+ collectibleId: '1',
14
+ query: {},
15
+ };
16
+
17
+ it('should fetch listings count successfully', async () => {
18
+ const { result } = renderHook(() =>
19
+ useCountListingsForCollectible(defaultArgs),
20
+ );
21
+
22
+ // Initially loading
23
+ expect(result.current.isLoading).toBe(true);
24
+ expect(result.current.data).toBeUndefined();
25
+
26
+ // Wait for data to be loaded
27
+ await waitFor(() => {
28
+ expect(result.current.isLoading).toBe(false);
29
+ });
30
+
31
+ // Verify the data matches our mock
32
+ expect(result.current.data).toEqual({ count: 1 });
33
+ expect(result.current.error).toBeNull();
34
+ });
35
+
36
+ it('should handle error states', async () => {
37
+ // Override the handler for this test to return an error
38
+ server.use(
39
+ http.post(
40
+ mockMarketplaceEndpoint('GetCountOfListingsForCollectible'),
41
+ () => {
42
+ return HttpResponse.json(
43
+ { error: { message: 'Failed to fetch listings count' } },
44
+ { status: 500 },
45
+ );
46
+ },
47
+ ),
48
+ );
49
+
50
+ const { result } = renderHook(() =>
51
+ useCountListingsForCollectible(defaultArgs),
52
+ );
53
+
54
+ await waitFor(() => {
55
+ expect(result.current.isError).toBe(true);
56
+ });
57
+
58
+ expect(result.current.error).toBeDefined();
59
+ expect(result.current.data).toBeUndefined();
60
+ });
61
+
62
+ it('should refetch when args change', async () => {
63
+ const { result, rerender } = renderHook(() =>
64
+ useCountListingsForCollectible(defaultArgs),
65
+ );
66
+
67
+ // Wait for initial data
68
+ await waitFor(() => {
69
+ expect(result.current.isLoading).toBe(false);
70
+ });
71
+
72
+ // Change args and rerender
73
+ const newArgs = {
74
+ ...defaultArgs,
75
+ collectionAddress:
76
+ '0x1234567890123456789012345678901234567890' as `0x${string}`,
77
+ collectibleId: '2',
78
+ };
79
+
80
+ rerender(() => useCountListingsForCollectible(newArgs));
81
+
82
+ // Wait for new data
83
+ await waitFor(() => {
84
+ expect(result.current.data).toBeDefined();
85
+ });
86
+
87
+ // Verify that the query was refetched with new args
88
+ expect(result.current.data).toBeDefined();
89
+ expect(result.current.isSuccess).toBe(true);
90
+ });
91
+
92
+ it('should handle query options', async () => {
93
+ const argsWithQuery = {
94
+ ...defaultArgs,
95
+ query: {
96
+ enabled: false,
97
+ },
98
+ };
99
+
100
+ const { result } = renderHook(() =>
101
+ useCountListingsForCollectible(argsWithQuery),
102
+ );
103
+
104
+ // Should not fetch when disabled
105
+ expect(result.current.isLoading).toBe(false);
106
+ expect(result.current.data).toBeUndefined();
107
+ });
108
+ });
@@ -0,0 +1,129 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { useCountOfCollectables } from '../useCountOfCollectables';
3
+ import { renderHook, waitFor } from '../../_internal/test-utils';
4
+ import { zeroAddress } from 'viem';
5
+ import type { UseCountOfCollectablesArgs } from '../useCountOfCollectables';
6
+ import { http, HttpResponse } from 'msw';
7
+ import { mockMarketplaceEndpoint } from '../../_internal/api/__mocks__/marketplace.msw';
8
+ import { OrderSide } from '../../_internal';
9
+ import { server } from '../../_internal/test/setup';
10
+
11
+ describe('useCountOfCollectables', () => {
12
+ const defaultArgs: UseCountOfCollectablesArgs = {
13
+ chainId: '1',
14
+ collectionAddress: zeroAddress,
15
+ query: {},
16
+ };
17
+
18
+ const defaultArgsWithFilter: UseCountOfCollectablesArgs = {
19
+ ...defaultArgs,
20
+ filter: {
21
+ includeEmpty: true,
22
+ },
23
+ side: OrderSide.listing,
24
+ };
25
+
26
+ it('should fetch count of all collectables successfully', async () => {
27
+ const { result } = renderHook(() => useCountOfCollectables(defaultArgs));
28
+
29
+ // Initially loading
30
+ expect(result.current.isLoading).toBe(true);
31
+ expect(result.current.data).toBeUndefined();
32
+
33
+ // Wait for data to be loaded
34
+ await waitFor(() => {
35
+ expect(result.current.isLoading).toBe(false);
36
+ });
37
+
38
+ // Verify the data matches our mock
39
+ expect(result.current.data).toBe(100); // matches mock count from marketplace.msw.ts
40
+ expect(result.current.error).toBeNull();
41
+ });
42
+
43
+ it('should fetch filtered count of collectables successfully', async () => {
44
+ const { result } = renderHook(() =>
45
+ useCountOfCollectables(defaultArgsWithFilter),
46
+ );
47
+
48
+ // Initially loading
49
+ expect(result.current.isLoading).toBe(true);
50
+ expect(result.current.data).toBeUndefined();
51
+
52
+ // Wait for data to be loaded
53
+ await waitFor(() => {
54
+ expect(result.current.isLoading).toBe(false);
55
+ });
56
+
57
+ // Verify the data matches our mock
58
+ expect(result.current.data).toBe(50); // matches mock count from marketplace.msw.ts
59
+ expect(result.current.error).toBeNull();
60
+ });
61
+
62
+ it('should handle error states', async () => {
63
+ // Override the handler for this test to return an error
64
+ server.use(
65
+ http.post(mockMarketplaceEndpoint('GetCountOfAllCollectibles'), () => {
66
+ return HttpResponse.json(
67
+ { error: { message: 'Failed to fetch count' } },
68
+ { status: 500 },
69
+ );
70
+ }),
71
+ );
72
+
73
+ const { result } = renderHook(() => useCountOfCollectables(defaultArgs));
74
+
75
+ await waitFor(() => {
76
+ expect(result.current.isError).toBe(true);
77
+ });
78
+
79
+ expect(result.current.error).toBeDefined();
80
+ expect(result.current.data).toBeUndefined();
81
+ });
82
+
83
+ it('should refetch when args change', async () => {
84
+ const { result, rerender } = renderHook(() =>
85
+ useCountOfCollectables(defaultArgs),
86
+ );
87
+
88
+ // Wait for initial data
89
+ await waitFor(() => {
90
+ expect(result.current.isLoading).toBe(false);
91
+ });
92
+
93
+ // Change args and rerender
94
+ const newArgs = {
95
+ ...defaultArgs,
96
+ collectionAddress:
97
+ '0x1234567890123456789012345678901234567890' as `0x${string}`,
98
+ };
99
+
100
+ rerender(() => useCountOfCollectables(newArgs));
101
+
102
+ // Wait for new data
103
+ await waitFor(() => {
104
+ expect(result.current.data).toBeDefined();
105
+ });
106
+
107
+ // Verify that the query was refetched with new args
108
+ expect(result.current.data).toBeDefined();
109
+ expect(result.current.isSuccess).toBe(true);
110
+ });
111
+
112
+ it('should handle undefined query params', async () => {
113
+ const argsWithoutQuery: UseCountOfCollectablesArgs = {
114
+ chainId: '1',
115
+ collectionAddress: zeroAddress,
116
+ };
117
+
118
+ const { result } = renderHook(() =>
119
+ useCountOfCollectables(argsWithoutQuery),
120
+ );
121
+
122
+ await waitFor(() => {
123
+ expect(result.current.isLoading).toBe(false);
124
+ });
125
+
126
+ expect(result.current.data).toBeDefined();
127
+ expect(result.current.error).toBeNull();
128
+ });
129
+ });
@@ -0,0 +1,108 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { useCountOffersForCollectible } from '../useCountOffersForCollectible';
3
+ import { renderHook, waitFor } from '../../_internal/test-utils';
4
+ import { zeroAddress } from 'viem';
5
+ import { http, HttpResponse } from 'msw';
6
+ import { server } from '../../_internal/test/setup';
7
+ import { mockMarketplaceEndpoint } from '../../_internal/api/__mocks__/marketplace.msw';
8
+
9
+ describe('useCountOffersForCollectible', () => {
10
+ const defaultArgs = {
11
+ chainId: '1',
12
+ collectionAddress: zeroAddress,
13
+ collectibleId: '1',
14
+ query: {},
15
+ };
16
+
17
+ it('should fetch offers count successfully', async () => {
18
+ const { result } = renderHook(() =>
19
+ useCountOffersForCollectible(defaultArgs),
20
+ );
21
+
22
+ // Initially loading
23
+ expect(result.current.isLoading).toBe(true);
24
+ expect(result.current.data).toBeUndefined();
25
+
26
+ // Wait for data to be loaded
27
+ await waitFor(() => {
28
+ expect(result.current.isLoading).toBe(false);
29
+ });
30
+
31
+ // Verify the data matches our mock
32
+ expect(result.current.data).toEqual({ count: 1 });
33
+ expect(result.current.error).toBeNull();
34
+ });
35
+
36
+ it('should handle error states', async () => {
37
+ // Override the handler for this test to return an error
38
+ server.use(
39
+ http.post(
40
+ mockMarketplaceEndpoint('GetCountOfOffersForCollectible'),
41
+ () => {
42
+ return HttpResponse.json(
43
+ { error: { message: 'Failed to fetch offers count' } },
44
+ { status: 500 },
45
+ );
46
+ },
47
+ ),
48
+ );
49
+
50
+ const { result } = renderHook(() =>
51
+ useCountOffersForCollectible(defaultArgs),
52
+ );
53
+
54
+ await waitFor(() => {
55
+ expect(result.current.isError).toBe(true);
56
+ });
57
+
58
+ expect(result.current.error).toBeDefined();
59
+ expect(result.current.data).toBeUndefined();
60
+ });
61
+
62
+ it('should refetch when args change', async () => {
63
+ const { result, rerender } = renderHook(() =>
64
+ useCountOffersForCollectible(defaultArgs),
65
+ );
66
+
67
+ // Wait for initial data
68
+ await waitFor(() => {
69
+ expect(result.current.isLoading).toBe(false);
70
+ });
71
+
72
+ // Change args and rerender
73
+ const newArgs = {
74
+ ...defaultArgs,
75
+ collectionAddress:
76
+ '0x1234567890123456789012345678901234567890' as `0x${string}`,
77
+ collectibleId: '2',
78
+ };
79
+
80
+ rerender(() => useCountOffersForCollectible(newArgs));
81
+
82
+ // Wait for new data
83
+ await waitFor(() => {
84
+ expect(result.current.data).toBeDefined();
85
+ });
86
+
87
+ // Verify that the query was refetched with new args
88
+ expect(result.current.data).toBeDefined();
89
+ expect(result.current.isSuccess).toBe(true);
90
+ });
91
+
92
+ it('should handle query options', async () => {
93
+ const argsWithQuery = {
94
+ ...defaultArgs,
95
+ query: {
96
+ enabled: false,
97
+ },
98
+ };
99
+
100
+ const { result } = renderHook(() =>
101
+ useCountOffersForCollectible(argsWithQuery),
102
+ );
103
+
104
+ // Should not fetch when disabled
105
+ expect(result.current.isLoading).toBe(false);
106
+ expect(result.current.data).toBeUndefined();
107
+ });
108
+ });
@@ -0,0 +1,176 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { useCurrencies } from '../useCurrencies';
3
+ import { renderHook, waitFor } from '../../_internal/test-utils';
4
+ import { http, HttpResponse } from 'msw';
5
+ import { server } from '../../_internal/test/setup';
6
+ import {
7
+ mockCurrencies,
8
+ mockMarketplaceEndpoint,
9
+ } from '../../_internal/api/__mocks__/marketplace.msw';
10
+ import { mockConfig } from '../options/__mocks__/marketplaceConfig.msw';
11
+
12
+ describe('useCurrencies', () => {
13
+ const defaultArgs = {
14
+ chainId: '1',
15
+ };
16
+
17
+ it('should fetch currencies successfully', async () => {
18
+ const { result } = renderHook(() => useCurrencies(defaultArgs));
19
+
20
+ // Initially loading
21
+ expect(result.current.isLoading).toBe(true);
22
+ expect(result.current.data).toBeUndefined();
23
+
24
+ // Wait for data to be loaded
25
+ await waitFor(() => {
26
+ expect(result.current.isLoading).toBe(false);
27
+ });
28
+
29
+ // Verify the data matches our mock
30
+ expect(result.current.data).toEqual(mockCurrencies);
31
+ expect(result.current.error).toBeNull();
32
+ });
33
+
34
+ it('should filter out native currency when includeNativeCurrency is false', async () => {
35
+ const argsWithoutNative = {
36
+ ...defaultArgs,
37
+ includeNativeCurrency: false,
38
+ };
39
+
40
+ const { result } = renderHook(() => useCurrencies(argsWithoutNative));
41
+
42
+ await waitFor(() => {
43
+ expect(result.current.isLoading).toBe(false);
44
+ });
45
+
46
+ expect(result.current.data).toEqual(
47
+ mockCurrencies.filter((currency) => !currency.nativeCurrency),
48
+ );
49
+ });
50
+
51
+ it('should filter currencies by collection address', async () => {
52
+ const args = {
53
+ ...defaultArgs,
54
+ collectionAddress: mockConfig.collections[1].address,
55
+ } satisfies Parameters<typeof useCurrencies>[0];
56
+
57
+ const { result } = renderHook(() => useCurrencies(args));
58
+
59
+ await waitFor(() => {
60
+ expect(result.current.isLoading).toBe(false);
61
+ });
62
+
63
+ const currencyAddresses = result.current.data?.map(
64
+ (c) => c.contractAddress,
65
+ );
66
+ expect(currencyAddresses).toEqual(
67
+ mockConfig.collections[1].currencyOptions,
68
+ );
69
+ });
70
+
71
+ it('should handle error states', async () => {
72
+ // Override the handler for this test to return an error
73
+ server.use(
74
+ http.post(mockMarketplaceEndpoint('ListCurrencies'), () => {
75
+ return HttpResponse.json(
76
+ { error: { message: 'Failed to fetch currencies' } },
77
+ { status: 500 },
78
+ );
79
+ }),
80
+ );
81
+
82
+ const { result } = renderHook(() => useCurrencies(defaultArgs));
83
+
84
+ await waitFor(() => {
85
+ expect(result.current.isError).toBe(true);
86
+ });
87
+
88
+ expect(result.current.error).toBeDefined();
89
+ expect(result.current.data).toBeUndefined();
90
+ });
91
+
92
+ it('should refetch when chainId changes', async () => {
93
+ const { result, rerender } = renderHook(() => useCurrencies(defaultArgs));
94
+
95
+ // Wait for initial data
96
+ await waitFor(() => {
97
+ expect(result.current.isLoading).toBe(false);
98
+ });
99
+
100
+ // Change chainId and rerender
101
+ const newArgs = {
102
+ ...defaultArgs,
103
+ chainId: '5',
104
+ };
105
+
106
+ rerender(() => useCurrencies(newArgs));
107
+
108
+ // Wait for new data
109
+ await waitFor(() => {
110
+ expect(result.current.data).toBeDefined();
111
+ });
112
+
113
+ // Verify that the query was refetched with new args
114
+ expect(result.current.data).toBeDefined();
115
+ expect(result.current.isSuccess).toBe(true);
116
+ });
117
+
118
+ it('should handle query options', async () => {
119
+ const argsWithQuery = {
120
+ ...defaultArgs,
121
+ query: {
122
+ enabled: false,
123
+ },
124
+ };
125
+
126
+ const { result } = renderHook(() => useCurrencies(argsWithQuery));
127
+
128
+ // Should not fetch when disabled
129
+ expect(result.current.isLoading).toBe(false);
130
+ expect(result.current.data).toBeUndefined();
131
+ });
132
+
133
+ it('should handle combined filters', async () => {
134
+ const argsWithCombinedFilters = {
135
+ ...defaultArgs,
136
+ includeNativeCurrency: false,
137
+ currencyOptions: [
138
+ '0x1234567890123456789012345678901234567890', // USDC address from mock
139
+ ],
140
+ };
141
+
142
+ const { result } = renderHook(() => useCurrencies(argsWithCombinedFilters));
143
+
144
+ await waitFor(() => {
145
+ expect(result.current.isLoading).toBe(false);
146
+ });
147
+
148
+ console.log('result.current.data', result.current.data);
149
+
150
+ // Should only include non-native currencies from the currencyOptions list
151
+ expect(result.current.data).toEqual(
152
+ mockCurrencies.filter(
153
+ (currency) =>
154
+ !currency.nativeCurrency &&
155
+ currency.contractAddress.toLowerCase() ===
156
+ '0x1234567890123456789012345678901234567890'.toLowerCase(),
157
+ ),
158
+ );
159
+ });
160
+
161
+ it('should handle collection filter', async () => {
162
+ const args = {
163
+ ...defaultArgs,
164
+ includeNativeCurrency: false,
165
+ collectionAddress: '0x1234567890123456789012345678901234567890',
166
+ } satisfies Parameters<typeof useCurrencies>[0];
167
+
168
+ const { result } = renderHook(() => useCurrencies(args));
169
+
170
+ await waitFor(() => {
171
+ expect(result.current.isLoading).toBe(false);
172
+ });
173
+
174
+ expect(result.current.data).toBeDefined();
175
+ });
176
+ });
@@ -0,0 +1,153 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
+ import { useCurrency } from '../useCurrency';
3
+ import { renderHook, waitFor } from '../../_internal/test-utils';
4
+ import { http, HttpResponse } from 'msw';
5
+ import { server } from '../../_internal/test/setup';
6
+ import {
7
+ mockCurrencies,
8
+ mockMarketplaceEndpoint,
9
+ } from '../../_internal/api/__mocks__/marketplace.msw';
10
+ import { getQueryClient } from '../../_internal';
11
+ import { currencyKeys } from '../../_internal';
12
+
13
+ describe('useCurrency', () => {
14
+ const defaultArgs = {
15
+ chainId: '1',
16
+ currencyAddress: '0x1234567890123456789012345678901234567890', // USDC address from mock
17
+ query: {},
18
+ };
19
+
20
+ // Clear query cache before each test
21
+ beforeEach(() => {
22
+ const queryClient = getQueryClient();
23
+ queryClient.clear();
24
+ });
25
+
26
+ it('should fetch currency successfully when cache is empty', async () => {
27
+ const { result } = renderHook(() => useCurrency(defaultArgs));
28
+
29
+ // Initially loading
30
+ expect(result.current.isLoading).toBe(true);
31
+ expect(result.current.data).toBeUndefined();
32
+
33
+ // Wait for data to be loaded
34
+ await waitFor(() => {
35
+ expect(result.current.isLoading).toBe(false);
36
+ });
37
+
38
+ // Verify the data matches our mock
39
+ expect(result.current.data).toEqual(
40
+ mockCurrencies.find(
41
+ (currency) =>
42
+ currency.contractAddress.toLowerCase() ===
43
+ defaultArgs.currencyAddress.toLowerCase(),
44
+ ),
45
+ );
46
+ expect(result.current.error).toBeNull();
47
+ });
48
+
49
+ it('should use cached currencies when available', async () => {
50
+ // Prefill the cache with currencies
51
+ const queryClient = getQueryClient();
52
+ await queryClient.prefetchQuery({
53
+ queryKey: [...currencyKeys.lists, defaultArgs.chainId],
54
+ queryFn: () => mockCurrencies,
55
+ });
56
+
57
+ const { result } = renderHook(() => useCurrency(defaultArgs));
58
+
59
+ await waitFor(() => {
60
+ expect(result.current.isLoading).toBe(false);
61
+ });
62
+
63
+ // Should resolve using cached data
64
+ expect(result.current.data).toEqual(
65
+ mockCurrencies.find(
66
+ (currency) =>
67
+ currency.contractAddress.toLowerCase() ===
68
+ defaultArgs.currencyAddress.toLowerCase(),
69
+ ),
70
+ );
71
+ });
72
+
73
+ it('should handle currency not found error', async () => {
74
+ const argsWithInvalidAddress = {
75
+ ...defaultArgs,
76
+ currencyAddress: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef',
77
+ };
78
+
79
+ const { result } = renderHook(() => useCurrency(argsWithInvalidAddress));
80
+
81
+ await waitFor(() => {
82
+ expect(result.current.isError).toBe(true);
83
+ });
84
+
85
+ expect(result.current.error).toBeDefined();
86
+ if (result.current.error instanceof Error) {
87
+ expect(result.current.error.message).toBe('Currency not found');
88
+ }
89
+ expect(result.current.data).toBeUndefined();
90
+ });
91
+
92
+ it('should handle API error states', async () => {
93
+ // Override the handler for this test to return an error
94
+ server.use(
95
+ http.post(mockMarketplaceEndpoint('ListCurrencies'), () => {
96
+ return HttpResponse.json(
97
+ { error: { message: 'Failed to fetch currencies' } },
98
+ { status: 500 },
99
+ );
100
+ }),
101
+ );
102
+
103
+ const { result } = renderHook(() => useCurrency(defaultArgs));
104
+
105
+ await waitFor(() => {
106
+ expect(result.current.isError).toBe(true);
107
+ });
108
+
109
+ expect(result.current.error).toBeDefined();
110
+ expect(result.current.data).toBeUndefined();
111
+ });
112
+
113
+ it('should refetch when chainId changes', async () => {
114
+ const { result, rerender } = renderHook(() => useCurrency(defaultArgs));
115
+
116
+ // Wait for initial data
117
+ await waitFor(() => {
118
+ expect(result.current.isLoading).toBe(false);
119
+ });
120
+
121
+ // Change chainId and rerender
122
+ const newArgs = {
123
+ ...defaultArgs,
124
+ chainId: '5',
125
+ };
126
+
127
+ rerender(() => useCurrency(newArgs));
128
+
129
+ // Wait for new data
130
+ await waitFor(() => {
131
+ expect(result.current.data).toBeDefined();
132
+ });
133
+
134
+ // Verify that the query was refetched with new args
135
+ expect(result.current.data).toBeDefined();
136
+ expect(result.current.isSuccess).toBe(true);
137
+ });
138
+
139
+ it('should handle query options', async () => {
140
+ const argsWithQuery = {
141
+ ...defaultArgs,
142
+ query: {
143
+ enabled: false,
144
+ },
145
+ };
146
+
147
+ const { result } = renderHook(() => useCurrency(argsWithQuery));
148
+
149
+ // Should not fetch when disabled
150
+ expect(result.current.isLoading).toBe(false);
151
+ expect(result.current.data).toBeUndefined();
152
+ });
153
+ });