@0xsequence/marketplace-sdk 0.7.0 → 0.8.0

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 (228) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.changeset/fuzzy-forks-smoke.md +5 -0
  4. package/CHANGELOG.md +7 -0
  5. package/dist/chunk-2MSBZYLW.js +128 -0
  6. package/dist/chunk-2MSBZYLW.js.map +1 -0
  7. package/dist/{chunk-MPBN3E54.js → chunk-2VHHJNXY.js} +3 -3
  8. package/dist/{chunk-FBUMNJQ4.js → chunk-3II5GLHE.js} +2 -2
  9. package/dist/chunk-3JU7SQVE.js +182 -0
  10. package/dist/chunk-3JU7SQVE.js.map +1 -0
  11. package/dist/{chunk-XNA64MZQ.js → chunk-BCO4CYE4.js} +2 -2
  12. package/dist/{chunk-4XK7XNJ7.js → chunk-BNAUZXPV.js} +73 -2
  13. package/dist/chunk-BNAUZXPV.js.map +1 -0
  14. package/dist/{chunk-Q5URKSC4.js → chunk-FMEEJFAF.js} +1 -1
  15. package/dist/{chunk-BBASZVT3.js → chunk-GBQVYNCD.js} +5 -6
  16. package/dist/chunk-GBQVYNCD.js.map +1 -0
  17. package/dist/{chunk-3AKOPSON.js → chunk-IZ44XPBH.js} +2 -9
  18. package/dist/chunk-IZ44XPBH.js.map +1 -0
  19. package/dist/{chunk-EAJ5K7QV.js → chunk-Q5RKAMYF.js} +3 -4
  20. package/dist/chunk-Q5RKAMYF.js.map +1 -0
  21. package/dist/{chunk-RBEPPVLT.js → chunk-QKGZXS4T.js} +147 -357
  22. package/dist/chunk-QKGZXS4T.js.map +1 -0
  23. package/dist/{chunk-HTFORA4Q.js → chunk-SBI52HTX.js} +1880 -1010
  24. package/dist/chunk-SBI52HTX.js.map +1 -0
  25. package/dist/{chunk-XTGMMNV5.js → chunk-WHFXVREI.js} +2 -2
  26. package/dist/{index-CzTANLaA.d.ts → index-CnaFSNE9.d.ts} +6 -7
  27. package/dist/index.css +113 -31
  28. package/dist/index.css.map +1 -1
  29. package/dist/index.d.ts +2 -4
  30. package/dist/index.js +9 -9
  31. package/dist/listCollectibles-B0tbqnRd.d.ts +155 -0
  32. package/dist/react/_internal/api/index.d.ts +28 -2
  33. package/dist/react/_internal/api/index.js +3 -1
  34. package/dist/react/_internal/databeat/index.js +11 -10
  35. package/dist/react/_internal/index.d.ts +2 -3
  36. package/dist/react/_internal/index.js +4 -4
  37. package/dist/react/_internal/wagmi/index.js +2 -2
  38. package/dist/react/hooks/index.d.ts +259 -674
  39. package/dist/react/hooks/index.js +10 -19
  40. package/dist/react/hooks/options/index.d.ts +1 -2
  41. package/dist/react/hooks/options/index.js +4 -4
  42. package/dist/react/index.d.ts +7 -7
  43. package/dist/react/index.js +14 -23
  44. package/dist/react/queries/index.d.ts +25 -0
  45. package/dist/react/queries/index.js +48 -0
  46. package/dist/react/queries/index.js.map +1 -0
  47. package/dist/react/ssr/index.js +3 -3
  48. package/dist/react/ui/components/collectible-card/index.d.ts +1 -6
  49. package/dist/react/ui/components/collectible-card/index.js +14 -13
  50. package/dist/react/ui/components/marketplace-logos/index.js +1 -1
  51. package/dist/react/ui/icons/index.js +7 -7
  52. package/dist/react/ui/index.d.ts +18 -22
  53. package/dist/react/ui/index.js +14 -13
  54. package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +6 -11
  55. package/dist/react/ui/modals/_internal/components/actionModal/index.js +11 -10
  56. package/dist/types/index.js +2 -2
  57. package/dist/{types-Ct1uCT3M.d.ts → types-o_pKUpQG.d.ts} +2 -5
  58. package/dist/utils/abi/index.js +5 -5
  59. package/dist/utils/index.d.ts +1 -5
  60. package/dist/utils/index.js +9 -9
  61. package/package.json +22 -16
  62. package/src/react/_internal/api/__mocks__/indexer.msw.ts +3 -1
  63. package/src/react/_internal/api/__mocks__/marketplace.msw.ts +1 -1
  64. package/src/react/_internal/api/__mocks__/metadata.msw.ts +14 -12
  65. package/src/react/_internal/api/index.ts +1 -0
  66. package/src/react/_internal/api/laos-api.ts +103 -0
  67. package/src/react/_internal/api/zod-schema.ts +3 -3
  68. package/src/react/_internal/types.ts +1 -10
  69. package/src/react/_internal/wallet/__tests__/wallet.test.ts +43 -0
  70. package/src/react/_internal/wallet/useWallet.ts +6 -3
  71. package/src/react/hooks/__tests__/useAutoSelectFeeOption.test.tsx +1 -1
  72. package/src/react/hooks/__tests__/useCancelOrder.test.tsx +1 -1
  73. package/src/react/hooks/__tests__/useCancelTransactionSteps.test.tsx +1 -1
  74. package/src/react/hooks/__tests__/useCollectible.test.tsx +2 -2
  75. package/src/react/hooks/__tests__/useCollection.test.tsx +2 -2
  76. package/src/react/hooks/__tests__/useComparePrices.test.tsx +1 -1
  77. package/src/react/hooks/__tests__/useConvertPriceToUSD.test.tsx +1 -1
  78. package/src/react/hooks/__tests__/useCountListingsForCollectible.test.tsx +1 -1
  79. package/src/react/hooks/__tests__/useCountOfCollectables.test.tsx +2 -2
  80. package/src/react/hooks/__tests__/useCountOffersForCollectible.test.tsx +1 -1
  81. package/src/react/hooks/__tests__/useCurrencies.test.tsx +2 -2
  82. package/src/react/hooks/__tests__/useCurrency.test.tsx +2 -2
  83. package/src/react/hooks/__tests__/useFilters.test.tsx +2 -2
  84. package/src/react/hooks/__tests__/useFloorOrder.test.tsx +2 -2
  85. package/src/react/hooks/__tests__/useGenerateCancelTransaction.test.tsx +1 -1
  86. package/src/react/hooks/__tests__/useGenerateListingTransaction.test.tsx +1 -1
  87. package/src/react/hooks/__tests__/useGenerateOfferTransaction.test.tsx +1 -1
  88. package/src/react/hooks/__tests__/useGenerateSellTransaction.test.tsx +1 -1
  89. package/src/react/hooks/__tests__/useListCollectibleActivities.test.tsx +2 -2
  90. package/src/react/hooks/__tests__/useListCollectibles.test.tsx +3 -2
  91. package/src/react/hooks/__tests__/useListCollectiblesPaginated.test.tsx +1 -1
  92. package/src/react/hooks/__tests__/useListCollectionActivities.test.tsx +1 -1
  93. package/src/react/hooks/__tests__/useListListingsForCollectible.test.tsx +1 -1
  94. package/src/react/hooks/__tests__/useListOffersForCollectible.test.tsx +1 -1
  95. package/src/react/hooks/__tests__/useLowestListing.test.tsx +1 -1
  96. package/src/react/hooks/__tests__/useRoyalty.test.tsx +1 -2
  97. package/src/react/hooks/index.ts +0 -1
  98. package/src/react/hooks/options/collectionOptions.ts +2 -3
  99. package/src/react/hooks/useAutoSelectFeeOption.tsx +1 -1
  100. package/src/react/hooks/useCancelOrder.tsx +3 -3
  101. package/src/react/hooks/useCancelTransactionSteps.tsx +1 -1
  102. package/src/react/hooks/useCheckoutOptions.tsx +1 -2
  103. package/src/react/hooks/useCollectible.tsx +2 -3
  104. package/src/react/hooks/useCollectionBalanceDetails.tsx +1 -2
  105. package/src/react/hooks/useComparePrices.tsx +2 -9
  106. package/src/react/hooks/useConvertPriceToUSD.tsx +1 -4
  107. package/src/react/hooks/useCountListingsForCollectible.tsx +1 -2
  108. package/src/react/hooks/useCountOfCollectables.tsx +1 -2
  109. package/src/react/hooks/useCountOffersForCollectible.tsx +1 -2
  110. package/src/react/hooks/useCurrencies.tsx +1 -4
  111. package/src/react/hooks/useCurrency.tsx +3 -8
  112. package/src/react/hooks/useFilters.tsx +5 -4
  113. package/src/react/hooks/useFloorOrder.tsx +1 -2
  114. package/src/react/hooks/useGenerateCancelTransaction.tsx +3 -6
  115. package/src/react/hooks/useGenerateListingTransaction.tsx +2 -3
  116. package/src/react/hooks/useGenerateOfferTransaction.tsx +2 -3
  117. package/src/react/hooks/useGenerateSellTransaction.tsx +3 -6
  118. package/src/react/hooks/useHighestOffer.tsx +1 -1
  119. package/src/react/hooks/useListCollectibles.tsx +33 -61
  120. package/src/react/hooks/useListCollectiblesPaginated.tsx +2 -6
  121. package/src/react/hooks/useListListingsForCollectible.tsx +1 -2
  122. package/src/react/hooks/useListOffersForCollectible.tsx +1 -2
  123. package/src/react/hooks/useLowestListing.tsx +1 -2
  124. package/src/react/hooks/useRoyalty.tsx +3 -8
  125. package/src/react/hooks/useTransferTokens.tsx +2 -2
  126. package/src/react/queries/balanceOfCollectible.ts +9 -32
  127. package/src/react/queries/getTokenSupplies.ts +38 -0
  128. package/src/react/queries/index.ts +5 -0
  129. package/src/react/queries/listCollectibles.ts +96 -0
  130. package/src/react/ui/components/_internals/action-button/ActionButton.tsx +1 -1
  131. package/src/react/ui/components/_internals/action-button/__tests__/ActionButton.test.tsx +1 -1
  132. package/src/react/ui/components/_internals/action-button/components/NonOwnerActions.tsx +4 -3
  133. package/src/react/ui/components/_internals/action-button/components/OwnerActions.tsx +1 -1
  134. package/src/react/ui/components/collectible-card/CollectibleCard.tsx +2 -3
  135. package/src/react/ui/components/collectible-card/__tests__/CollectibleCard.test.tsx +1 -1
  136. package/src/react/ui/modals/BuyModal/ERC1155QuantityModal.tsx +127 -0
  137. package/src/react/ui/modals/BuyModal/Modal.tsx +67 -85
  138. package/src/react/ui/modals/BuyModal/__tests__/Modal.test.tsx +85 -226
  139. package/src/react/ui/modals/BuyModal/__tests__/Modal1155.test.tsx +140 -0
  140. package/src/react/ui/modals/BuyModal/__tests__/store.test.ts +67 -76
  141. package/src/react/ui/modals/BuyModal/hooks/__tests__/useCheckoutOptions.test.tsx +1 -60
  142. package/src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx +1 -1
  143. package/src/react/ui/modals/BuyModal/hooks/useCheckoutOptions.ts +29 -13
  144. package/src/react/ui/modals/BuyModal/hooks/useLoadData.ts +26 -21
  145. package/src/react/ui/modals/BuyModal/hooks/usePaymentModalParams.ts +200 -0
  146. package/src/react/ui/modals/BuyModal/index.tsx +4 -14
  147. package/src/react/ui/modals/BuyModal/store.ts +71 -76
  148. package/src/react/ui/modals/CreateListingModal/Modal.tsx +71 -7
  149. package/src/react/ui/modals/CreateListingModal/__tests__/Modal.test.tsx +2 -2
  150. package/src/react/ui/modals/CreateListingModal/hooks/useCreateListing.tsx +1 -1
  151. package/src/react/ui/modals/CreateListingModal/hooks/useGetTokenApproval.ts +1 -1
  152. package/src/react/ui/modals/CreateListingModal/hooks/useTransactionSteps.tsx +9 -5
  153. package/src/react/ui/modals/CreateListingModal/store.ts +7 -2
  154. package/src/react/ui/modals/MakeOfferModal/Modal.tsx +103 -6
  155. package/src/react/ui/modals/MakeOfferModal/__tests__/Modal.test.tsx +1 -1
  156. package/src/react/ui/modals/MakeOfferModal/hooks/useGetTokenApproval.tsx +1 -1
  157. package/src/react/ui/modals/MakeOfferModal/hooks/useMakeOffer.tsx +1 -1
  158. package/src/react/ui/modals/MakeOfferModal/hooks/useTransactionSteps.tsx +8 -4
  159. package/src/react/ui/modals/MakeOfferModal/store.ts +5 -3
  160. package/src/react/ui/modals/SellModal/Modal.tsx +76 -4
  161. package/src/react/ui/modals/SellModal/__tests__/Modal.test.tsx +1 -1
  162. package/src/react/ui/modals/SellModal/hooks/useGetTokenApproval.tsx +1 -1
  163. package/src/react/ui/modals/SellModal/hooks/useSell.tsx +1 -1
  164. package/src/react/ui/modals/SellModal/hooks/useTransactionSteps.tsx +16 -8
  165. package/src/react/ui/modals/SellModal/store.ts +5 -3
  166. package/src/react/ui/modals/TransferModal/_store.ts +15 -3
  167. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/TokenQuantityInput.tsx +58 -0
  168. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/TransferButton.tsx +56 -0
  169. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/WalletAddressInput.tsx +50 -0
  170. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +94 -66
  171. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/useHandleTransfer.tsx +22 -14
  172. package/src/react/ui/modals/TransferModal/index.tsx +72 -38
  173. package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +43 -42
  174. package/src/react/ui/modals/_internal/components/actionModal/store.ts +1 -2
  175. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +2 -2
  176. package/src/react/ui/modals/_internal/components/expirationDateSelect/index.tsx +9 -1
  177. package/src/react/ui/modals/_internal/components/floorPriceText/index.tsx +27 -12
  178. package/src/react/ui/modals/_internal/components/priceInput/__tests__/index.test.tsx +1 -1
  179. package/src/react/ui/modals/_internal/components/priceInput/index.tsx +19 -3
  180. package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +3 -0
  181. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/_components/ActionButtons.tsx +60 -0
  182. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/_components/BalanceIndicator.tsx +30 -0
  183. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/index.tsx +126 -0
  184. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/store.ts +25 -0
  185. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/useWaasFeeOptionManager.tsx +74 -0
  186. package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +1 -2
  187. package/src/react/ui/modals/_internal/components/switchChainModal/store.ts +1 -2
  188. package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +1 -1
  189. package/src/react/ui/modals/_internal/components/transaction-footer/index.tsx +4 -7
  190. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +1 -1
  191. package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +1 -1
  192. package/src/react/ui/modals/_internal/components/transactionStatusModal/__tests__/TransactionStatusModal.test.tsx +1 -1
  193. package/src/react/ui/modals/_internal/components/transactionStatusModal/hooks/useTransactionStatus.ts +1 -1
  194. package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +6 -1
  195. package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +2 -2
  196. package/src/react/ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect.tsx +10 -31
  197. package/src/react/ui/modals/_internal/hooks/useSelectWaasFeeOptions.ts +53 -0
  198. package/src/react/ui/modals/_internal/types.ts +2 -1
  199. package/src/types/waas-types.ts +38 -0
  200. package/src/utils/network.ts +2 -4
  201. package/test/const.ts +1 -1
  202. package/test/setup.ts +10 -0
  203. package/test/test-utils.tsx +31 -5
  204. package/tsconfig.tsbuildinfo +1 -1
  205. package/dist/chunk-3AKOPSON.js.map +0 -1
  206. package/dist/chunk-4XK7XNJ7.js.map +0 -1
  207. package/dist/chunk-BBASZVT3.js.map +0 -1
  208. package/dist/chunk-EAJ5K7QV.js.map +0 -1
  209. package/dist/chunk-HTFORA4Q.js.map +0 -1
  210. package/dist/chunk-OFY7OFTL.js +0 -458
  211. package/dist/chunk-OFY7OFTL.js.map +0 -1
  212. package/dist/chunk-RBEPPVLT.js.map +0 -1
  213. package/src/react/hooks/__tests__/useGenerateBuyTransaction.test.tsx +0 -172
  214. package/src/react/hooks/useGenerateBuyTransaction.tsx +0 -80
  215. package/src/react/ui/modals/BuyModal/hooks/__tests__/useBuyCollectable.test.tsx +0 -349
  216. package/src/react/ui/modals/BuyModal/hooks/__tests__/useLoadData.test.tsx +0 -185
  217. package/src/react/ui/modals/BuyModal/hooks/useBuyCollectable.ts +0 -170
  218. package/src/react/ui/modals/BuyModal/modals/CheckoutModal.tsx +0 -47
  219. package/src/react/ui/modals/BuyModal/modals/Modal1155.tsx +0 -140
  220. package/src/react/ui/modals/BuyModal/modals/__tests__/CheckoutModal.test.tsx +0 -162
  221. package/src/react/ui/modals/BuyModal/modals/__tests__/Modal1155.test.tsx +0 -327
  222. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/index.tsx +0 -124
  223. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/store.ts +0 -12
  224. /package/dist/{chunk-MPBN3E54.js.map → chunk-2VHHJNXY.js.map} +0 -0
  225. /package/dist/{chunk-FBUMNJQ4.js.map → chunk-3II5GLHE.js.map} +0 -0
  226. /package/dist/{chunk-XNA64MZQ.js.map → chunk-BCO4CYE4.js.map} +0 -0
  227. /package/dist/{chunk-Q5URKSC4.js.map → chunk-FMEEJFAF.js.map} +0 -0
  228. /package/dist/{chunk-XTGMMNV5.js.map → chunk-WHFXVREI.js.map} +0 -0
@@ -1,185 +0,0 @@
1
- import { renderHook } from '@test';
2
- import { describe, expect, it, vi } from 'vitest';
3
- import { MarketplaceKind } from '../../../../../_internal';
4
- import { useCollectible, useCollection } from '../../../../../hooks';
5
- import { useCheckoutOptions } from '../useCheckoutOptions';
6
- import { useLoadData } from '../useLoadData';
7
-
8
- // Mock dependencies
9
- vi.mock('../../../../../hooks', () => ({
10
- useCollection: vi.fn(),
11
- useCollectible: vi.fn(),
12
- }));
13
-
14
- vi.mock('../useCheckoutOptions', () => ({
15
- useCheckoutOptions: vi.fn(),
16
- }));
17
-
18
- describe('useLoadData', () => {
19
- const defaultProps = {
20
- chainId: 1,
21
- collectionAddress: '0x123' as `0x${string}`,
22
- collectibleId: '1',
23
- orderId: '1',
24
- marketplace: MarketplaceKind.sequence_marketplace_v2,
25
- };
26
-
27
- it('should return loading state when any data is loading', () => {
28
- // Mock one hook to be loading
29
- (useCollection as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
30
- data: null,
31
- isLoading: true,
32
- isError: false,
33
- });
34
-
35
- (useCollectible as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
36
- data: null,
37
- isLoading: false,
38
- isError: false,
39
- });
40
-
41
- (useCheckoutOptions as unknown as ReturnType<typeof vi.fn>).mockReturnValue(
42
- {
43
- data: null,
44
- isLoading: false,
45
- isError: false,
46
- },
47
- );
48
-
49
- const { result } = renderHook(() => useLoadData(defaultProps));
50
-
51
- expect(result.current.isLoading).toBe(true);
52
- expect(result.current.isError).toBe(false);
53
- expect(result.current.collection).toBeNull();
54
- expect(result.current.collectable).toBeNull();
55
- expect(result.current.checkoutOptions).toBeNull();
56
- });
57
-
58
- it('should return error state when any request fails', () => {
59
- // Mock one hook to have an error
60
- (useCollection as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
61
- data: null,
62
- isLoading: false,
63
- isError: true,
64
- });
65
-
66
- (useCollectible as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
67
- data: null,
68
- isLoading: false,
69
- isError: false,
70
- });
71
-
72
- (useCheckoutOptions as unknown as ReturnType<typeof vi.fn>).mockReturnValue(
73
- {
74
- data: null,
75
- isLoading: false,
76
- isError: false,
77
- },
78
- );
79
-
80
- const { result } = renderHook(() => useLoadData(defaultProps));
81
-
82
- expect(result.current.isError).toBe(true);
83
- expect(result.current.isLoading).toBe(false);
84
- });
85
-
86
- it('should return all data when successfully loaded', () => {
87
- const mockCollection = { type: 'ERC721', name: 'Test Collection' };
88
- const mockCollectable = { tokenId: '1', name: 'Test NFT' };
89
- const mockCheckoutOptions = {
90
- swap: [],
91
- nftCheckout: [],
92
- onRamp: [],
93
- crypto: ['ETH'],
94
- };
95
-
96
- (useCollection as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
97
- data: mockCollection,
98
- isLoading: false,
99
- isError: false,
100
- });
101
-
102
- (useCollectible as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
103
- data: mockCollectable,
104
- isLoading: false,
105
- isError: false,
106
- });
107
-
108
- (useCheckoutOptions as unknown as ReturnType<typeof vi.fn>).mockReturnValue(
109
- {
110
- data: mockCheckoutOptions,
111
- isLoading: false,
112
- isError: false,
113
- },
114
- );
115
-
116
- const { result } = renderHook(() => useLoadData(defaultProps));
117
-
118
- expect(result.current.isLoading).toBe(false);
119
- expect(result.current.isError).toBe(false);
120
- expect(result.current.collection).toBe(mockCollection);
121
- expect(result.current.collectable).toBe(mockCollectable);
122
- expect(result.current.checkoutOptions).toBe(mockCheckoutOptions);
123
- });
124
-
125
- it('should handle partial data loading states', () => {
126
- // Mock different loading states for each hook
127
- (useCollection as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
128
- data: { type: 'ERC721', name: 'Test Collection' },
129
- isLoading: false,
130
- isError: false,
131
- });
132
-
133
- (useCollectible as unknown as ReturnType<typeof vi.fn>).mockReturnValue({
134
- data: null,
135
- isLoading: true,
136
- isError: false,
137
- });
138
-
139
- (useCheckoutOptions as unknown as ReturnType<typeof vi.fn>).mockReturnValue(
140
- {
141
- data: {
142
- swap: [],
143
- nftCheckout: [],
144
- onRamp: [],
145
- crypto: ['ETH'],
146
- },
147
- isLoading: false,
148
- isError: false,
149
- },
150
- );
151
-
152
- const { result } = renderHook(() => useLoadData(defaultProps));
153
-
154
- // Should be loading if any data is loading
155
- expect(result.current.isLoading).toBe(true);
156
- expect(result.current.isError).toBe(false);
157
-
158
- // Should have partial data available
159
- expect(result.current.collection).toBeDefined();
160
- expect(result.current.collectable).toBeNull();
161
- expect(result.current.checkoutOptions).toBeDefined();
162
-
163
- // Verify hook calls
164
- expect(useCollection).toHaveBeenCalledWith({
165
- chainId: defaultProps.chainId,
166
- collectionAddress: defaultProps.collectionAddress,
167
- });
168
-
169
- expect(useCollectible).toHaveBeenCalledWith({
170
- chainId: String(defaultProps.chainId),
171
- collectionAddress: defaultProps.collectionAddress,
172
- collectibleId: defaultProps.collectibleId,
173
- query: {
174
- enabled: !!defaultProps.collectibleId,
175
- },
176
- });
177
-
178
- expect(useCheckoutOptions).toHaveBeenCalledWith({
179
- chainId: defaultProps.chainId,
180
- collectionAddress: defaultProps.collectionAddress,
181
- orderId: defaultProps.orderId,
182
- marketplace: defaultProps.marketplace,
183
- });
184
- });
185
- });
@@ -1,170 +0,0 @@
1
- import { useSelectPaymentModal } from '@0xsequence/checkout';
2
- import type { QueryKey } from '@tanstack/react-query';
3
- import type { Hash, Hex } from 'viem';
4
- import { decodeERC20Approval } from '../../../../../utils/decode/erc20';
5
- import {
6
- type CheckoutOptions,
7
- type MarketplaceKind,
8
- StepType,
9
- WalletKind,
10
- balanceQueries,
11
- collectableKeys,
12
- getMarketplaceClient,
13
- getQueryClient,
14
- } from '../../../../_internal';
15
- import { useWallet } from '../../../../_internal/wallet/useWallet';
16
- import { useConfig } from '../../../../hooks';
17
- import type { ModalCallbacks } from '../../_internal/types';
18
- import { buyModal$ } from '../store';
19
- import { useFees } from './useFees';
20
-
21
- interface UseBuyCollectableProps {
22
- chainId: string;
23
- collectionAddress: string;
24
- tokenId: string | undefined;
25
- callbacks?: ModalCallbacks;
26
- priceCurrencyAddress: string;
27
- setCheckoutModalIsLoading: (isLoading: boolean) => void;
28
- setCheckoutModalLoaded: (isLoaded: boolean) => void;
29
- customProviderCallback?: (args: { data: string; value: string }) => void;
30
- }
31
-
32
- type BuyCollectableReturn =
33
- | { status: 'loading'; buy: null; isLoading: true; isError: false }
34
- | { status: 'error'; buy: null; isLoading: false; isError: true }
35
- | {
36
- status: 'ready';
37
- isLoading: false;
38
- isError: false;
39
- buy: (input: {
40
- orderId: string;
41
- quantity: string;
42
- collectableDecimals: number;
43
- marketplace: MarketplaceKind;
44
- checkoutOptions: CheckoutOptions;
45
- }) => Promise<void>;
46
- };
47
-
48
- export const useBuyCollectable = ({
49
- chainId,
50
- collectionAddress,
51
- tokenId,
52
- callbacks,
53
- priceCurrencyAddress,
54
- setCheckoutModalIsLoading,
55
- setCheckoutModalLoaded,
56
- customProviderCallback,
57
- }: UseBuyCollectableProps): BuyCollectableReturn => {
58
- const { openSelectPaymentModal } = useSelectPaymentModal();
59
- const config = useConfig();
60
- const marketplaceClient = getMarketplaceClient(Number(chainId), config);
61
- const fees = useFees({ chainId: Number(chainId), collectionAddress });
62
- const { wallet, isLoading, isError } = useWallet();
63
-
64
- if (isLoading) {
65
- return { status: 'loading', buy: null, isLoading, isError: false };
66
- }
67
-
68
- if (isError || !wallet || !tokenId) {
69
- return { status: 'error', buy: null, isLoading, isError: true };
70
- }
71
-
72
- const invalidateQueries = async (queriesToInvalidate: QueryKey[]) => {
73
- const queryClient = getQueryClient();
74
- for (const queryKey of queriesToInvalidate) {
75
- await queryClient.invalidateQueries({ queryKey });
76
- }
77
- };
78
-
79
- return {
80
- status: 'ready',
81
- isLoading,
82
- isError,
83
- buy: async (input) => {
84
- setCheckoutModalIsLoading(true);
85
- const { steps } = await marketplaceClient.generateBuyTransaction({
86
- collectionAddress,
87
- buyer: await wallet.address(),
88
- marketplace: input.marketplace,
89
- ordersData: [
90
- {
91
- orderId: input.orderId,
92
- quantity: input.quantity,
93
- tokenId: tokenId,
94
- },
95
- ],
96
- additionalFees: [fees],
97
- walletType: WalletKind.unknown,
98
- });
99
-
100
- // these states are necessary to manage appearance of the quantity modal
101
- setCheckoutModalLoaded(true);
102
- setCheckoutModalIsLoading(false);
103
-
104
- const buyStep = steps.find((step) => step.id === StepType.buy);
105
- const approveStep = steps.find(
106
- (step) => step.id === StepType.tokenApproval,
107
- );
108
-
109
- const approvedSpenderAddress = approveStep
110
- ? decodeERC20Approval(approveStep.data as Hex).spender
111
- : undefined;
112
-
113
- if (!buyStep) {
114
- throw new Error('Buy step not found');
115
- }
116
-
117
- const openSelectPaymentModalConfig = {
118
- chain: chainId,
119
- collectibles: [
120
- {
121
- tokenId: tokenId,
122
- quantity: input.quantity,
123
- decimals: input.collectableDecimals,
124
- },
125
- ],
126
- currencyAddress: priceCurrencyAddress,
127
- price: buyStep.price,
128
- targetContractAddress: buyStep.to,
129
- approvedSpenderAddress,
130
- txData: buyStep.data as Hex,
131
- collectionAddress,
132
- recipientAddress: await wallet.address(),
133
- enableMainCurrencyPayment: true,
134
- enableSwapPayments: !!input.checkoutOptions.swap,
135
- creditCardProviders: customProviderCallback
136
- ? ['custom']
137
- : input.checkoutOptions.nftCheckout || [],
138
- onSuccess: (hash: string) => {
139
- callbacks?.onSuccess?.({ hash: hash as Hash });
140
- },
141
- supplementaryAnalyticsInfo: {
142
- orderId: input.orderId,
143
- marketplaceKind: input.marketplace,
144
- },
145
- onError: callbacks?.onError,
146
- onClose: () => {
147
- invalidateQueries([
148
- collectableKeys.listings,
149
- collectableKeys.lowestListings,
150
- collectableKeys.listingsCount,
151
- collectableKeys.lists,
152
- collectableKeys.userBalances,
153
- balanceQueries.all,
154
- balanceQueries.collectionBalanceDetails,
155
- ]);
156
-
157
- buyModal$.close();
158
- },
159
- ...(customProviderCallback && {
160
- customProviderCallback: () => {
161
- customProviderCallback(buyStep);
162
- buyModal$.close();
163
- },
164
- }),
165
- };
166
-
167
- openSelectPaymentModal(openSelectPaymentModalConfig);
168
- },
169
- };
170
- };
@@ -1,47 +0,0 @@
1
- 'use client';
2
-
3
- import { useEffect } from 'react';
4
- import { parseUnits } from 'viem';
5
- import type { Order } from '../../../../_internal';
6
- import type {
7
- MarketplaceKind,
8
- TokenMetadata,
9
- } from '../../../../_internal/api/marketplace.gen';
10
- import { buyModal$ } from '../store';
11
-
12
- export interface BuyInput {
13
- orderId: string;
14
- collectableDecimals: number;
15
- marketplace: MarketplaceKind;
16
- quantity: string;
17
- }
18
-
19
- export interface CheckoutModalProps {
20
- buy: (props: BuyInput) => void;
21
- collectable: TokenMetadata;
22
- order: Order;
23
- isLoading?: boolean;
24
- }
25
- export function CheckoutModal({ buy, collectable, order }: CheckoutModalProps) {
26
- // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
27
- useEffect(() => {
28
- if (
29
- buyModal$.state.checkoutModalIsLoading.get() ||
30
- buyModal$.state.checkoutModalLoaded.get()
31
- )
32
- return;
33
-
34
- const executeBuy = () => {
35
- buy({
36
- orderId: order.orderId,
37
- collectableDecimals: collectable.decimals || 0,
38
- quantity: parseUnits('1', collectable.decimals || 0).toString(),
39
- marketplace: order.marketplace,
40
- });
41
- };
42
-
43
- executeBuy();
44
- }, []);
45
-
46
- return null;
47
- }
@@ -1,140 +0,0 @@
1
- 'use client';
2
-
3
- import { observer } from '@legendapp/state/react';
4
- import * as dn from 'dnum';
5
- import type { Hex } from 'viem';
6
-
7
- import { Text, TokenImage } from '@0xsequence/design-system';
8
- import { DEFAULT_MARKETPLACE_FEE_PERCENTAGE } from '../../../../../consts';
9
- import { compareAddress } from '../../../../../utils/address';
10
- import type { Order } from '../../../../_internal';
11
- import { useCurrency, useMarketplaceConfig } from '../../../../hooks';
12
- import { ActionModal } from '../../_internal/components/actionModal';
13
- import QuantityInput from '../../_internal/components/quantityInput';
14
- import { buyModal$ } from '../store';
15
- import type { CheckoutModalProps } from './CheckoutModal';
16
-
17
- interface ERC1155QuantityModalProps extends CheckoutModalProps {
18
- chainId: string;
19
- collectionAddress: Hex;
20
- collectibleId: string | undefined;
21
- }
22
-
23
- export const ERC1155QuantityModal = observer(
24
- ({ buy, collectable, order }: ERC1155QuantityModalProps) => {
25
- if (
26
- buyModal$.state.checkoutModalLoaded.get() &&
27
- buyModal$.isOpen.get() &&
28
- buyModal$.state.checkoutModalIsLoading.get() &&
29
- buyModal$.state.purchaseProcessing.get()
30
- ) {
31
- return null;
32
- }
33
-
34
- return (
35
- <ActionModal
36
- isOpen={buyModal$.isOpen.get()}
37
- chainId={order.chainId}
38
- onClose={() => buyModal$.close()}
39
- title="Select Quantity"
40
- disableAnimation={true}
41
- ctas={[
42
- {
43
- label: 'Buy now',
44
- onClick: () => {
45
- buyModal$.state.checkoutModalIsLoading.set(true);
46
- buyModal$.state.purchaseProcessing.set(true);
47
-
48
- buy({
49
- quantity: buyModal$.state.quantity.get(),
50
- orderId: order.orderId,
51
- collectableDecimals: collectable.decimals || 0,
52
- marketplace: order.marketplace,
53
- });
54
- },
55
- disabled: buyModal$.state.checkoutModalIsLoading.get(),
56
- pending: buyModal$.state.checkoutModalIsLoading.get(),
57
- },
58
- ]}
59
- >
60
- <div className="flex w-full flex-col gap-4">
61
- <QuantityInput
62
- $quantity={buyModal$.state.quantity}
63
- $invalidQuantity={buyModal$.state.invalidQuantity}
64
- decimals={order.quantityDecimals}
65
- maxQuantity={order.quantityRemaining}
66
- />
67
-
68
- <TotalPrice order={order} />
69
- </div>
70
- </ActionModal>
71
- );
72
- },
73
- );
74
-
75
- const TotalPrice = observer(({ order }: { order: Order }) => {
76
- const { data: marketplaceConfig } = useMarketplaceConfig();
77
- const { data: currency, isLoading: isCurrencyLoading } = useCurrency({
78
- chainId: order.chainId,
79
- currencyAddress: order.priceCurrencyAddress,
80
- });
81
-
82
- const quantityStr = buyModal$.state.quantity.get();
83
-
84
- let formattedPrice = '0';
85
-
86
- if (currency) {
87
- const quantity = BigInt(quantityStr);
88
- const totalPriceWithoutFees = dn.format(
89
- dn.multiply(quantity, order.priceAmountFormatted),
90
- {
91
- digits: currency.decimals,
92
- trailingZeros: false,
93
- },
94
- );
95
- const marketplaceFeePercentage =
96
- marketplaceConfig?.collections.find((collection) =>
97
- compareAddress(collection.address, order.collectionContractAddress),
98
- )?.feePercentage || DEFAULT_MARKETPLACE_FEE_PERCENTAGE;
99
- const feeMultiplier = dn.from(1 + marketplaceFeePercentage / 100);
100
- const totalPrice = dn.format(
101
- dn.multiply(totalPriceWithoutFees, feeMultiplier),
102
- {
103
- digits: currency.decimals,
104
- trailingZeros: false,
105
- },
106
- );
107
-
108
- formattedPrice = totalPrice;
109
- }
110
-
111
- return (
112
- <div className="flex justify-between">
113
- <Text className="font-body font-medium text-xs" color="text50">
114
- Total Price
115
- </Text>
116
-
117
- <div className="flex items-center gap-0.5">
118
- {isCurrencyLoading || !currency ? (
119
- <div className="flex items-center gap-2">
120
- <Text className="font-body text-text-50 text-xs">Loading...</Text>
121
- </div>
122
- ) : (
123
- <>
124
- {currency.imageUrl && (
125
- <TokenImage src={currency.imageUrl} size="xs" />
126
- )}
127
-
128
- <Text className="font-body font-bold text-text-100 text-xs">
129
- {formattedPrice}
130
- </Text>
131
-
132
- <Text className="font-body font-bold text-text-80 text-xs">
133
- {currency?.symbol}
134
- </Text>
135
- </>
136
- )}
137
- </div>
138
- </div>
139
- );
140
- });
@@ -1,162 +0,0 @@
1
- import { render, waitFor } from '@testing-library/react';
2
- import { parseUnits } from 'viem';
3
- import { beforeEach, describe, expect, it, vi } from 'vitest';
4
- import type { Order, TokenMetadata } from '../../../../../_internal';
5
- import {
6
- MarketplaceKind,
7
- OrderSide,
8
- OrderStatus,
9
- } from '../../../../../_internal';
10
- import { CheckoutModal } from '../CheckoutModal';
11
-
12
- describe('CheckoutModal', () => {
13
- const mockBuy = vi.fn();
14
-
15
- const defaultOrder: Order = {
16
- orderId: '123',
17
- marketplace: MarketplaceKind.sequence_marketplace_v2,
18
- priceAmount: '1000000000000000000',
19
- priceCurrencyAddress: '0x0',
20
- quantityRemaining: '1',
21
- priceUSDFormatted: '$1,800.00',
22
- createdAt: new Date().toISOString(),
23
- side: OrderSide.listing,
24
- status: OrderStatus.active,
25
- chainId: 1,
26
- originName: 'test',
27
- collectionContractAddress: '0x1234567890123456789012345678901234567890',
28
- tokenId: '1',
29
- createdBy: '0x1234567890123456789012345678901234567890',
30
- priceAmountFormatted: '1.0',
31
- priceAmountNet: '950000000000000000',
32
- priceAmountNetFormatted: '0.95',
33
- priceDecimals: 18,
34
- priceUSD: 1800.0,
35
- quantityInitial: '1',
36
- quantityInitialFormatted: '1',
37
- quantityRemainingFormatted: '1',
38
- quantityAvailable: '1',
39
- quantityAvailableFormatted: '1',
40
- quantityDecimals: 0,
41
- feeBps: 500,
42
- feeBreakdown: [],
43
- validFrom: new Date().toISOString(),
44
- validUntil: new Date(Date.now() + 86400000).toISOString(),
45
- blockNumber: 1234567,
46
- updatedAt: new Date().toISOString(),
47
- };
48
-
49
- const defaultCollectable: TokenMetadata = {
50
- tokenId: '1',
51
- name: 'Test NFT',
52
- description: 'Test Description',
53
- image: 'https://test.com/image.png',
54
- attributes: [],
55
- decimals: 0,
56
- };
57
-
58
- beforeEach(() => {
59
- vi.clearAllMocks();
60
- });
61
-
62
- it('should auto-execute buy function when mounted', async () => {
63
- render(
64
- <CheckoutModal
65
- buy={mockBuy}
66
- order={defaultOrder}
67
- collectable={defaultCollectable}
68
- />,
69
- );
70
-
71
- await waitFor(() => {
72
- expect(mockBuy).toHaveBeenCalledTimes(1);
73
- });
74
- });
75
-
76
- it('should execute buy even when loading (current implementation)', async () => {
77
- render(
78
- <CheckoutModal
79
- buy={mockBuy}
80
- order={defaultOrder}
81
- collectable={defaultCollectable}
82
- isLoading={true}
83
- />,
84
- );
85
-
86
- await waitFor(() => {
87
- expect(mockBuy).toHaveBeenCalledTimes(1);
88
- expect(mockBuy).toHaveBeenCalledWith({
89
- orderId: defaultOrder.orderId,
90
- collectableDecimals: defaultCollectable.decimals || 0,
91
- quantity: '1',
92
- marketplace: defaultOrder.marketplace,
93
- });
94
- });
95
- });
96
-
97
- it('should call buy with correct parameters', async () => {
98
- render(
99
- <CheckoutModal
100
- buy={mockBuy}
101
- order={defaultOrder}
102
- collectable={defaultCollectable}
103
- />,
104
- );
105
-
106
- await waitFor(() => {
107
- expect(mockBuy).toHaveBeenCalledWith({
108
- orderId: defaultOrder.orderId,
109
- collectableDecimals: defaultCollectable.decimals || 0,
110
- quantity: '1',
111
- marketplace: defaultOrder.marketplace,
112
- });
113
- });
114
- });
115
-
116
- it('should handle decimals correctly', async () => {
117
- const collectableWithDecimals: TokenMetadata = {
118
- ...defaultCollectable,
119
- decimals: 18,
120
- };
121
-
122
- render(
123
- <CheckoutModal
124
- buy={mockBuy}
125
- order={defaultOrder}
126
- collectable={collectableWithDecimals}
127
- />,
128
- );
129
-
130
- await waitFor(() => {
131
- expect(mockBuy).toHaveBeenCalledWith({
132
- orderId: defaultOrder.orderId,
133
- collectableDecimals: collectableWithDecimals.decimals,
134
- quantity: parseUnits('1', 18).toString(),
135
- marketplace: defaultOrder.marketplace,
136
- });
137
- });
138
-
139
- // Test with different decimal values
140
- const collectableWithCustomDecimals: TokenMetadata = {
141
- ...defaultCollectable,
142
- decimals: 6,
143
- };
144
-
145
- render(
146
- <CheckoutModal
147
- buy={mockBuy}
148
- order={defaultOrder}
149
- collectable={collectableWithCustomDecimals}
150
- />,
151
- );
152
-
153
- await waitFor(() => {
154
- expect(mockBuy).toHaveBeenCalledWith({
155
- orderId: defaultOrder.orderId,
156
- collectableDecimals: collectableWithCustomDecimals.decimals,
157
- quantity: parseUnits('1', 6).toString(),
158
- marketplace: defaultOrder.marketplace,
159
- });
160
- });
161
- });
162
- });