@0xsequence/marketplace-sdk 0.7.0 → 0.8.1

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 (227) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.changeset/seven-doors-taste.md +5 -0
  4. package/CHANGELOG.md +13 -0
  5. package/dist/{chunk-MPBN3E54.js → chunk-2VHHJNXY.js} +3 -3
  6. package/dist/{chunk-FBUMNJQ4.js → chunk-3II5GLHE.js} +2 -2
  7. package/dist/chunk-3JU7SQVE.js +182 -0
  8. package/dist/chunk-3JU7SQVE.js.map +1 -0
  9. package/dist/{chunk-XTGMMNV5.js → chunk-A5ACY5YV.js} +2 -2
  10. package/dist/chunk-ABSYNRT5.js +128 -0
  11. package/dist/chunk-ABSYNRT5.js.map +1 -0
  12. package/dist/{chunk-XNA64MZQ.js → chunk-BCO4CYE4.js} +2 -2
  13. package/dist/{chunk-HTFORA4Q.js → chunk-BN36GABQ.js} +1883 -1010
  14. package/dist/chunk-BN36GABQ.js.map +1 -0
  15. package/dist/{chunk-4XK7XNJ7.js → chunk-BNAUZXPV.js} +73 -2
  16. package/dist/chunk-BNAUZXPV.js.map +1 -0
  17. package/dist/{chunk-Q5URKSC4.js → chunk-FMEEJFAF.js} +1 -1
  18. package/dist/{chunk-BBASZVT3.js → chunk-GBQVYNCD.js} +5 -6
  19. package/dist/chunk-GBQVYNCD.js.map +1 -0
  20. package/dist/{chunk-3AKOPSON.js → chunk-IZ44XPBH.js} +2 -9
  21. package/dist/chunk-IZ44XPBH.js.map +1 -0
  22. package/dist/{chunk-EAJ5K7QV.js → chunk-Q5RKAMYF.js} +3 -4
  23. package/dist/chunk-Q5RKAMYF.js.map +1 -0
  24. package/dist/{chunk-RBEPPVLT.js → chunk-X3QNSQER.js} +145 -355
  25. package/dist/chunk-X3QNSQER.js.map +1 -0
  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 +4 -4
  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 +10 -9
  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 +11 -20
  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 +15 -24
  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 +13 -12
  50. package/dist/react/ui/components/marketplace-logos/index.js +1 -1
  51. package/dist/react/ui/icons/index.js +6 -6
  52. package/dist/react/ui/index.d.ts +18 -22
  53. package/dist/react/ui/index.js +13 -12
  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 +10 -9
  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/index.d.ts +1 -5
  59. package/dist/utils/index.js +4 -4
  60. package/package.json +22 -16
  61. package/src/react/_internal/api/__mocks__/indexer.msw.ts +3 -1
  62. package/src/react/_internal/api/__mocks__/marketplace.msw.ts +1 -1
  63. package/src/react/_internal/api/__mocks__/metadata.msw.ts +14 -12
  64. package/src/react/_internal/api/index.ts +1 -0
  65. package/src/react/_internal/api/laos-api.ts +103 -0
  66. package/src/react/_internal/api/zod-schema.ts +3 -3
  67. package/src/react/_internal/types.ts +1 -10
  68. package/src/react/_internal/wallet/__tests__/wallet.test.ts +43 -0
  69. package/src/react/_internal/wallet/useWallet.ts +6 -3
  70. package/src/react/hooks/__tests__/useAutoSelectFeeOption.test.tsx +1 -1
  71. package/src/react/hooks/__tests__/useCancelOrder.test.tsx +1 -1
  72. package/src/react/hooks/__tests__/useCancelTransactionSteps.test.tsx +1 -1
  73. package/src/react/hooks/__tests__/useCollectible.test.tsx +2 -2
  74. package/src/react/hooks/__tests__/useCollection.test.tsx +2 -2
  75. package/src/react/hooks/__tests__/useComparePrices.test.tsx +1 -1
  76. package/src/react/hooks/__tests__/useConvertPriceToUSD.test.tsx +1 -1
  77. package/src/react/hooks/__tests__/useCountListingsForCollectible.test.tsx +1 -1
  78. package/src/react/hooks/__tests__/useCountOfCollectables.test.tsx +2 -2
  79. package/src/react/hooks/__tests__/useCountOffersForCollectible.test.tsx +1 -1
  80. package/src/react/hooks/__tests__/useCurrencies.test.tsx +2 -2
  81. package/src/react/hooks/__tests__/useCurrency.test.tsx +2 -2
  82. package/src/react/hooks/__tests__/useFilters.test.tsx +2 -2
  83. package/src/react/hooks/__tests__/useFloorOrder.test.tsx +2 -2
  84. package/src/react/hooks/__tests__/useGenerateCancelTransaction.test.tsx +1 -1
  85. package/src/react/hooks/__tests__/useGenerateListingTransaction.test.tsx +1 -1
  86. package/src/react/hooks/__tests__/useGenerateOfferTransaction.test.tsx +1 -1
  87. package/src/react/hooks/__tests__/useGenerateSellTransaction.test.tsx +1 -1
  88. package/src/react/hooks/__tests__/useListCollectibleActivities.test.tsx +2 -2
  89. package/src/react/hooks/__tests__/useListCollectibles.test.tsx +3 -2
  90. package/src/react/hooks/__tests__/useListCollectiblesPaginated.test.tsx +1 -1
  91. package/src/react/hooks/__tests__/useListCollectionActivities.test.tsx +1 -1
  92. package/src/react/hooks/__tests__/useListListingsForCollectible.test.tsx +1 -1
  93. package/src/react/hooks/__tests__/useListOffersForCollectible.test.tsx +1 -1
  94. package/src/react/hooks/__tests__/useLowestListing.test.tsx +1 -1
  95. package/src/react/hooks/__tests__/useRoyalty.test.tsx +1 -2
  96. package/src/react/hooks/index.ts +0 -1
  97. package/src/react/hooks/options/collectionOptions.ts +2 -3
  98. package/src/react/hooks/useAutoSelectFeeOption.tsx +1 -1
  99. package/src/react/hooks/useCancelOrder.tsx +3 -3
  100. package/src/react/hooks/useCancelTransactionSteps.tsx +1 -1
  101. package/src/react/hooks/useCheckoutOptions.tsx +1 -2
  102. package/src/react/hooks/useCollectible.tsx +2 -3
  103. package/src/react/hooks/useCollectionBalanceDetails.tsx +1 -2
  104. package/src/react/hooks/useComparePrices.tsx +2 -9
  105. package/src/react/hooks/useConvertPriceToUSD.tsx +1 -4
  106. package/src/react/hooks/useCountListingsForCollectible.tsx +1 -2
  107. package/src/react/hooks/useCountOfCollectables.tsx +1 -2
  108. package/src/react/hooks/useCountOffersForCollectible.tsx +1 -2
  109. package/src/react/hooks/useCurrencies.tsx +1 -4
  110. package/src/react/hooks/useCurrency.tsx +3 -8
  111. package/src/react/hooks/useFilters.tsx +5 -4
  112. package/src/react/hooks/useFloorOrder.tsx +1 -2
  113. package/src/react/hooks/useGenerateCancelTransaction.tsx +3 -6
  114. package/src/react/hooks/useGenerateListingTransaction.tsx +2 -3
  115. package/src/react/hooks/useGenerateOfferTransaction.tsx +2 -3
  116. package/src/react/hooks/useGenerateSellTransaction.tsx +3 -6
  117. package/src/react/hooks/useHighestOffer.tsx +1 -1
  118. package/src/react/hooks/useListCollectibles.tsx +33 -61
  119. package/src/react/hooks/useListCollectiblesPaginated.tsx +2 -6
  120. package/src/react/hooks/useListListingsForCollectible.tsx +1 -2
  121. package/src/react/hooks/useListOffersForCollectible.tsx +1 -2
  122. package/src/react/hooks/useLowestListing.tsx +1 -2
  123. package/src/react/hooks/useRoyalty.tsx +3 -8
  124. package/src/react/hooks/useTransferTokens.tsx +2 -2
  125. package/src/react/queries/balanceOfCollectible.ts +9 -32
  126. package/src/react/queries/getTokenSupplies.ts +38 -0
  127. package/src/react/queries/index.ts +5 -0
  128. package/src/react/queries/listCollectibles.ts +96 -0
  129. package/src/react/ui/components/_internals/action-button/ActionButton.tsx +1 -1
  130. package/src/react/ui/components/_internals/action-button/__tests__/ActionButton.test.tsx +1 -1
  131. package/src/react/ui/components/_internals/action-button/components/NonOwnerActions.tsx +4 -3
  132. package/src/react/ui/components/_internals/action-button/components/OwnerActions.tsx +1 -1
  133. package/src/react/ui/components/collectible-card/CollectibleCard.tsx +2 -3
  134. package/src/react/ui/components/collectible-card/__tests__/CollectibleCard.test.tsx +1 -1
  135. package/src/react/ui/modals/BuyModal/ERC1155QuantityModal.tsx +127 -0
  136. package/src/react/ui/modals/BuyModal/Modal.tsx +70 -85
  137. package/src/react/ui/modals/BuyModal/__tests__/Modal.test.tsx +85 -226
  138. package/src/react/ui/modals/BuyModal/__tests__/Modal1155.test.tsx +140 -0
  139. package/src/react/ui/modals/BuyModal/__tests__/store.test.ts +67 -76
  140. package/src/react/ui/modals/BuyModal/hooks/__tests__/useCheckoutOptions.test.tsx +1 -60
  141. package/src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx +1 -1
  142. package/src/react/ui/modals/BuyModal/hooks/useCheckoutOptions.ts +29 -13
  143. package/src/react/ui/modals/BuyModal/hooks/useLoadData.ts +26 -21
  144. package/src/react/ui/modals/BuyModal/hooks/usePaymentModalParams.ts +200 -0
  145. package/src/react/ui/modals/BuyModal/index.tsx +4 -14
  146. package/src/react/ui/modals/BuyModal/store.ts +71 -76
  147. package/src/react/ui/modals/CreateListingModal/Modal.tsx +71 -7
  148. package/src/react/ui/modals/CreateListingModal/__tests__/Modal.test.tsx +2 -2
  149. package/src/react/ui/modals/CreateListingModal/hooks/useCreateListing.tsx +1 -1
  150. package/src/react/ui/modals/CreateListingModal/hooks/useGetTokenApproval.ts +1 -1
  151. package/src/react/ui/modals/CreateListingModal/hooks/useTransactionSteps.tsx +9 -5
  152. package/src/react/ui/modals/CreateListingModal/store.ts +7 -2
  153. package/src/react/ui/modals/MakeOfferModal/Modal.tsx +103 -6
  154. package/src/react/ui/modals/MakeOfferModal/__tests__/Modal.test.tsx +1 -1
  155. package/src/react/ui/modals/MakeOfferModal/hooks/useGetTokenApproval.tsx +1 -1
  156. package/src/react/ui/modals/MakeOfferModal/hooks/useMakeOffer.tsx +1 -1
  157. package/src/react/ui/modals/MakeOfferModal/hooks/useTransactionSteps.tsx +8 -4
  158. package/src/react/ui/modals/MakeOfferModal/store.ts +5 -3
  159. package/src/react/ui/modals/SellModal/Modal.tsx +76 -4
  160. package/src/react/ui/modals/SellModal/__tests__/Modal.test.tsx +1 -1
  161. package/src/react/ui/modals/SellModal/hooks/useGetTokenApproval.tsx +1 -1
  162. package/src/react/ui/modals/SellModal/hooks/useSell.tsx +1 -1
  163. package/src/react/ui/modals/SellModal/hooks/useTransactionSteps.tsx +16 -8
  164. package/src/react/ui/modals/SellModal/store.ts +5 -3
  165. package/src/react/ui/modals/TransferModal/_store.ts +15 -3
  166. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/TokenQuantityInput.tsx +58 -0
  167. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/TransferButton.tsx +56 -0
  168. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/WalletAddressInput.tsx +50 -0
  169. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +94 -66
  170. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/useHandleTransfer.tsx +22 -14
  171. package/src/react/ui/modals/TransferModal/index.tsx +72 -38
  172. package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +43 -42
  173. package/src/react/ui/modals/_internal/components/actionModal/store.ts +1 -2
  174. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +2 -2
  175. package/src/react/ui/modals/_internal/components/expirationDateSelect/index.tsx +9 -1
  176. package/src/react/ui/modals/_internal/components/floorPriceText/index.tsx +27 -12
  177. package/src/react/ui/modals/_internal/components/priceInput/__tests__/index.test.tsx +1 -1
  178. package/src/react/ui/modals/_internal/components/priceInput/index.tsx +19 -3
  179. package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +3 -0
  180. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/_components/ActionButtons.tsx +60 -0
  181. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/_components/BalanceIndicator.tsx +30 -0
  182. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/index.tsx +126 -0
  183. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/store.ts +25 -0
  184. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/useWaasFeeOptionManager.tsx +74 -0
  185. package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +1 -2
  186. package/src/react/ui/modals/_internal/components/switchChainModal/store.ts +1 -2
  187. package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +1 -1
  188. package/src/react/ui/modals/_internal/components/transaction-footer/index.tsx +4 -7
  189. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +1 -1
  190. package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +1 -1
  191. package/src/react/ui/modals/_internal/components/transactionStatusModal/__tests__/TransactionStatusModal.test.tsx +1 -1
  192. package/src/react/ui/modals/_internal/components/transactionStatusModal/hooks/useTransactionStatus.ts +1 -1
  193. package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +6 -1
  194. package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +2 -2
  195. package/src/react/ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect.tsx +10 -31
  196. package/src/react/ui/modals/_internal/hooks/useSelectWaasFeeOptions.ts +53 -0
  197. package/src/react/ui/modals/_internal/types.ts +2 -1
  198. package/src/types/waas-types.ts +38 -0
  199. package/src/utils/network.ts +2 -4
  200. package/test/const.ts +1 -1
  201. package/test/setup.ts +10 -0
  202. package/test/test-utils.tsx +31 -5
  203. package/tsconfig.tsbuildinfo +1 -1
  204. package/dist/chunk-3AKOPSON.js.map +0 -1
  205. package/dist/chunk-4XK7XNJ7.js.map +0 -1
  206. package/dist/chunk-BBASZVT3.js.map +0 -1
  207. package/dist/chunk-EAJ5K7QV.js.map +0 -1
  208. package/dist/chunk-HTFORA4Q.js.map +0 -1
  209. package/dist/chunk-OFY7OFTL.js +0 -458
  210. package/dist/chunk-OFY7OFTL.js.map +0 -1
  211. package/dist/chunk-RBEPPVLT.js.map +0 -1
  212. package/src/react/hooks/__tests__/useGenerateBuyTransaction.test.tsx +0 -172
  213. package/src/react/hooks/useGenerateBuyTransaction.tsx +0 -80
  214. package/src/react/ui/modals/BuyModal/hooks/__tests__/useBuyCollectable.test.tsx +0 -349
  215. package/src/react/ui/modals/BuyModal/hooks/__tests__/useLoadData.test.tsx +0 -185
  216. package/src/react/ui/modals/BuyModal/hooks/useBuyCollectable.ts +0 -170
  217. package/src/react/ui/modals/BuyModal/modals/CheckoutModal.tsx +0 -47
  218. package/src/react/ui/modals/BuyModal/modals/Modal1155.tsx +0 -140
  219. package/src/react/ui/modals/BuyModal/modals/__tests__/CheckoutModal.test.tsx +0 -162
  220. package/src/react/ui/modals/BuyModal/modals/__tests__/Modal1155.test.tsx +0 -327
  221. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/index.tsx +0 -124
  222. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/store.ts +0 -12
  223. /package/dist/{chunk-MPBN3E54.js.map → chunk-2VHHJNXY.js.map} +0 -0
  224. /package/dist/{chunk-FBUMNJQ4.js.map → chunk-3II5GLHE.js.map} +0 -0
  225. /package/dist/{chunk-XTGMMNV5.js.map → chunk-A5ACY5YV.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
@@ -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
- });