@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
@@ -1,267 +1,209 @@
1
- import { renderHook } from '@testing-library/react';
2
- import { describe, it, expect, vi, beforeEach } from 'vitest';
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3
2
  import { useCheckoutOptions } from '../useCheckoutOptions';
4
3
  import { useWallet } from '../../../../../_internal/wallet/useWallet';
5
- import { useConfig } from '../../../../../hooks';
6
4
  import { useFees } from '../useFees';
5
+ import { MarketplaceKind } from '../../../../../_internal';
7
6
  import {
8
- MarketplaceKind,
9
- getMarketplaceClient,
10
- } from '../../../../../_internal';
11
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
12
- import type { ReactNode } from 'react';
7
+ renderHook,
8
+ waitFor,
9
+ type RenderHookOptions,
10
+ } from '../../../../../_internal/test-utils';
11
+ import { http, HttpResponse } from 'msw';
12
+ import { server } from '../../../../../_internal/test/setup';
13
+ import { createMockWallet } from '../../../../../_internal/test/mocks/wallet';
14
+ import { mockMarketplaceEndpoint } from '../../../../../_internal/api/__mocks__/marketplace.msw';
15
+ import { zeroAddress } from 'viem';
16
+ import { TransactionCrypto } from '../../../../../_internal/api/marketplace.gen';
13
17
 
14
18
  // Mock dependencies
15
- vi.mock('../../../../../_internal/wallet/useWallet', () => ({
16
- useWallet: vi.fn(),
17
- }));
18
-
19
- vi.mock('../../../../../hooks', () => ({
20
- useConfig: vi.fn(),
21
- }));
22
-
23
- vi.mock('../useFees', () => ({
24
- useFees: vi.fn(),
25
- }));
26
-
27
- vi.mock('../../../../../_internal', async () => {
28
- const actual = (await vi.importActual('../../../../../_internal')) as Record<
29
- string,
30
- unknown
31
- >;
32
- return {
33
- ...actual,
34
- getMarketplaceClient: vi.fn(),
35
- };
36
- });
19
+ vi.mock('../../../../../_internal/wallet/useWallet');
20
+ vi.mock('../useFees');
37
21
 
38
- const createWrapper = () => {
39
- const queryClient = new QueryClient({
40
- defaultOptions: {
41
- queries: {
42
- retry: false,
43
- },
44
- },
45
- });
46
- return ({ children }: { children: ReactNode }) => (
47
- <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
48
- );
49
- };
22
+ // Create mock wallet instance
23
+ const mockWallet = createMockWallet({
24
+ address: vi.fn().mockResolvedValue(zeroAddress),
25
+ });
50
26
 
51
27
  describe('useCheckoutOptions', () => {
52
- const defaultProps = {
28
+ const defaultInput = {
53
29
  chainId: 1,
54
- collectionAddress: '0x123' as `0x${string}`,
55
- orderId: '1',
30
+ collectionAddress: zeroAddress,
31
+ orderId: '123',
56
32
  marketplace: MarketplaceKind.sequence_marketplace_v2,
57
33
  };
58
34
 
59
35
  beforeEach(() => {
60
36
  vi.clearAllMocks();
61
37
 
62
- // Setup default mock implementations
63
- (useConfig as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
64
- projectAccessKey: 'test-key',
65
- projectId: 'test-id',
66
- });
38
+ // Set up default wallet mock
39
+ vi.mocked(useWallet).mockReturnValue({
40
+ wallet: mockWallet,
41
+ isLoading: false,
42
+ isError: false,
43
+ });
44
+
45
+ // Set up default fees mock
46
+ vi.mocked(useFees).mockReturnValue({
47
+ amount: '100000000000000000',
48
+ receiver: zeroAddress,
49
+ });
50
+
51
+ // Set up default API response
52
+ server.use(
53
+ http.post(mockMarketplaceEndpoint('CheckoutOptionsMarketplace'), () => {
54
+ return HttpResponse.json({
55
+ options: {
56
+ crypto: TransactionCrypto.all,
57
+ swap: [],
58
+ nftCheckout: [],
59
+ onRamp: [],
60
+ },
61
+ });
62
+ }),
63
+ );
64
+ });
67
65
 
68
- (useFees as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
69
- amount: '250',
70
- receiver: '0x123',
71
- });
66
+ afterEach(() => {
67
+ server.resetHandlers();
72
68
  });
73
69
 
74
- it('should return undefined when wallet is not available', () => {
75
- // Mock useWallet to return no wallet
76
- (useWallet as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
77
- wallet: undefined,
78
- });
70
+ it('should fetch checkout options successfully', async () => {
71
+ const { result } = renderHook(() => useCheckoutOptions(defaultInput));
79
72
 
80
- const { result } = renderHook(() => useCheckoutOptions(defaultProps), {
81
- wrapper: createWrapper(),
73
+ await waitFor(() => {
74
+ expect(result.current.isSuccess).toBe(true);
82
75
  });
83
76
 
84
- expect(result.current.data).toBeUndefined();
77
+ expect(result.current.data).toEqual({
78
+ crypto: TransactionCrypto.all,
79
+ swap: [],
80
+ nftCheckout: [],
81
+ onRamp: [],
82
+ });
85
83
  });
86
84
 
87
- it('should fetch checkout options when wallet is available', async () => {
88
- // Mock useWallet to return a valid wallet
89
- (useWallet as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
90
- wallet: {
91
- address: async () => '0x123',
92
- },
85
+ it('should not fetch when wallet is not available', () => {
86
+ vi.mocked(useWallet).mockReturnValue({
87
+ wallet: null,
88
+ isLoading: false,
89
+ isError: false,
93
90
  });
94
91
 
95
- // Mock the marketplace client
96
- const checkoutOptionsMarketplaceMock = vi.fn().mockResolvedValue({
97
- options: {
98
- swap: [],
99
- nftCheckout: [],
100
- onRamp: [],
101
- crypto: ['ETH', 'USDC'],
102
- },
103
- });
92
+ const { result } = renderHook(() => useCheckoutOptions(defaultInput));
104
93
 
105
- const marketplaceClientMock = {
106
- checkoutOptionsMarketplace: checkoutOptionsMarketplaceMock,
107
- };
94
+ expect(result.current.data).toBeUndefined();
95
+ expect(result.current.isLoading).toBe(false);
96
+ });
108
97
 
109
- (
110
- getMarketplaceClient as unknown as ReturnType<typeof vi.fn>
111
- ).mockReturnValue(marketplaceClientMock);
98
+ it('should include fees in the API request', async () => {
99
+ const mockFeeAmount = '200000000000000000';
100
+ vi.mocked(useFees).mockReturnValue({
101
+ amount: mockFeeAmount,
102
+ receiver: zeroAddress,
103
+ });
104
+
105
+ let capturedRequest:
106
+ | {
107
+ wallet: string;
108
+ orders: Array<{
109
+ contractAddress: string;
110
+ orderId: string;
111
+ marketplace: MarketplaceKind;
112
+ }>;
113
+ additionalFee: number;
114
+ }
115
+ | undefined;
116
+
117
+ server.use(
118
+ http.post(
119
+ mockMarketplaceEndpoint('CheckoutOptionsMarketplace'),
120
+ async ({ request }) => {
121
+ capturedRequest = (await request.json()) as typeof capturedRequest;
122
+ return HttpResponse.json({
123
+ options: {
124
+ crypto: TransactionCrypto.all,
125
+ swap: [],
126
+ nftCheckout: [],
127
+ onRamp: [],
128
+ },
129
+ });
130
+ },
131
+ ),
132
+ );
112
133
 
113
- const { result } = renderHook(() => useCheckoutOptions(defaultProps), {
114
- wrapper: createWrapper(),
115
- });
134
+ const { result } = renderHook(() => useCheckoutOptions(defaultInput));
116
135
 
117
- // Wait for the query to complete
118
- await vi.waitFor(() => {
136
+ await waitFor(() => {
119
137
  expect(result.current.isSuccess).toBe(true);
120
138
  });
121
139
 
122
- // Verify the marketplace client was called with correct parameters
123
- expect(checkoutOptionsMarketplaceMock).toHaveBeenCalledWith({
124
- wallet: '0x123',
125
- orders: [
126
- {
127
- contractAddress: defaultProps.collectionAddress,
128
- orderId: defaultProps.orderId,
129
- marketplace: defaultProps.marketplace,
130
- },
131
- ],
132
- additionalFee: 250,
133
- });
134
-
135
- // Verify the returned data
136
- expect(result.current.data).toEqual({
137
- swap: [],
138
- nftCheckout: [],
139
- onRamp: [],
140
- crypto: ['ETH', 'USDC'],
141
- });
140
+ expect(capturedRequest?.additionalFee).toBe(Number(mockFeeAmount));
142
141
  });
143
142
 
144
- it('should call marketplaceClient.checkoutOptionsMarketplace with correct params', async () => {
145
- // Mock useWallet to return a valid wallet
146
- (useWallet as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
147
- wallet: {
148
- address: async () => '0x456',
149
- },
150
- });
143
+ it('should handle API errors gracefully', async () => {
144
+ server.use(
145
+ http.post(mockMarketplaceEndpoint('CheckoutOptionsMarketplace'), () => {
146
+ return HttpResponse.error();
147
+ }),
148
+ );
151
149
 
152
- // Mock the marketplace client
153
- const checkoutOptionsMarketplaceMock = vi.fn().mockResolvedValue({
154
- options: {
155
- swap: ['uniswap'],
156
- nftCheckout: ['moonpay'],
157
- onRamp: ['ramp'],
158
- crypto: ['ETH'],
159
- },
160
- });
150
+ const { result } = renderHook(() => useCheckoutOptions(defaultInput));
161
151
 
162
- const marketplaceClientMock = {
163
- checkoutOptionsMarketplace: checkoutOptionsMarketplaceMock,
164
- };
165
-
166
- (
167
- getMarketplaceClient as unknown as ReturnType<typeof vi.fn>
168
- ).mockReturnValue(marketplaceClientMock);
169
-
170
- const customProps = {
171
- chainId: 137,
172
- collectionAddress: '0x789' as `0x${string}`,
173
- orderId: '42',
174
- marketplace: MarketplaceKind.sequence_marketplace_v2,
175
- };
176
-
177
- // Mock fees with different values to ensure they're passed correctly
178
- (useFees as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
179
- amount: '500',
180
- receiver: '0xabc',
152
+ await waitFor(() => {
153
+ expect(result.current.isError).toBe(true);
181
154
  });
182
155
 
183
- renderHook(() => useCheckoutOptions(customProps), {
184
- wrapper: createWrapper(),
156
+ expect(result.current.data).toBeUndefined();
157
+ });
158
+
159
+ it('should refetch when input parameters change', async () => {
160
+ const { result, rerender } = renderHook<
161
+ typeof defaultInput,
162
+ ReturnType<typeof useCheckoutOptions>
163
+ >((props) => useCheckoutOptions(props), {
164
+ initialProps: defaultInput,
165
+ } as RenderHookOptions<typeof defaultInput>);
166
+
167
+ await waitFor(() => {
168
+ expect(result.current.isSuccess).toBe(true);
185
169
  });
186
170
 
187
- // Wait for the query to be called
188
- await vi.waitFor(() => {
189
- expect(checkoutOptionsMarketplaceMock).toHaveBeenCalledTimes(1);
171
+ // Change input
172
+ rerender({
173
+ ...defaultInput,
174
+ orderId: '456',
190
175
  });
191
176
 
192
- // Verify exact parameters passed to the marketplace client
193
- expect(checkoutOptionsMarketplaceMock).toHaveBeenCalledWith({
194
- wallet: '0x456',
195
- orders: [
196
- {
197
- contractAddress: customProps.collectionAddress,
198
- orderId: customProps.orderId,
199
- marketplace: customProps.marketplace,
200
- },
201
- ],
202
- additionalFee: 500, // Using the mocked fee amount
177
+ await waitFor(() => {
178
+ expect(result.current.isSuccess).toBe(true);
203
179
  });
204
180
 
205
- // Verify the marketplace client was initialized with correct chain ID
206
- expect(getMarketplaceClient).toHaveBeenCalledWith(
207
- customProps.chainId,
208
- expect.objectContaining({
209
- projectAccessKey: 'test-key',
210
- projectId: 'test-id',
211
- }),
212
- );
181
+ // Verify that the query was refetched
182
+ expect(result.current.data).toEqual({
183
+ crypto: TransactionCrypto.all,
184
+ swap: [],
185
+ nftCheckout: [],
186
+ onRamp: [],
187
+ });
213
188
  });
214
189
 
215
- it('should handle API errors', async () => {
216
- // Mock useWallet to return a valid wallet
217
- (useWallet as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
218
- wallet: {
219
- address: async () => '0x123',
220
- },
190
+ it('should handle wallet address resolution failure', async () => {
191
+ const mockWalletWithFailure = createMockWallet({
192
+ address: vi.fn().mockRejectedValue(new Error('Failed to get address')),
221
193
  });
222
194
 
223
- // Mock the marketplace client to throw an error
224
- const errorMessage = 'Failed to fetch checkout options';
225
- const checkoutOptionsMarketplaceMock = vi
226
- .fn()
227
- .mockRejectedValue(new Error(errorMessage));
228
-
229
- const marketplaceClientMock = {
230
- checkoutOptionsMarketplace: checkoutOptionsMarketplaceMock,
231
- };
232
-
233
- (
234
- getMarketplaceClient as unknown as ReturnType<typeof vi.fn>
235
- ).mockReturnValue(marketplaceClientMock);
236
-
237
- const { result } = renderHook(() => useCheckoutOptions(defaultProps), {
238
- wrapper: createWrapper(),
195
+ vi.mocked(useWallet).mockReturnValue({
196
+ wallet: mockWalletWithFailure,
197
+ isLoading: false,
198
+ isError: false,
239
199
  });
240
200
 
241
- // Wait for the query to fail
242
- await vi.waitFor(() => {
201
+ const { result } = renderHook(() => useCheckoutOptions(defaultInput));
202
+
203
+ await waitFor(() => {
243
204
  expect(result.current.isError).toBe(true);
244
205
  });
245
206
 
246
- // Verify error state
247
207
  expect(result.current.error).toBeDefined();
248
- expect(result.current.error).toBeInstanceOf(Error);
249
- expect((result.current.error as Error).message).toBe(errorMessage);
250
-
251
- // Verify data is undefined when there's an error
252
- expect(result.current.data).toBeUndefined();
253
-
254
- // Verify the API was called with correct parameters despite the error
255
- expect(checkoutOptionsMarketplaceMock).toHaveBeenCalledWith({
256
- wallet: '0x123',
257
- orders: [
258
- {
259
- contractAddress: defaultProps.collectionAddress,
260
- orderId: defaultProps.orderId,
261
- marketplace: defaultProps.marketplace,
262
- },
263
- ],
264
- additionalFee: 250,
265
- });
266
208
  });
267
209
  });
@@ -1,29 +1,14 @@
1
- import { renderHook } from '@testing-library/react';
2
1
  import { describe, it, expect, vi, beforeEach } from 'vitest';
3
2
  import { useFees } from '../useFees';
4
3
  import { useMarketplaceConfig } from '../../../../../hooks';
5
4
  import { avalanche, optimism } from 'viem/chains';
6
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
7
- import type { ReactNode } from 'react';
5
+ import { renderHook } from '../../../../../_internal/test-utils';
8
6
 
9
7
  // Mock dependencies
10
8
  vi.mock('../../../../../hooks', () => ({
11
9
  useMarketplaceConfig: vi.fn(),
12
10
  }));
13
11
 
14
- const createWrapper = () => {
15
- const queryClient = new QueryClient({
16
- defaultOptions: {
17
- queries: {
18
- retry: false,
19
- },
20
- },
21
- });
22
- return ({ children }: { children: ReactNode }) => (
23
- <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
24
- );
25
- };
26
-
27
12
  describe('useFees', () => {
28
13
  const defaultProps = {
29
14
  chainId: 1,
@@ -47,17 +32,15 @@ describe('useFees', () => {
47
32
  data: {
48
33
  collections: [
49
34
  {
50
- collectionAddress: '0x456',
35
+ address: '0x456',
51
36
  chainId: '1',
52
- marketplaceFeePercentage: '5.0',
37
+ feePercentage: '5.0',
53
38
  },
54
39
  ],
55
40
  },
56
41
  });
57
42
 
58
- const { result } = renderHook(() => useFees(defaultProps), {
59
- wrapper: createWrapper(),
60
- });
43
+ const { result } = renderHook(() => useFees(defaultProps));
61
44
 
62
45
  // Default fee should be 2.5%, which is 250 in BPS (basis points)
63
46
  expect(result.current).toEqual({
@@ -78,19 +61,16 @@ describe('useFees', () => {
78
61
  data: {
79
62
  collections: [
80
63
  {
81
- collectionAddress,
64
+ address: collectionAddress,
82
65
  chainId: chainId.toString(),
83
- marketplaceFeePercentage: collectionFee,
66
+ feePercentage: collectionFee,
84
67
  },
85
68
  ],
86
69
  },
87
70
  });
88
71
 
89
- const { result } = renderHook(
90
- () => useFees({ chainId, collectionAddress }),
91
- {
92
- wrapper: createWrapper(),
93
- },
72
+ const { result } = renderHook(() =>
73
+ useFees({ chainId, collectionAddress }),
94
74
  );
95
75
 
96
76
  // 5.0% fee should be 500 in BPS (basis points)
@@ -102,11 +82,8 @@ describe('useFees', () => {
102
82
 
103
83
  it('should use Avalanche/Optimism fee recipient for those chains', () => {
104
84
  // Test Avalanche chain
105
- const { result: avalancheResult } = renderHook(
106
- () => useFees({ ...defaultProps, chainId: avalanche.id }),
107
- {
108
- wrapper: createWrapper(),
109
- },
85
+ const { result: avalancheResult } = renderHook(() =>
86
+ useFees({ ...defaultProps, chainId: avalanche.id }),
110
87
  );
111
88
 
112
89
  expect(avalancheResult.current.receiver).toBe(
@@ -114,11 +91,8 @@ describe('useFees', () => {
114
91
  );
115
92
 
116
93
  // Test Optimism chain
117
- const { result: optimismResult } = renderHook(
118
- () => useFees({ ...defaultProps, chainId: optimism.id }),
119
- {
120
- wrapper: createWrapper(),
121
- },
94
+ const { result: optimismResult } = renderHook(() =>
95
+ useFees({ ...defaultProps, chainId: optimism.id }),
122
96
  );
123
97
 
124
98
  expect(optimismResult.current.receiver).toBe(
@@ -138,23 +112,19 @@ describe('useFees', () => {
138
112
  data: {
139
113
  collections: [
140
114
  {
141
- collectionAddress: collectionAddress.toLowerCase(),
115
+ address: collectionAddress.toLowerCase(),
142
116
  chainId: chainId.toString(),
143
- marketplaceFeePercentage: collectionFee,
117
+ feePercentage: collectionFee,
144
118
  },
145
119
  ],
146
120
  },
147
121
  });
148
122
 
149
- const { result } = renderHook(
150
- () =>
151
- useFees({
152
- chainId,
153
- collectionAddress: collectionAddress.toUpperCase(),
154
- }),
155
- {
156
- wrapper: createWrapper(),
157
- },
123
+ const { result } = renderHook(() =>
124
+ useFees({
125
+ chainId,
126
+ collectionAddress: collectionAddress.toUpperCase(),
127
+ }),
158
128
  );
159
129
 
160
130
  // 3.5% fee should be 350 in BPS (basis points)
@@ -5,7 +5,10 @@ import { useMarketplaceConfig } from '../../../../hooks';
5
5
  export const useFees = ({
6
6
  chainId,
7
7
  collectionAddress,
8
- }: { chainId: number; collectionAddress: string }) => {
8
+ }: {
9
+ chainId: number;
10
+ collectionAddress: string;
11
+ }) => {
9
12
  const defaultFee = 2.5;
10
13
  const defaultPlatformFeeRecipient =
11
14
  '0x858dB1cbF6D09D447C96A11603189b49B2D1C219';
@@ -15,8 +18,7 @@ export const useFees = ({
15
18
 
16
19
  const collection = marketplaceConfig?.collections.find(
17
20
  (collection) =>
18
- collection.collectionAddress.toLowerCase() ===
19
- collectionAddress.toLowerCase() &&
21
+ collection.address.toLowerCase() === collectionAddress.toLowerCase() &&
20
22
  chainId === Number(collection.chainId),
21
23
  );
22
24
 
@@ -30,9 +32,7 @@ export const useFees = ({
30
32
  (Number(percentage) * 10000) / 100;
31
33
 
32
34
  return {
33
- amount: percentageToBPS(
34
- collection?.marketplaceFeePercentage || defaultFee,
35
- ).toString(),
35
+ amount: percentageToBPS(collection?.feePercentage || defaultFee).toString(),
36
36
  receiver,
37
37
  } satisfies AdditionalFee;
38
38
  };
@@ -3,8 +3,8 @@ import { observer } from '@legendapp/state/react';
3
3
  import type { Hex } from 'viem';
4
4
  import { formatUnits, parseUnits } from 'viem';
5
5
  import { useCurrency } from '../../../../hooks';
6
- import QuantityInput from '../../_internal/components/quantityInput';
7
6
  import { ActionModal } from '../../_internal/components/actionModal';
7
+ import QuantityInput from '../../_internal/components/quantityInput';
8
8
  import { buyModal$ } from '../store';
9
9
  import type { CheckoutModalProps } from './CheckoutModal';
10
10
 
@@ -28,7 +28,8 @@ export const ERC1155QuantityModal = observer(
28
28
  if (
29
29
  buyModal$.state.checkoutModalLoaded.get() &&
30
30
  buyModal$.isOpen.get() &&
31
- buyModal$.state.checkoutModalIsLoading.get()
31
+ buyModal$.state.checkoutModalIsLoading.get() &&
32
+ buyModal$.state.purchaseProcessing.get()
32
33
  ) {
33
34
  return null;
34
35
  }
@@ -44,6 +45,7 @@ export const ERC1155QuantityModal = observer(
44
45
  label: 'Buy now',
45
46
  onClick: () => {
46
47
  buyModal$.state.checkoutModalIsLoading.set(true);
48
+ buyModal$.state.purchaseProcessing.set(true);
47
49
 
48
50
  buy({
49
51
  quantity: parseUnits(