@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,111 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { useCurrencyBalance } from '../useCurrencyBalance';
3
+ import { renderHook, waitFor } from '../../_internal/test-utils';
4
+ import { zeroAddress } from 'viem';
5
+ import {
6
+ createMockPublicClient,
7
+ commonPublicClientMocks,
8
+ } from '../../_internal/test/mocks/publicClient';
9
+ import { getPublicRpcClient } from '../../../utils/get-public-rpc-client';
10
+
11
+ // Mock the getPublicRpcClient function
12
+ vi.mock('../../../utils/get-public-rpc-client', () => ({
13
+ getPublicRpcClient: vi.fn(() => createMockPublicClient()),
14
+ }));
15
+
16
+ describe('useCurrencyBalance', () => {
17
+ const defaultArgs = {
18
+ chainId: 1,
19
+ userAddress: '0x1234567890123456789012345678901234567890' as `0x${string}`,
20
+ currencyAddress: zeroAddress,
21
+ };
22
+
23
+ beforeEach(() => {
24
+ vi.clearAllMocks();
25
+ });
26
+
27
+ it('should fetch native token balance successfully', async () => {
28
+ const { result } = renderHook(() => useCurrencyBalance(defaultArgs));
29
+
30
+ // Initially loading
31
+ expect(result.current.isLoading).toBe(true);
32
+ expect(result.current.data).toBeUndefined();
33
+
34
+ // Wait for data to be loaded
35
+ await waitFor(() => {
36
+ expect(result.current.isLoading).toBe(false);
37
+ });
38
+
39
+ // Verify the data matches our mock
40
+ expect(result.current.data).toEqual({
41
+ value: BigInt('1000000000000000000'),
42
+ formatted: '1',
43
+ });
44
+ expect(result.current.error).toBeNull();
45
+ expect(commonPublicClientMocks.getBalance).toHaveBeenCalledWith({
46
+ address: defaultArgs.userAddress,
47
+ });
48
+ });
49
+
50
+ it('should fetch ERC20 token balance successfully', async () => {
51
+ const erc20Args = {
52
+ ...defaultArgs,
53
+ currencyAddress:
54
+ '0x1234567890123456789012345678901234567890' as `0x${string}`,
55
+ };
56
+
57
+ const { result } = renderHook(() => useCurrencyBalance(erc20Args));
58
+
59
+ // Initially loading
60
+ expect(result.current.isLoading).toBe(true);
61
+ expect(result.current.data).toBeUndefined();
62
+
63
+ // Wait for data to be loaded
64
+ await waitFor(() => {
65
+ expect(result.current.isLoading).toBe(false);
66
+ });
67
+
68
+ // Verify the data matches our mock
69
+ expect(result.current.data).toEqual({
70
+ value: BigInt('1000000000000000000'),
71
+ formatted: '1',
72
+ });
73
+ expect(result.current.error).toBeNull();
74
+ expect(commonPublicClientMocks.readContract).toHaveBeenCalledTimes(2);
75
+ });
76
+
77
+ it('should return skipToken when required parameters are missing', () => {
78
+ const { result } = renderHook(() =>
79
+ useCurrencyBalance({
80
+ chainId: undefined,
81
+ userAddress: undefined,
82
+ currencyAddress: undefined,
83
+ }),
84
+ );
85
+
86
+ expect(result.current.data).toBeUndefined();
87
+ expect(result.current.isLoading).toBe(false);
88
+ expect(commonPublicClientMocks.getBalance).not.toHaveBeenCalled();
89
+ expect(commonPublicClientMocks.readContract).not.toHaveBeenCalled();
90
+ });
91
+
92
+ it('should handle errors from public client', async () => {
93
+ // Mock error response
94
+ const mockError = new Error('Failed to fetch balance');
95
+ const mockPublicClient = createMockPublicClient({
96
+ getBalance: vi.fn().mockRejectedValue(mockError),
97
+ });
98
+
99
+ // Override the mock for this test
100
+ vi.mocked(getPublicRpcClient).mockReturnValue(mockPublicClient);
101
+
102
+ const { result } = renderHook(() => useCurrencyBalance(defaultArgs));
103
+
104
+ await waitFor(() => {
105
+ expect(result.current.isError).toBe(true);
106
+ });
107
+
108
+ expect(result.current.error).toBeDefined();
109
+ expect(result.current.data).toBeUndefined();
110
+ });
111
+ });
@@ -0,0 +1,127 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { useFilters } from '../useFilters';
3
+ import { renderHook, waitFor } from '../../_internal/test-utils';
4
+ import { zeroAddress } from 'viem';
5
+ import type { UseFiltersArgs } from '../useFilters';
6
+ import { http, HttpResponse } from 'msw';
7
+ import { mockMetadataEndpoint } from '../../_internal/api/__mocks__/metadata.msw';
8
+ import { server } from '../../_internal/test/setup';
9
+
10
+ describe('useFilters', () => {
11
+ const defaultArgs: UseFiltersArgs = {
12
+ chainId: '1',
13
+ collectionAddress: zeroAddress,
14
+ };
15
+
16
+ it('should fetch filters successfully', async () => {
17
+ const { result } = renderHook(() => useFilters(defaultArgs));
18
+
19
+ // Initially loading
20
+ expect(result.current.isLoading).toBe(true);
21
+ expect(result.current.data).toBeUndefined();
22
+
23
+ // Wait for data to be loaded
24
+ await waitFor(() => {
25
+ expect(result.current.isLoading).toBe(false);
26
+ });
27
+
28
+ expect(result.current.data).toBeDefined();
29
+ expect(result.current.error).toBeNull();
30
+ });
31
+
32
+ it('should handle error states', async () => {
33
+ // Override the handler for this test to return an error
34
+ server.use(
35
+ http.post(mockMetadataEndpoint('TokenCollectionFilters'), () => {
36
+ return HttpResponse.json(
37
+ { error: { message: 'Failed to fetch filters' } },
38
+ { status: 500 },
39
+ );
40
+ }),
41
+ );
42
+
43
+ const { result } = renderHook(() => useFilters(defaultArgs));
44
+
45
+ await waitFor(() => {
46
+ expect(result.current.isError).toBe(true);
47
+ });
48
+
49
+ expect(result.current.error).toBeDefined();
50
+ expect(result.current.data).toBeUndefined();
51
+ });
52
+
53
+ it('should apply different filter exclusion rules', async () => {
54
+ const { result } = renderHook(() => useFilters(defaultArgs));
55
+
56
+ await waitFor(() => {
57
+ expect(result.current.isSuccess).toBe(true);
58
+ });
59
+
60
+ // Verify that:
61
+ // 1. "Sample" is excluded from Type filter
62
+ // 2. Rarity filter is unchanged
63
+ // 3. Filters are in the correct order
64
+ expect(result.current.data).toMatchInlineSnapshot(`
65
+ [
66
+ {
67
+ "name": "Type",
68
+ "type": "STRING",
69
+ "values": [
70
+ "Mock",
71
+ "Test",
72
+ ],
73
+ },
74
+ {
75
+ "name": "Rarity",
76
+ "type": "STRING",
77
+ "values": [
78
+ "Common",
79
+ "Uncommon",
80
+ "Rare",
81
+ "Epic",
82
+ "Legendary",
83
+ ],
84
+ },
85
+ ]
86
+ `);
87
+ });
88
+
89
+ it('should validate input parameters', async () => {
90
+ const invalidArgs: UseFiltersArgs = {
91
+ ...defaultArgs,
92
+ // @ts-expect-error
93
+ chainId: {}, // Using an object instead of a string/number will fail validation
94
+ };
95
+
96
+ const { result } = renderHook(() => useFilters(invalidArgs));
97
+
98
+ await waitFor(() => {
99
+ expect(result.current.isError).toBe(true);
100
+ });
101
+
102
+ expect(result.current.error).toBeDefined();
103
+ });
104
+
105
+ it('should return filter values in correct format', async () => {
106
+ const { result } = renderHook(() => useFilters(defaultArgs));
107
+
108
+ await waitFor(() => {
109
+ expect(result.current.isSuccess).toBe(true);
110
+ });
111
+
112
+ // Verify filter structure and processing
113
+ expect(result.current.data).toEqual(
114
+ expect.arrayContaining([
115
+ expect.objectContaining({
116
+ name: expect.any(String),
117
+ type: expect.any(String),
118
+ values: expect.arrayContaining([expect.any(String)]),
119
+ }),
120
+ ]),
121
+ );
122
+
123
+ // Verify that "Sample" is excluded from Type filter
124
+ const typeFilter = result.current.data?.find((f) => f.name === 'Type');
125
+ expect(typeFilter?.values).not.toContain('Sample');
126
+ });
127
+ });
@@ -0,0 +1,101 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { useFloorOrder } from '../useFloorOrder';
3
+ import { renderHook, waitFor } from '../../_internal/test-utils';
4
+ import { zeroAddress } from 'viem';
5
+ import type { UseFloorOrderArgs } from '../useFloorOrder';
6
+ import { http, HttpResponse } from 'msw';
7
+ import {
8
+ mockCollectibleOrder,
9
+ mockMarketplaceEndpoint,
10
+ } from '../../_internal/api/__mocks__/marketplace.msw';
11
+ import { server } from '../../_internal/test/setup';
12
+
13
+ describe('useFloorOrder', () => {
14
+ const defaultArgs: UseFloorOrderArgs = {
15
+ chainId: '1',
16
+ collectionAddress: zeroAddress,
17
+ query: {},
18
+ };
19
+
20
+ it('should fetch floor order data successfully', async () => {
21
+ const { result } = renderHook(() => useFloorOrder(defaultArgs));
22
+
23
+ // Initially loading
24
+ expect(result.current.isLoading).toBe(true);
25
+ expect(result.current.data).toBeUndefined();
26
+
27
+ // Wait for data to be loaded
28
+ await waitFor(() => {
29
+ expect(result.current.isLoading).toBe(false);
30
+ });
31
+
32
+ // Verify the data matches our mock
33
+ expect(result.current.data).toEqual(mockCollectibleOrder);
34
+ expect(result.current.error).toBeNull();
35
+ });
36
+
37
+ it('should handle error states', async () => {
38
+ // Override the handler for this test to return an error
39
+ server.use(
40
+ http.post(mockMarketplaceEndpoint('GetFloorOrder'), () => {
41
+ return HttpResponse.json(
42
+ { error: { message: 'Failed to fetch floor order' } },
43
+ { status: 500 },
44
+ );
45
+ }),
46
+ );
47
+
48
+ const { result } = renderHook(() => useFloorOrder(defaultArgs));
49
+
50
+ await waitFor(() => {
51
+ expect(result.current.isError).toBe(true);
52
+ });
53
+
54
+ expect(result.current.error).toBeDefined();
55
+ expect(result.current.data).toBeUndefined();
56
+ });
57
+
58
+ it('should refetch when args change', async () => {
59
+ const { result, rerender } = renderHook(() => useFloorOrder(defaultArgs));
60
+
61
+ // Wait for initial data
62
+ await waitFor(() => {
63
+ expect(result.current.isLoading).toBe(false);
64
+ });
65
+
66
+ // Change args and rerender
67
+ const newArgs = {
68
+ ...defaultArgs,
69
+ collectionAddress:
70
+ '0x1234567890123456789012345678901234567890' as `0x${string}`,
71
+ };
72
+
73
+ rerender(() => useFloorOrder(newArgs));
74
+
75
+ // Wait for new data
76
+ await waitFor(() => {
77
+ expect(result.current.data).toBeDefined();
78
+ });
79
+
80
+ // Verify that the query was refetched with new args
81
+ expect(result.current.data).toBeDefined();
82
+ expect(result.current.isSuccess).toBe(true);
83
+ });
84
+
85
+ it('should handle undefined query params', async () => {
86
+ const argsWithoutQuery: UseFloorOrderArgs = {
87
+ chainId: '1',
88
+ collectionAddress: zeroAddress,
89
+ query: {},
90
+ };
91
+
92
+ const { result } = renderHook(() => useFloorOrder(argsWithoutQuery));
93
+
94
+ await waitFor(() => {
95
+ expect(result.current.isLoading).toBe(false);
96
+ });
97
+
98
+ expect(result.current.data).toBeDefined();
99
+ expect(result.current.error).toBeNull();
100
+ });
101
+ });
@@ -0,0 +1,173 @@
1
+ import { describe, expect, it, vi, beforeEach } from 'vitest';
2
+ import { useGenerateBuyTransaction } from '../useGenerateBuyTransaction';
3
+ import { MarketplaceKind, WalletKind } from '../../_internal';
4
+ import { http, HttpResponse } from 'msw';
5
+ import {
6
+ mockSteps,
7
+ mockMarketplaceEndpoint,
8
+ } from '../../_internal/api/__mocks__/marketplace.msw';
9
+ import { server } from '../../_internal/test/setup';
10
+ import { renderHook } from '../../_internal/test-utils';
11
+ import { useDisconnect, useConnect, mock, useAccount } from 'wagmi';
12
+
13
+ describe('useGenerateBuyTransaction', () => {
14
+ const defaultArgs = {
15
+ chainId: '1',
16
+ collectionAddress:
17
+ '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' as `0x${string}`,
18
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
19
+ ordersData: [
20
+ {
21
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
22
+ orderId: '1',
23
+ quantity: '1',
24
+ price: '1',
25
+ currency: 'ETH',
26
+ currencyAddress:
27
+ '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' as `0x${string}`,
28
+ currencyDecimals: 18,
29
+ currencySymbol: 'ETH',
30
+ currencyName: 'Ether',
31
+ },
32
+ ],
33
+ walletType: WalletKind.sequence,
34
+ query: {},
35
+ };
36
+
37
+ beforeEach(() => {
38
+ vi.clearAllMocks();
39
+
40
+ // Mock default steps response with delay to simulate loading state
41
+ server.use(
42
+ http.post(mockMarketplaceEndpoint('GenerateBuyTransaction'), async () => {
43
+ await new Promise((resolve) => setTimeout(resolve, 100)); // Add small delay
44
+ return HttpResponse.json({
45
+ steps: mockSteps,
46
+ });
47
+ }),
48
+ );
49
+ });
50
+
51
+ it('should skip query when no address is available', async () => {
52
+ const { result: generateBuyTransactionResult } = renderHook(() =>
53
+ useGenerateBuyTransaction(defaultArgs),
54
+ );
55
+ const { result: disconnectResult } = renderHook(() => useDisconnect());
56
+
57
+ // make sure we are disconnected
58
+ await disconnectResult.current.disconnectAsync();
59
+
60
+ expect(generateBuyTransactionResult.current.isLoading).toBe(false);
61
+ expect(generateBuyTransactionResult.current.error).toBeNull();
62
+ expect(generateBuyTransactionResult.current.data).toBeUndefined();
63
+ });
64
+
65
+ it('should fetch transaction data when wallet is connected', async () => {
66
+ // Setup mock wallet connection
67
+ const mockAddress = '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266';
68
+ const { result: accountResult } = renderHook(() => useAccount());
69
+ const { result: connectResult } = renderHook(() => useConnect());
70
+
71
+ await connectResult.current.connectAsync({
72
+ connector: mock({
73
+ accounts: [mockAddress],
74
+ }),
75
+ });
76
+
77
+ // Ensure we have a connected wallet
78
+ expect(accountResult.current.address).toBe(mockAddress);
79
+
80
+ const { result } = renderHook(() => useGenerateBuyTransaction(defaultArgs));
81
+
82
+ // Initial state should be loading
83
+ expect(result.current.isLoading).toBe(true);
84
+ expect(result.current.data).toBeUndefined();
85
+
86
+ // Wait for the query to complete
87
+ await vi.waitFor(() => {
88
+ expect(result.current.isLoading).toBe(false);
89
+ });
90
+
91
+ // Verify the data matches our mock
92
+ expect(result.current.error).toBeNull();
93
+ expect(result.current.data).toEqual(mockSteps);
94
+ });
95
+
96
+ it('should handle API errors correctly', async () => {
97
+ // Setup mock wallet connection
98
+ const mockAddress = '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266';
99
+ const { result: connectResult } = renderHook(() => useConnect());
100
+
101
+ await connectResult.current.connectAsync({
102
+ connector: mock({
103
+ accounts: [mockAddress],
104
+ }),
105
+ });
106
+
107
+ // Mock API error response
108
+ server.use(
109
+ http.post(mockMarketplaceEndpoint('GenerateBuyTransaction'), () => {
110
+ return HttpResponse.json(
111
+ { message: 'Invalid order data' },
112
+ { status: 400 },
113
+ );
114
+ }),
115
+ );
116
+
117
+ const { result } = renderHook(() => useGenerateBuyTransaction(defaultArgs));
118
+
119
+ // Initial state should be loading
120
+ expect(result.current.isLoading).toBe(true);
121
+ expect(result.current.error).toBeNull();
122
+ expect(result.current.data).toBeUndefined();
123
+
124
+ // Wait for the query to complete
125
+ await vi.waitFor(() => {
126
+ expect(result.current.isLoading).toBe(false);
127
+ });
128
+
129
+ // Verify error state
130
+ expect(result.current.error).toBeTruthy();
131
+ expect(result.current.data).toBeUndefined();
132
+ });
133
+
134
+ it('should handle invalid input arguments correctly', async () => {
135
+ // Setup mock wallet connection
136
+ const mockAddress = '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266';
137
+ const { result: connectResult } = renderHook(() => useConnect());
138
+
139
+ await connectResult.current.connectAsync({
140
+ connector: mock({
141
+ accounts: [mockAddress],
142
+ }),
143
+ });
144
+
145
+ // Create invalid args by omitting required fields and using invalid types
146
+ const invalidArgs = {
147
+ ...defaultArgs,
148
+ chainId: 1, // Should be string
149
+ collectionAddress: 'invalid-address', // Invalid address format
150
+ ordersData: [
151
+ {
152
+ ...defaultArgs.ordersData[0],
153
+ quantity: 1, // Should be string
154
+ orderId: undefined, // Required field missing
155
+ },
156
+ ],
157
+ };
158
+
159
+ const { result } = renderHook(() =>
160
+ // @ts-expect-error - Testing runtime validation
161
+ useGenerateBuyTransaction(invalidArgs),
162
+ );
163
+
164
+ // Wait for the query to complete
165
+ await vi.waitFor(() => {
166
+ expect(result.current.isLoading).toBe(false);
167
+ });
168
+
169
+ // Verify validation error state
170
+ expect(result.current.error).toBeTruthy();
171
+ expect(result.current.data).toBeUndefined();
172
+ });
173
+ });