@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,52 @@
1
+ import { globalStyle, style } from '@vanilla-extract/css';
2
+
3
+ export {
4
+ closeButton,
5
+ dialogContent,
6
+ dialogOverlay,
7
+ } from '../../styles/modal.css';
8
+
9
+ export const collectiblesGrid = style({
10
+ display: 'grid',
11
+ gridTemplateColumns: 'repeat(auto-fill, minmax(150px, 1fr))',
12
+ });
13
+
14
+ export const collectiblesGridItem = style({
15
+ width: '150px',
16
+ height: '150px',
17
+ });
18
+
19
+ globalStyle(
20
+ `${collectiblesGrid} > ${collectiblesGridItem}:nth-child(1):only-child`,
21
+ {
22
+ width: '312px',
23
+ height: '312px',
24
+ },
25
+ );
26
+
27
+ // horizontal centering for the 3rd item
28
+ globalStyle(`${collectiblesGrid} > ${collectiblesGridItem}:nth-child(3)`, {
29
+ gridColumn: '1 / -1',
30
+ justifySelf: 'center',
31
+ });
32
+
33
+ globalStyle(
34
+ `${collectiblesGrid}:has(${collectiblesGridItem}:nth-child(4)) > ${collectiblesGridItem}`,
35
+ {
36
+ gridColumn: 'unset',
37
+ },
38
+ );
39
+
40
+ export const collectiblesGridImage = style({
41
+ width: '100%',
42
+ height: '100%',
43
+ objectFit: 'contain',
44
+ });
45
+
46
+ export const collectiblesGridImagePale = style([
47
+ collectiblesGridImage,
48
+ {
49
+ // opacity:1 is set to inline style of the @0xsequence/design-system Image component, so we need to use !important
50
+ opacity: '0.4 !important',
51
+ },
52
+ ]);
@@ -0,0 +1,58 @@
1
+ import { observable } from '@legendapp/state';
2
+ import type { ShowTransferModalArgs } from '.';
3
+ import type { Hex } from 'viem';
4
+ import type { Messages } from '../../../../types/messages';
5
+ import type { CollectionType } from '@internal';
6
+
7
+ export interface TransferModalState {
8
+ isOpen: boolean;
9
+ open: (args: ShowTransferModalArgs) => void;
10
+ close: () => void;
11
+ state: {
12
+ chainId: string;
13
+ collectionAddress: Hex;
14
+ collectionType?: CollectionType | undefined;
15
+ tokenId: string;
16
+ quantity: string;
17
+ receiverAddress: string;
18
+ messages?: Messages;
19
+ };
20
+ view: 'enterReceiverAddress' | 'followWalletInstructions' | undefined;
21
+ hash: Hex | undefined;
22
+ }
23
+
24
+ export const initialState: TransferModalState = {
25
+ isOpen: false,
26
+ open: ({
27
+ chainId,
28
+ collectionAddress,
29
+ tokenId,
30
+ messages,
31
+ }: ShowTransferModalArgs) => {
32
+ transferModal$.state.set({
33
+ ...transferModal$.state.get(),
34
+ chainId,
35
+ collectionAddress,
36
+ tokenId,
37
+ messages,
38
+ });
39
+ transferModal$.isOpen.set(true);
40
+ },
41
+ close: () => {
42
+ transferModal$.isOpen.set(false);
43
+ transferModal$.state.set({
44
+ ...initialState.state,
45
+ });
46
+ },
47
+ state: {
48
+ receiverAddress: '',
49
+ collectionAddress: '0x',
50
+ chainId: '',
51
+ tokenId: '',
52
+ quantity: '1',
53
+ },
54
+ view: 'enterReceiverAddress',
55
+ hash: undefined,
56
+ };
57
+
58
+ export const transferModal$ = observable(initialState);
@@ -0,0 +1,28 @@
1
+ import type { ConfirmationStatus } from '../../_internal/components/transactionStatusModal/store';
2
+
3
+ export const getTransferTransactionTitle = (params: ConfirmationStatus) => {
4
+ if (params.isConfirmed) {
5
+ return 'Transfer has processed';
6
+ }
7
+
8
+ if (params.isFailed) {
9
+ return 'Transfer has failed';
10
+ }
11
+
12
+ return 'Transfer is processing';
13
+ };
14
+
15
+ export const getTransferTransactionMessage = (
16
+ params: ConfirmationStatus,
17
+ collectibleName: string,
18
+ ) => {
19
+ if (params.isConfirmed) {
20
+ return `You just tranferred ${collectibleName}. It’s been confirmed on the blockchain!`;
21
+ }
22
+
23
+ if (params.isFailed) {
24
+ return `Transferring ${collectibleName} has failed. Please try again.`;
25
+ }
26
+
27
+ return `You just transferred ${collectibleName}. It should be confirmed on the blockchain shortly.`;
28
+ };
@@ -0,0 +1,102 @@
1
+ import { useCollection } from '@react-hooks/useCollection';
2
+ import AlertMessage from '../../../_internal/components/alertMessage';
3
+ import QuantityInput from '../../../_internal/components/quantityInput';
4
+ import { transferModal$ } from '../../_store';
5
+ import getMessage from '../../messages';
6
+ import { Box, Button, Text, TextInput } from '@0xsequence/design-system';
7
+ import { isAddress } from 'viem';
8
+ import { type CollectionType, ContractType } from '@internal';
9
+ import { useTokenBalances } from '@react-hooks/useListBalances';
10
+ import { useAccount } from 'wagmi';
11
+
12
+ const EnterWalletAddressView = () => {
13
+ const { address } = useAccount();
14
+ const { collectionAddress, chainId, tokenId, collectionType } =
15
+ transferModal$.state.get();
16
+ const $quantity = transferModal$.state.quantity;
17
+ const isWalletAddressValid = isAddress(
18
+ transferModal$.state.receiverAddress.get(),
19
+ );
20
+ const { data: tokenBalance } = useTokenBalances({
21
+ chainId,
22
+ contractAddress: collectionAddress,
23
+ tokenId,
24
+ accountAddress: address,
25
+ });
26
+ const balanceAmount = tokenBalance?.pages[0].balances[0].balance;
27
+ const { data: collection } = useCollection({
28
+ collectionAddress,
29
+ chainId,
30
+ });
31
+ transferModal$.state.collectionType.set(
32
+ collection?.type as CollectionType | undefined,
33
+ );
34
+ const insufficientBalance: boolean = $quantity.get() > balanceAmount!;
35
+
36
+ function handleChangeWalletAddress(
37
+ event: React.ChangeEvent<HTMLInputElement>,
38
+ ) {
39
+ transferModal$.state.receiverAddress.set(event.target.value);
40
+ }
41
+
42
+ function handleChangeView() {
43
+ transferModal$.view.set('followWalletInstructions');
44
+ }
45
+
46
+ return (
47
+ <Box display="grid" gap="6" flexGrow="1">
48
+ <Text color="white" fontSize="large" fontWeight="bold">
49
+ Transfer your item
50
+ </Text>
51
+
52
+ <Box display="flex" flexDirection="column" gap="3">
53
+ <AlertMessage
54
+ message={getMessage('enterReceiverAddress')}
55
+ type="warning"
56
+ />
57
+
58
+ <TextInput
59
+ label="Wallet address"
60
+ labelLocation="top"
61
+ value={transferModal$.state.receiverAddress.get()}
62
+ onChange={handleChangeWalletAddress}
63
+ name="walletAddress"
64
+ placeholder="Enter wallet address of recipient"
65
+ />
66
+
67
+ {collectionType === ContractType.ERC1155 && balanceAmount && (
68
+ <>
69
+ <QuantityInput
70
+ $quantity={$quantity}
71
+ chainId={chainId}
72
+ collectionAddress={collectionAddress}
73
+ collectibleId={tokenId}
74
+ />
75
+
76
+ <Text
77
+ color={insufficientBalance ? 'negative' : 'text50'}
78
+ fontSize="small"
79
+ fontWeight="medium"
80
+ >
81
+ {`You have ${balanceAmount} of this item`}
82
+ </Text>
83
+ </>
84
+ )}
85
+ </Box>
86
+
87
+ <Button
88
+ onClick={handleChangeView}
89
+ disabled={!isWalletAddressValid || insufficientBalance}
90
+ title="Transfer"
91
+ label="Transfer"
92
+ variant="primary"
93
+ shape="square"
94
+ size="sm"
95
+ justifySelf="flex-end"
96
+ paddingX="10"
97
+ />
98
+ </Box>
99
+ );
100
+ };
101
+
102
+ export default EnterWalletAddressView;
@@ -0,0 +1,130 @@
1
+ import { observer } from '@legendapp/state/react';
2
+ import AlertMessage from '../../../_internal/components/alertMessage';
3
+ import getMessage from '../../messages';
4
+ import { Box, Button, Text } from '@0xsequence/design-system';
5
+ import { ContractType } from '@internal';
6
+ import { transferModal$ } from '../../_store';
7
+ import { useCollection } from '@react-hooks/useCollection';
8
+ import { useTransferTokens } from '@react-hooks/useTransferTokens';
9
+ import type { Hex } from 'viem';
10
+ import { useTransactionStatusModal } from '../../../_internal/components/transactionStatusModal';
11
+ import {
12
+ getTransferTransactionMessage,
13
+ getTransferTransactionTitle,
14
+ } from '../../_utils/getTransferTransactionTitleMessage';
15
+ import { useCollectible } from '@react-hooks/useCollectible';
16
+ import { useEffect } from 'react';
17
+
18
+ const FollowWalletInstructionsView = observer(() => {
19
+ const {
20
+ receiverAddress,
21
+ collectionAddress,
22
+ tokenId,
23
+ quantity,
24
+ chainId,
25
+ messages,
26
+ } = transferModal$.state.get();
27
+ const { transferTokensAsync, hash } = useTransferTokens();
28
+ const { show: showTransactionStatusModal } = useTransactionStatusModal();
29
+ const { data: collection, isSuccess: collectionSuccess } = useCollection({
30
+ collectionAddress,
31
+ chainId,
32
+ });
33
+ const { data: collectible, isSuccess: collectibleSuccess } = useCollectible({
34
+ collectionAddress,
35
+ collectibleId: tokenId,
36
+ chainId,
37
+ });
38
+
39
+ useEffect(() => {
40
+ if (!hash && collectionSuccess) {
41
+ transfer();
42
+ }
43
+ }, [collectionSuccess, collectibleSuccess, hash]);
44
+
45
+ async function transfer() {
46
+ if (collection!.type === ContractType.ERC721) {
47
+ try {
48
+ const hash = await transferTokensAsync({
49
+ receiverAddress: receiverAddress as Hex,
50
+ collectionAddress,
51
+ tokenId,
52
+ chainId,
53
+ contractType: ContractType.ERC721,
54
+ });
55
+
56
+ transferModal$.close();
57
+
58
+ showTransactionStatusModal({
59
+ hash: hash,
60
+ collectionAddress,
61
+ chainId,
62
+ tokenId,
63
+ price: undefined,
64
+ getTitle: getTransferTransactionTitle,
65
+ getMessage: (params) =>
66
+ getTransferTransactionMessage(params, collectible!.name),
67
+ type: 'transfer',
68
+ });
69
+ } catch (error) {
70
+ messages?.transferCollectibles?.onUnknownError &&
71
+ messages.transferCollectibles.onUnknownError(error);
72
+ }
73
+ }
74
+
75
+ try {
76
+ const hash = await transferTokensAsync({
77
+ receiverAddress: receiverAddress as Hex,
78
+ collectionAddress,
79
+ tokenId,
80
+ chainId,
81
+ contractType: ContractType.ERC1155,
82
+ quantity: String(quantity),
83
+ });
84
+
85
+ transferModal$.close();
86
+
87
+ showTransactionStatusModal({
88
+ hash: hash,
89
+ collectionAddress,
90
+ chainId,
91
+ tokenId,
92
+ price: undefined,
93
+ getTitle: getTransferTransactionTitle,
94
+ getMessage: (params) =>
95
+ getTransferTransactionMessage(params, collectible!.name),
96
+ type: 'transfer',
97
+ });
98
+ } catch (error) {
99
+ messages?.transferCollectibles?.onUnknownError &&
100
+ messages.transferCollectibles.onUnknownError(error);
101
+ }
102
+ }
103
+ return (
104
+ <Box display="grid" gap="6" flexGrow="1">
105
+ <Text color="white" fontSize="large" fontWeight="bold">
106
+ Transfer your item
107
+ </Text>
108
+
109
+ <Box display="flex" flexDirection="column" gap="3">
110
+ <AlertMessage
111
+ message={getMessage('followWalletInstructions')}
112
+ type="info"
113
+ />
114
+ </Box>
115
+
116
+ <Button
117
+ disabled={true}
118
+ title="Transfer"
119
+ label="Transfer"
120
+ variant="primary"
121
+ shape="square"
122
+ size="sm"
123
+ justifySelf="flex-end"
124
+ paddingX="10"
125
+ />
126
+ </Box>
127
+ );
128
+ });
129
+
130
+ export default FollowWalletInstructionsView;
@@ -0,0 +1,92 @@
1
+ import { transferModal$ } from './_store';
2
+ import { closeButton, dialogOverlay, transferModalContent } from './styles.css';
3
+ import { CloseIcon, IconButton } from '@0xsequence/design-system';
4
+ import { observer, Show } from '@legendapp/state/react';
5
+ import { Close, Content, Overlay, Portal, Root } from '@radix-ui/react-dialog';
6
+ import { useAccount } from 'wagmi';
7
+ import { useSwitchChainModal } from '../_internal/components/switchChainModal';
8
+ import type { Messages } from '../../../../types/messages';
9
+ import type { Hex } from 'viem';
10
+ import EnterWalletAddressView from './_views/enterWalletAddress';
11
+ import FollowWalletInstructionsView from './_views/followWalletInstructions';
12
+
13
+ export type ShowTransferModalArgs = {
14
+ collectionAddress: Hex;
15
+ tokenId: string;
16
+ chainId: string;
17
+ messages?: Messages;
18
+ };
19
+
20
+ export const useTransferModal = () => {
21
+ const { chainId: accountChainId } = useAccount();
22
+ const { show: showSwitchNetworkModal } = useSwitchChainModal();
23
+
24
+ const openModal = (args: ShowTransferModalArgs) => {
25
+ transferModal$.open(args);
26
+ };
27
+
28
+ const handleShowModal = (args: ShowTransferModalArgs) => {
29
+ const isSameChain = accountChainId === Number(args.chainId);
30
+
31
+ if (!isSameChain) {
32
+ showSwitchNetworkModal({
33
+ chainIdToSwitchTo: Number(args.chainId),
34
+ onSwitchChain: () => openModal(args),
35
+ messages: args.messages?.switchChain,
36
+ });
37
+ return;
38
+ }
39
+
40
+ openModal(args);
41
+ };
42
+
43
+ return {
44
+ show: handleShowModal,
45
+ close: () => transferModal$.close(),
46
+ };
47
+ };
48
+
49
+ export const TransferModal = () => {
50
+ return (
51
+ <Show if={transferModal$.isOpen}>
52
+ <Modal />
53
+ </Show>
54
+ );
55
+ };
56
+
57
+ const Modal = () => {
58
+ return <ModalContent />;
59
+ };
60
+
61
+ const ModalContent = observer(() => {
62
+ return (
63
+ <Root open={true}>
64
+ <Portal>
65
+ <Overlay className={dialogOverlay} />
66
+
67
+ <Content className={transferModalContent}>
68
+ <TransactionModalView />
69
+
70
+ <Close onClick={transferModal$.close} className={closeButton} asChild>
71
+ <IconButton size="xs" aria-label="Close modal" icon={CloseIcon} />
72
+ </Close>
73
+ </Content>
74
+ </Portal>
75
+ </Root>
76
+ );
77
+ });
78
+
79
+ const TransactionModalView = observer(() => {
80
+ const { view } = transferModal$.get();
81
+
82
+ switch (view) {
83
+ case 'enterReceiverAddress':
84
+ return <EnterWalletAddressView />;
85
+
86
+ case 'followWalletInstructions':
87
+ return <FollowWalletInstructionsView />;
88
+
89
+ default:
90
+ return null;
91
+ }
92
+ });
@@ -0,0 +1,14 @@
1
+ import type { TransferModalState } from './_store';
2
+
3
+ type MessageKey = NonNullable<TransferModalState['view']>;
4
+
5
+ const baseMessages: Record<MessageKey, string> = {
6
+ enterReceiverAddress:
7
+ "Items sent to the wrong wallet address can't be recovered!",
8
+ followWalletInstructions:
9
+ "Follow your wallet's instructions to submit a transaction to transfer your assets.",
10
+ };
11
+
12
+ export default function getMessage(key: MessageKey): string {
13
+ return baseMessages[key];
14
+ }
@@ -0,0 +1,20 @@
1
+ import { dialogContent } from '../../styles/index';
2
+ import { atoms } from '@0xsequence/design-system';
3
+ import { style } from '@vanilla-extract/css';
4
+
5
+ export { closeButton, dialogOverlay } from '../../styles/modal.css';
6
+
7
+ export const transferModalContent = style([
8
+ dialogContent.wide,
9
+ atoms({
10
+ padding: '7',
11
+ }),
12
+ {
13
+ width: '540px',
14
+ '@media': {
15
+ 'screen and (max-width: 540px)': {
16
+ width: '100%',
17
+ },
18
+ },
19
+ },
20
+ ]);
@@ -0,0 +1,94 @@
1
+ 'use client';
2
+
3
+ import type React from 'react';
4
+ import type { ComponentProps } from 'react';
5
+
6
+ import {
7
+ Box,
8
+ Button,
9
+ CloseIcon,
10
+ IconButton,
11
+ Text,
12
+ } from '@0xsequence/design-system';
13
+ import { getProviderEl } from '@internal';
14
+ import type { Observable } from '@legendapp/state';
15
+ import { observer } from '@legendapp/state/react';
16
+ import { Close, Content, Overlay, Portal, Root } from '@radix-ui/react-dialog';
17
+ import type { ActionModalState } from './store';
18
+ import {
19
+ closeButton,
20
+ cta as ctaStyle,
21
+ dialogContent,
22
+ dialogOverlay,
23
+ } from './styles.css';
24
+
25
+ export interface ActionModalProps {
26
+ store: Observable<ActionModalState>;
27
+ onClose: () => void;
28
+ title: string;
29
+ children: React.ReactNode;
30
+ ctas: {
31
+ label: string;
32
+ onClick: () => void;
33
+ pending?: boolean;
34
+ disabled?: boolean;
35
+ hidden?: boolean;
36
+ variant?: ComponentProps<typeof Button>['variant'];
37
+ }[];
38
+ }
39
+
40
+ export const ActionModal = observer(
41
+ ({ store, onClose, title, children, ctas }: ActionModalProps) => {
42
+ return (
43
+ <Root open={store.isOpen.get()}>
44
+ <Portal container={getProviderEl()}>
45
+ <Overlay className={dialogOverlay} />
46
+ <Content className={dialogContent.narrow}>
47
+ <Box
48
+ display="flex"
49
+ flexGrow={'1'}
50
+ alignItems="center"
51
+ flexDirection="column"
52
+ gap="4"
53
+ position={'relative'}
54
+ >
55
+ <Text
56
+ fontSize="medium"
57
+ fontWeight="bold"
58
+ textAlign="center"
59
+ width="full"
60
+ color="text100"
61
+ >
62
+ {title}
63
+ </Text>
64
+
65
+ {children}
66
+
67
+ <Box width="full" display="flex" flexDirection="column" gap="2">
68
+ {ctas.map(
69
+ (cta) =>
70
+ !cta.hidden && (
71
+ <Button
72
+ key={cta.label}
73
+ className={ctaStyle}
74
+ onClick={cta.onClick}
75
+ variant={cta.variant || 'primary'}
76
+ pending={cta.pending}
77
+ disabled={cta.disabled}
78
+ size="lg"
79
+ width="full"
80
+ label={cta.label}
81
+ />
82
+ ),
83
+ )}
84
+ </Box>
85
+ </Box>
86
+ <Close className={closeButton} asChild onClick={onClose}>
87
+ <IconButton size="xs" aria-label="Close modal" icon={CloseIcon} />
88
+ </Close>
89
+ </Content>
90
+ </Portal>
91
+ </Root>
92
+ );
93
+ },
94
+ );
@@ -0,0 +1,3 @@
1
+ export * from './ActionModal';
2
+ export * from './store';
3
+ export * from './styles.css';
@@ -0,0 +1,19 @@
1
+ import { type Observable, observable } from '@legendapp/state';
2
+
3
+ export interface ActionModalState {
4
+ isOpen: boolean;
5
+ }
6
+
7
+ export function createActionModalStore() {
8
+ return observable<ActionModalState>({
9
+ isOpen: false,
10
+ });
11
+ }
12
+
13
+ export function openModal(store: Observable<ActionModalState>) {
14
+ store.isOpen.set(true);
15
+ }
16
+
17
+ export function closeModal(store: Observable<ActionModalState>) {
18
+ store.isOpen.set(false);
19
+ }
@@ -0,0 +1,15 @@
1
+ import { globalStyle, style } from '@vanilla-extract/css';
2
+
3
+ export {
4
+ closeButton,
5
+ dialogContent,
6
+ dialogOverlay,
7
+ } from '../../../../styles/modal.css';
8
+
9
+ export const cta = style({
10
+ borderRadius: '12px !important',
11
+ });
12
+
13
+ globalStyle(`${cta} > div`, {
14
+ justifyContent: 'center !important',
15
+ });
@@ -0,0 +1,21 @@
1
+ import SvgInfoIcon from '../../../../icons/InfoIcon';
2
+ import { alertMessageBox, alertMessageBoxVariants } from './styles.css';
3
+ import { Box, Text, WarningIcon } from '@0xsequence/design-system';
4
+
5
+ type AlertMessageProps = {
6
+ message: string;
7
+ type: 'warning' | 'info';
8
+ };
9
+
10
+ export default function AlertMessage({ message, type }: AlertMessageProps) {
11
+ return (
12
+ <Box className={`${alertMessageBox} ${alertMessageBoxVariants[type]}`}>
13
+ <Text color="white" fontSize="normal" fontWeight="medium">
14
+ {message}
15
+ </Text>
16
+
17
+ {type === 'warning' && <WarningIcon size="sm" color="white" />}
18
+ {type === 'info' && <SvgInfoIcon size="sm" color="white" />}
19
+ </Box>
20
+ );
21
+ }
@@ -0,0 +1,22 @@
1
+ import { atoms } from '@0xsequence/design-system';
2
+ import { style, styleVariants } from '@vanilla-extract/css';
3
+
4
+ export const alertMessageBox = style([
5
+ atoms({
6
+ display: 'flex',
7
+ alignItems: 'center',
8
+ justifyContent: 'space-between',
9
+ gap: '3',
10
+ padding: '4',
11
+ borderRadius: 'md',
12
+ }),
13
+ ]);
14
+
15
+ export const alertMessageBoxVariants = styleVariants({
16
+ warning: {
17
+ background: 'hsla(39, 71%, 40%, 0.3)',
18
+ },
19
+ info: {
20
+ background: 'hsla(247, 100%, 75%, 0.3)',
21
+ },
22
+ });