@0xsequence/marketplace-sdk 0.0.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 (258) hide show
  1. package/README.md +8 -0
  2. package/dist/chunk-3TYUQEFM.js +115 -0
  3. package/dist/chunk-3TYUQEFM.js.map +1 -0
  4. package/dist/chunk-4ESPWOBV.js +13 -0
  5. package/dist/chunk-4ESPWOBV.js.map +1 -0
  6. package/dist/chunk-4PFMUVE4.js +78 -0
  7. package/dist/chunk-4PFMUVE4.js.map +1 -0
  8. package/dist/chunk-5WRI5ZAA.js +31 -0
  9. package/dist/chunk-5WRI5ZAA.js.map +1 -0
  10. package/dist/chunk-6S4FYXP6.js +43 -0
  11. package/dist/chunk-6S4FYXP6.js.map +1 -0
  12. package/dist/chunk-7OO74L2K.js +41 -0
  13. package/dist/chunk-7OO74L2K.js.map +1 -0
  14. package/dist/chunk-BBB3XUB4.js +213 -0
  15. package/dist/chunk-BBB3XUB4.js.map +1 -0
  16. package/dist/chunk-BCNFYVAL.js +1 -0
  17. package/dist/chunk-BCNFYVAL.js.map +1 -0
  18. package/dist/chunk-D7QQP6MS.js +2 -0
  19. package/dist/chunk-D7QQP6MS.js.map +1 -0
  20. package/dist/chunk-DBFOPEV6.js +23 -0
  21. package/dist/chunk-DBFOPEV6.js.map +1 -0
  22. package/dist/chunk-EDTC7UES.js +176 -0
  23. package/dist/chunk-EDTC7UES.js.map +1 -0
  24. package/dist/chunk-G3D572BT.js +249 -0
  25. package/dist/chunk-G3D572BT.js.map +1 -0
  26. package/dist/chunk-HGBEC3WX.js +1285 -0
  27. package/dist/chunk-HGBEC3WX.js.map +1 -0
  28. package/dist/chunk-MJ4YU7RW.js +2 -0
  29. package/dist/chunk-MJ4YU7RW.js.map +1 -0
  30. package/dist/chunk-NJ2GXOPW.js +2 -0
  31. package/dist/chunk-NJ2GXOPW.js.map +1 -0
  32. package/dist/chunk-O5JXKTWP.js +1029 -0
  33. package/dist/chunk-O5JXKTWP.js.map +1 -0
  34. package/dist/chunk-O642NH7U.js +15 -0
  35. package/dist/chunk-O642NH7U.js.map +1 -0
  36. package/dist/chunk-QOJXWHRZ.js +71 -0
  37. package/dist/chunk-QOJXWHRZ.js.map +1 -0
  38. package/dist/chunk-QVFMD6S2.js +21 -0
  39. package/dist/chunk-QVFMD6S2.js.map +1 -0
  40. package/dist/chunk-RNUHUVLC.js +214 -0
  41. package/dist/chunk-RNUHUVLC.js.map +1 -0
  42. package/dist/chunk-SM7V6ZWI.js +2740 -0
  43. package/dist/chunk-SM7V6ZWI.js.map +1 -0
  44. package/dist/chunk-STO74F2I.js +14 -0
  45. package/dist/chunk-STO74F2I.js.map +1 -0
  46. package/dist/chunk-TZGLKJRF.js +198 -0
  47. package/dist/chunk-TZGLKJRF.js.map +1 -0
  48. package/dist/chunk-UYRQ5MJQ.js +1027 -0
  49. package/dist/chunk-UYRQ5MJQ.js.map +1 -0
  50. package/dist/chunk-VPGWEMWL.js +162 -0
  51. package/dist/chunk-VPGWEMWL.js.map +1 -0
  52. package/dist/chunk-ZE2LNX65.js +394 -0
  53. package/dist/chunk-ZE2LNX65.js.map +1 -0
  54. package/dist/create-config-Dz0gCiQ0.d.ts +8 -0
  55. package/dist/get-query-client-D46hbjk6.d.ts +5 -0
  56. package/dist/index.css +232 -0
  57. package/dist/index.d.ts +16 -0
  58. package/dist/index.js +76 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/marketplace-config-DZbtyrma.d.ts +57 -0
  61. package/dist/marketplace.gen-Ceofb9Cs.d.ts +904 -0
  62. package/dist/react/_internal/api/index.d.ts +51 -0
  63. package/dist/react/_internal/api/index.js +134 -0
  64. package/dist/react/_internal/api/index.js.map +1 -0
  65. package/dist/react/_internal/index.d.ts +22 -0
  66. package/dist/react/_internal/index.js +150 -0
  67. package/dist/react/_internal/index.js.map +1 -0
  68. package/dist/react/_internal/wagmi/index.d.ts +12 -0
  69. package/dist/react/_internal/wagmi/index.js +12 -0
  70. package/dist/react/_internal/wagmi/index.js.map +1 -0
  71. package/dist/react/hooks/index.d.ts +381 -0
  72. package/dist/react/hooks/index.js +82 -0
  73. package/dist/react/hooks/index.js.map +1 -0
  74. package/dist/react/index.css +233 -0
  75. package/dist/react/index.css.map +1 -0
  76. package/dist/react/index.d.ts +27 -0
  77. package/dist/react/index.js +113 -0
  78. package/dist/react/index.js.map +1 -0
  79. package/dist/react/ssr/index.d.ts +94 -0
  80. package/dist/react/ssr/index.js +351 -0
  81. package/dist/react/ssr/index.js.map +1 -0
  82. package/dist/react/ui/icons/index.css +25 -0
  83. package/dist/react/ui/icons/index.css.map +1 -0
  84. package/dist/react/ui/icons/index.d.ts +2 -0
  85. package/dist/react/ui/icons/index.js +12 -0
  86. package/dist/react/ui/icons/index.js.map +1 -0
  87. package/dist/react/ui/index.css +233 -0
  88. package/dist/react/ui/index.css.map +1 -0
  89. package/dist/react/ui/index.d.ts +112 -0
  90. package/dist/react/ui/index.js +34 -0
  91. package/dist/react/ui/index.js.map +1 -0
  92. package/dist/react/ui/modals/_internal/components/actionModal/index.css +44 -0
  93. package/dist/react/ui/modals/_internal/components/actionModal/index.css.map +1 -0
  94. package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +31 -0
  95. package/dist/react/ui/modals/_internal/components/actionModal/index.js +39 -0
  96. package/dist/react/ui/modals/_internal/components/actionModal/index.js.map +1 -0
  97. package/dist/react/ui/styles/index.css +36 -0
  98. package/dist/react/ui/styles/index.css.map +1 -0
  99. package/dist/react/ui/styles/index.d.ts +5 -0
  100. package/dist/react/ui/styles/index.js +13 -0
  101. package/dist/react/ui/styles/index.js.map +1 -0
  102. package/dist/sdk-config-xWkdBdrL.d.ts +24 -0
  103. package/dist/services-BIwQ1C1c.d.ts +20 -0
  104. package/dist/styles/index.css +233 -0
  105. package/dist/styles/index.css.map +1 -0
  106. package/dist/styles/index.d.ts +58 -0
  107. package/dist/styles/index.js +5019 -0
  108. package/dist/styles/index.js.map +1 -0
  109. package/dist/styles.css-BVaTR5nO.d.ts +3 -0
  110. package/dist/types/index.d.ts +12 -0
  111. package/dist/types/index.js +39 -0
  112. package/dist/types/index.js.map +1 -0
  113. package/dist/types-BrAQ8-w4.d.ts +12 -0
  114. package/dist/utils/abi/abi/standard/index.d.ts +25 -0
  115. package/dist/utils/abi/abi/standard/index.js +8 -0
  116. package/dist/utils/abi/abi/standard/index.js.map +1 -0
  117. package/dist/utils/abi/abi/token/index.d.ts +1125 -0
  118. package/dist/utils/abi/abi/token/index.js +13 -0
  119. package/dist/utils/abi/abi/token/index.js.map +1 -0
  120. package/dist/utils/abi/clients/index.d.ts +27 -0
  121. package/dist/utils/abi/clients/index.js +13 -0
  122. package/dist/utils/abi/clients/index.js.map +1 -0
  123. package/dist/utils/index.d.ts +23 -0
  124. package/dist/utils/index.js +37 -0
  125. package/dist/utils/index.js.map +1 -0
  126. package/package.json +74 -0
  127. package/src/consts.ts +2 -0
  128. package/src/index.ts +3 -0
  129. package/src/react/_internal/api/get-query-client.ts +32 -0
  130. package/src/react/_internal/api/index.ts +5 -0
  131. package/src/react/_internal/api/marketplace-api.ts +31 -0
  132. package/src/react/_internal/api/marketplace.gen.ts +1911 -0
  133. package/src/react/_internal/api/query-keys.ts +61 -0
  134. package/src/react/_internal/api/services.ts +101 -0
  135. package/src/react/_internal/consts.ts +1 -0
  136. package/src/react/_internal/get-provider.ts +6 -0
  137. package/src/react/_internal/index.ts +5 -0
  138. package/src/react/_internal/types.ts +13 -0
  139. package/src/react/_internal/wagmi/create-config.ts +62 -0
  140. package/src/react/_internal/wagmi/embedded.ts +87 -0
  141. package/src/react/_internal/wagmi/index.ts +3 -0
  142. package/src/react/_internal/wagmi/universal.ts +82 -0
  143. package/src/react/hooks/index.ts +17 -0
  144. package/src/react/hooks/options/marketplaceConfigOptions.ts +62 -0
  145. package/src/react/hooks/useBalanceOfCollectible.tsx +51 -0
  146. package/src/react/hooks/useCollectible.tsx +47 -0
  147. package/src/react/hooks/useCollection.tsx +42 -0
  148. package/src/react/hooks/useCollectionCounts.tsx +61 -0
  149. package/src/react/hooks/useConfig.tsx +15 -0
  150. package/src/react/hooks/useCurrencies.tsx +76 -0
  151. package/src/react/hooks/useFilters.tsx +39 -0
  152. package/src/react/hooks/useFloorOrder.tsx +28 -0
  153. package/src/react/hooks/useGenerateListingTransaction.tsx +63 -0
  154. package/src/react/hooks/useGenerateOfferTransaction.tsx +60 -0
  155. package/src/react/hooks/useGenerateSellTransaction.tsx +43 -0
  156. package/src/react/hooks/useHighestOffer.tsx +46 -0
  157. package/src/react/hooks/useListBalances.tsx +56 -0
  158. package/src/react/hooks/useListCollectibles.tsx +54 -0
  159. package/src/react/hooks/useListOffersForCollectible.tsx +53 -0
  160. package/src/react/hooks/useLowestListing.tsx +47 -0
  161. package/src/react/hooks/useMarketplaceConfig.tsx +10 -0
  162. package/src/react/hooks/useRoyaltyPercentage.tsx +45 -0
  163. package/src/react/hooks/useTransferTokens.tsx +81 -0
  164. package/src/react/index.ts +5 -0
  165. package/src/react/provider.tsx +24 -0
  166. package/src/react/ssr/create-ssr-client.ts +31 -0
  167. package/src/react/ssr/index.ts +1 -0
  168. package/src/react/ui/icons/ArrowUp.tsx +29 -0
  169. package/src/react/ui/icons/CalendarIcon.tsx +29 -0
  170. package/src/react/ui/icons/InfoIcon.tsx +36 -0
  171. package/src/react/ui/icons/InventoryIcon.tsx +41 -0
  172. package/src/react/ui/icons/MinusIcon.tsx +31 -0
  173. package/src/react/ui/icons/PlusIcon.tsx +29 -0
  174. package/src/react/ui/icons/PositiveCircleIcon.tsx +35 -0
  175. package/src/react/ui/icons/index.ts +7 -0
  176. package/src/react/ui/icons/styles.css.ts +35 -0
  177. package/src/react/ui/index.ts +6 -0
  178. package/src/react/ui/modals/Account/index.tsx +29 -0
  179. package/src/react/ui/modals/CreateListingModal/_store.ts +326 -0
  180. package/src/react/ui/modals/CreateListingModal/_utils/getCreateListingTransactionTitleMessage.ts +30 -0
  181. package/src/react/ui/modals/CreateListingModal/index.tsx +146 -0
  182. package/src/react/ui/modals/MakeOfferModal/_store.ts +296 -0
  183. package/src/react/ui/modals/MakeOfferModal/_utils/getMakeOfferTransactionTitleMessage.ts +28 -0
  184. package/src/react/ui/modals/MakeOfferModal/index.tsx +157 -0
  185. package/src/react/ui/modals/SellModal/_store.ts +274 -0
  186. package/src/react/ui/modals/SellModal/_utils/getSellTransactionTitleMessage.ts +28 -0
  187. package/src/react/ui/modals/SellModal/index.tsx +126 -0
  188. package/src/react/ui/modals/SellModal/utils.ts +38 -0
  189. package/src/react/ui/modals/SuccessfulPurchaseModal/_store.ts +58 -0
  190. package/src/react/ui/modals/SuccessfulPurchaseModal/index.tsx +186 -0
  191. package/src/react/ui/modals/SuccessfulPurchaseModal/styles.css.ts +52 -0
  192. package/src/react/ui/modals/TransferModal/_store.ts +58 -0
  193. package/src/react/ui/modals/TransferModal/_utils/getTransferTransactionTitleMessage.ts +28 -0
  194. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +102 -0
  195. package/src/react/ui/modals/TransferModal/_views/followWalletInstructions/index.tsx +130 -0
  196. package/src/react/ui/modals/TransferModal/index.tsx +92 -0
  197. package/src/react/ui/modals/TransferModal/messages.ts +14 -0
  198. package/src/react/ui/modals/TransferModal/styles.css.ts +20 -0
  199. package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +94 -0
  200. package/src/react/ui/modals/_internal/components/actionModal/index.ts +3 -0
  201. package/src/react/ui/modals/_internal/components/actionModal/store.ts +19 -0
  202. package/src/react/ui/modals/_internal/components/actionModal/styles.css.ts +15 -0
  203. package/src/react/ui/modals/_internal/components/alertMessage/index.tsx +21 -0
  204. package/src/react/ui/modals/_internal/components/alertMessage/styles.css.ts +22 -0
  205. package/src/react/ui/modals/_internal/components/calendar/index.tsx +59 -0
  206. package/src/react/ui/modals/_internal/components/calendarPopover/index.tsx +41 -0
  207. package/src/react/ui/modals/_internal/components/calendarPopover/styles.css.ts +16 -0
  208. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +76 -0
  209. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/styles.css.ts +33 -0
  210. package/src/react/ui/modals/_internal/components/expirationDateSelect/index.tsx +127 -0
  211. package/src/react/ui/modals/_internal/components/expirationDateSelect/styles.css.ts +25 -0
  212. package/src/react/ui/modals/_internal/components/floorPriceText/index.tsx +54 -0
  213. package/src/react/ui/modals/_internal/components/priceInput/index.tsx +72 -0
  214. package/src/react/ui/modals/_internal/components/priceInput/styles.css.ts +23 -0
  215. package/src/react/ui/modals/_internal/components/priceInput/types.ts +4 -0
  216. package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +168 -0
  217. package/src/react/ui/modals/_internal/components/quantityInput/styles.css.ts +30 -0
  218. package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +132 -0
  219. package/src/react/ui/modals/_internal/components/switchChainModal/store.ts +41 -0
  220. package/src/react/ui/modals/_internal/components/switchChainModal/styles.css.ts +37 -0
  221. package/src/react/ui/modals/_internal/components/timeAgo/index.tsx +32 -0
  222. package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +58 -0
  223. package/src/react/ui/modals/_internal/components/tokenPreview/styles.css.ts +11 -0
  224. package/src/react/ui/modals/_internal/components/transaction-footer/index.tsx +48 -0
  225. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +80 -0
  226. package/src/react/ui/modals/_internal/components/transactionHeader/index.tsx +30 -0
  227. package/src/react/ui/modals/_internal/components/transactionPreview/consts.ts +27 -0
  228. package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +111 -0
  229. package/src/react/ui/modals/_internal/components/transactionPreview/useTransactionPreviewTitle.tsx +24 -0
  230. package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +123 -0
  231. package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +87 -0
  232. package/src/react/ui/modals/_internal/components/transactionStatusModal/styles.css.ts +15 -0
  233. package/src/react/ui/modals/_internal/stores/accountModal.ts +3 -0
  234. package/src/react/ui/modals/modal-provider.tsx +27 -0
  235. package/src/react/ui/styles/index.ts +1 -0
  236. package/src/react/ui/styles/modal.css.ts +73 -0
  237. package/src/styles/index.ts +18 -0
  238. package/src/types/api-types.ts +48 -0
  239. package/src/types/index.ts +4 -0
  240. package/src/types/marketplace-config.ts +63 -0
  241. package/src/types/messages.ts +43 -0
  242. package/src/types/sdk-config.ts +23 -0
  243. package/src/types/types.ts +6 -0
  244. package/src/utils/abi/abi/standard/EIP2981.ts +15 -0
  245. package/src/utils/abi/abi/standard/index.ts +1 -0
  246. package/src/utils/abi/abi/token/ERC1155.ts +324 -0
  247. package/src/utils/abi/abi/token/ERC20.ts +185 -0
  248. package/src/utils/abi/abi/token/ERC721.ts +506 -0
  249. package/src/utils/abi/abi/token/index.ts +3 -0
  250. package/src/utils/abi/clients/ERC1155.ts +82 -0
  251. package/src/utils/abi/clients/ERC20.ts +101 -0
  252. package/src/utils/abi/clients/ERC721.ts +97 -0
  253. package/src/utils/abi/clients/index.ts +3 -0
  254. package/src/utils/address.ts +26 -0
  255. package/src/utils/get-public-rpc-client.ts +32 -0
  256. package/src/utils/index.ts +6 -0
  257. package/src/utils/network.ts +5 -0
  258. package/src/utils/price.ts +21 -0
@@ -0,0 +1,274 @@
1
+ import { observable, when } from '@legendapp/state';
2
+ import {
3
+ MarketplaceKind,
4
+ StepType,
5
+ type Order,
6
+ type Step,
7
+ type WalletKind,
8
+ } from '@types';
9
+ import { useMount, useSelector } from '@legendapp/state/react';
10
+ import { useGenerateSellTransaction } from '@react-hooks/useGenerateSellTransaction';
11
+ import { useAccount, useSendTransaction } from 'wagmi';
12
+ import type { Hex } from 'viem';
13
+ import type { ShowSellModalArgs } from '.';
14
+ import type { Messages } from '../../../../types/messages';
15
+ import { useTransactionStatusModal } from '../_internal/components/transactionStatusModal';
16
+ import {
17
+ getSellTransactionMessage,
18
+ getSellTransactionTitle,
19
+ } from './_utils/getSellTransactionTitleMessage';
20
+ import { useCollectible } from '@react-hooks/useCollectible';
21
+ import { useCurrencies } from '@react-hooks/useCurrencies';
22
+
23
+ export interface SellModalState {
24
+ isOpen: boolean;
25
+ open: (args: ShowSellModalArgs) => void;
26
+ close: () => void;
27
+ state: {
28
+ collectionAddress: string;
29
+ chainId: string;
30
+ tokenId: string;
31
+ order: Order | undefined;
32
+ messages?: Messages;
33
+ };
34
+ steps: {
35
+ isLoading: () => boolean;
36
+ stepsData: Step[] | undefined;
37
+ _currentStep: null | 'tokenApproval' | 'sell';
38
+ tokenApproval: {
39
+ isNeeded: () => boolean;
40
+ pending: boolean;
41
+ getStep: () => Step | undefined;
42
+ execute: () => void;
43
+ };
44
+ sell: {
45
+ pending: boolean;
46
+ execute: () => void;
47
+ };
48
+ };
49
+ hash: Hex | undefined;
50
+ }
51
+
52
+ export const initialState: SellModalState = {
53
+ isOpen: false,
54
+ open: ({
55
+ collectionAddress,
56
+ chainId,
57
+ tokenId,
58
+ order,
59
+ messages,
60
+ }: ShowSellModalArgs) => {
61
+ sellModal$.state.set({
62
+ ...sellModal$.state.get(),
63
+ collectionAddress,
64
+ chainId,
65
+ tokenId,
66
+ order,
67
+ messages,
68
+ });
69
+ sellModal$.isOpen.set(true);
70
+ },
71
+ close: () => {
72
+ sellModal$.isOpen.set(false);
73
+ sellModal$.state.set({
74
+ ...initialState.state,
75
+ });
76
+ },
77
+ state: {
78
+ collectionAddress: '',
79
+ chainId: '',
80
+ tokenId: '',
81
+ order: undefined,
82
+ },
83
+ steps: {
84
+ isLoading: () => !!sellModal$.steps.stepsData.get(),
85
+ stepsData: undefined,
86
+ _currentStep: null,
87
+ tokenApproval: {} as SellModalState['steps']['tokenApproval'],
88
+ sell: {} as SellModalState['steps']['sell'],
89
+ },
90
+ hash: undefined,
91
+ };
92
+
93
+ export const sellModal$ = observable(initialState);
94
+
95
+ export const useHydrate = () => {
96
+ const chainId = useSelector(sellModal$.state.chainId);
97
+
98
+ const collectionAddress = useSelector(sellModal$.state.collectionAddress);
99
+
100
+ const order = useSelector(sellModal$.state.order);
101
+
102
+ useTokenApprovalHandler(chainId);
103
+ useSellHandler(chainId);
104
+
105
+ const { generateSellTransactionAsync } = useGenerateSellTransaction({
106
+ chainId,
107
+ });
108
+
109
+ const { connector, address } = useAccount();
110
+
111
+ useMount(() => {
112
+ const setSteps = async () => {
113
+ const sellTransactionData = await generateSellTransactionAsync({
114
+ walletType: connector?.walletType as WalletKind,
115
+ collectionAddress: collectionAddress,
116
+ seller: address as string,
117
+ marketplace: MarketplaceKind.sequence_marketplace_v1,
118
+ ordersData: [
119
+ {
120
+ ...order!,
121
+ orderId: order!.orderId,
122
+ quantity: '1',
123
+ },
124
+ ],
125
+ additionalFees: [],
126
+ });
127
+ sellModal$.steps.stepsData.set(sellTransactionData.steps);
128
+ };
129
+
130
+ when(() => !!order && !!connector, setSteps);
131
+ });
132
+ };
133
+
134
+ const useTokenApprovalHandler = (chainId: string) => {
135
+ const { sendTransactionAsync, isPending, isSuccess } = useSendTransaction();
136
+ const {
137
+ onUnknownError,
138
+ onSuccess,
139
+ }: { onUnknownError?: Function; onSuccess?: Function } =
140
+ sellModal$.state.get().messages?.approveToken || {};
141
+
142
+ sellModal$.steps.tokenApproval.set({
143
+ isNeeded: () => !!sellModal$.steps.tokenApproval.getStep(),
144
+ getStep: () =>
145
+ sellModal$.steps.stepsData
146
+ ?.get()
147
+ ?.find((s) => s.id === StepType.tokenApproval),
148
+ pending:
149
+ sellModal$.steps._currentStep.get() === 'tokenApproval' && isPending,
150
+ execute: async () => {
151
+ const step = sellModal$.steps.tokenApproval.getStep();
152
+ if (!step) return;
153
+ sellModal$.steps._currentStep.set('tokenApproval');
154
+ try {
155
+ await sendTransactionAsync({
156
+ to: step.to as Hex,
157
+ chainId: Number(chainId),
158
+ data: step.data as Hex,
159
+ value: BigInt(step.value || '0'),
160
+ });
161
+ onSuccess && onSuccess();
162
+ } catch (error) {
163
+ onUnknownError && onUnknownError(error);
164
+ }
165
+ },
166
+ });
167
+
168
+ if (isSuccess && sellModal$.steps._currentStep.get() === 'tokenApproval') {
169
+ sellModal$.steps._currentStep.set(null);
170
+ }
171
+ };
172
+
173
+ const useSellHandler = (chainId: string) => {
174
+ const { address } = useAccount();
175
+ const { tokenId, collectionAddress } = sellModal$.state.get();
176
+ const {
177
+ generateSellTransactionAsync,
178
+ isPending: generateSellTransactionPending,
179
+ error: generateSellTransactionError,
180
+ } = useGenerateSellTransaction({
181
+ chainId,
182
+ });
183
+ const { data: collectible } = useCollectible({
184
+ chainId,
185
+ collectibleId: tokenId,
186
+ collectionAddress,
187
+ });
188
+ const { data: currencies } = useCurrencies({ chainId });
189
+ const {
190
+ onUnknownError,
191
+ onSuccess,
192
+ }: { onUnknownError?: Function; onSuccess?: Function } =
193
+ sellModal$.state.get().messages?.sellCollectible || {};
194
+
195
+ const { sendTransactionAsync, isPending: sendTransactionPending } =
196
+ useSendTransaction();
197
+ const { show: showTransactionStatusModal } = useTransactionStatusModal();
198
+
199
+ function setSellStep() {
200
+ sellModal$.steps.sell.set({
201
+ pending:
202
+ sellModal$.steps._currentStep.get() === 'sell' &&
203
+ (generateSellTransactionPending || sendTransactionPending),
204
+ execute: () => {
205
+ sellModal$.steps._currentStep.set('sell');
206
+ const { collectionAddress, order } = sellModal$.state.get();
207
+ generateSellTransactionAsync({
208
+ collectionAddress: collectionAddress,
209
+ seller: address as string,
210
+ marketplace: order!.marketplace,
211
+ ordersData: [
212
+ {
213
+ ...order!,
214
+ quantity: '1',
215
+ },
216
+ ],
217
+ additionalFees: [
218
+ {
219
+ amount: String(order!.feeBps),
220
+ receiver: order!.feeBreakdown[0].recipientAddress,
221
+ },
222
+ ],
223
+ })
224
+ .then(async (response) => {
225
+ const step = response.steps.find((s) => s.id === StepType.sell);
226
+ if (!step) throw new Error('No steps found');
227
+ try {
228
+ const hash = await sendTransactionAsync({
229
+ to: step.to as Hex,
230
+ chainId: Number(chainId),
231
+ data: step.data as Hex,
232
+ value: BigInt(step.value || '0'),
233
+ });
234
+
235
+ sellModal$.hash.set(hash);
236
+
237
+ sellModal$.steps._currentStep.set(null);
238
+
239
+ showTransactionStatusModal({
240
+ hash: hash!,
241
+ price: {
242
+ amountRaw: order!.priceAmount,
243
+ currency: currencies!.find(
244
+ (currency) =>
245
+ currency.contractAddress === order!.priceCurrencyAddress,
246
+ )!,
247
+ },
248
+ collectionAddress,
249
+ chainId,
250
+ tokenId,
251
+ getTitle: getSellTransactionTitle,
252
+ getMessage: (params) =>
253
+ getSellTransactionMessage(params, collectible?.name || ''),
254
+ type: StepType.sell,
255
+ });
256
+
257
+ sellModal$.close();
258
+
259
+ onSuccess && onSuccess();
260
+ } catch (error) {}
261
+ })
262
+ .catch((error) => {
263
+ onUnknownError && onUnknownError(error);
264
+ });
265
+ },
266
+ });
267
+ }
268
+
269
+ when(currencies && collectible, setSellStep);
270
+
271
+ if (generateSellTransactionError) {
272
+ onUnknownError && onUnknownError(generateSellTransactionError);
273
+ }
274
+ };
@@ -0,0 +1,28 @@
1
+ import type { ConfirmationStatus } from '../../_internal/components/transactionStatusModal/store';
2
+
3
+ export const getSellTransactionTitle = (params: ConfirmationStatus) => {
4
+ if (params.isConfirmed) {
5
+ return 'Your sale has processed';
6
+ }
7
+
8
+ if (params.isFailed) {
9
+ return 'Your sale has failed';
10
+ }
11
+
12
+ return 'Your sale is processing';
13
+ };
14
+
15
+ export const getSellTransactionMessage = (
16
+ params: ConfirmationStatus,
17
+ collectibleName: string,
18
+ ) => {
19
+ if (params.isConfirmed) {
20
+ return `You just sold ${collectibleName}. It’s been confirmed on the blockchain!`;
21
+ }
22
+
23
+ if (params.isFailed) {
24
+ return `Your sale of ${collectibleName} has failed. Please try again.`;
25
+ }
26
+
27
+ return `You just sold ${collectibleName}. It should be confirmed on the blockchain shortly.`;
28
+ };
@@ -0,0 +1,126 @@
1
+ import {
2
+ ActionModal,
3
+ type ActionModalProps,
4
+ } from '../_internal/components/actionModal/ActionModal';
5
+ import { sellModal$, useHydrate } from './_store';
6
+ import { observer, Show } from '@legendapp/state/react';
7
+ import { useCollection } from '@react-hooks/useCollection';
8
+ import type { Order, Price } from '@types';
9
+ import TransactionHeader from '../_internal/components/transactionHeader';
10
+ import TokenPreview from '../_internal/components/tokenPreview';
11
+ import TransactionDetails from '../_internal/components/transactionDetails';
12
+ import { useCurrencies } from '@react-hooks/useCurrencies';
13
+ import { useAccount } from 'wagmi';
14
+ import { useSwitchChainModal } from '../_internal/components/switchChainModal';
15
+ import type { Messages } from '../../../../types/messages';
16
+
17
+ export type ShowSellModalArgs = {
18
+ chainId: string;
19
+ collectionAddress: string;
20
+ tokenId: string;
21
+ order: Order;
22
+ collectibleName: string | undefined;
23
+ messages?: Messages;
24
+ };
25
+
26
+ export const useSellModal = () => {
27
+ const { chainId: accountChainId } = useAccount();
28
+ const { show: showSwitchNetworkModal } = useSwitchChainModal();
29
+
30
+ const openModal = (args: ShowSellModalArgs) => {
31
+ sellModal$.open(args);
32
+ };
33
+
34
+ const handleShowModal = (args: ShowSellModalArgs) => {
35
+ const isSameChain = accountChainId === Number(args.chainId);
36
+
37
+ if (!isSameChain) {
38
+ showSwitchNetworkModal({
39
+ chainIdToSwitchTo: Number(args.chainId),
40
+ onSwitchChain: () => openModal(args),
41
+ messages: args.messages?.switchChain,
42
+ });
43
+ return;
44
+ }
45
+
46
+ openModal(args);
47
+ };
48
+
49
+ return {
50
+ show: handleShowModal,
51
+ close: () => sellModal$.close(),
52
+ };
53
+ };
54
+
55
+ export const SellModal = () => {
56
+ return (
57
+ <Show if={sellModal$.isOpen}>
58
+ <Modal />
59
+ </Show>
60
+ );
61
+ };
62
+
63
+ const Modal = () => {
64
+ useHydrate();
65
+ return <ModalContent />;
66
+ };
67
+
68
+ const ModalContent = observer(() => {
69
+ const modalState = sellModal$.state.get();
70
+ const { collectionAddress, chainId, tokenId, order } = modalState;
71
+
72
+ const { steps } = sellModal$.get();
73
+
74
+ const { data: collection } = useCollection({ chainId, collectionAddress });
75
+ const { data: currencies } = useCurrencies({ chainId, collectionAddress });
76
+ const currency = currencies?.find(
77
+ (currency) => currency.contractAddress === order?.priceCurrencyAddress,
78
+ );
79
+
80
+ const ctas = [
81
+ {
82
+ label: 'Approve TOKEN',
83
+ onClick: steps.tokenApproval.execute,
84
+ hidden: !steps.tokenApproval.isNeeded(),
85
+ pending: steps.tokenApproval.pending,
86
+ variant: 'glass' as const,
87
+ },
88
+ {
89
+ label: 'Accept',
90
+ onClick: steps.sell.execute,
91
+ pending: steps.sell.pending,
92
+ disabled: steps.tokenApproval.isNeeded(),
93
+ },
94
+ ] satisfies ActionModalProps['ctas'];
95
+
96
+ return (
97
+ <ActionModal
98
+ store={sellModal$}
99
+ onClose={() => sellModal$.close()}
100
+ title="You have an offer"
101
+ ctas={ctas}
102
+ >
103
+ <TransactionHeader
104
+ title="Offer received"
105
+ chainId={Number(chainId)}
106
+ date={order && new Date(order.createdAt)}
107
+ />
108
+ <TokenPreview
109
+ collectionName={collection?.name}
110
+ collectionAddress={collectionAddress}
111
+ collectibleId={tokenId}
112
+ chainId={chainId}
113
+ />
114
+ <TransactionDetails
115
+ collectibleId={tokenId}
116
+ collectionAddress={collectionAddress}
117
+ chainId={chainId}
118
+ price={
119
+ currency
120
+ ? ({ amountRaw: order?.priceAmount, currency } as Price)
121
+ : undefined
122
+ }
123
+ />
124
+ </ActionModal>
125
+ );
126
+ });
@@ -0,0 +1,38 @@
1
+ import type { ConfirmationStatus } from '../_internal/components/transactionStatusModal/store';
2
+
3
+ export const getSellModalTitle = ({
4
+ isConfirming,
5
+ isConfirmed,
6
+ isFailed,
7
+ }: ConfirmationStatus): string => {
8
+ if (isConfirming) {
9
+ return 'Your sale is processing';
10
+ }
11
+ if (isConfirmed) {
12
+ return 'Your sale has processed';
13
+ }
14
+ if (isFailed) {
15
+ return 'Your sale has failed';
16
+ }
17
+
18
+ return 'Unknown status'; // Default return
19
+ };
20
+
21
+ export const getSellModalMessage = ({
22
+ isConfirming,
23
+ isConfirmed,
24
+ isFailed,
25
+ collectibleName,
26
+ }: ConfirmationStatus & { collectibleName?: string }) => {
27
+ if (isConfirming) {
28
+ return `You just sold ${collectibleName}. It should be confirmed on the blockchain shortly.`;
29
+ }
30
+ if (isConfirmed) {
31
+ return `You just sold ${collectibleName}. It’s been confirmed on the blockchain!`;
32
+ }
33
+ if (isFailed) {
34
+ return `${collectibleName} could not be sold. Please try again.`;
35
+ }
36
+
37
+ return 'Unknown status'; // Default return
38
+ };
@@ -0,0 +1,58 @@
1
+ import type { ComponentType } from 'react';
2
+
3
+ import type { IconProps } from '@0xsequence/design-system';
4
+ import type { TokenMetadata } from '@internal';
5
+ import { observable } from '@legendapp/state';
6
+
7
+ export interface SuccessfulPurchaseModalState {
8
+ isOpen: boolean;
9
+ open: (args: SuccessfulPurchaseModalState['state']) => void;
10
+ close: () => void;
11
+ state: {
12
+ collectibles: TokenMetadata[];
13
+ totalPrice: string;
14
+ explorerName: string;
15
+ explorerUrl: string;
16
+ ctaOptions?: {
17
+ ctaLabel: string;
18
+ ctaOnClick: () => void;
19
+ ctaIcon?: ComponentType<IconProps>;
20
+ };
21
+ };
22
+ }
23
+
24
+ const initialState: SuccessfulPurchaseModalState = {
25
+ isOpen: false,
26
+ open: ({
27
+ collectibles,
28
+ totalPrice,
29
+ explorerName,
30
+ explorerUrl,
31
+ ctaOptions,
32
+ }: SuccessfulPurchaseModalState['state']) => {
33
+ successfulPurchaseModal$.state.set({
34
+ ...successfulPurchaseModal$.state.get(),
35
+ collectibles,
36
+ totalPrice,
37
+ explorerName,
38
+ explorerUrl: explorerUrl,
39
+ ctaOptions,
40
+ });
41
+ successfulPurchaseModal$.isOpen.set(true);
42
+ },
43
+ close: () => {
44
+ successfulPurchaseModal$.isOpen.set(false);
45
+ successfulPurchaseModal$.state.set({
46
+ ...initialState.state,
47
+ });
48
+ },
49
+ state: {
50
+ collectibles: [],
51
+ totalPrice: '0',
52
+ explorerName: '',
53
+ explorerUrl: '',
54
+ ctaOptions: undefined,
55
+ },
56
+ };
57
+
58
+ export const successfulPurchaseModal$ = observable(initialState);
@@ -0,0 +1,186 @@
1
+ 'use client';
2
+
3
+ import {
4
+ successfulPurchaseModal$,
5
+ type SuccessfulPurchaseModalState,
6
+ } from './_store';
7
+ import {
8
+ closeButton,
9
+ collectiblesGrid,
10
+ collectiblesGridItem,
11
+ collectiblesGridImage,
12
+ collectiblesGridImagePale,
13
+ dialogContent,
14
+ dialogOverlay,
15
+ } from './styles.css';
16
+ import {
17
+ Box,
18
+ Button,
19
+ CloseIcon,
20
+ ExternalLinkIcon,
21
+ IconButton,
22
+ Image,
23
+ Text,
24
+ } from '@0xsequence/design-system';
25
+ import { observer } from '@legendapp/state/react';
26
+ import { Close, Content, Overlay, Portal, Root } from '@radix-ui/react-dialog';
27
+ import type { TokenMetadata } from '@types';
28
+
29
+ export const useSuccessfulPurchaseModal = () => {
30
+ return {
31
+ show: (args: SuccessfulPurchaseModalState['state']) =>
32
+ successfulPurchaseModal$.open(args),
33
+ close: () => successfulPurchaseModal$.close(),
34
+ };
35
+ };
36
+
37
+ const SuccessfulPurchaseModal = observer(() => {
38
+ return (
39
+ <Root open={successfulPurchaseModal$.isOpen.get()}>
40
+ <Portal>
41
+ <Overlay className={dialogOverlay} />
42
+
43
+ <Content className={dialogContent.narrow}>
44
+ <Box display="flex" flexDirection="column" gap="4" width="full">
45
+ <Text
46
+ textAlign="center"
47
+ fontSize="medium"
48
+ fontWeight="bold"
49
+ color="text100"
50
+ >
51
+ Successful purchase!
52
+ </Text>
53
+
54
+ <CollectiblesGrid
55
+ collectibles={successfulPurchaseModal$.state.get().collectibles}
56
+ />
57
+
58
+ <Box display="flex" alignItems="center" gap="1">
59
+ <Text fontSize="normal" fontWeight="medium" color="text80">
60
+ You bought
61
+ </Text>
62
+
63
+ <Text fontSize="normal" fontWeight="medium" color="text100">
64
+ {successfulPurchaseModal$.state.get().collectibles.length}
65
+ </Text>
66
+
67
+ <Text fontSize="normal" fontWeight="medium" color="text80">
68
+ items for
69
+ </Text>
70
+
71
+ <Text fontSize="normal" fontWeight="medium" color="text100">
72
+ {successfulPurchaseModal$.state.get().totalPrice}
73
+ </Text>
74
+ </Box>
75
+
76
+ <SuccessfulPurchaseActions />
77
+ </Box>
78
+
79
+ <Close
80
+ onClick={() => {
81
+ successfulPurchaseModal$.close();
82
+ }}
83
+ className={closeButton}
84
+ asChild
85
+ >
86
+ <IconButton size="xs" aria-label="Close modal" icon={CloseIcon} />
87
+ </Close>
88
+ </Content>
89
+ </Portal>
90
+ </Root>
91
+ );
92
+ });
93
+
94
+ function SuccessfulPurchaseActions() {
95
+ return (
96
+ <Box display="flex" flexDirection="column" gap="2">
97
+ {successfulPurchaseModal$.state.ctaOptions.get() && (
98
+ <Button
99
+ shape="square"
100
+ leftIcon={
101
+ successfulPurchaseModal$.state.ctaOptions.ctaIcon.get() || undefined
102
+ }
103
+ label={successfulPurchaseModal$.state.ctaOptions.ctaLabel.get()}
104
+ width="full"
105
+ onClick={
106
+ successfulPurchaseModal$.state.ctaOptions.ctaOnClick.get() ||
107
+ undefined
108
+ }
109
+ />
110
+ )}
111
+
112
+ <Button
113
+ as={'a'}
114
+ href={successfulPurchaseModal$.state.explorerUrl.get()}
115
+ target="_blank"
116
+ rel="noopener noreferrer"
117
+ shape="square"
118
+ leftIcon={ExternalLinkIcon}
119
+ label={`View on ${successfulPurchaseModal$.state.explorerName.get()}`}
120
+ width="full"
121
+ />
122
+ </Box>
123
+ );
124
+ }
125
+
126
+ function CollectiblesGrid({ collectibles }: { collectibles: TokenMetadata[] }) {
127
+ const total = collectibles.length;
128
+ const shownCollectibles = total > 4 ? collectibles.slice(0, 4) : collectibles;
129
+
130
+ return (
131
+ <Box className={collectiblesGrid} display={'grid'} gap={'2'}>
132
+ {shownCollectibles.map((collectible) => {
133
+ const showPlus = total > 4 && collectibles.indexOf(collectible) === 3;
134
+
135
+ return (
136
+ <Box
137
+ key={collectible.tokenId}
138
+ className={collectiblesGridItem}
139
+ position="relative"
140
+ >
141
+ <Image
142
+ src={collectible.image}
143
+ alt={collectible.name}
144
+ className={
145
+ showPlus ? collectiblesGridImagePale : collectiblesGridImage
146
+ }
147
+ aspectRatio="1/1"
148
+ background="backgroundSecondary"
149
+ borderRadius="sm"
150
+ />
151
+
152
+ {showPlus && (
153
+ <Box
154
+ position="absolute"
155
+ top="0"
156
+ left="0"
157
+ right="0"
158
+ bottom="0"
159
+ display="flex"
160
+ alignItems="center"
161
+ justifyContent="center"
162
+ background="backgroundOverlay"
163
+ backdropFilter="blur"
164
+ >
165
+ <Text
166
+ fontSize="small"
167
+ fontWeight="medium"
168
+ color="text80"
169
+ paddingX="2"
170
+ paddingY="1.5"
171
+ borderRadius="sm"
172
+ background="backgroundSecondary"
173
+ backdropFilter="blur"
174
+ >
175
+ {total} TOTAL
176
+ </Text>
177
+ </Box>
178
+ )}
179
+ </Box>
180
+ );
181
+ })}
182
+ </Box>
183
+ );
184
+ }
185
+
186
+ export default SuccessfulPurchaseModal;