@0xsequence/marketplace-sdk 0.5.2 → 0.5.4

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 (184) hide show
  1. package/dist/builder-types-Jl3Ymws8.d.ts +73 -0
  2. package/dist/{chunk-XP3WY5AX.js → chunk-7C7ADZ2H.js} +3 -3
  3. package/dist/{chunk-XP3WY5AX.js.map → chunk-7C7ADZ2H.js.map} +1 -1
  4. package/dist/{chunk-FCF57DZI.js → chunk-7FN62HOP.js} +5 -9
  5. package/dist/chunk-7FN62HOP.js.map +1 -0
  6. package/dist/chunk-DZKPDV63.js +27 -0
  7. package/dist/chunk-DZKPDV63.js.map +1 -0
  8. package/dist/{chunk-ZUEQGPLO.js → chunk-J6F5QOW5.js} +2 -2
  9. package/dist/{chunk-ZUEQGPLO.js.map → chunk-J6F5QOW5.js.map} +1 -1
  10. package/dist/{chunk-I37CRQ4S.js → chunk-JWNONWD6.js} +259 -173
  11. package/dist/chunk-JWNONWD6.js.map +1 -0
  12. package/dist/{chunk-LJAB3S6U.js → chunk-TFRAOS7F.js} +22 -13
  13. package/dist/chunk-TFRAOS7F.js.map +1 -0
  14. package/dist/{chunk-MKGSGTQC.js → chunk-TLNRD4BQ.js} +3 -3
  15. package/dist/{chunk-5NORRVPM.js → chunk-UZIAX32Y.js} +1 -1
  16. package/dist/{chunk-5NORRVPM.js.map → chunk-UZIAX32Y.js.map} +1 -1
  17. package/dist/chunk-WGGZEQHL.js +56 -0
  18. package/dist/chunk-WGGZEQHL.js.map +1 -0
  19. package/dist/{chunk-MWDG7UTB.js → chunk-ZBLU3Q22.js} +1 -1
  20. package/dist/{chunk-MSTTVFVQ.js → chunk-ZGVCOQ4I.js} +383 -283
  21. package/dist/chunk-ZGVCOQ4I.js.map +1 -0
  22. package/dist/{create-config-BXvwUh55.d.ts → create-config-DOUq8Day.d.ts} +2 -2
  23. package/dist/index.css +1 -1
  24. package/dist/index.d.ts +5 -4
  25. package/dist/index.js +10 -6
  26. package/dist/{sdk-config-B32_2bG3.d.ts → marketplace.gen-D0ADxbfH.d.ts} +1 -24
  27. package/dist/react/_internal/api/index.d.ts +3 -2
  28. package/dist/react/_internal/databeat/index.css +82 -0
  29. package/dist/react/_internal/databeat/index.css.map +1 -0
  30. package/dist/react/_internal/databeat/index.d.ts +68 -0
  31. package/dist/react/_internal/databeat/index.js +26 -0
  32. package/dist/react/_internal/databeat/index.js.map +1 -0
  33. package/dist/react/_internal/index.d.ts +6 -5
  34. package/dist/react/_internal/index.js +6 -6
  35. package/dist/react/_internal/wagmi/index.d.ts +4 -4
  36. package/dist/react/_internal/wagmi/index.js +1 -1
  37. package/dist/react/hooks/index.d.ts +367 -22
  38. package/dist/react/hooks/index.js +9 -7
  39. package/dist/react/index.css +1 -1
  40. package/dist/react/index.css.map +1 -1
  41. package/dist/react/index.d.ts +7 -6
  42. package/dist/react/index.js +15 -12
  43. package/dist/react/ssr/index.d.ts +54 -41
  44. package/dist/react/ssr/index.js +5 -9
  45. package/dist/react/ssr/index.js.map +1 -1
  46. package/dist/react/ui/components/collectible-card/index.css +1 -1
  47. package/dist/react/ui/components/collectible-card/index.css.map +1 -1
  48. package/dist/react/ui/components/collectible-card/index.d.ts +4 -3
  49. package/dist/react/ui/components/collectible-card/index.js +9 -8
  50. package/dist/react/ui/components/marketplace-logos/index.js +1 -1
  51. package/dist/react/ui/index.css +1 -1
  52. package/dist/react/ui/index.css.map +1 -1
  53. package/dist/react/ui/index.d.ts +4 -3
  54. package/dist/react/ui/index.js +9 -8
  55. package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +4 -3
  56. package/dist/react/ui/modals/_internal/components/actionModal/index.js +6 -6
  57. package/dist/react/ui/styles/index.d.ts +1 -1
  58. package/dist/sdk-config-xWkdBdrL.d.ts +24 -0
  59. package/dist/{services-BRBVE0mm.d.ts → services-Dd2MoBTM.d.ts} +2 -1
  60. package/dist/styles/index.css +1 -1
  61. package/dist/styles/index.css.map +1 -1
  62. package/dist/styles/index.d.ts +1 -1
  63. package/dist/styles/index.js +1 -1
  64. package/dist/types/index.d.ts +4 -5
  65. package/dist/types/index.js +9 -5
  66. package/dist/{types-Yto6KrTN.d.ts → types-vOfhbBkR.d.ts} +3 -2
  67. package/dist/utils/index.d.ts +4 -3
  68. package/dist/utils/index.js +4 -4
  69. package/package.json +12 -10
  70. package/src/react/_internal/api/__mocks__/indexer.msw.ts +197 -0
  71. package/src/react/_internal/api/__mocks__/marketplace.msw.ts +140 -1
  72. package/src/react/_internal/api/__mocks__/metadata.msw.ts +162 -0
  73. package/src/react/_internal/databeat/index.ts +63 -0
  74. package/src/react/_internal/databeat/types.ts +70 -0
  75. package/src/react/_internal/test/mocks/publicClient.ts +39 -0
  76. package/src/react/_internal/test/mocks/wagmi.ts +61 -0
  77. package/src/react/_internal/test/mocks/wallet.ts +61 -0
  78. package/src/react/_internal/test/setup.ts +28 -0
  79. package/src/react/_internal/test-utils.tsx +31 -2
  80. package/src/react/_internal/wagmi/__tests__/create-config.test.ts +53 -20
  81. package/src/react/_internal/wagmi/create-config.ts +3 -4
  82. package/src/react/_internal/wagmi/embedded.ts +1 -4
  83. package/src/react/_internal/wagmi/universal.ts +1 -4
  84. package/src/react/_internal/wallet/wallet.ts +1 -0
  85. package/src/react/hooks/__tests__/useAutoSelectFeeOption.test.tsx +314 -0
  86. package/src/react/hooks/__tests__/useBalanceOfCollectible.test.tsx +148 -0
  87. package/src/react/hooks/__tests__/useCancelOrder.test.tsx +410 -0
  88. package/src/react/hooks/__tests__/useCancelTransactionSteps.test.tsx +269 -0
  89. package/src/react/hooks/__tests__/useCollectible.test.tsx +120 -0
  90. package/src/react/hooks/__tests__/useCollection.test.tsx +101 -0
  91. package/src/react/hooks/__tests__/useCollectionBalanceDetails.test.tsx +175 -0
  92. package/src/react/hooks/__tests__/useCollectionDetails.test.tsx +82 -0
  93. package/src/react/hooks/__tests__/useCollectionDetailsPolling.test.tsx +133 -0
  94. package/src/react/hooks/__tests__/useCountListingsForCollectible.test.tsx +108 -0
  95. package/src/react/hooks/__tests__/useCountOfCollectables.test.tsx +129 -0
  96. package/src/react/hooks/__tests__/useCountOffersForCollectible.test.tsx +108 -0
  97. package/src/react/hooks/__tests__/useCurrencies.test.tsx +176 -0
  98. package/src/react/hooks/__tests__/useCurrency.test.tsx +153 -0
  99. package/src/react/hooks/__tests__/useCurrencyBalance.test.tsx +111 -0
  100. package/src/react/hooks/__tests__/useFilters.test.tsx +127 -0
  101. package/src/react/hooks/__tests__/useFloorOrder.test.tsx +101 -0
  102. package/src/react/hooks/__tests__/useGenerateBuyTransaction.test.tsx +173 -0
  103. package/src/react/hooks/__tests__/useGenerateCancelTransaction.test.tsx +207 -0
  104. package/src/react/hooks/__tests__/useGenerateListingTransaction.test.tsx +207 -0
  105. package/src/react/hooks/__tests__/useGenerateOfferTransaction.test.tsx +205 -0
  106. package/src/react/hooks/__tests__/useGenerateSellTransaction.test.tsx +181 -0
  107. package/src/react/hooks/__tests__/useHighestOffer.test.tsx +118 -0
  108. package/src/react/hooks/__tests__/useListBalances.test.tsx +136 -0
  109. package/src/react/hooks/__tests__/useListCollectibleActivities.test.tsx +200 -0
  110. package/src/react/hooks/__tests__/useListCollectibles.test.tsx +232 -0
  111. package/src/react/hooks/__tests__/useListCollectiblesPaginated.test.tsx +217 -0
  112. package/src/react/hooks/__tests__/useListCollectionActivities.test.tsx +235 -0
  113. package/src/react/hooks/__tests__/useListCollections.test.tsx +296 -0
  114. package/src/react/hooks/__tests__/useListListingsForCollectible.test.tsx +140 -0
  115. package/src/react/hooks/__tests__/useListOffersForCollectible.test.tsx +140 -0
  116. package/src/react/hooks/__tests__/useLowestListing.test.tsx +148 -0
  117. package/src/react/hooks/__tests__/useMarketplaceConfig.test.tsx +106 -0
  118. package/src/react/hooks/__tests__/useRoyaltyPercentage.test.tsx +129 -0
  119. package/src/react/hooks/index.ts +1 -1
  120. package/src/react/hooks/options/__mocks__/marketplaceConfig.msw.ts +66 -10
  121. package/src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx +2 -11
  122. package/src/react/hooks/options/marketplaceConfigOptions.ts +8 -3
  123. package/src/react/hooks/useAutoSelectFeeOption.tsx +4 -3
  124. package/src/react/hooks/useCancelTransactionSteps.tsx +17 -9
  125. package/src/react/hooks/useCollectionDetailsPolling.tsx +1 -1
  126. package/src/react/hooks/useCurrencies.tsx +29 -28
  127. package/src/react/hooks/useFilters.tsx +75 -2
  128. package/src/react/hooks/useGenerateBuyTransaction.tsx +13 -5
  129. package/src/react/hooks/useListCollectibleActivities.tsx +1 -0
  130. package/src/react/hooks/useListCollectibles.tsx +1 -0
  131. package/src/react/hooks/useListCollectiblesPaginated.tsx +78 -0
  132. package/src/react/hooks/useListCollectionActivities.tsx +1 -0
  133. package/src/react/hooks/useListCollections.tsx +2 -2
  134. package/src/react/ui/components/_internals/custom-select/__tests__/CustomSelect.test.tsx +6 -2
  135. package/src/react/ui/components/collectible-card/CollectibleCard.tsx +1 -1
  136. package/src/react/ui/components/collectible-card/Footer.tsx +9 -5
  137. package/src/react/ui/modals/BuyModal/Modal.tsx +9 -4
  138. package/src/react/ui/modals/BuyModal/__tests__/Modal.test.tsx +0 -1
  139. package/src/react/ui/modals/BuyModal/__tests__/store.test.ts +4 -2
  140. package/src/react/ui/modals/BuyModal/hooks/__tests__/useBuyCollectable.test.tsx +1 -24
  141. package/src/react/ui/modals/BuyModal/hooks/__tests__/useCheckoutOptions.test.tsx +152 -210
  142. package/src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx +19 -49
  143. package/src/react/ui/modals/BuyModal/hooks/useFees.ts +6 -6
  144. package/src/react/ui/modals/BuyModal/modals/Modal1155.tsx +4 -2
  145. package/src/react/ui/modals/BuyModal/modals/__tests__/Modal1155.test.tsx +161 -52
  146. package/src/react/ui/modals/BuyModal/store.ts +7 -0
  147. package/src/react/ui/modals/CreateListingModal/Modal.tsx +1 -3
  148. package/src/react/ui/modals/CreateListingModal/__tests__/Modal.test.tsx +59 -227
  149. package/src/react/ui/modals/CreateListingModal/hooks/useCreateListing.tsx +2 -1
  150. package/src/react/ui/modals/CreateListingModal/hooks/useTransactionSteps.tsx +47 -7
  151. package/src/react/ui/modals/MakeOfferModal/Modal.tsx +1 -8
  152. package/src/react/ui/modals/MakeOfferModal/__tests__/Modal.test.tsx +41 -118
  153. package/src/react/ui/modals/MakeOfferModal/hooks/useMakeOffer.tsx +2 -1
  154. package/src/react/ui/modals/MakeOfferModal/hooks/useTransactionSteps.tsx +34 -6
  155. package/src/react/ui/modals/SellModal/Modal.tsx +3 -1
  156. package/src/react/ui/modals/SellModal/__tests__/Modal.test.tsx +4 -3
  157. package/src/react/ui/modals/SellModal/hooks/useGetTokenApproval.tsx +33 -31
  158. package/src/react/ui/modals/SellModal/hooks/useSell.tsx +11 -7
  159. package/src/react/ui/modals/SellModal/hooks/useTransactionSteps.tsx +58 -16
  160. package/src/react/ui/modals/SuccessfulPurchaseModal/__tests__/Modal.test.tsx +0 -1
  161. package/src/react/ui/modals/_internal/components/actionModal/ErrorModal.tsx +4 -2
  162. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/__tests__/index.test.tsx +129 -57
  163. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +1 -3
  164. package/src/react/ui/modals/_internal/components/priceInput/__tests__/index.test.tsx +1 -3
  165. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +2 -2
  166. package/src/react/ui/modals/_internal/components/transactionStatusModal/__tests__/TransactionStatusModal.test.tsx +8 -8
  167. package/src/react/ui/modals/_internal/components/transactionStatusModal/hooks/useTransactionStatus.ts +1 -0
  168. package/src/types/builder-types.ts +79 -0
  169. package/src/types/index.ts +1 -1
  170. package/src/utils/__tests__/get-public-rpc-client.test.ts +2 -0
  171. package/src/utils/getMarketplaceDetails.ts +2 -2
  172. package/tsconfig.tsbuildinfo +1 -1
  173. package/vitest.config.js +2 -1
  174. package/dist/chunk-FCF57DZI.js.map +0 -1
  175. package/dist/chunk-I37CRQ4S.js.map +0 -1
  176. package/dist/chunk-LJAB3S6U.js.map +0 -1
  177. package/dist/chunk-MSTTVFVQ.js.map +0 -1
  178. package/dist/chunk-RK6KYMZM.js +0 -18
  179. package/dist/chunk-RK6KYMZM.js.map +0 -1
  180. package/dist/marketplace-config-znEu4L0K.d.ts +0 -60
  181. package/src/react/hooks/useCurrencyOptions.tsx +0 -16
  182. package/src/types/marketplace-config.ts +0 -67
  183. /package/dist/{chunk-MKGSGTQC.js.map → chunk-TLNRD4BQ.js.map} +0 -0
  184. /package/dist/{chunk-MWDG7UTB.js.map → chunk-ZBLU3Q22.js.map} +0 -0
@@ -0,0 +1,410 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { renderHook, waitFor } from '../../_internal/test-utils';
3
+ import { useCancelOrder } from '../useCancelOrder';
4
+ import { MarketplaceKind } from '../../../types';
5
+ import { server } from '../../_internal/test/setup';
6
+ import { http, HttpResponse } from 'msw';
7
+ import { mockMarketplaceEndpoint } from '../../_internal/api/__mocks__/marketplace.msw';
8
+ import { useWallet } from '../../_internal/wallet/useWallet';
9
+ import {
10
+ createMockWallet,
11
+ commonWalletMocks,
12
+ } from '../../_internal/test/mocks/wallet';
13
+ import { StepType } from '../../_internal/api/marketplace.gen';
14
+
15
+ // Mock useWallet hook
16
+ vi.mock('../../_internal/wallet/useWallet');
17
+
18
+ // Mock @0xsequence/kit
19
+ vi.mock('@0xsequence/kit', () => ({
20
+ useWaasFeeOptions: () => [null, vi.fn()],
21
+ useChain: () => ({
22
+ id: 1,
23
+ name: 'Ethereum',
24
+ nativeCurrency: {
25
+ name: 'Ether',
26
+ symbol: 'ETH',
27
+ decimals: 18,
28
+ },
29
+ }),
30
+ }));
31
+
32
+ // Mock wagmi
33
+ vi.mock('wagmi', () => ({
34
+ useAccount: () => ({
35
+ address: '0x1234567890123456789012345678901234567890',
36
+ isConnected: true,
37
+ }),
38
+ createConfig: () => ({
39
+ chains: [
40
+ {
41
+ id: 1,
42
+ name: 'Ethereum',
43
+ nativeCurrency: {
44
+ name: 'Ether',
45
+ symbol: 'ETH',
46
+ decimals: 18,
47
+ },
48
+ },
49
+ ],
50
+ connectors: [],
51
+ transports: {},
52
+ }),
53
+ http: () => ({}),
54
+ WagmiProvider: ({ children }: { children: React.ReactNode }) => children,
55
+ }));
56
+
57
+ describe('useCancelOrder', () => {
58
+ const defaultProps = {
59
+ collectionAddress: '0x1234567890123456789012345678901234567890',
60
+ chainId: '1',
61
+ };
62
+
63
+ const mockOrderId = '0x9876543210987654321098765432109876543210';
64
+ const mockTxHash = '0xabcd1234';
65
+
66
+ // Create mock wallet instance with custom implementations
67
+ const mockWallet = createMockWallet({
68
+ getChainId: vi.fn().mockResolvedValue(1),
69
+ address: vi
70
+ .fn()
71
+ .mockResolvedValue('0x1234567890123456789012345678901234567890'),
72
+ handleSendTransactionStep: vi.fn().mockResolvedValue(mockTxHash),
73
+ handleSignMessageStep: vi.fn().mockResolvedValue('0xsignature'),
74
+ handleConfirmTransactionStep: vi.fn().mockResolvedValue(undefined),
75
+ isWaaS: true,
76
+ switchChain: vi.fn().mockResolvedValue(undefined),
77
+ });
78
+
79
+ beforeEach(() => {
80
+ vi.clearAllMocks();
81
+
82
+ // Set up the mock implementation for useWallet
83
+ vi.mocked(useWallet).mockReturnValue({
84
+ wallet: mockWallet,
85
+ isLoading: false,
86
+ isError: false,
87
+ });
88
+
89
+ // Mock default steps response
90
+ server.use(
91
+ http.post(mockMarketplaceEndpoint('GenerateCancelTransaction'), () => {
92
+ return HttpResponse.json({
93
+ steps: [
94
+ {
95
+ id: StepType.cancel,
96
+ data: '0x...',
97
+ to: defaultProps.collectionAddress,
98
+ value: '0',
99
+ executeType: 'order',
100
+ },
101
+ ],
102
+ });
103
+ }),
104
+ http.post(mockMarketplaceEndpoint('Execute'), () => {
105
+ return HttpResponse.json({
106
+ orderId: mockOrderId,
107
+ hash: mockTxHash,
108
+ });
109
+ }),
110
+ http.post('*/GetTokenBalancesDetails', () => {
111
+ return HttpResponse.json({
112
+ page: { page: 1, pageSize: 10, more: false },
113
+ balances: [],
114
+ nativeBalances: [
115
+ {
116
+ balance: '2000000000000000000', // 2 ETH
117
+ blockHash: '0x1234',
118
+ blockNumber: 1234567,
119
+ },
120
+ ],
121
+ });
122
+ }),
123
+ );
124
+ });
125
+
126
+ afterEach(() => {
127
+ server.resetHandlers();
128
+ vi.clearAllMocks();
129
+ });
130
+
131
+ it('should initialize with default state', () => {
132
+ const { result } = renderHook(() => useCancelOrder(defaultProps));
133
+
134
+ expect(result.current.isExecuting).toBe(false);
135
+ expect(result.current.cancellingOrderId).toBeNull();
136
+ });
137
+
138
+ it('should handle cancellation error', async () => {
139
+ const onError = vi.fn();
140
+
141
+ server.use(
142
+ http.post(mockMarketplaceEndpoint('GenerateCancelTransaction'), () => {
143
+ return HttpResponse.error();
144
+ }),
145
+ );
146
+
147
+ const { result } = renderHook(() =>
148
+ useCancelOrder({
149
+ ...defaultProps,
150
+ onError,
151
+ }),
152
+ );
153
+
154
+ try {
155
+ await result.current.cancelOrder({
156
+ orderId: mockOrderId,
157
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
158
+ });
159
+ } catch (error) {
160
+ // Error is expected
161
+ }
162
+
163
+ await waitFor(() => {
164
+ expect(onError).toHaveBeenCalled();
165
+ expect(result.current.cancellingOrderId).toBeNull();
166
+ expect(result.current.isExecuting).toBe(false);
167
+ });
168
+ });
169
+
170
+ it('should update state during cancellation process', async () => {
171
+ const { result } = renderHook(() => useCancelOrder(defaultProps));
172
+
173
+ // Mock a delayed response
174
+ server.use(
175
+ http.post(mockMarketplaceEndpoint('GenerateCancelTransaction'), () => {
176
+ return new Promise((resolve) =>
177
+ setTimeout(
178
+ () =>
179
+ resolve(
180
+ HttpResponse.json({
181
+ steps: [
182
+ {
183
+ id: StepType.cancel,
184
+ data: '0x...',
185
+ to: defaultProps.collectionAddress,
186
+ value: '0',
187
+ executeType: 'order',
188
+ },
189
+ ],
190
+ }),
191
+ ),
192
+ 100,
193
+ ),
194
+ );
195
+ }),
196
+ );
197
+
198
+ // Start the cancellation
199
+ const cancelPromise = result.current.cancelOrder({
200
+ orderId: mockOrderId,
201
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
202
+ });
203
+
204
+ // Wait for immediate state updates
205
+ await waitFor(() => {
206
+ expect(result.current.cancellingOrderId).toBe(mockOrderId);
207
+ });
208
+
209
+ // Wait for execution state to be true
210
+ await waitFor(() => {
211
+ expect(result.current.isExecuting).toBe(true);
212
+ });
213
+
214
+ // Wait for the cancellation to complete
215
+ await cancelPromise;
216
+ });
217
+
218
+ it('should handle chain switching failure', async () => {
219
+ const onError = vi.fn();
220
+
221
+ // Mock wallet to fail chain switch
222
+ const mockWalletWithFailedChainSwitch = createMockWallet({
223
+ ...commonWalletMocks,
224
+ getChainId: vi.fn().mockResolvedValue(2), // Different chain than required
225
+ switchChain: vi
226
+ .fn()
227
+ .mockRejectedValue(new Error('Failed to switch chain')),
228
+ isWaaS: true,
229
+ });
230
+
231
+ vi.mocked(useWallet).mockReturnValue({
232
+ wallet: mockWalletWithFailedChainSwitch,
233
+ isLoading: false,
234
+ isError: false,
235
+ });
236
+
237
+ const { result } = renderHook(() =>
238
+ useCancelOrder({
239
+ ...defaultProps,
240
+ onError,
241
+ }),
242
+ );
243
+
244
+ try {
245
+ await result.current.cancelOrder({
246
+ orderId: mockOrderId,
247
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
248
+ });
249
+ } catch (error) {
250
+ // Error is expected
251
+ }
252
+
253
+ await waitFor(() => {
254
+ expect(onError).toHaveBeenCalledWith(expect.any(Error));
255
+ expect(mockWalletWithFailedChainSwitch.switchChain).toHaveBeenCalledWith(
256
+ 1,
257
+ );
258
+ expect(result.current.cancellingOrderId).toBeNull();
259
+ expect(result.current.isExecuting).toBe(false);
260
+ });
261
+ });
262
+
263
+ it('should handle transaction confirmation failure', async () => {
264
+ const onError = vi.fn();
265
+
266
+ // Mock wallet with failed transaction confirmation
267
+ const mockWalletWithFailedConfirmation = createMockWallet({
268
+ ...commonWalletMocks,
269
+ getChainId: vi.fn().mockResolvedValue(1),
270
+ handleSendTransactionStep: vi.fn().mockResolvedValue(mockTxHash),
271
+ handleSignMessageStep: vi.fn().mockResolvedValue('0xsignature'),
272
+ handleConfirmTransactionStep: vi
273
+ .fn()
274
+ .mockRejectedValue(new Error('Transaction confirmation failed')),
275
+ isWaaS: true,
276
+ });
277
+
278
+ vi.mocked(useWallet).mockReturnValue({
279
+ wallet: mockWalletWithFailedConfirmation,
280
+ isLoading: false,
281
+ isError: false,
282
+ });
283
+
284
+ const { result } = renderHook(() =>
285
+ useCancelOrder({
286
+ ...defaultProps,
287
+ onError,
288
+ }),
289
+ );
290
+
291
+ try {
292
+ await result.current.cancelOrder({
293
+ orderId: mockOrderId,
294
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
295
+ });
296
+ } catch (error) {
297
+ // Error is expected
298
+ }
299
+
300
+ await waitFor(() => {
301
+ expect(onError).toHaveBeenCalledWith(expect.any(Error));
302
+ expect(
303
+ mockWalletWithFailedConfirmation.handleConfirmTransactionStep,
304
+ ).toHaveBeenCalled();
305
+ expect(result.current.cancellingOrderId).toBeNull();
306
+ expect(result.current.isExecuting).toBe(false);
307
+ });
308
+ });
309
+
310
+ it('should successfully cancel an order', async () => {
311
+ const onSuccess = vi.fn();
312
+
313
+ // Mock successful responses for all steps
314
+ server.use(
315
+ http.post(mockMarketplaceEndpoint('GenerateCancelTransaction'), () => {
316
+ return new Promise((resolve) =>
317
+ setTimeout(
318
+ () =>
319
+ resolve(
320
+ HttpResponse.json({
321
+ steps: [
322
+ {
323
+ id: StepType.cancel,
324
+ data: '0x1234',
325
+ to: defaultProps.collectionAddress,
326
+ value: '0',
327
+ executeType: 'order',
328
+ },
329
+ ],
330
+ }),
331
+ ),
332
+ 50,
333
+ ),
334
+ );
335
+ }),
336
+ http.post(mockMarketplaceEndpoint('Execute'), () => {
337
+ return HttpResponse.json({
338
+ hash: mockTxHash,
339
+ });
340
+ }),
341
+ );
342
+
343
+ const mockSuccessWallet = createMockWallet({
344
+ ...commonWalletMocks,
345
+ getChainId: vi.fn().mockResolvedValue(1),
346
+ handleSendTransactionStep: vi.fn().mockResolvedValue(mockTxHash),
347
+ handleSignMessageStep: vi.fn().mockResolvedValue('0xsignature'),
348
+ handleConfirmTransactionStep: vi.fn().mockResolvedValue(undefined),
349
+ isWaaS: true,
350
+ });
351
+
352
+ vi.mocked(useWallet).mockReturnValue({
353
+ wallet: mockSuccessWallet,
354
+ isLoading: false,
355
+ isError: false,
356
+ });
357
+
358
+ const { result } = renderHook(() =>
359
+ useCancelOrder({
360
+ ...defaultProps,
361
+ onSuccess,
362
+ }),
363
+ );
364
+
365
+ // Start the cancellation
366
+ result.current.cancelOrder({
367
+ orderId: mockOrderId,
368
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
369
+ });
370
+
371
+ // First, wait for the orderId to be set
372
+ await waitFor(
373
+ () => {
374
+ expect(result.current.cancellingOrderId).toBe(mockOrderId);
375
+ },
376
+ { timeout: 1000 },
377
+ );
378
+
379
+ // Then wait for execution to start
380
+ await waitFor(
381
+ () => {
382
+ expect(result.current.isExecuting).toBe(true);
383
+ },
384
+ { timeout: 1000 },
385
+ );
386
+
387
+ // Wait for the success callback to be called
388
+ await waitFor(
389
+ () => {
390
+ expect(onSuccess).toHaveBeenCalledWith({
391
+ hash: mockTxHash,
392
+ });
393
+ },
394
+ { timeout: 1000 },
395
+ );
396
+
397
+ // Finally verify the states are reset
398
+ await waitFor(
399
+ () => {
400
+ expect(mockSuccessWallet.handleSendTransactionStep).toHaveBeenCalled();
401
+ expect(
402
+ mockSuccessWallet.handleConfirmTransactionStep,
403
+ ).toHaveBeenCalled();
404
+ expect(result.current.cancellingOrderId).toBeNull();
405
+ expect(result.current.isExecuting).toBe(false);
406
+ },
407
+ { timeout: 1000 },
408
+ );
409
+ });
410
+ });
@@ -0,0 +1,269 @@
1
+ import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
2
+ import { useCancelTransactionSteps } from '../useCancelTransactionSteps';
3
+ import { renderHook, waitFor } from '../../_internal/test-utils';
4
+ import { zeroAddress } from 'viem';
5
+ import { http, HttpResponse } from 'msw';
6
+ import {
7
+ mockSteps,
8
+ mockMarketplaceEndpoint,
9
+ } from '../../_internal/api/__mocks__/marketplace.msw';
10
+ import { server } from '../../_internal/test/setup';
11
+ import { MarketplaceKind, StepType } from '../../_internal/api/marketplace.gen';
12
+ import {
13
+ ChainSwitchUserRejectedError,
14
+ WalletInstanceNotFoundError,
15
+ } from '../../../utils/_internal/error/transaction';
16
+ import { useWallet } from '../../_internal/wallet/useWallet';
17
+ import {
18
+ createMockWallet,
19
+ commonWalletMocks,
20
+ } from '../../_internal/test/mocks/wallet';
21
+
22
+ // Create mock wallet instance with default successful implementations
23
+ const mockWallet = createMockWallet({
24
+ getChainId: commonWalletMocks.successfulChainId,
25
+ address: commonWalletMocks.successfulAddress,
26
+ handleSendTransactionStep: commonWalletMocks.successfulTransaction,
27
+ handleSignMessageStep: commonWalletMocks.successfulSignature,
28
+ handleConfirmTransactionStep: commonWalletMocks.successfulConfirmation,
29
+ });
30
+
31
+ // Mock useWallet hook
32
+ vi.mock('../../_internal/wallet/useWallet');
33
+
34
+ // Mock switch chain modal
35
+ vi.mock('../../ui/modals/_internal/components/switchChainModal', () => ({
36
+ useSwitchChainModal: () => ({
37
+ show: vi.fn((args) => args.onSuccess()),
38
+ }),
39
+ }));
40
+
41
+ describe('useCancelTransactionSteps', () => {
42
+ const mockSetSteps = vi.fn();
43
+ const mockOnSuccess = vi.fn();
44
+ const mockOnError = vi.fn();
45
+
46
+ const defaultArgs = {
47
+ chainId: '1',
48
+ collectionAddress: zeroAddress,
49
+ setSteps: mockSetSteps,
50
+ onSuccess: mockOnSuccess,
51
+ onError: mockOnError,
52
+ };
53
+
54
+ beforeEach(() => {
55
+ vi.clearAllMocks();
56
+
57
+ // Set up the mock implementation for useWallet in beforeEach
58
+ vi.mocked(useWallet).mockReturnValue({
59
+ wallet: mockWallet,
60
+ isLoading: false,
61
+ isError: false,
62
+ });
63
+
64
+ // Mock default steps response
65
+ server.use(
66
+ http.post(mockMarketplaceEndpoint('GenerateCancelTransaction'), () => {
67
+ return HttpResponse.json({
68
+ steps: [
69
+ {
70
+ ...mockSteps[0],
71
+ id: StepType.cancel,
72
+ },
73
+ ],
74
+ });
75
+ }),
76
+ );
77
+ });
78
+
79
+ afterEach(() => {
80
+ server.resetHandlers();
81
+ });
82
+
83
+ it('should handle transaction steps successfully', async () => {
84
+ const { result } = renderHook(() => useCancelTransactionSteps(defaultArgs));
85
+
86
+ await result.current.cancelOrder({
87
+ orderId: '123',
88
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
89
+ });
90
+
91
+ // Verify that setSteps was called with a function that sets isExecuting to true
92
+ const setStepsCall = mockSetSteps.mock.calls[0][0];
93
+ expect(typeof setStepsCall).toBe('function');
94
+ const updatedState = setStepsCall({ isExecuting: false });
95
+ expect(updatedState.isExecuting).toBe(true);
96
+
97
+ expect(mockOnSuccess).toHaveBeenCalled();
98
+ expect(mockOnError).not.toHaveBeenCalled();
99
+ });
100
+
101
+ it('should handle signature steps successfully', async () => {
102
+ // Mock steps to include signature step
103
+ server.use(
104
+ http.post(mockMarketplaceEndpoint('GenerateCancelTransaction'), () => {
105
+ return HttpResponse.json({
106
+ steps: [
107
+ {
108
+ ...mockSteps[0],
109
+ id: StepType.signEIP712,
110
+ },
111
+ ],
112
+ });
113
+ }),
114
+ );
115
+
116
+ const { result } = renderHook(() => useCancelTransactionSteps(defaultArgs));
117
+
118
+ await result.current.cancelOrder({
119
+ orderId: '123',
120
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
121
+ });
122
+
123
+ expect(mockWallet.handleSignMessageStep).toHaveBeenCalled();
124
+ expect(mockOnSuccess).toHaveBeenCalled();
125
+ expect(mockOnError).not.toHaveBeenCalled();
126
+ });
127
+
128
+ it('should handle chain switching', async () => {
129
+ // Mock different chain ID
130
+ commonWalletMocks.successfulChainId.mockResolvedValueOnce(2);
131
+
132
+ const { result } = renderHook(() => useCancelTransactionSteps(defaultArgs));
133
+
134
+ await result.current.cancelOrder({
135
+ orderId: '123',
136
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
137
+ });
138
+
139
+ expect(mockWallet.getChainId).toHaveBeenCalled();
140
+
141
+ waitFor(() => {
142
+ expect(mockWallet.switchChain).toHaveBeenCalled();
143
+
144
+ expect(mockOnSuccess).toHaveBeenCalled();
145
+ expect(mockOnError).not.toHaveBeenCalled();
146
+ });
147
+ });
148
+
149
+ it('should handle wallet not initialized error', async () => {
150
+ // Override the mock for this specific test
151
+ vi.mocked(useWallet).mockReturnValue({
152
+ wallet: null,
153
+ isLoading: false,
154
+ isError: false,
155
+ });
156
+
157
+ const { result } = renderHook(() => useCancelTransactionSteps(defaultArgs));
158
+
159
+ try {
160
+ await result.current.cancelOrder({
161
+ orderId: '123',
162
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
163
+ });
164
+ } catch (error) {
165
+ expect(error).toBeInstanceOf(WalletInstanceNotFoundError);
166
+ }
167
+
168
+ expect(mockOnSuccess).not.toHaveBeenCalled();
169
+ });
170
+
171
+ it('should handle chain switch rejection', async () => {
172
+ // Create a new mock wallet with chain switch rejection
173
+ const mockWalletWithRejection = createMockWallet({
174
+ ...mockWallet,
175
+ getChainId: vi.fn().mockResolvedValue(2),
176
+ switchChain: commonWalletMocks.chainSwitchRejection,
177
+ });
178
+
179
+ // Override the mock for this specific test
180
+ vi.mocked(useWallet).mockReturnValue({
181
+ wallet: mockWalletWithRejection,
182
+ isLoading: false,
183
+ isError: false,
184
+ });
185
+
186
+ // Mock switch chain modal to reject
187
+ vi.mock('../../ui/modals/_internal/components/switchChainModal', () => ({
188
+ useSwitchChainModal: () => ({
189
+ show: vi.fn((args) => args.onClose()),
190
+ }),
191
+ }));
192
+
193
+ const { result } = renderHook(() =>
194
+ useCancelTransactionSteps({
195
+ ...defaultArgs,
196
+ callbacks: {
197
+ onError: mockOnError,
198
+ },
199
+ }),
200
+ );
201
+
202
+ await result.current.cancelOrder({
203
+ orderId: '123',
204
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
205
+ });
206
+
207
+ expect(mockOnError).toHaveBeenCalledWith(
208
+ expect.any(ChainSwitchUserRejectedError),
209
+ );
210
+ expect(mockOnSuccess).not.toHaveBeenCalled();
211
+ });
212
+
213
+ it('should handle transaction failure', async () => {
214
+ // Create a new mock wallet with transaction failure
215
+ const mockWalletWithFailure = createMockWallet({
216
+ ...mockWallet,
217
+ handleSendTransactionStep: commonWalletMocks.transactionFailure,
218
+ });
219
+
220
+ // Override the mock for this specific test
221
+ vi.mocked(useWallet).mockReturnValue({
222
+ wallet: mockWalletWithFailure,
223
+ isLoading: false,
224
+ isError: false,
225
+ });
226
+
227
+ const { result } = renderHook(() => useCancelTransactionSteps(defaultArgs));
228
+
229
+ await result.current.cancelOrder({
230
+ orderId: '123',
231
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
232
+ });
233
+
234
+ // Verify that setSteps was called with a function that sets isExecuting to false
235
+ const setStepsCall =
236
+ mockSetSteps.mock.calls[mockSetSteps.mock.calls.length - 1][0];
237
+ expect(typeof setStepsCall).toBe('function');
238
+ const updatedState = setStepsCall({ isExecuting: true });
239
+ expect(updatedState.isExecuting).toBe(false);
240
+
241
+ expect(mockOnError).toHaveBeenCalledWith(expect.any(Error));
242
+ expect(mockOnSuccess).not.toHaveBeenCalled();
243
+ });
244
+
245
+ it('should handle missing steps error', async () => {
246
+ // Mock empty steps response
247
+ server.use(
248
+ http.post(mockMarketplaceEndpoint('GenerateCancelTransaction'), () => {
249
+ return HttpResponse.json({
250
+ steps: [],
251
+ });
252
+ }),
253
+ );
254
+
255
+ const { result } = renderHook(() => useCancelTransactionSteps(defaultArgs));
256
+
257
+ await result.current.cancelOrder({
258
+ orderId: '123',
259
+ marketplace: MarketplaceKind.sequence_marketplace_v2,
260
+ });
261
+
262
+ expect(mockOnError).toHaveBeenCalledWith(
263
+ expect.objectContaining({
264
+ message: 'No transaction or signature step found',
265
+ }),
266
+ );
267
+ expect(mockOnSuccess).not.toHaveBeenCalled();
268
+ });
269
+ });