From 40e30e53a4c29322c026368395383f9fb962ab45 Mon Sep 17 00:00:00 2001 From: Benedek Robert George <72063093+911-Benedek-RobertGeorge@users.noreply.github.com> Date: Wed, 6 Sep 2023 00:23:26 +0300 Subject: [PATCH 01/46] #870 Add the transaction limitation to guardrails --- package-lock.json | 56 ------------------- src/libs/config.ts | 6 ++ src/pages/GuardRails/GuardRails.tsx | 19 ++++++- .../GuardRails/components/guardRailsCards.tsx | 50 +++++++++++++++++ 4 files changed, 74 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index 466e0f2c..73e88de0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8990,16 +8990,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "peer": true, - "dependencies": { - "semver": "^7.0.0" - } - }, "node_modules/bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -11381,26 +11371,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-es-x": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.2.0.tgz", - "integrity": "sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": ">=8" - } - }, "node_modules/eslint-plugin-flowtype": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", @@ -11561,32 +11531,6 @@ "semver": "bin/semver.js" } }, - "node_modules/eslint-plugin-n": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.0.1.tgz", - "integrity": "sha512-CDmHegJN0OF3L5cz5tATH84RPQm9kG+Yx39wIqIwPR2C0uhBGMWfbbOtetR83PQjjidA5aXMu+LEFw1jaSwvTA==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.1.0", - "ignore": "^5.2.4", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.3" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, "node_modules/eslint-plugin-prettier": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", diff --git a/src/libs/config.ts b/src/libs/config.ts index 963a1d3d..127f9f3c 100644 --- a/src/libs/config.ts +++ b/src/libs/config.ts @@ -445,6 +445,8 @@ export const historicGuardrails = [ maximum_royalties_newPrice: null, time_between_mints_oldPrice: null, time_between_mints_newPrice: null, + transaction_limitation_old: null, + transaction_limitation_new: null, max_data_nft_supply: null, antiSpam_tax_oldPrice: null, antiSpam_tax_newPrice: null, @@ -465,6 +467,8 @@ export const historicGuardrails = [ maximum_royalties_newPrice: null, time_between_mints_oldPrice: null, time_between_mints_newPrice: null, + transaction_limitation_old: null, + transaction_limitation_new: null, max_data_nft_supply: null, antiSpam_tax_oldPrice: null, antiSpam_tax_newPrice: null, @@ -485,6 +489,8 @@ export const historicGuardrails = [ // maximum_royalties_newPrice: "90", // time_between_mints_oldPrice: "20", // time_between_mints_newPrice: "20", + // transaction_limitation_old: null, + // transaction_limitation_new: null, // max_data_nft_supply: "3000", // antiSpam_tax_oldPrice: "10", // antiSpam_tax_newPrice: "10", diff --git a/src/pages/GuardRails/GuardRails.tsx b/src/pages/GuardRails/GuardRails.tsx index 2e0af826..f6d73dbd 100644 --- a/src/pages/GuardRails/GuardRails.tsx +++ b/src/pages/GuardRails/GuardRails.tsx @@ -104,7 +104,6 @@ export const GuardRails: React.FC = () => { setWhitelistedAddresses(_whitelistedAddresses); })(); }, []); - return ( @@ -173,6 +172,15 @@ export const GuardRails: React.FC = () => { + + Transaction limitation:  + + + {process.env.REACT_APP_MAX_BUY_LIMIT_PER_SFT ? process.env.REACT_APP_MAX_BUY_LIMIT_PER_SFT : "-"} + + + + Max Data NFT supply:  @@ -207,6 +215,7 @@ export const GuardRails: React.FC = () => { + {/* add the the transaction limit here also */} @@ -271,6 +280,14 @@ export const GuardRails: React.FC = () => { + + Transaction limitation:  + + + {process.env.REACT_APP_MAX_BUY_LIMIT_PER_SFT ? process.env.REACT_APP_MAX_BUY_LIMIT_PER_SFT : "-"} + + + Max Data NFT supply:  diff --git a/src/pages/GuardRails/components/guardRailsCards.tsx b/src/pages/GuardRails/components/guardRailsCards.tsx index 326f1acf..b09226cb 100644 --- a/src/pages/GuardRails/components/guardRailsCards.tsx +++ b/src/pages/GuardRails/components/guardRailsCards.tsx @@ -60,6 +60,11 @@ export const GuardRailsCards: React.FC = (props) => { const isEqualTimeBetweenMints = parseInt(currentItem?.time_between_mints_oldPrice ?? "0") === parseInt(currentItem?.time_between_mints_newPrice ?? "0"); const isNullTimeBetweenMints = "-"; + const isLowerTransactionLimitation = parseInt(currentItem?.transaction_limitation_old ?? "0") < parseInt(currentItem?.transaction_limitation_new ?? "0"); + const isHigherTransactionLimitation = parseInt(currentItem?.transaction_limitation_old ?? "0") > parseInt(currentItem?.transaction_limitation_new ?? "0"); + const isEqualTransactionLimitation = parseInt(currentItem?.transaction_limitation_old ?? "0") === parseInt(currentItem?.transaction_limitation_new ?? "0"); + const isNullTransactionLimitation = "-"; + const isLowerAntiSpamFee = parseInt(currentItem?.antiSpam_tax_oldPrice ?? "0") < parseInt(currentItem?.antiSpam_tax_newPrice ?? "0"); const isHigherAntiSpamFee = parseInt(currentItem?.antiSpam_tax_oldPrice ?? "0") > parseInt(currentItem?.antiSpam_tax_newPrice ?? "0"); const isEqualAntiSpamFee = parseInt(currentItem?.antiSpam_tax_oldPrice ?? "0") === parseInt(currentItem?.antiSpam_tax_newPrice ?? "0"); @@ -295,6 +300,51 @@ export const GuardRailsCards: React.FC = (props) => { + + + Transaction limitation:  + + {currentItem.transaction_limitation_new ? ( + + {!isEqualTransactionLimitation ? ( + + {currentItem.transaction_limitation_old} + + ) : ( + + {currentItem.transaction_limitation_old} + + )} + {isLowerTransactionLimitation && ( + + {arrowUp} + + )} + {isHigherTransactionLimitation && ( + + {arrowDown} + + )} + {isEqualTransactionLimitation && ( + + {equal} + + )} + + {currentItem.transaction_limitation_new} + + +  ({currentItem.date}) + + + ) : ( + + {isNullTransactionLimitation} + + )} + + + Max Data NFT supply:  From 9080ec10d1160724453db2a07f74c3420c130c15 Mon Sep 17 00:00:00 2001 From: Benedek Robert George <72063093+911-Benedek-RobertGeorge@users.noreply.github.com> Date: Wed, 6 Sep 2023 15:16:55 +0300 Subject: [PATCH 02/46] #902 and made a menu like dark-light mode --- src/components/Sections/AppHeader.tsx | 36 ++++++++++++++++----------- src/index.tsx | 3 ++- src/libs/config.ts | 1 + src/pages/DataNFT/DataNFTDetails.tsx | 14 +++++------ src/pages/GuardRails/GuardRails.tsx | 6 ++--- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/components/Sections/AppHeader.tsx b/src/components/Sections/AppHeader.tsx index d44bb76a..f180f168 100644 --- a/src/components/Sections/AppHeader.tsx +++ b/src/components/Sections/AppHeader.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useState } from "react"; -import { WarningTwoIcon } from "@chakra-ui/icons"; +import { SunIcon, WarningTwoIcon } from "@chakra-ui/icons"; + import { Accordion, AccordionItem, @@ -43,10 +44,9 @@ import { import { useGetAccountInfo, useGetLoginInfo } from "@multiversx/sdk-dapp/hooks/account"; import { useGetPendingTransactions } from "@multiversx/sdk-dapp/hooks/transactions"; import { AiFillHome } from "react-icons/ai"; -import { FaStore, FaUserCheck } from "react-icons/fa"; +import { FaStore, FaUserCheck, FaLaptop } from "react-icons/fa"; import { MdAccountBalanceWallet, MdDarkMode, MdMenu, MdPerson, MdSpaceDashboard } from "react-icons/md"; import { RiExchangeFill } from "react-icons/ri"; -import { TbSunset2 } from "react-icons/tb"; import { TiArrowSortedDown } from "react-icons/ti"; import { Link as ReactRouterLink, useLocation, useNavigate } from "react-router-dom"; import logoSmlL from "assets/img/logo-icon-b.png"; @@ -131,7 +131,7 @@ const AppHeader = ({ onLaunchMode, menuItem, setMenuItem, handleLogout }: { onLa const { chainMeta: _chainMeta } = useChainMeta(); const { hasPendingTransactions } = useGetPendingTransactions(); const { address: mxAddress } = useGetAccountInfo(); - const { colorMode, toggleColorMode } = useColorMode(); + const { colorMode, setColorMode } = useColorMode(); const { isLoggedIn: isMxLoggedIn } = useGetLoginInfo(); const { pathname } = useLocation(); @@ -372,17 +372,25 @@ const AppHeader = ({ onLaunchMode, menuItem, setMenuItem, handleLogout }: { onLa )} {onLaunchMode && !isMxLoggedIn && } Toggle Mode - - : } - aria-label="Change Color Theme" - color="teal.200" - onClick={toggleColorMode} + + : } + variant="solid" /> - + + } command="⌘N" onClick={() => setColorMode("light")}> + Light + + } command="⌘⇧N" onClick={() => setColorMode("dark")}> + Dark + + } command="⌘O" onClick={() => setColorMode("system")}> + System + + + diff --git a/src/index.tsx b/src/index.tsx index d0722442..81c51384 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -34,7 +34,8 @@ const breakpoints = { const theme = extendTheme({ breakpoints, config: { - initialColorMode: "dark", + initialColorMode: "system", + useSystemColorMode: true, }, fontSizes: { xs: "0.65rem", diff --git a/src/libs/config.ts b/src/libs/config.ts index 127f9f3c..f83fc48d 100644 --- a/src/libs/config.ts +++ b/src/libs/config.ts @@ -506,6 +506,7 @@ export const upcomingGuardRails = { minimum_royalties: null, maximum_royalties: null, time_between_mints: null, + transaction_limitation: null, max_data_nft_supply: null, antiSpam_tax: null, accepted_payments: null, diff --git a/src/pages/DataNFT/DataNFTDetails.tsx b/src/pages/DataNFT/DataNFTDetails.tsx index 3a1ba046..d02bfab7 100644 --- a/src/pages/DataNFT/DataNFTDetails.tsx +++ b/src/pages/DataNFT/DataNFTDetails.tsx @@ -336,7 +336,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { - + {amountError} @@ -478,18 +478,18 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { <> {!offer ? ( <> - {totalOffers.length === 1 - ? `${totalOffers.filter((to: any) => (offerId ? to.index !== Number(offerId) : to.index)).length} Offer:` + {totalOffers.length === 2 + ? `One offer:` : totalOffers.filter((to: any) => (offerId ? to.index !== Number(offerId) : to.index)).length === 0 - ? "Offers:" + ? "No other offers" : `${totalOffers.filter((to: any) => (offerId ? to.index !== Number(offerId) : to.index)).length} Offers:`} ) : ( <> - {totalOffers.length === 1 - ? `${totalOffers.filter((to: any) => (offerId ? to.index !== Number(offerId) : to.index)).length} other offer:` + {totalOffers.length === 2 /// 2 here because we are always going to have the current offer and the other one + ? `One other offer:` : totalOffers.filter((to: any) => (offerId ? to.index !== Number(offerId) : to.index)).length === 0 - ? "Other offers:" + ? "No other offers" : `${totalOffers.filter((to: any) => (offerId ? to.index !== Number(offerId) : to.index)).length} other offers:`} )} diff --git a/src/pages/GuardRails/GuardRails.tsx b/src/pages/GuardRails/GuardRails.tsx index f6d73dbd..8de6567d 100644 --- a/src/pages/GuardRails/GuardRails.tsx +++ b/src/pages/GuardRails/GuardRails.tsx @@ -282,9 +282,9 @@ export const GuardRails: React.FC = () => { Transaction limitation:  - - - {process.env.REACT_APP_MAX_BUY_LIMIT_PER_SFT ? process.env.REACT_APP_MAX_BUY_LIMIT_PER_SFT : "-"} + + + {upcomingGuardRails.transaction_limitation ? upcomingGuardRails.transaction_limitation : "-"} From cf492946350fee1eb9f9693f131c863cbea6930d Mon Sep 17 00:00:00 2001 From: Benedek Robert George <72063093+911-Benedek-RobertGeorge@users.noreply.github.com> Date: Thu, 7 Sep 2023 21:02:38 +0300 Subject: [PATCH 03/46] messy pile of cards --- .../UtilComps/UpperCardComponent.tsx | 102 +++++++++++++++++- .../DataNFT/DataNFTMarketplaceMultiversX.tsx | 46 +++++++- 2 files changed, 142 insertions(+), 6 deletions(-) diff --git a/src/components/UtilComps/UpperCardComponent.tsx b/src/components/UtilComps/UpperCardComponent.tsx index acc376b4..6fb212d4 100644 --- a/src/components/UtilComps/UpperCardComponent.tsx +++ b/src/components/UtilComps/UpperCardComponent.tsx @@ -2,6 +2,7 @@ import React, { Dispatch, FC, SetStateAction, useRef } from "react"; import { ExternalLinkIcon } from "@chakra-ui/icons"; import { Box, + Container, Flex, Image, Link, @@ -29,6 +30,7 @@ import { convertToLocalString, convertWeiToEsdt, getTokenWantedRepresentation, p import { useMarketStore, useMintStore } from "store"; import { useChainMeta } from "store/ChainMetaContext"; import ShortAddress from "./ShortAddress"; +import { relative } from "path"; type UpperCardComponentProps = { nftImageLoading: boolean; @@ -83,12 +85,14 @@ const UpperCardComponent: FC = ({ borderColor="#00C79740" position="relative" mb="1rem"> - + {"item.dataPreview"} = ({ currentTarget.src = DEFAULT_NFT_IMAGE; }} /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + style={{ + transform: "rotate(-5deg)", // Rotate the image by -5 degrees + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + style={{ + transform: "rotate(-10deg)", // Rotate the image by -5 degrees + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + style={{ + transform: "rotate(5deg)", // Rotate the image by -5 degrees + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + style={{ + transform: "rotate(10deg)", // Rotate the image by -5 degrees + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + style={{ + transform: "rotate(10deg)", // Rotate the image by -5 degrees + }} + /> = ({ - + - + {nftMetadata && ( <> diff --git a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx index e7fb29d3..73c1093b 100644 --- a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx +++ b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx @@ -2,7 +2,9 @@ import React, { FC, useEffect, useState } from "react"; import { Icon } from "@chakra-ui/icons"; import { Box, + Button, CloseButton, + Container, Flex, Heading, HStack, @@ -69,6 +71,7 @@ export const Marketplace: FC = ({ tabState }) => { const isMarketPaused = useMarketStore((state) => state.isMarketPaused); const offers = useMarketStore((state) => state.offers); + const updateOffers = useMarketStore((state) => state.updateOffers); const loadingOffers = useMarketStore((state) => state.loadingOffers); const updateLoadingOffers = useMarketStore((state) => state.updateLoadingOffers); @@ -90,7 +93,7 @@ export const Marketplace: FC = ({ tabState }) => { const { isOpen: isOpenDataNftDetails, onOpen: onOpenDataNftDetails, onClose: onCloseDataNftDetails } = useDisclosure(); const [myListedCount, setMyListedCount] = useState(0); const [publicMarketCount, setPublicMarketCount] = useState(0); - + const [showGroupedDataNfts, setShowGroupedDataNfts] = useState(false); const setPageIndex = (newPageIndex: number) => { navigate(`/datanfts/marketplace/${tabState === 1 ? "market" : "my"}${newPageIndex > 0 ? "/" + newPageIndex : ""}`); }; @@ -101,6 +104,13 @@ export const Marketplace: FC = ({ tabState }) => { } }); + const groupDataNfts = () => { + console.log(offers[0]); + console.log("META", nftMetadatas[0]); + console.log(offers[offers.length - 1]); + console.log("META", nftMetadatas[offers.length - 1]); + setShowGroupedDataNfts(!showGroupedDataNfts); + }; useEffect(() => { (async () => { if (!_chainMeta.networkId) return; @@ -321,7 +331,12 @@ export const Marketplace: FC = ({ tabState }) => { )} - + + + + @@ -351,6 +366,33 @@ export const Marketplace: FC = ({ tabState }) => { openNftDetailsDrawer={openNftDetailsModal}> + + /* + + + + {" "} + + + + + */ ))} )} From 0c60543ae116833cd7ca10404636f14dc5da3394 Mon Sep 17 00:00:00 2001 From: Benedek Robert George <72063093+911-Benedek-RobertGeorge@users.noreply.github.com> Date: Wed, 20 Sep 2023 15:15:29 +0300 Subject: [PATCH 04/46] group logic and UI group logic and UI --- src/components/MyListedDataLowerCard.tsx | 2 +- src/components/Sections/AppHeader.tsx | 2 +- .../UtilComps/UpperCardComponent.tsx | 201 +++++++++--------- src/libs/MultiversX/api.ts | 1 - src/libs/MultiversX/backend-api.ts | 1 - src/pages/DataNFT/DataNFTDetails.tsx | 4 +- .../DataNFT/DataNFTMarketplaceMultiversX.tsx | 181 +++++++++++----- .../Profile/components/DataCreatorTabs.tsx | 3 +- 8 files changed, 233 insertions(+), 162 deletions(-) diff --git a/src/components/MyListedDataLowerCard.tsx b/src/components/MyListedDataLowerCard.tsx index c4b35f84..0c642d66 100644 --- a/src/components/MyListedDataLowerCard.tsx +++ b/src/components/MyListedDataLowerCard.tsx @@ -154,7 +154,7 @@ const MyListedDataLowerCard: FC = ({ offer, nftMetad onClick={() => { window.open(nftMetadata.dataPreview); }}> - + Preview Data diff --git a/src/components/Sections/AppHeader.tsx b/src/components/Sections/AppHeader.tsx index f180f168..128284a4 100644 --- a/src/components/Sections/AppHeader.tsx +++ b/src/components/Sections/AppHeader.tsx @@ -411,7 +411,7 @@ const AppHeader = ({ onLaunchMode, menuItem, setMenuItem, handleLogout }: { onLa - + {exploreRouterMenu.map((menu) => ( diff --git a/src/components/UtilComps/UpperCardComponent.tsx b/src/components/UtilComps/UpperCardComponent.tsx index 6fb212d4..eee80df4 100644 --- a/src/components/UtilComps/UpperCardComponent.tsx +++ b/src/components/UtilComps/UpperCardComponent.tsx @@ -1,4 +1,4 @@ -import React, { Dispatch, FC, SetStateAction, useRef } from "react"; +import React, { Dispatch, FC, SetStateAction, useEffect, useRef } from "react"; import { ExternalLinkIcon } from "@chakra-ui/icons"; import { Box, @@ -13,7 +13,6 @@ import { PopoverContent, PopoverHeader, PopoverTrigger, - Portal, Skeleton, Stack, Text, @@ -30,7 +29,6 @@ import { convertToLocalString, convertWeiToEsdt, getTokenWantedRepresentation, p import { useMarketStore, useMintStore } from "store"; import { useChainMeta } from "store/ChainMetaContext"; import ShortAddress from "./ShortAddress"; -import { relative } from "path"; type UpperCardComponentProps = { nftImageLoading: boolean; @@ -40,6 +38,7 @@ type UpperCardComponentProps = { offer: OfferType; index: number; marketFreezedNonces: number[]; + grouped: boolean; children?: React.ReactNode; openNftDetailsDrawer?: (e: number) => void; }; @@ -54,6 +53,7 @@ const UpperCardComponent: FC = ({ offer, marketFreezedNonces, openNftDetailsDrawer, + grouped, }) => { const { colorMode } = useColorMode(); @@ -78,119 +78,118 @@ const UpperCardComponent: FC = ({ - + mb="1.5rem" + mt={grouped ? "1rem" : "0"}> + {"item.dataPreview"} setNftImageLoaded(true)} onError={({ currentTarget }) => { currentTarget.src = DEFAULT_NFT_IMAGE; }} /> - {"item.dataPreview"} setNftImageLoaded(true)} - onError={({ currentTarget }) => { - currentTarget.src = DEFAULT_NFT_IMAGE; - }} - style={{ - transform: "rotate(-5deg)", // Rotate the image by -5 degrees - }} - /> - {"item.dataPreview"} setNftImageLoaded(true)} - onError={({ currentTarget }) => { - currentTarget.src = DEFAULT_NFT_IMAGE; - }} - style={{ - transform: "rotate(-10deg)", // Rotate the image by -5 degrees - }} - /> - {"item.dataPreview"} setNftImageLoaded(true)} - onError={({ currentTarget }) => { - currentTarget.src = DEFAULT_NFT_IMAGE; - }} - style={{ - transform: "rotate(5deg)", // Rotate the image by -5 degrees - }} - /> - {"item.dataPreview"} setNftImageLoaded(true)} - onError={({ currentTarget }) => { - currentTarget.src = DEFAULT_NFT_IMAGE; - }} - style={{ - transform: "rotate(10deg)", // Rotate the image by -5 degrees - }} - /> - {"item.dataPreview"} setNftImageLoaded(true)} - onError={({ currentTarget }) => { - currentTarget.src = DEFAULT_NFT_IMAGE; - }} - style={{ - transform: "rotate(10deg)", // Rotate the image by -5 degrees - }} - /> + {grouped && ( + <> + + + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + style={{ + transform: "rotate(8deg)", + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + style={{ + transform: "rotate(14deg)", + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + style={{ + transform: "rotate(-8deg)", + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + style={{ + transform: "rotate(-14deg)", + }} + /> + + )} + = ({ - - + {nftMetadata && ( <> @@ -326,7 +324,6 @@ const UpperCardComponent: FC = ({ )} - (url, { timeout: uxConfig.mxAPITimeoutMs, }); - return data; } catch (error) { console.error(error); diff --git a/src/pages/DataNFT/DataNFTDetails.tsx b/src/pages/DataNFT/DataNFTDetails.tsx index d02bfab7..a346bdfa 100644 --- a/src/pages/DataNFT/DataNFTDetails.tsx +++ b/src/pages/DataNFT/DataNFTDetails.tsx @@ -175,7 +175,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { // Extracting nonce const nonceHex = inputString?.split("-")[2]; const nonceDec = parseInt(nonceHex, 16); - + console.log("Colectie: ", identifier, nonceDec, nonceHex); const _offers = await getOffersByIdAndNoncesFromBackendApi(networkId, identifier, [nonceDec]); setTotalOffers(_offers); const price = Math.min(..._offers.map((offer: any) => offer.wanted_token_amount)); @@ -528,7 +528,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { {tokenId && pathname?.includes(tokenId) ? ( - diff --git a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx index 73c1093b..417dbe68 100644 --- a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx +++ b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx @@ -39,7 +39,7 @@ import ConditionalRender from "components/UtilComps/ApiWrapper"; import UpperCardComponent from "components/UtilComps/UpperCardComponent"; import useThrottle from "components/UtilComps/UseThrottle"; import { getOffersCountFromBackendApi, getOffersFromBackendApi } from "libs/MultiversX"; -import { getApi, getNetworkProvider, getNftsByIds } from "libs/MultiversX/api"; +import { getApi, getCollectionNfts, getNetworkProvider, getNftsByIds } from "libs/MultiversX/api"; import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; import { DataNftMintContract } from "libs/MultiversX/dataNftMint"; import { DataNftMetadataType, OfferType } from "libs/MultiversX/types"; @@ -48,6 +48,8 @@ import { networkIdBasedOnLoggedInStatus } from "libs/utils/util"; import DataNFTDetails from "pages/DataNFT/DataNFTDetails"; import { useMarketStore } from "store"; import { useChainMeta } from "store/ChainMetaContext"; +import { DataNft } from "@itheum/sdk-mx-data-nft/out"; +import { off } from "process"; interface PropsType { tabState: number; // 1 for "Public Marketplace", 2 for "My Data NFTs" @@ -78,7 +80,6 @@ export const Marketplace: FC = ({ tabState }) => { // pagination const pageCount = useMarketStore((state) => state.pageCount); const updatePageCount = useMarketStore((state) => state.updatePageCount); - const pageSize = 8; const [nftMetadatas, setNftMetadatas] = useState([]); @@ -94,6 +95,11 @@ export const Marketplace: FC = ({ tabState }) => { const [myListedCount, setMyListedCount] = useState(0); const [publicMarketCount, setPublicMarketCount] = useState(0); const [showGroupedDataNfts, setShowGroupedDataNfts] = useState(false); + + const [nonceOfferMap, setNonceOfferMap] = useState>(new Map()); // a dictionary-> nonce => dataNft (lowest price) + const [groupedMetadatas, setGroupedMetadatas] = useState([]); + const [currentPageGroupedOffers, setCurrentPageGroupedOffers] = useState([]); + const setPageIndex = (newPageIndex: number) => { navigate(`/datanfts/marketplace/${tabState === 1 ? "market" : "my"}${newPageIndex > 0 ? "/" + newPageIndex : ""}`); }; @@ -105,12 +111,79 @@ export const Marketplace: FC = ({ tabState }) => { }); const groupDataNfts = () => { - console.log(offers[0]); - console.log("META", nftMetadatas[0]); - console.log(offers[offers.length - 1]); - console.log("META", nftMetadatas[offers.length - 1]); + console.log(showGroupedDataNfts); + if (!showGroupedDataNfts) { + (async () => { + console.log("FETCH"); + if (hasPendingTransactions) return; + if (!_chainMeta.networkId) return; + + // start loading offers + updateLoadingOffers(true); + //const theCollections: any = await getCollectionNfts("DATANFTFT4-3ba099", _chainMeta.networkId); + //console.log("COLLECTIONS ", theCollections); + //console.log(theCollections[0]); + ///TODO CHECK IF COLLECTIONS AND MAP IS THE SAME + let _offers: OfferType[] = []; + const start = 0; + if (isApiUp && isMarketplaceApiUp) { + // console.log('Api Up'); + _offers = await getOffersFromBackendApi(_chainMeta.networkId, start, publicMarketCount, undefined); + } else { + return; + // console.log('Api Down'); + //_offers = await marketContract.viewPagedOffers(start, start + pageSize - 1, tabState === 1 ? "" : address); + } + console.log(_offers.length); + /// populate the map with the best choice(price-wise) from each nonce + const _nonceOfferMap = new Map(); + _offers.forEach((offer) => { + if (_nonceOfferMap.has(offer.offered_token_nonce)) { + const previousOffer = _nonceOfferMap.get(offer.offered_token_nonce); + + if (previousOffer?.wanted_token_amount && parseFloat(offer.wanted_token_amount) < parseFloat(previousOffer?.wanted_token_amount)) { + // console.log("CHANGED"); + // console.log(parseFloat(offer.wanted_token_amount)); + // console.log(previousOffer.wanted_token_amount); + if (offer.wanted_token_amount) _nonceOfferMap.set(offer.offered_token_nonce, offer); + } + } else { + _nonceOfferMap.set(offer.offered_token_nonce, offer); + } + }); + if (_nonceOfferMap !== undefined) { + Array.from(_nonceOfferMap.entries()) + .slice(0, 20) + .map(([nonce, offer]) => { + console.log(nonce, offer); + }); + } + setNonceOfferMap(_nonceOfferMap); + //make pagination + ///get nftMetadatas for the grouped offers + setNftMetadatasLoading(true); + const nftIds = Array.from(_nonceOfferMap.entries()) + .slice(0, 20) + .map(([nonce, offer]) => createNftId(offer.offered_token_identifier, offer.offered_token_nonce)); + const _nfts = await getNftsByIds(nftIds, networkId); + const _metadatas: DataNftMetadataType[] = []; + for (let i = 0; i < _nfts.length; i++) { + _metadatas.push(mintContract.decodeNftAttributes(_nfts[i], i)); + } + console.log("META GROUP", _metadatas); + setGroupedMetadatas(_metadatas); + setCurrentPageGroupedOffers(Array.from(_nonceOfferMap.values()).slice(0, 20)); + + setNftMetadatasLoading(false); + ///console.log("KEYS ", nonceOfferMap.keys()); + + updateLoadingOffers(false); + })(); + } + setShowGroupedDataNfts(!showGroupedDataNfts); }; + useEffect(() => { (async () => { if (!_chainMeta.networkId) return; @@ -174,7 +247,6 @@ export const Marketplace: FC = ({ tabState }) => { _offers = await marketContract.viewPagedOffers(start, start + pageSize - 1, tabState === 1 ? "" : address); } - // console.log("_offers", _offers); updateOffers(_offers); setNftMetadatasLoading(true); @@ -194,7 +266,8 @@ export const Marketplace: FC = ({ tabState }) => { }, [pageIndex, pageSize, tabState, hasPendingTransactions]); function openNftDetailsModal(index: number) { - setOfferForDrawer(offers[index]); + if (showGroupedDataNfts) setOfferForDrawer(currentPageGroupedOffers[index]); + else setOfferForDrawer(offers[index]); onOpenDataNftDetails(); } @@ -257,6 +330,9 @@ export const Marketplace: FC = ({ tabState }) => { } }, [pendingTransactions]); + //todo pagination, + // refresh the page when somebody buys something (Haspending transaction) + return ( <> @@ -334,7 +410,7 @@ export const Marketplace: FC = ({ tabState }) => { @@ -347,53 +423,51 @@ export const Marketplace: FC = ({ tabState }) => { ) : ( - {offers.length > 0 && - offers.map((offer, index) => ( - - - - - /* - - - - {" "} - - - - - */ - ))} + {!showGroupedDataNfts + ? offers.map((offer, index) => ( + + + + )) + : Array.from(nonceOfferMap.entries()) + .slice(0, 24) + .map(([nonce, offer], index) => { + console.log(index, offer, groupedMetadatas[index]); + + return ( + + + + ); + })} )} @@ -418,6 +492,7 @@ export const Marketplace: FC = ({ tabState }) => { offer={offer} index={index} marketFreezedNonces={marketFreezedNonces} + grouped={false} openNftDetailsDrawer={openNftDetailsModal}> diff --git a/src/pages/Profile/components/DataCreatorTabs.tsx b/src/pages/Profile/components/DataCreatorTabs.tsx index e9bfb70b..7624ccb8 100644 --- a/src/pages/Profile/components/DataCreatorTabs.tsx +++ b/src/pages/Profile/components/DataCreatorTabs.tsx @@ -328,7 +328,8 @@ export const DataCreatorTabs: React.FC = ({ tabState }) => { offer={offer} index={index} marketFreezedNonces={marketFreezedNonces} - openNftDetailsDrawer={openNftDetailsModal}> + openNftDetailsDrawer={openNftDetailsModal} + grouped={false}> ))} From b557392e19f5f8ceca6a10aee5a8ac0cd64dcdf8 Mon Sep 17 00:00:00 2001 From: Benedek Robert George <72063093+911-Benedek-RobertGeorge@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:07:24 +0300 Subject: [PATCH 05/46] new design --- package-lock.json | 109 ------- src/components/Sections/AppHeader.tsx | 26 +- .../DataNFT/DataNFTMarketplaceMultiversX.tsx | 67 ++-- src/pages/DataNFT/DataNftCollection.tsx | 302 ++++++++++++++++++ 4 files changed, 346 insertions(+), 158 deletions(-) create mode 100644 src/pages/DataNFT/DataNftCollection.tsx diff --git a/package-lock.json b/package-lock.json index b496a549..e02e0940 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9697,52 +9697,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "peer": true, - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/builtins/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/builtins/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/builtins/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true - }, "node_modules/bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -12237,69 +12191,6 @@ "semver": "bin/semver.js" } }, - "node_modules/eslint-plugin-n": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.1.0.tgz", - "integrity": "sha512-3wv/TooBst0N4ND+pnvffHuz9gNPmk/NkLwAxOt2JykTl/hcuECe6yhTtLJcZjIxtZwN+GX92ACp/QTLpHA3Hg==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.1.0", - "get-tsconfig": "^4.7.0", - "ignore": "^5.2.4", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.3" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-n/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-n/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-n/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true - }, "node_modules/eslint-plugin-prettier": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", diff --git a/src/components/Sections/AppHeader.tsx b/src/components/Sections/AppHeader.tsx index dba62af0..62b22396 100644 --- a/src/components/Sections/AppHeader.tsx +++ b/src/components/Sections/AppHeader.tsx @@ -125,7 +125,7 @@ const AppHeader = ({ onShowConnectWalletModal, setMenuItem, handleLogout }: { on const { chainID } = useGetNetworkConfig(); const { hasPendingTransactions } = useGetPendingTransactions(); const { address: mxAddress } = useGetAccountInfo(); - const { colorMode, setColorMode } = useColorMode(); + const { colorMode, setColorMode, toggleColorMode } = useColorMode(); const { isLoggedIn: isMxLoggedIn } = useGetLoginInfo(); const { pathname } = useLocation(); @@ -224,29 +224,6 @@ const AppHeader = ({ onShowConnectWalletModal, setMenuItem, handleLogout }: { on - {isMxLoggedIn ? ( - - : } - aria-label="Change Color Theme" - color="teal.200" - onClick={toggleColorMode} - /> - - ) : ( - - : } - aria-label="Change Color Theme" - color="teal.200" - onClick={toggleColorMode} - /> - - )} @@ -415,6 +392,7 @@ const AppHeader = ({ onShowConnectWalletModal, setMenuItem, handleLogout }: { on Toggle Mode : } diff --git a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx index 4ceefed7..66055e1f 100644 --- a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx +++ b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx @@ -3,6 +3,7 @@ import { Icon } from "@chakra-ui/icons"; import { Box, Button, + Checkbox, CloseButton, Container, Flex, @@ -21,6 +22,7 @@ import { TabPanels, Tabs, Text, + Tooltip, useColorMode, useDisclosure, useToast, @@ -39,17 +41,18 @@ import { NoDataHere } from "components/Sections/NoDataHere"; import ConditionalRender from "components/UtilComps/ApiWrapper"; import UpperCardComponent from "components/UtilComps/UpperCardComponent"; import useThrottle from "components/UtilComps/UseThrottle"; + import { getOffersCountFromBackendApi, getOffersFromBackendApi } from "libs/MultiversX"; import { getApi, getCollectionNfts, getNetworkProvider, getNftsByIds } from "libs/MultiversX/api"; import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; import { DataNftMintContract } from "libs/MultiversX/dataNftMint"; import { DataNftMetadataType, OfferType } from "libs/MultiversX/types"; -import { createNftId, hexZero, sleep } from "libs/utils"; +import { convertWeiToEsdt, createNftId, hexZero, sleep, tokenDecimals } from "libs/utils"; import DataNFTDetails from "pages/DataNFT/DataNFTDetails"; import { useMarketStore } from "store"; -import { useChainMeta } from "store/ChainMetaContext"; -import { DataNft } from "@itheum/sdk-mx-data-nft/out"; -import { off } from "process"; +import { MdOutlineInfo } from "react-icons/md"; +import { DataNftCollection } from "./DataNftCollection"; +import BigNumber from "bignumber.js"; interface PropsType { tabState: number; // 1 for "Public Marketplace", 2 for "My Data NFTs" @@ -116,7 +119,7 @@ export const Marketplace: FC = ({ tabState }) => { (async () => { console.log("FETCH"); if (hasPendingTransactions) return; - if (!_chainMeta.networkId) return; + if (!chainID) return; // start loading offers updateLoadingOffers(true); @@ -128,7 +131,7 @@ export const Marketplace: FC = ({ tabState }) => { const start = 0; if (isApiUp && isMarketplaceApiUp) { // console.log('Api Up'); - _offers = await getOffersFromBackendApi(_chainMeta.networkId, start, publicMarketCount, undefined); + _offers = await getOffersFromBackendApi(chainID, start, publicMarketCount, undefined); } else { return; // console.log('Api Down'); @@ -165,7 +168,7 @@ export const Marketplace: FC = ({ tabState }) => { const nftIds = Array.from(_nonceOfferMap.entries()) .slice(0, 20) .map(([nonce, offer]) => createNftId(offer.offered_token_identifier, offer.offered_token_nonce)); - const _nfts = await getNftsByIds(nftIds, networkId); + const _nfts = await getNftsByIds(nftIds, chainID); const _metadatas: DataNftMetadataType[] = []; for (let i = 0; i < _nfts.length; i++) { _metadatas.push(mintContract.decodeNftAttributes(_nfts[i], i)); @@ -406,11 +409,21 @@ export const Marketplace: FC = ({ tabState }) => { - + */} + + + {" "} + + + Group by collection + + + + - + @@ -419,19 +432,13 @@ export const Marketplace: FC = ({ tabState }) => { {!loadingOffers && !nftMetadatasLoading && offers.length === 0 ? ( ) : ( - + {!showGroupedDataNfts ? offers.map((offer, index) => ( = ({ tabState }) => { console.log(index, offer, groupedMetadatas[index]); return ( - + ); + })} + + )} + {/* imageUrl={`https://${getApi(networkId)}/nfts/${offer?.offered_token_identifier}-${hexZero( offer?.offered_token_nonce )}/thumbnail`} setNftImageLoaded={setOneNFTImgLoaded} @@ -462,11 +483,7 @@ export const Marketplace: FC = ({ tabState }) => { openNftDetailsDrawer={openNftDetailsModal} grouped={showGroupedDataNfts}> - - ); - })} - - )} + */} {!loadingOffers && !nftMetadatasLoading && offers.length === 0 ? ( diff --git a/src/pages/DataNFT/DataNftCollection.tsx b/src/pages/DataNFT/DataNftCollection.tsx new file mode 100644 index 00000000..07a6f71d --- /dev/null +++ b/src/pages/DataNFT/DataNftCollection.tsx @@ -0,0 +1,302 @@ +import React, { FC } from "react"; +import { Stack, Text, Box, HStack, VStack, Button, Image, Skeleton } from "@chakra-ui/react"; +import { DEFAULT_NFT_IMAGE } from "libs/mxConstants"; + +type DataNftCollectionComponentProps = { + nftImageLoading: boolean; + //setNftImageLoaded: Dispatch>; + imageUrl: string; + //nftMetadata: DataNftMetadataType; + title: string; + description: string; + listed: number; + supply: number; + floorPrice: number; + //offer: OfferType; + //index: number; + //marketFreezedNonces: number[]; + //grouped: boolean; + children?: React.ReactNode; + openNftDetailsDrawer?: (e: number) => void; +}; +export const DataNftCollection: FC = ({ + nftImageLoading, + //setNftImageLoaded, + imageUrl, + title, + description, + listed, + supply, + + floorPrice, + //nftMetadata, + //index, + //children, + //offer, + //marketFreezedNonces, + openNftDetailsDrawer, + //grouped, +}) => { + return ( + + + + + {title} + + + + {description} + + + + + + Total supply: {supply} + + + Listed: {listed} + + + + Floor price: {floorPrice} + + + + Fully Transferable License + + + + + + + + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + {"item.dataPreview"} setNftImageLoaded(true)} + onError={({ currentTarget }) => { + currentTarget.src = DEFAULT_NFT_IMAGE; + }} + /> + + {/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */} + + + + ); +}; From addff574ee8b3c72f692d956c44c637b07eaefc1 Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 14 Dec 2023 11:23:27 +0200 Subject: [PATCH 06/46] refactor faucet in separate component --- package-lock.json | 350 +++++++++++++++--------------- package.json | 10 +- src/components/Faucet/Faucet.tsx | 107 +++++++++ src/pages/Home/HomeMultiversX.tsx | 69 +----- 4 files changed, 299 insertions(+), 237 deletions(-) create mode 100644 src/components/Faucet/Faucet.tsx diff --git a/package-lock.json b/package-lock.json index 7a80a44b..d216b836 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,17 +15,17 @@ "@hookform/resolvers": "3.3.2", "@itheum/sdk-mx-data-nft": "2.4.0", "@itheum/sdk-mx-enterprise": "0.0.7", - "@multiversx/sdk-core": "12.15.0", - "@multiversx/sdk-dapp": "2.24.3", - "@multiversx/sdk-native-auth-client": "1.0.5", - "@multiversx/sdk-network-providers": "2.2.0", + "@multiversx/sdk-core": "12.16.0", + "@multiversx/sdk-dapp": "2.24.4", + "@multiversx/sdk-native-auth-client": "1.0.6", + "@multiversx/sdk-network-providers": "2.1.0", "@sentry/react": "7.80.0", "@tanstack/match-sorter-utils": "8.8.4", "@tanstack/react-table": "8.10.7", "@testing-library/jest-dom": "6.1.4", "@testing-library/react": "14.1.0", "@testing-library/user-event": "14.5.1", - "axios": "1.6.1", + "axios": "1.6.2", "dotenv": "16.3.1", "framer-motion": "10.16.4", "mime": "3.0.0", @@ -198,21 +198,21 @@ } }, "node_modules/@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", "devOptional": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -279,12 +279,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "devOptional": true, "dependencies": { - "@babel/types": "^7.23.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -318,14 +318,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "devOptional": true, "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -343,9 +343,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz", - "integrity": "sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.6.tgz", + "integrity": "sha512-cBXU1vZni/CpGF29iTu4YRbOZt3Wat6zCoMDxRF1MayiEc4URxOj31tT65HUM0CRpMowA3HCJaAOVOUnMf96cw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", @@ -401,9 +401,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", - "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", + "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -623,14 +623,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", "devOptional": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" @@ -714,9 +714,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "devOptional": true, "bin": { "parser": "bin/babel-parser.js" @@ -791,14 +791,15 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.5.tgz", - "integrity": "sha512-6IsY8jOeWibsengGlWIezp7cuZEFzNlAghFpzh9wiZwhQ42/hRcPnY/QV9HJoKTlujupinSlnQPiEy/u2C1ZfQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.6.tgz", + "integrity": "sha512-D7Ccq9LfkBFnow3azZGJvZYgcfeqAw3I1e5LoTpj6UKIFQilh8yqXsIGcRIqbBdsPWIz+Ze7ZZfggSj62Qp+Fg==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.23.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "@babel/plugin-syntax-decorators": "^7.23.3" }, @@ -1469,12 +1470,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", - "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1936,9 +1938,9 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.4.tgz", - "integrity": "sha512-ITwqpb6V4btwUG0YJR82o2QvmWrLgDnx/p2A3CTPYGaRgULkDiC0DRA2C4jlRB9uXGUEfaSS/IGHfVW+ohzYDw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.6.tgz", + "integrity": "sha512-kF1Zg62aPseQ11orDhFRw+aPG/eynNQtI+TyY+m33qJa2cJ5EEvza2P2BNTIA9E5MyqFABHEyY6CPHwgdy9aNg==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.22.15", @@ -2041,13 +2043,13 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.5.tgz", - "integrity": "sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", + "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.23.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-typescript": "^7.23.3" }, @@ -2122,13 +2124,13 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz", - "integrity": "sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.6.tgz", + "integrity": "sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", @@ -2168,7 +2170,7 @@ "@babel/plugin-transform-dynamic-import": "^7.23.4", "@babel/plugin-transform-exponentiation-operator": "^7.23.3", "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.3", + "@babel/plugin-transform-for-of": "^7.23.6", "@babel/plugin-transform-function-name": "^7.23.3", "@babel/plugin-transform-json-strings": "^7.23.4", "@babel/plugin-transform-literals": "^7.23.3", @@ -2284,9 +2286,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", - "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz", + "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2309,20 +2311,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", "devOptional": true, "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -2339,9 +2341,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -4733,11 +4735,11 @@ } }, "node_modules/@ledgerhq/hw-transport-web-ble/node_modules/@ledgerhq/devices": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.1.0.tgz", - "integrity": "sha512-Vsdv84Nwzee0qhObdwVzhkxW1+h2cFoD1AWuU8N1V/2OJKiVS35A1qloSCF0oHapg+KTJvim8tr5rRvlkCYyzQ==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.2.0.tgz", + "integrity": "sha512-XROTW2gTmmuy+YPPDjdtKKTQ3mfxrPtKtV+a9QFbj8f5MnjVMV0Zpy1BIB4CyIMsVVi4z6+nI67auT7IlsM3SQ==", "dependencies": { - "@ledgerhq/errors": "^6.16.0", + "@ledgerhq/errors": "^6.16.1", "@ledgerhq/logs": "^6.12.0", "rxjs": "^7.8.1", "semver": "^7.3.5" @@ -4752,17 +4754,17 @@ } }, "node_modules/@ledgerhq/hw-transport-web-ble/node_modules/@ledgerhq/errors": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.16.0.tgz", - "integrity": "sha512-vnew6lf4jN6E+WI0DFhD4WY0uM8LYL8HCumtUr86hNwvmEfebi7LxxpJGmYfVQD5TgEC7NibYnQ+2q9XWAc02A==" + "version": "6.16.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.16.1.tgz", + "integrity": "sha512-4D4wKecGzQpIu7sx03Sg4uE1e8g1oZUndWgw9gw776H8h9ov9c5TxPaldTn2j6orPECAERViLf7LTO4L5pE2Cw==" }, "node_modules/@ledgerhq/hw-transport-web-ble/node_modules/@ledgerhq/hw-transport": { - "version": "6.30.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.30.0.tgz", - "integrity": "sha512-wrAwn/wCAaGP2Yuy78cLyqmQNzbuDvUv4gJYF/UO4djvUz0jjvD2w5kxRWxF/W93vyKT+/RplRtFk3CJzD3e3A==", + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.30.1.tgz", + "integrity": "sha512-Xeeo4nt33g5Fsp3CdsPvcc2Uk7dwYeKRSlSFLWcYAAKprf/PmxgNekhke1eaNU/wLoeLOWhY2Cki8F8w9nLMdQ==", "dependencies": { - "@ledgerhq/devices": "^8.1.0", - "@ledgerhq/errors": "^6.16.0", + "@ledgerhq/devices": "^8.2.0", + "@ledgerhq/errors": "^6.16.1", "@ledgerhq/logs": "^6.12.0", "events": "^3.3.0" } @@ -4823,9 +4825,9 @@ } }, "node_modules/@multiversx/sdk-core": { - "version": "12.15.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-12.15.0.tgz", - "integrity": "sha512-PdjKxGeYBCDksKhsy/JSeH6dLUdK9RtLPbfk5nvO1+2fXJj9fmaGaM1347U8hqE30CVEYS/jl6alzuKbBS8TZg==", + "version": "12.16.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-12.16.0.tgz", + "integrity": "sha512-b2htlSeXVkZwrnEVAxoUgNe0oiiOheEjibEbxwNXqtWnsSI31fAtVXxXMersVgcliMJGjmtHkpFAItAucG3OSg==", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", "bech32": "1.1.4", @@ -4846,9 +4848,9 @@ } }, "node_modules/@multiversx/sdk-dapp": { - "version": "2.24.3", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-dapp/-/sdk-dapp-2.24.3.tgz", - "integrity": "sha512-2+JIXP2DSXwNBKaO0IaneQjyOQEL06o9KYAXCPhUP7vlq+/dweWPKVXXmiPzNABe46RGSAT3V3HeZclSsGvpYQ==", + "version": "2.24.4", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-dapp/-/sdk-dapp-2.24.4.tgz", + "integrity": "sha512-OUCpTe85RtIOl8SJIP5VNhJlFPsicXGS4D9OrkpxVyW35XRLj8M5zUaVFnZ1TE85NaDIZ4VtPSE14p+eJPj2/w==", "dependencies": { "@multiversx/sdk-core": "12.6.0", "@multiversx/sdk-extension-provider": "3.0.0", @@ -4911,6 +4913,14 @@ "protobufjs": "7.2.4" } }, + "node_modules/@multiversx/sdk-dapp/node_modules/@multiversx/sdk-native-auth-client": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-client/-/sdk-native-auth-client-1.0.5.tgz", + "integrity": "sha512-MA9KCNy2K0Irw+RMn01mxXB3Z+EcpMuUFBqr6ZhVQyxmXjujK+CHvlXH5TSADIm5Yw2SfGjFGdiqRu64lNVvuA==", + "dependencies": { + "axios": "0.24.0" + } + }, "node_modules/@multiversx/sdk-dapp/node_modules/@multiversx/sdk-network-providers": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-1.5.0.tgz", @@ -4966,33 +4976,33 @@ } }, "node_modules/@multiversx/sdk-native-auth-client": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-client/-/sdk-native-auth-client-1.0.5.tgz", - "integrity": "sha512-MA9KCNy2K0Irw+RMn01mxXB3Z+EcpMuUFBqr6ZhVQyxmXjujK+CHvlXH5TSADIm5Yw2SfGjFGdiqRu64lNVvuA==", - "dependencies": { - "axios": "0.24.0" - } - }, - "node_modules/@multiversx/sdk-native-auth-client/node_modules/axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-client/-/sdk-native-auth-client-1.0.6.tgz", + "integrity": "sha512-IGJZnanNYGv0CTA02qh402EJ5UbQ73J5tOjRenz2yQBNrqenJCfBJsEX5JJc5Quk/ppuZhl3GppQIBqsrGOidg==", "dependencies": { - "follow-redirects": "^1.14.4" + "axios": "^1.6.2" } }, "node_modules/@multiversx/sdk-network-providers": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.2.0.tgz", - "integrity": "sha512-2n/+7Ap6S9rJGTiX38GCZ2TmY9zQ1U7o1DwnWpHNRJRxArSN/xzLrbcSKy8InMyc+4A+VHf5pV0Pk8NdPV6++w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.1.0.tgz", + "integrity": "sha512-BiU2R9nu7OKKZckxZ7jjjUbFIyHM9Z6Qera224s9xIel+FjYDDkNCm1qtnvZ5Pc7ftQggFUZ7W/WnEgFhqEZGA==", "dependencies": { - "axios": "1.6.1", + "axios": "0.24.0", "bech32": "1.1.4", "bignumber.js": "9.0.1", "buffer": "6.0.3", "json-bigint": "1.0.0" } }, + "node_modules/@multiversx/sdk-network-providers/node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, "node_modules/@multiversx/sdk-network-providers/node_modules/bignumber.js": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", @@ -6511,9 +6521,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.44.8", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz", - "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==", + "version": "8.44.9", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.9.tgz", + "integrity": "sha512-6yBxcvwnnYoYT1Uk2d+jvIfsuP4mb2EdIxFnrPABj5a/838qe5bGkNLFOiipX4ULQ7XVQvTxOh7jO+BTAiqsEw==", "dev": true, "dependencies": { "@types/estree": "*", @@ -8286,9 +8296,9 @@ } }, "node_modules/axios": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz", - "integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -8418,13 +8428,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", - "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz", + "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.3", + "@babel/helper-define-polyfill-provider": "^0.4.4", "semver": "^6.3.1" }, "peerDependencies": { @@ -8441,12 +8451,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", - "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz", + "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3", + "@babel/helper-define-polyfill-provider": "^0.4.4", "core-js-compat": "^3.33.1" }, "peerDependencies": { @@ -8454,12 +8464,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", - "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz", + "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3" + "@babel/helper-define-polyfill-provider": "^0.4.4" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -9031,9 +9041,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001565", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", - "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", "devOptional": true, "funding": [ { @@ -9372,9 +9382,9 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/color2k": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.2.tgz", - "integrity": "sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz", + "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==" }, "node_modules/colord": { "version": "2.9.3", @@ -9568,9 +9578,9 @@ } }, "node_modules/core-js": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz", - "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==", + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.34.0.tgz", + "integrity": "sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==", "dev": true, "hasInstallScript": true, "funding": { @@ -9579,12 +9589,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.3.tgz", - "integrity": "sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==", + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.34.0.tgz", + "integrity": "sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==", "dev": true, "dependencies": { - "browserslist": "^4.22.1" + "browserslist": "^4.22.2" }, "funding": { "type": "opencollective", @@ -9592,9 +9602,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.3.tgz", - "integrity": "sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ==", + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.34.0.tgz", + "integrity": "sha512-pmhivkYXkymswFfbXsANmBAewXx86UBfmagP+w0wkK06kLsLlTK5oQmsURPivzMkIBQiYq2cjamcZExIwlFQIg==", "dev": true, "hasInstallScript": true, "funding": { @@ -9947,9 +9957,9 @@ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" }, "node_modules/cssdb": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.9.0.tgz", - "integrity": "sha512-WPMT9seTQq6fPAa1yN4zjgZZeoTriSN2LqW9C+otjar12DQIWA4LuSfFrvFJiKp4oD0xIk1vumDLw8K9ur4NBw==", + "version": "7.9.1", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.9.1.tgz", + "integrity": "sha512-fqy6ZnNfpb8qAvTT0qijWyTsUmYThsDX2F2ctMG4ceI7mI4DtsMILSiMBiuuDnVIYTyWvCctdp9Nb08p/6m2SQ==", "dev": true, "funding": [ { @@ -10115,9 +10125,9 @@ "devOptional": true }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -10873,9 +10883,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.601", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.601.tgz", - "integrity": "sha512-SpwUMDWe9tQu8JX5QCO1+p/hChAi9AE9UpoC3rcHVc+gdCGlbT3SGb5I1klgb952HRIyvt9wZhSz9bNBYz9swA==", + "version": "1.4.612", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.612.tgz", + "integrity": "sha512-dM8BMtXtlH237ecSMnYdYuCkib2QHq0kpWfUnavjdYsyr/6OsAwg5ZGUfnQ9KD1Ga4QgB2sqXlB2NT8zy2GnVg==", "devOptional": true }, "node_modules/emittery": { @@ -11805,15 +11815,15 @@ } }, "node_modules/eslint-plugin-n": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.3.1.tgz", - "integrity": "sha512-w46eDIkxQ2FaTHcey7G40eD+FhTXOdKudDXPUO2n9WNcslze/i/HT2qJ3GXjHngYSGDISIgPNhwGtgoix4zeOw==", + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.4.0.tgz", + "integrity": "sha512-IkqJjGoWYGskVaJA7WQuN8PINIxc0N/Pk/jLeYT4ees6Fo5lAhpwGsYek6gS9tCUxgDC4zJ+OwY2bY/6/9OMKQ==", "dev": true, "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.1.0", + "eslint-plugin-es-x": "^7.5.0", "get-tsconfig": "^4.7.0", "ignore": "^5.2.4", "is-builtin-module": "^3.2.1", @@ -13242,9 +13252,9 @@ } }, "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -13621,9 +13631,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", - "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.4.tgz", + "integrity": "sha512-3wNSaVVxdxcu0jd4FpQFoICdqgxs4zIQQvj+2yQKFfBOnLETQ6X5CDWdeasuGlSsooFlMkEioWDTqBv1wvw5Iw==", "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -22128,9 +22138,9 @@ "dev": true }, "node_modules/tailwindcss": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz", - "integrity": "sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.6.tgz", + "integrity": "sha512-AKjF7qbbLvLaPieoKeTjG1+FyNZT6KaJMJPFeQyLfIp7l82ggH1fbHJSsYIvnbTFQOlkh+gBYpyby5GT1LIdLw==", "dev": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -22229,9 +22239,9 @@ } }, "node_modules/terser": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.24.0.tgz", - "integrity": "sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==", + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -23452,9 +23462,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", + "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -23586,9 +23596,9 @@ } }, "node_modules/whatwg-fetch": { - "version": "3.6.19", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz", - "integrity": "sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==", + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", "dev": true }, "node_modules/whatwg-mimetype": { diff --git a/package.json b/package.json index baf38bd7..8fa1c704 100644 --- a/package.json +++ b/package.json @@ -10,17 +10,17 @@ "@hookform/resolvers": "3.3.2", "@itheum/sdk-mx-data-nft": "2.4.0", "@itheum/sdk-mx-enterprise": "0.0.7", - "@multiversx/sdk-core": "12.15.0", - "@multiversx/sdk-dapp": "2.24.3", - "@multiversx/sdk-native-auth-client": "1.0.5", - "@multiversx/sdk-network-providers": "2.2.0", + "@multiversx/sdk-core": "12.16.0", + "@multiversx/sdk-dapp": "2.24.4", + "@multiversx/sdk-native-auth-client": "1.0.6", + "@multiversx/sdk-network-providers": "2.1.0", "@sentry/react": "7.80.0", "@tanstack/match-sorter-utils": "8.8.4", "@tanstack/react-table": "8.10.7", "@testing-library/jest-dom": "6.1.4", "@testing-library/react": "14.1.0", "@testing-library/user-event": "14.5.1", - "axios": "1.6.1", + "axios": "1.6.2", "dotenv": "16.3.1", "framer-motion": "10.16.4", "mime": "3.0.0", diff --git a/src/components/Faucet/Faucet.tsx b/src/components/Faucet/Faucet.tsx new file mode 100644 index 00000000..c5616aac --- /dev/null +++ b/src/components/Faucet/Faucet.tsx @@ -0,0 +1,107 @@ +import React, { useEffect, useState } from "react"; +import { WarningTwoIcon } from "@chakra-ui/icons"; +import { + Alert, + AlertDescription, + AlertIcon, + AlertTitle, + Badge, + Box, + Button, + Flex, + Heading, + HStack, + SimpleGrid, + Spacer, + Spinner, + Stack, + Text, + Tooltip, + useBreakpointValue, + useColorMode, + useDisclosure, + useToast, +} from "@chakra-ui/react"; +import { useGetNetworkConfig } from "@multiversx/sdk-dapp/hooks"; +import { useGetAccountInfo, useGetLoginInfo } from "@multiversx/sdk-dapp/hooks/account"; +import { useGetPendingTransactions } from "@multiversx/sdk-dapp/hooks/transactions"; +import moment from "moment"; +import { useNavigate } from "react-router-dom"; +import myNFMe from "assets/img/my-nfme.png"; +import ClaimModalMx from "components/ClaimModal/ClaimModalMultiversX"; +import ExplainerArticles from "components/Sections/ExplainerArticles"; +import RecentDataNFTs from "components/Sections/RecentDataNFTs"; +import ChainSupportedComponent from "components/UtilComps/ChainSupportedComponent"; +import { CHAIN_TOKEN_SYMBOL, CLAIM_TYPES, MENU, uxConfig } from "libs/config"; +import { ClaimsContract } from "libs/MultiversX/claims"; +import { FaucetContract } from "libs/MultiversX/faucet"; +import { formatNumberToShort } from "libs/utils"; +import AppMarketplace from "pages/Home/AppMarketplace"; + +const Faucet = ({ tileBoxW, tileBoxH }: any) => { + const { chainID } = useGetNetworkConfig(); + const { colorMode } = useColorMode(); + const { address: mxAddress } = useGetAccountInfo(); + const [isMxFaucetDisabled, setIsMxFaucetDisabled] = useState(false); + const { hasPendingTransactions } = useGetPendingTransactions(); + + useEffect(() => { + // hasPendingTransactions will fire with false during init and then move from true to false each time a TX is done... + // ... so if it's 'false' we need check and prevent faucet from being used too often + if (chainID === "D" && mxAddress && mxFaucetContract && !hasPendingTransactions) { + mxFaucetContract.getFaucetTime(mxAddress).then((lastUsedTime) => { + const timeNow = new Date().getTime(); + + if (lastUsedTime + 120000 > timeNow) { + setIsMxFaucetDisabled(true); + + // after 2 min wait we reenable the button on the UI automatically + setTimeout( + () => { + setIsMxFaucetDisabled(false); + }, + lastUsedTime + 120 * 60 * 1000 + 1000 - timeNow + ); + } else { + setIsMxFaucetDisabled(false); + } + }); + } + }, [mxAddress, hasPendingTransactions]); + + useEffect(() => { + if (hasPendingTransactions) { + setIsMxFaucetDisabled(true); + } + }, [hasPendingTransactions]); + + const mxFaucetContract = new FaucetContract(chainID); + const handleOnChainFaucet = async () => { + if (mxAddress) { + mxFaucetContract.sendActivateFaucetTransaction(mxAddress); + } + }; + + return ( + + + + {CHAIN_TOKEN_SYMBOL(chainID)} Faucet + + + + Get some free {CHAIN_TOKEN_SYMBOL(chainID)} tokens to try DEX features + + + + + + + + + ); +}; + +export default Faucet; diff --git a/src/pages/Home/HomeMultiversX.tsx b/src/pages/Home/HomeMultiversX.tsx index 905bfb98..ede60f5c 100644 --- a/src/pages/Home/HomeMultiversX.tsx +++ b/src/pages/Home/HomeMultiversX.tsx @@ -35,8 +35,9 @@ import ChainSupportedComponent from "components/UtilComps/ChainSupportedComponen import { CHAIN_TOKEN_SYMBOL, CLAIM_TYPES, MENU, uxConfig } from "libs/config"; import { ClaimsContract } from "libs/MultiversX/claims"; import { FaucetContract } from "libs/MultiversX/faucet"; -import { formatNumberRoundFloor, formatNumberToShort } from "libs/utils"; +import { formatNumberToShort } from "libs/utils"; import AppMarketplace from "pages/Home/AppMarketplace"; +import Faucet from "components/Faucet/Faucet"; export default function HomeMultiversX({ setMenuItem, @@ -57,7 +58,6 @@ export default function HomeMultiversX({ const { isLoggedIn: isMxLoggedIn } = useGetLoginInfo(); const [isOnChainInteractionDisabled, setIsOnChainInteractionDisabled] = useState(false); - const [isMxFaucetDisabled, setIsMxFaucetDisabled] = useState(false); const [claimsBalances, setClaimsBalances] = useState({ claimBalanceValues: ["-1", "-1", "-1", "-1"], // -1 is loading, -2 is error claimBalanceDates: [0, 0, 0, 0], @@ -65,41 +65,8 @@ export default function HomeMultiversX({ const [claimContractPauseValue, setClaimContractPauseValue] = useState(false); const navigate = useNavigate(); - const mxFaucetContract = new FaucetContract(chainID); const mxClaimsContract = new ClaimsContract(chainID); - // S: Faucet - useEffect(() => { - // hasPendingTransactions will fire with false during init and then move from true to false each time a TX is done... - // ... so if it's 'false' we need check and prevent faucet from being used too often - if (chainID === "D" && mxAddress && mxFaucetContract && !hasPendingTransactions) { - mxFaucetContract.getFaucetTime(mxAddress).then((lastUsedTime) => { - const timeNow = new Date().getTime(); - - if (lastUsedTime + 120000 > timeNow) { - setIsMxFaucetDisabled(true); - - // after 2 min wait we reenable the button on the UI automatically - setTimeout( - () => { - setIsMxFaucetDisabled(false); - }, - lastUsedTime + 120 * 60 * 1000 + 1000 - timeNow - ); - } else { - setIsMxFaucetDisabled(false); - } - }); - } - }, [mxAddress, hasPendingTransactions]); - - const handleOnChainFaucet = async () => { - if (mxAddress) { - mxFaucetContract.sendActivateFaucetTransaction(mxAddress); - } - }; - // E: Faucet - // S: Claims useEffect(() => { // this will trigger during component load/page load, so let's get the latest claims balances @@ -162,12 +129,8 @@ export default function HomeMultiversX({ if (hasPendingTransactions) { // block user trying to do other claims or on-chain tx until current one completes setIsOnChainInteractionDisabled(true); - - // user just triggered a faucet tx, so we prevent them from clicking ui again until tx is complete - setIsMxFaucetDisabled(true); } else { // mxClaimsBalancesUpdate(); // get latest claims balances from on-chain as well - setIsOnChainInteractionDisabled(false); // unlock, and let them do other on-chain tx work } }, [hasPendingTransactions]); @@ -248,7 +211,7 @@ export default function HomeMultiversX({ }; // E: claims related logic - const tileBoxMdW = "310px"; + const tileBoxW = "310px"; const tileBoxH = "360px"; const claimsStackMinW = "220px"; const heroGridMargin = useBreakpointValue({ base: "auto", md: "initial" }); @@ -259,7 +222,7 @@ export default function HomeMultiversX({ - + {!dataCATAccount && ( @@ -333,28 +296,10 @@ export default function HomeMultiversX({ - - - - {CHAIN_TOKEN_SYMBOL(chainID)} Faucet - - - - Get some free {CHAIN_TOKEN_SYMBOL(chainID)} tokens to try DEX features - - - - {/**/} - - - - - + - + NFMe ID Avatar @@ -372,7 +317,7 @@ export default function HomeMultiversX({ - + My Claims From 1f52d75c77de15dae4e2539746071102139132ac Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 21 Dec 2023 15:56:42 +0200 Subject: [PATCH 07/46] v bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index afaab398..ddb1a440 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "data-dex", - "version": "1.9.1", + "version": "1.10.0", "description": "The Itheum Data DEX enables you to trade your data using web3 tech", "dependencies": { "@chakra-ui/icons": "2.1.1", From 693faadb2f52b8cba5ae633730f3d944bf3cf65f Mon Sep 17 00:00:00 2001 From: Bucur David Date: Tue, 9 Jan 2024 15:45:23 +0200 Subject: [PATCH 08/46] feat: new methods to add/remove/get favorites and trending Data NFTs Refs: #969 Signed-off-by: Bucur David --- src/libs/MultiversX/backend-api.ts | 66 +++++++++++++++++++++++++++++- src/libs/MultiversX/types.ts | 13 ++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/libs/MultiversX/backend-api.ts b/src/libs/MultiversX/backend-api.ts index b6975f3a..520e36b0 100644 --- a/src/libs/MultiversX/backend-api.ts +++ b/src/libs/MultiversX/backend-api.ts @@ -2,7 +2,7 @@ import { MarketplaceRequirements } from "@itheum/sdk-mx-data-nft/out"; import axios from "axios"; import { backendApi } from "libs/utils"; import { uxConfig } from "."; -import { OfferType } from "./types"; +import { Favorite, OfferType, TrendingNft } from "./types"; export async function getHealthCheckFromBackendApi(chainID: string): Promise { try { @@ -18,6 +18,70 @@ export async function getHealthCheckFromBackendApi(chainID: string): Promise { + try { + const url = `${backendApi(chainId)}/favorites`; + const { data } = await axios.get(url, { + timeout: uxConfig.mxAPITimeoutMs, + }); + return data; + } catch (error) { + console.error(error); + return []; + } +} + +export async function addFavoriteToBackendApi(chainID: string, tokenIdentifier: string): Promise { + try { + const url = `${backendApi(chainID)}/addFavorite`; + const { data } = await axios.post( + url, + { + identifier: tokenIdentifier, + }, + { + timeout: uxConfig.mxAPITimeoutMs, + } + ); + return data; + } catch (error) { + console.error(error); + return {} as Favorite; + } +} + +export async function removeFavoriteFromBackendApi(chainID: string, id: string): Promise { + try { + const url = `${backendApi(chainID)}/removeFavorite`; + const { data } = await axios.post( + url, + { + id: id, + }, + { + timeout: uxConfig.mxAPITimeoutMs, + } + ); + return data; + } catch (error) { + console.error(error); + return {} as Favorite; + } +} + +export async function getTrendingFromBackendApi(chainID: string): Promise { + try { + const url = `${backendApi(chainID)}/trending`; + const { data } = await axios.get(url, { + timeout: uxConfig.mxAPITimeoutMs, + }); + return data; + } catch (error) { + console.error(error); + return []; + } +} + export async function getMarketplaceHealthCheckFromBackendApi(chainID: string): Promise { try { const url = `${backendApi(chainID)}/health-check?marketplace=1`; diff --git a/src/libs/MultiversX/types.ts b/src/libs/MultiversX/types.ts index 78d01898..3e2cf2ad 100644 --- a/src/libs/MultiversX/types.ts +++ b/src/libs/MultiversX/types.ts @@ -60,6 +60,19 @@ export interface OfferType { quantity: number; } +export interface Favorite { + id: string; + address: string; + tokenIdentifier: string; + timestamp: number; +} + +export interface TrendingNft { + uuid: string; + tokenIdentifier: string; + rating: number; +} + export interface DataNftType { index: number; id: string; From 2d5d179a3a48c514d317f0c97cb03e4a5cf1aa60 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Tue, 9 Jan 2024 15:49:27 +0200 Subject: [PATCH 09/46] fix: add bearer token for methods that require native auth Signed-off-by: Bucur David --- src/libs/MultiversX/backend-api.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libs/MultiversX/backend-api.ts b/src/libs/MultiversX/backend-api.ts index 520e36b0..c5e92eae 100644 --- a/src/libs/MultiversX/backend-api.ts +++ b/src/libs/MultiversX/backend-api.ts @@ -18,11 +18,14 @@ export async function getHealthCheckFromBackendApi(chainID: string): Promise { +export async function getFavoritesFromBackendApi(chainId: string, bearerToken: string): Promise { try { const url = `${backendApi(chainId)}/favorites`; const { data } = await axios.get(url, { timeout: uxConfig.mxAPITimeoutMs, + headers: { + Authorization: `Bearer ${bearerToken}`, + }, }); return data; } catch (error) { @@ -31,7 +34,7 @@ export async function getFavoritesFromBackendApi(chainId: string): Promise { +export async function addFavoriteToBackendApi(chainID: string, tokenIdentifier: string, bearerToken: string): Promise { try { const url = `${backendApi(chainID)}/addFavorite`; const { data } = await axios.post( @@ -41,6 +44,9 @@ export async function addFavoriteToBackendApi(chainID: string, tokenIdentifier: }, { timeout: uxConfig.mxAPITimeoutMs, + headers: { + Authorization: `Bearer ${bearerToken}`, + }, } ); return data; @@ -50,7 +56,7 @@ export async function addFavoriteToBackendApi(chainID: string, tokenIdentifier: } } -export async function removeFavoriteFromBackendApi(chainID: string, id: string): Promise { +export async function removeFavoriteFromBackendApi(chainID: string, id: string, bearerToken: string): Promise { try { const url = `${backendApi(chainID)}/removeFavorite`; const { data } = await axios.post( @@ -60,6 +66,9 @@ export async function removeFavoriteFromBackendApi(chainID: string, id: string): }, { timeout: uxConfig.mxAPITimeoutMs, + headers: { + Authorization: `Bearer ${bearerToken}`, + }, } ); return data; From 6e53986d2cc944f12901987cdb621f94d6c7ddf1 Mon Sep 17 00:00:00 2001 From: Enciusan Date: Tue, 9 Jan 2024 18:06:59 +0200 Subject: [PATCH 10/46] fixed #1157 --- package-lock.json | 4 ++-- src/components/Tables/Components/DataTable.tsx | 2 +- src/pages/DataNFT/DataNFTDetails.tsx | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 07bd61e9..ae9efa1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "data-dex", - "version": "1.9.0", + "version": "1.10.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-dex", - "version": "1.9.0", + "version": "1.10.0", "dependencies": { "@chakra-ui/icons": "2.1.1", "@chakra-ui/react": "2.8.2", diff --git a/src/components/Tables/Components/DataTable.tsx b/src/components/Tables/Components/DataTable.tsx index ae0972c9..5cf6aa80 100644 --- a/src/components/Tables/Components/DataTable.tsx +++ b/src/components/Tables/Components/DataTable.tsx @@ -102,7 +102,7 @@ export function DataTable({ data, columns }: DataTableProps -
+
{table.getHeaderGroups().map((headerGroup) => ( diff --git a/src/pages/DataNFT/DataNFTDetails.tsx b/src/pages/DataNFT/DataNFTDetails.tsx index a7053f4d..f78b0c05 100644 --- a/src/pages/DataNFT/DataNFTDetails.tsx +++ b/src/pages/DataNFT/DataNFTDetails.tsx @@ -681,9 +681,9 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { Data NFT Activity - + - + {nftData && offer && ( From fae10ba4fd5517c8f57604eb6ce4ae4a39e36e24 Mon Sep 17 00:00:00 2001 From: Enciusan Date: Wed, 10 Jan 2024 18:10:28 +0200 Subject: [PATCH 11/46] lib delete --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index ddb1a440..8875a752 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "bignumber.js": "9.1.2", "dotenv": "16.3.1", "framer-motion": "10.16.16", - "mime": "4.0.0", "moment": "2.29.4", "nft.storage": "7.1.1", "react": "18.2.0", From a4402e6187fd764c0122450c6eb7d79344abd2eb Mon Sep 17 00:00:00 2001 From: Benedek Robert George Date: Wed, 10 Jan 2024 18:54:08 +0200 Subject: [PATCH 12/46] feat: Group by collection - marketplace feature --- package-lock.json | 4 +- src/components/CustomPagination.tsx | 2 +- .../UtilComps/UpperCardComponent.tsx | 13 +- .../DataNFT/DataNFTMarketplaceMultiversX.tsx | 142 ++++++++---------- src/pages/DataNFT/DataNftCollection.tsx | 92 +++++++----- 5 files changed, 125 insertions(+), 128 deletions(-) diff --git a/package-lock.json b/package-lock.json index 07bd61e9..ae9efa1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "data-dex", - "version": "1.9.0", + "version": "1.10.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-dex", - "version": "1.9.0", + "version": "1.10.0", "dependencies": { "@chakra-ui/icons": "2.1.1", "@chakra-ui/react": "2.8.2", diff --git a/src/components/CustomPagination.tsx b/src/components/CustomPagination.tsx index 946b97b9..ccbefbf7 100644 --- a/src/components/CustomPagination.tsx +++ b/src/components/CustomPagination.tsx @@ -25,7 +25,7 @@ export const CustomPagination: FC = ({ pageCount, pageIndex, gotoPage }; return ( - + void; }; @@ -56,7 +55,6 @@ const UpperCardComponent: FC = ({ offer, marketFreezedNonces, openNftDetailsDrawer, - grouped, }) => { const { colorMode } = useColorMode(); @@ -83,15 +81,14 @@ const UpperCardComponent: FC = ({ - + mb="1.5rem"> + = ({ currentTarget.src = DEFAULT_NFT_IMAGE; }} /> - {grouped && ( + {/* {grouped && ( <> = ({ }} /> - )} + )} */} = ({ tabState }) => { const [nonceOfferMap, setNonceOfferMap] = useState>(new Map()); // a dictionary-> nonce => dataNft (lowest price) const [groupedMetadatas, setGroupedMetadatas] = useState([]); + const [currentPageGroupedOffers, setCurrentPageGroupedOffers] = useState([]); const hasWebWalletTx = sessionStorage.getItem("web-wallet-tx"); @@ -114,30 +115,22 @@ export const Marketplace: FC = ({ tabState }) => { }); const groupDataNfts = () => { - console.log(showGroupedDataNfts); if (!showGroupedDataNfts) { (async () => { - console.log("FETCH"); if (hasPendingTransactions) return; if (!chainID) return; // start loading offers updateLoadingOffers(true); - //const theCollections: any = await getCollectionNfts("DATANFTFT4-3ba099", _chainMeta.networkId); - //console.log("COLLECTIONS ", theCollections); - //console.log(theCollections[0]); + ///TODO CHECK IF COLLECTIONS AND MAP IS THE SAME let _offers: OfferType[] = []; const start = 0; if (isApiUp && isMarketplaceApiUp) { - // console.log('Api Up'); _offers = await getOffersFromBackendApi(chainID, start, publicMarketCount, undefined); } else { return; - // console.log('Api Down'); - //_offers = await marketContract.viewPagedOffers(start, start + pageSize - 1, tabState === 1 ? "" : address); } - console.log(_offers.length); /// populate the map with the best choice(price-wise) from each nonce const _nonceOfferMap = new Map(); _offers.forEach((offer) => { @@ -145,40 +138,35 @@ export const Marketplace: FC = ({ tabState }) => { const previousOffer = _nonceOfferMap.get(offer.offered_token_nonce); if (previousOffer?.wanted_token_amount && parseFloat(offer.wanted_token_amount) < parseFloat(previousOffer?.wanted_token_amount)) { - // console.log("CHANGED"); - // console.log(parseFloat(offer.wanted_token_amount)); - // console.log(previousOffer.wanted_token_amount); if (offer.wanted_token_amount) _nonceOfferMap.set(offer.offered_token_nonce, offer); } } else { _nonceOfferMap.set(offer.offered_token_nonce, offer); } }); - if (_nonceOfferMap !== undefined) { - Array.from(_nonceOfferMap.entries()) - .slice(0, 20) - .map(([nonce, offer]) => { - console.log(nonce, offer); - }); - } + // if (_nonceOfferMap !== undefined) { + // Array.from(_nonceOfferMap.entries()) + // .slice(0, 20) + // .map(([nonce, offer]) => { + // console.log(nonce, offer); + // }); + // } setNonceOfferMap(_nonceOfferMap); - //make pagination + + //TODO make pagination + ///get nftMetadatas for the grouped offers setNftMetadatasLoading(true); - const nftIds = Array.from(_nonceOfferMap.entries()) - .slice(0, 20) - .map(([nonce, offer]) => createNftId(offer.offered_token_identifier, offer.offered_token_nonce)); + const nftIds = Array.from(_nonceOfferMap.entries()).map(([nonce, offer]) => createNftId(offer.offered_token_identifier, offer.offered_token_nonce)); const _nfts = await getNftsByIds(nftIds, chainID); const _metadatas: DataNftMetadataType[] = []; for (let i = 0; i < _nfts.length; i++) { _metadatas.push(mintContract.decodeNftAttributes(_nfts[i], i)); } - console.log("META GROUP", _metadatas); setGroupedMetadatas(_metadatas); - setCurrentPageGroupedOffers(Array.from(_nonceOfferMap.values()).slice(0, 20)); + setCurrentPageGroupedOffers(Array.from(_nonceOfferMap.values())); setNftMetadatasLoading(false); - ///console.log("KEYS ", nonceOfferMap.keys()); updateLoadingOffers(false); })(); @@ -304,10 +292,10 @@ export const Marketplace: FC = ({ tabState }) => { matches[1] == "acceptOffer" ? "Purchase transaction failed" : matches[1] == "cancelOffer" - ? "De-List transaction failed" - : matches[1] == "changeOfferPrice" - ? "Update price transaction failed" - : "Transaction failed"; + ? "De-List transaction failed" + : matches[1] == "changeOfferPrice" + ? "Update price transaction failed" + : "Transaction failed"; const description = matches[matches.length - 1]; toast({ @@ -382,6 +370,7 @@ export const Marketplace: FC = ({ tabState }) => { fontSize={{ base: "sm", md: "md" }} onClick={() => { if (hasPendingTransactions) return; + setShowGroupedDataNfts(false); navigate("/datanfts/marketplace/my"); }}> {isMxLoggedIn && ( @@ -412,18 +401,19 @@ export const Marketplace: FC = ({ tabState }) => { {/* */} - - - {" "} - - - Group by collection - - - - - - + {!window.location.href.includes("my") && ( + + + + Group by collection + + + + + )} + {!showGroupedDataNfts && ( + + )} @@ -432,7 +422,13 @@ export const Marketplace: FC = ({ tabState }) => { {!loadingOffers && !nftMetadatasLoading && offers.length === 0 ? ( ) : ( - + {!showGroupedDataNfts ? offers.map((offer, index) => ( = ({ tabState }) => { offer={offer} index={index} marketFreezedNonces={marketFreezedNonces} - openNftDetailsDrawer={openNftDetailsModal} - grouped={showGroupedDataNfts}> + openNftDetailsDrawer={openNftDetailsModal}> )) - : Array.from(nonceOfferMap.entries()) - .slice(0, 24) - .map(([nonce, offer], index) => { - console.log(index, offer, groupedMetadatas[index]); - - return ( - - ); - })} + : Array.from(nonceOfferMap.entries()).map(([nonce, offer], index) => { + return ( + + ); + })} )} - {/* imageUrl={`https://${getApi(networkId)}/nfts/${offer?.offered_token_identifier}-${hexZero( - offer?.offered_token_nonce - )}/thumbnail`} - setNftImageLoaded={setOneNFTImgLoaded} - nftMetadata={groupedMetadatas[index]} - offer={offer} - index={index} - marketFreezedNonces={marketFreezedNonces} - openNftDetailsDrawer={openNftDetailsModal} - grouped={showGroupedDataNfts}> - - */} {!loadingOffers && !nftMetadatasLoading && offers.length === 0 ? ( @@ -506,7 +487,6 @@ export const Marketplace: FC = ({ tabState }) => { offer={offer} index={index} marketFreezedNonces={marketFreezedNonces} - grouped={false} openNftDetailsDrawer={openNftDetailsModal}> @@ -518,7 +498,7 @@ export const Marketplace: FC = ({ tabState }) => { { /* show bottom pagination only if offers exist */ - offers.length > 0 && ( + offers.length > 0 && !showGroupedDataNfts && ( diff --git a/src/pages/DataNFT/DataNftCollection.tsx b/src/pages/DataNFT/DataNftCollection.tsx index 07a6f71d..10c007fd 100644 --- a/src/pages/DataNFT/DataNftCollection.tsx +++ b/src/pages/DataNFT/DataNftCollection.tsx @@ -1,56 +1,63 @@ import React, { FC } from "react"; -import { Stack, Text, Box, HStack, VStack, Button, Image, Skeleton } from "@chakra-ui/react"; +import { Stack, Text, HStack, VStack, Button, Image, Skeleton, Tooltip } from "@chakra-ui/react"; import { DEFAULT_NFT_IMAGE } from "libs/mxConstants"; +import { useMarketStore } from "store"; +import { convertToLocalString, shouldPreviewDataBeEnabled, viewDataDisabledMessage } from "libs/utils"; +import { useLocalStorage } from "libs/hooks"; +import { PREVIEW_DATA_ON_DEVNET_SESSION_KEY } from "libs/config"; +import { useGetLoginInfo, useGetNetworkConfig } from "@multiversx/sdk-dapp/hooks"; type DataNftCollectionComponentProps = { + index: number; nftImageLoading: boolean; - //setNftImageLoaded: Dispatch>; imageUrl: string; - //nftMetadata: DataNftMetadataType; title: string; description: string; listed: number; supply: number; floorPrice: number; - //offer: OfferType; - //index: number; - //marketFreezedNonces: number[]; - //grouped: boolean; children?: React.ReactNode; openNftDetailsDrawer?: (e: number) => void; + dataPreview?: string; }; + export const DataNftCollection: FC = ({ + index, nftImageLoading, - //setNftImageLoaded, imageUrl, title, description, listed, supply, - floorPrice, - //nftMetadata, - //index, - //children, - //offer, - //marketFreezedNonces, openNftDetailsDrawer, - //grouped, + dataPreview, }) => { + const itheumPrice = useMarketStore((state) => state.itheumPrice); + const [previewDataOnDevnetSession] = useLocalStorage(PREVIEW_DATA_ON_DEVNET_SESSION_KEY, null); + const { chainID } = useGetNetworkConfig(); + const { loginMethod } = useGetLoginInfo(); return ( - + + width={"600px"} + height={"450px"} + padding={"32px"}> {title} @@ -70,7 +77,7 @@ export const DataNftCollection: FC = ({ - Floor price: {floorPrice} + Floor price: {floorPrice} ITHEUM {floorPrice && itheumPrice ? `(~${convertToLocalString(floorPrice * itheumPrice, 2)} USD)` : ""} @@ -78,25 +85,38 @@ export const DataNftCollection: FC = ({ - + + + Date: Thu, 11 Jan 2024 09:55:27 +0200 Subject: [PATCH 13/46] refactor accessdatastreammodal --- .../WalletDataNFTMX/AccessDatastreamModal.tsx | 59 ++ .../WalletDataNFTMX/WalletDataNFTMX.tsx | 837 ++++++++++++++++++ src/pages/DataNFT/MyDataNFTsMultiversX.tsx | 2 +- 3 files changed, 897 insertions(+), 1 deletion(-) create mode 100644 src/components/WalletDataNFTMX/AccessDatastreamModal.tsx create mode 100644 src/components/WalletDataNFTMX/WalletDataNFTMX.tsx diff --git a/src/components/WalletDataNFTMX/AccessDatastreamModal.tsx b/src/components/WalletDataNFTMX/AccessDatastreamModal.tsx new file mode 100644 index 00000000..8f4745ef --- /dev/null +++ b/src/components/WalletDataNFTMX/AccessDatastreamModal.tsx @@ -0,0 +1,59 @@ +import React from "react"; +import { Alert, AlertTitle, AlertIcon, AlertDescription } from "@chakra-ui/alert"; +import { Button } from "@chakra-ui/button"; +import { CloseButton } from "@chakra-ui/close-button"; +import { CheckCircleIcon } from "@chakra-ui/icons"; +import { Stack, HStack, Text } from "@chakra-ui/layout"; +import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody } from "@chakra-ui/modal"; +import { Spinner } from "@chakra-ui/spinner"; + +type DatastreamModalPropType = { + isOpen: boolean; + onClose: () => void; + unlockAccessProgress: { s1: number; s2: number; s3: number }; + errorMessage: string; +}; + +export default function AccessDataStreamModal(props: DatastreamModalPropType) { + const { isOpen, onClose, unlockAccessProgress, errorMessage } = props; + return ( + + + + Data Access Unlock Progress + + + + + {(!unlockAccessProgress.s1 && ) || } + Initiating handshake with Data Marshal + + + + {(!unlockAccessProgress.s3 && ) || } + Verifying data access rights to unlock Data Stream + + + {errorMessage && ( + + + + + Process Error + + {errorMessage && {errorMessage}} + + + + )} + {unlockAccessProgress.s1 && unlockAccessProgress.s2 && unlockAccessProgress.s3 && ( + + )} + + + + + ); +} diff --git a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx new file mode 100644 index 00000000..fe1dd834 --- /dev/null +++ b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx @@ -0,0 +1,837 @@ +import React, { useEffect, useState } from "react"; +import { CheckCircleIcon, ExternalLinkIcon, InfoIcon } from "@chakra-ui/icons"; +import { + Alert, + AlertDescription, + AlertIcon, + AlertTitle, + Badge, + Box, + Button, + CloseButton, + Flex, + HStack, + Image, + Link, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalHeader, + ModalOverlay, + NumberDecrementStepper, + NumberIncrementStepper, + NumberInput, + NumberInputField, + NumberInputStepper, + Popover, + PopoverArrow, + PopoverBody, + PopoverCloseButton, + PopoverContent, + PopoverHeader, + PopoverTrigger, + Skeleton, + Spinner, + Stack, + Text, + Tooltip, + useColorMode, + useDisclosure, + useToast, +} from "@chakra-ui/react"; +import { DataNft } from "@itheum/sdk-mx-data-nft/out"; +import { useGetAccountInfo, useGetLoginInfo, useGetNetworkConfig, useGetPendingTransactions, useGetSignedTransactions } from "@multiversx/sdk-dapp/hooks"; +import axios from "axios"; +import { motion } from "framer-motion"; +import moment from "moment"; +import { MdOutlineInfo } from "react-icons/md"; +import { useNavigate } from "react-router-dom"; +import imgGuidePopup from "assets/img/guide-unblock-popups.png"; +import ExploreAppButton from "components/UtilComps/ExploreAppButton"; +import ShortAddress from "components/UtilComps/ShortAddress"; +import { CHAIN_TX_VIEWER, PREVIEW_DATA_ON_DEVNET_SESSION_KEY, contractsForChain, uxConfig } from "libs/config"; +import { useLocalStorage } from "libs/hooks"; +import { labels } from "libs/language"; +import { getApi } from "libs/MultiversX/api"; +import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; +import { DataNftMintContract } from "libs/MultiversX/dataNftMint"; +import { DataNftType } from "libs/MultiversX/types"; +import { + backendApi, + convertToLocalString, + decodeNativeAuthToken, + isValidNumericCharacter, + shouldPreviewDataBeEnabled, + sleep, + transformDescription, + viewDataDisabledMessage, +} from "libs/utils"; +import { useMarketStore, useMintStore } from "store"; +import ListDataNFTModal from "../ListDataNFTModal"; +import AccessDataStreamModal from "./AccessDatastreamModal"; + +export type WalletDataNFTMxPropType = { + hasLoaded: boolean; + maxPayment: number; + setHasLoaded: (hasLoaded: boolean) => void; + sellerFee: number; + openNftDetailsDrawer: (e: number) => void; + isProfile?: boolean; +} & DataNftType; + +export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { + const { chainID, network } = useGetNetworkConfig(); + const { loginMethod, tokenLogin } = useGetLoginInfo(); + const { colorMode } = useColorMode(); + const { address } = useGetAccountInfo(); + const { hasPendingTransactions } = useGetPendingTransactions(); + const toast = useToast(); + const navigate = useNavigate(); + const isWebWallet = loginMethod == "wallet"; + const userData = useMintStore((state) => state.userData); + const isMarketPaused = useMarketStore((state) => state.isMarketPaused); + const marketRequirements = useMarketStore((state) => state.marketRequirements); + + const { isOpen: isAccessProgressModalOpen, onOpen: onAccessProgressModalOpen, onClose: onAccessProgressModalClose } = useDisclosure(); + const [unlockAccessProgress, setUnlockAccessProgress] = useState({ + s1: 0, + s2: 0, + s3: 0, + }); + const [errUnlockAccessGeneric, setErrUnlockAccessGeneric] = useState(""); + const [burnNFTModalState, setBurnNFTModalState] = useState(1); // 1 and 2 + const mintContract = new DataNftMintContract(chainID); + const marketContract = new DataNftMarketContract(chainID); + const [dataNftBurnAmount, setDataNftBurnAmount] = useState(1); + const [dataNftBurnAmountError, setDataNftBurnAmountError] = useState(""); + const [selectedDataNft, setSelectedDataNft] = useState(); + const { isOpen: isBurnNFTOpen, onOpen: onBurnNFTOpen, onClose: onBurnNFTClose } = useDisclosure(); + const { isOpen: isListNFTOpen, onOpen: onListNFTOpen, onClose: onListNFTClose } = useDisclosure(); + const [amount, setAmount] = useState(1); + const [amountError, setAmountError] = useState(""); + const [price, setPrice] = useState(10); + const [priceError, setPriceError] = useState(""); + const [previewDataOnDevnetSession] = useLocalStorage(PREVIEW_DATA_ON_DEVNET_SESSION_KEY, null); + const [webWalletListTxHash, setWebWalletListTxHash] = useState(""); + const maxListLimit = process.env.REACT_APP_MAX_LIST_LIMIT_PER_SFT ? Number(process.env.REACT_APP_MAX_LIST_LIMIT_PER_SFT) : 0; + const maxListNumber = maxListLimit > 0 ? Math.min(maxListLimit, item.balance) : item.balance; + const backendUrl = backendApi(chainID); + const { signedTransactionsArray, hasSignedTransactions } = useGetSignedTransactions(); + + useEffect(() => { + if (!isWebWallet) return; + if (!hasSignedTransactions) return; + + const [, sessionInfo] = signedTransactionsArray[0]; + try { + const txHash = sessionInfo.transactions[0].hash; + + if (webWalletListTxHash == "") { + setWebWalletListTxHash(txHash); + } + } catch (e) { + sessionStorage.removeItem("web-wallet-tx"); + } + }, [hasSignedTransactions]); + + useEffect(() => { + if (!isWebWallet) return; + if (!webWalletListTxHash) return; + const data = sessionStorage.getItem("web-wallet-tx"); + + if (!data) return; + + const txData = JSON.parse(data); + + if (txData) { + if (txData.type === "add-offer-tx") { + addOfferBackend( + webWalletListTxHash, + txData.offered_token_identifier, + txData.offered_token_nonce, + txData.offered_token_amount, + txData.title, + txData.description, + txData.wanted_token_identifier, + txData.wanted_token_nonce, + txData.wanted_token_amount, + txData.quantity, + txData.owner + ); + } + sessionStorage.removeItem("web-wallet-tx"); + } + }, [webWalletListTxHash]); + + async function addOfferBackend( + txHash: string, + offered_token_identifier: string, + offered_token_nonce: string, + offered_token_amount: string, + title: string, + description: string, + wanted_token_identifier: string, + wanted_token_nonce: string, + wanted_token_amount: string, + quantity: number, + owner: string + ) { + try { + let indexResponse; + let success = false; + + // Use a loop with a boolean condition + while (!success) { + indexResponse = await axios.get( + `https://${getApi(chainID)}/accounts/${contractsForChain(chainID).market}/transactions?hashes=${txHash}&withScResults=true&withLogs=true` + ); + + if (indexResponse.data[0].status === "success" && typeof indexResponse.data[0].pendingResults === "undefined") { + success = true; + break; + } + + await new Promise((resolve) => setTimeout(resolve, 4000)); + } + + if (indexResponse) { + const results = indexResponse.data[0].results; + const txLogs = indexResponse.data[0].logs.events; + + const allLogs = []; + + for (const result of results) { + if (result.logs && result.logs.events) { + const events = result.logs.events; + allLogs.push(...events); + } + } + + allLogs.push(...txLogs); + + const addOfferEvent = allLogs.find((log: any) => log.identifier === "addOffer"); + + const indexFound = addOfferEvent.topics[1]; + const index = parseInt(Buffer.from(indexFound, "base64").toString("hex"), 16); + const headers = { + Authorization: `Bearer ${tokenLogin?.nativeAuthToken}`, + "Content-Type": "application/json", + }; + + const requestBody = { + index: index, + offered_token_identifier: offered_token_identifier, + offered_token_nonce: offered_token_nonce, + offered_token_amount: offered_token_amount, + title: title, + description: description, + wanted_token_identifier: wanted_token_identifier, + wanted_token_nonce: wanted_token_nonce, + wanted_token_amount: wanted_token_amount, + quantity: quantity, + owner: owner, + }; + + const response = await fetch(`${backendUrl}/addOffer`, { + method: "POST", + headers: headers, + body: JSON.stringify(requestBody), + }); + + const data = await response.json(); + console.log("Response:", data); + } + } catch (error) { + console.log("Error:", error); + } + } + + const showErrorToast = (title: string) => { + toast({ + title, + status: "error", + isClosable: true, + }); + }; + + const onBurn = () => { + const errorMessages = { + noWalletConn: labels.ERR_BURN_NO_WALLET_CONN, + noNFTSelected: labels.ERR_BURN_NO_NFT_SELECTED, + }; + + const conditions = [ + { + condition: !address, + errorMessage: errorMessages.noWalletConn, + }, + { + condition: !selectedDataNft, + errorMessage: errorMessages.noNFTSelected, + }, + ]; + + const shouldReturn = conditions.some(({ condition, errorMessage }) => { + if (condition) { + showErrorToast(errorMessage); + return true; + } + return false; + }); + + if (shouldReturn || !selectedDataNft) { + return; + } + + mintContract.sendBurnTransaction( + address, + selectedDataNft.collection, + selectedDataNft.nonce, + dataNftBurnAmount, + contractsForChain(chainID).dataNftTokens.find((t) => t.id === selectedDataNft.collection)?.contract + ); + + onBurnNFTClose(); + }; + + async function accessDataStream(tokenIdentifier: string, nonce: number) { + try { + onAccessProgressModalOpen(); + + setUnlockAccessProgress((prevProgress) => ({ + ...prevProgress, + s1: 1, + s2: 1, + })); + await sleep(3); + + // auto download the file without ever exposing the url + if (!(tokenLogin && tokenLogin.nativeAuthToken)) { + throw Error(labels.NATIVE_AUTH_TOKEN_MISSING); + } + + DataNft.setNetworkConfig(network.id); + const dataNft = await DataNft.createFromApi({ tokenIdentifier, nonce }); + const arg = { + mvxNativeAuthOrigins: [decodeNativeAuthToken(tokenLogin.nativeAuthToken).origin], + mvxNativeAuthMaxExpirySeconds: 3600, + fwdHeaderMapLookup: { + "authorization": `Bearer ${tokenLogin.nativeAuthToken}`, + }, + }; + const res = await dataNft.viewDataViaMVXNativeAuth(arg); + + if (!res.error) { + const link = document.createElement("a"); + link.target = "_blank"; + link.download = `DataNFT-${nonce}`; + link.href = window.URL.createObjectURL(new Blob([res.data], { type: res.contentType })); + link.click(); + } else { + throw Error(res.error); + } + + setUnlockAccessProgress((prevProgress) => ({ + ...prevProgress, + s3: 1, + })); + } catch (e: any) { + setErrUnlockAccessGeneric(e.toString()); + } + } + + const cleanupAccessDataStreamProcess = () => { + setUnlockAccessProgress({ s1: 0, s2: 0, s3: 0 }); + setErrUnlockAccessGeneric(""); + onAccessProgressModalClose(); + }; + + const onBurnButtonClick = (nft: DataNftType) => { + setSelectedDataNft(nft); + setDataNftBurnAmount(Number(nft.balance)); + setBurnNFTModalState(1); + onBurnNFTOpen(); + }; + + const onListButtonClick = (nft: DataNftType) => { + if (isMarketPaused) { + toast({ + title: "Marketplace is paused", + status: "error", + duration: 9000, + isClosable: true, + }); + } else { + setSelectedDataNft(nft); + onListNFTOpen(); + } + }; + + const onChangeDataNftBurnAmount = (valueAsString: string) => { + let error = ""; + const valueAsNumber = Number(valueAsString); + if (valueAsNumber < 1) { + error = "Burn amount cannot be zero or negative"; + } else if (selectedDataNft && valueAsNumber > Number(selectedDataNft.balance)) { + error = "Data NFT balance exceeded"; + } + + setDataNftBurnAmountError(error); + setDataNftBurnAmount(valueAsNumber); + }; + + const formatButtonNumber = (_price: number, _amount: number) => { + if (_price > 0) { + if (_price >= item.maxPayment) { + return item.maxPayment.toString() + " ITHEUM " + (_amount > 1 ? "each" : ""); + } else { + return _price.toString() + " ITHEUM " + (_amount > 1 ? "each" : ""); + } + } else { + return "Free"; + } + }; + + return ( + + + + item.setHasLoaded(true)} + onClick={() => item.openNftDetailsDrawer(item.index)} + /> + item.setHasLoaded(true)} + onClick={() => item.openNftDetailsDrawer(item.index)} + whileHover={{ opacity: 1, backdropFilter: "blur(1px)", backgroundColor: "#1b1b1ba0" }}> + + + Details + + + + + + + + + {item.tokenName} + + + + +
+ + {item.title} + + + + + {transformDescription(item.description)} + + +
+
+ + + {item.title} + + + + + + {transformDescription(item.description)} + + + +
+ + + Creator:  + navigate(`/profile/${item.creator}`)}> + + + + + + + {`Creation time: ${moment(item.creationTime).format(uxConfig.dateStr)}`} + + + + + + You are the {item.creator !== address ? "Owner" : "Creator"} + + + + + + Fully Transferable License + + + + + + + + + + + {`Balance: ${item.balance}`}
+ {`Total supply: ${item.supply}`}
+ {`Royalty: ${convertToLocalString(item.royalties * 100)}%`} +
+ + + + + + + + + + + + + + How many to list:{" "} + + { + let error = ""; + const valueAsNumber = Number(value); + if (valueAsNumber <= 0) { + error = "Cannot be zero or negative"; + } else if (valueAsNumber > item.balance) { + error = "Not enough balance"; + } else if (maxListLimit > 0 && valueAsNumber > maxListLimit) { + error = "Cannot exceed max list limit"; + } + + setAmountError(error); + setAmount(valueAsNumber); + }}> + + + + + + + + + + {amountError && ( + + {amountError} + + )} + + + + + + Access fee for each: + + + { + let error = ""; + const valueAsNumber = Number(valueString); + if (valueAsNumber < 0) { + error = "Cannot be negative"; + } else if (valueAsNumber > item.maxPayment ? item.maxPayment : 0) { + error = "Maximum listing fee is" + " " + item.maxPayment; + } + setPriceError(error); + setPrice(valueAsNumber); + }} + keepWithinRange={false}> + + + + + + + + + {priceError && ( + + {priceError} + + )} + + + + + +
+
+ + + + - FROZEN -{" "} + + Data NFT is under investigation by the DAO as there was a complaint received against it + + + + {selectedDataNft && ( + + + + {burnNFTModalState === 1 ? ( + <> + Burn Supply from my Data NFT + + + + + + + {selectedDataNft.tokenName} + + + + + + You have ownership of {selectedDataNft.balance} Data NFTs (out of a total of {selectedDataNft.supply}). You can burn these{" "} + {selectedDataNft.balance} Data NFTs and remove them from your wallet. + {selectedDataNft.supply - selectedDataNft.balance > 0 && + ` The remaining ${selectedDataNft.supply - selectedDataNft.balance} ${ + selectedDataNft.supply - selectedDataNft.balance > 1 ? "are" : "is" + } not under your ownership.`} + + + + + + Please note that Data NFTs not listed in the Data NFT marketplace are "NOT public" and are "Private" to only you so no + one can see or access them. So only burn Data NFTs if you are sure you want to destroy your Data NFTs for good. Once burned you will not + be able to recover them again. + + + + How many do you want to burn? + + + + + + + + + {dataNftBurnAmountError && ( + + {dataNftBurnAmountError} + + )} + + + + + + + + ) : ( + <> + Are you sure? + + + + Data NFT Title:   + + + {selectedDataNft.title} + + + + + Burn Amount:    + + + {dataNftBurnAmount} + + + + Are you sure you want to proceed with burning the Data NFTs? You cannot undo this action. + + + + + + + + )} + + + )} + {selectedDataNft && ( + + )} + + +
+
+ ); +} diff --git a/src/pages/DataNFT/MyDataNFTsMultiversX.tsx b/src/pages/DataNFT/MyDataNFTsMultiversX.tsx index dbe9c440..60176bae 100644 --- a/src/pages/DataNFT/MyDataNFTsMultiversX.tsx +++ b/src/pages/DataNFT/MyDataNFTsMultiversX.tsx @@ -32,7 +32,7 @@ import { useNavigate } from "react-router-dom"; import { NoDataHere } from "components/Sections/NoDataHere"; import InteractionTxTable from "components/Tables/InteractionTxTable"; import useThrottle from "components/UtilComps/UseThrottle"; -import WalletDataNFTMX from "components/WalletDataNFTMX"; +import WalletDataNFTMX from "components/WalletDataNFTMX/WalletDataNFTMX"; import { contractsForChain } from "libs/config"; import dataNftMintJson from "libs/MultiversX/ABIs/datanftmint.abi.json"; import { getNftsOfACollectionForAnAddress } from "libs/MultiversX/api"; From efb0641092011a6e76aa984afeaa840520f30377 Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 11 Jan 2024 10:05:44 +0200 Subject: [PATCH 14/46] refactor remove unused imports --- src/components/Faucet/Faucet.tsx | 41 +++---------------- .../WalletDataNFTMX/WalletDataNFTMX.tsx | 12 +----- src/pages/Home/HomeMultiversX.tsx | 5 +-- 3 files changed, 9 insertions(+), 49 deletions(-) diff --git a/src/components/Faucet/Faucet.tsx b/src/components/Faucet/Faucet.tsx index c5616aac..c9233ffc 100644 --- a/src/components/Faucet/Faucet.tsx +++ b/src/components/Faucet/Faucet.tsx @@ -1,42 +1,11 @@ -import React, { useEffect, useState } from "react"; -import { WarningTwoIcon } from "@chakra-ui/icons"; -import { - Alert, - AlertDescription, - AlertIcon, - AlertTitle, - Badge, - Box, - Button, - Flex, - Heading, - HStack, - SimpleGrid, - Spacer, - Spinner, - Stack, - Text, - Tooltip, - useBreakpointValue, - useColorMode, - useDisclosure, - useToast, -} from "@chakra-ui/react"; +import React from "react"; +import { useEffect, useState } from "react"; +import { Box, Button, Heading, Spacer, Stack, Text, useColorMode } from "@chakra-ui/react"; import { useGetNetworkConfig } from "@multiversx/sdk-dapp/hooks"; -import { useGetAccountInfo, useGetLoginInfo } from "@multiversx/sdk-dapp/hooks/account"; +import { useGetAccountInfo } from "@multiversx/sdk-dapp/hooks/account"; import { useGetPendingTransactions } from "@multiversx/sdk-dapp/hooks/transactions"; -import moment from "moment"; -import { useNavigate } from "react-router-dom"; -import myNFMe from "assets/img/my-nfme.png"; -import ClaimModalMx from "components/ClaimModal/ClaimModalMultiversX"; -import ExplainerArticles from "components/Sections/ExplainerArticles"; -import RecentDataNFTs from "components/Sections/RecentDataNFTs"; -import ChainSupportedComponent from "components/UtilComps/ChainSupportedComponent"; -import { CHAIN_TOKEN_SYMBOL, CLAIM_TYPES, MENU, uxConfig } from "libs/config"; -import { ClaimsContract } from "libs/MultiversX/claims"; +import { CHAIN_TOKEN_SYMBOL } from "libs/config"; import { FaucetContract } from "libs/MultiversX/faucet"; -import { formatNumberToShort } from "libs/utils"; -import AppMarketplace from "pages/Home/AppMarketplace"; const Faucet = ({ tileBoxW, tileBoxH }: any) => { const { chainID } = useGetNetworkConfig(); diff --git a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx index fe1dd834..121553be 100644 --- a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx +++ b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx @@ -1,21 +1,15 @@ import React, { useEffect, useState } from "react"; -import { CheckCircleIcon, ExternalLinkIcon, InfoIcon } from "@chakra-ui/icons"; +import { ExternalLinkIcon } from "@chakra-ui/icons"; import { - Alert, - AlertDescription, - AlertIcon, - AlertTitle, Badge, Box, Button, - CloseButton, Flex, HStack, Image, Link, Modal, ModalBody, - ModalCloseButton, ModalContent, ModalHeader, ModalOverlay, @@ -32,7 +26,6 @@ import { PopoverHeader, PopoverTrigger, Skeleton, - Spinner, Stack, Text, Tooltip, @@ -47,7 +40,6 @@ import { motion } from "framer-motion"; import moment from "moment"; import { MdOutlineInfo } from "react-icons/md"; import { useNavigate } from "react-router-dom"; -import imgGuidePopup from "assets/img/guide-unblock-popups.png"; import ExploreAppButton from "components/UtilComps/ExploreAppButton"; import ShortAddress from "components/UtilComps/ShortAddress"; import { CHAIN_TX_VIEWER, PREVIEW_DATA_ON_DEVNET_SESSION_KEY, contractsForChain, uxConfig } from "libs/config"; @@ -68,8 +60,8 @@ import { viewDataDisabledMessage, } from "libs/utils"; import { useMarketStore, useMintStore } from "store"; -import ListDataNFTModal from "../ListDataNFTModal"; import AccessDataStreamModal from "./AccessDatastreamModal"; +import ListDataNFTModal from "../ListDataNFTModal"; export type WalletDataNFTMxPropType = { hasLoaded: boolean; diff --git a/src/pages/Home/HomeMultiversX.tsx b/src/pages/Home/HomeMultiversX.tsx index b4f3fc6a..3a73ce7f 100644 --- a/src/pages/Home/HomeMultiversX.tsx +++ b/src/pages/Home/HomeMultiversX.tsx @@ -29,15 +29,14 @@ import moment from "moment"; import { useNavigate } from "react-router-dom"; import myNFMe from "assets/img/my-nfme.png"; import ClaimModalMx from "components/ClaimModal/ClaimModalMultiversX"; +import Faucet from "components/Faucet/Faucet"; import ExplainerArticles from "components/Sections/ExplainerArticles"; import RecentDataNFTs from "components/Sections/RecentDataNFTs"; import ChainSupportedComponent from "components/UtilComps/ChainSupportedComponent"; -import { CHAIN_TOKEN_SYMBOL, CLAIM_TYPES, MENU, uxConfig } from "libs/config"; +import { CLAIM_TYPES, MENU, uxConfig } from "libs/config"; import { ClaimsContract } from "libs/MultiversX/claims"; -import { FaucetContract } from "libs/MultiversX/faucet"; import { formatNumberToShort } from "libs/utils"; import AppMarketplace from "pages/Home/AppMarketplace"; -import Faucet from "components/Faucet/Faucet"; export default function HomeMultiversX({ setMenuItem, From 79c268f0d92e032698a4cc816bf3dc7603702fa5 Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 11 Jan 2024 10:20:26 +0200 Subject: [PATCH 15/46] refactor burndatanftmodal from walletdatanftmx --- .../WalletDataNFTMX/BurnDataNFTModal.tsx | 209 ++++++++++++++++++ .../WalletDataNFTMX/WalletDataNFTMX.tsx | 189 +--------------- 2 files changed, 211 insertions(+), 187 deletions(-) create mode 100644 src/components/WalletDataNFTMX/BurnDataNFTModal.tsx diff --git a/src/components/WalletDataNFTMX/BurnDataNFTModal.tsx b/src/components/WalletDataNFTMX/BurnDataNFTModal.tsx new file mode 100644 index 00000000..f120b539 --- /dev/null +++ b/src/components/WalletDataNFTMX/BurnDataNFTModal.tsx @@ -0,0 +1,209 @@ +import React, { useState } from "react"; +import { Button } from "@chakra-ui/button"; +import { useColorMode } from "@chakra-ui/color-mode"; +import { Image } from "@chakra-ui/image"; +import { Stack, HStack, Text, Box, Flex } from "@chakra-ui/layout"; +import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalBody } from "@chakra-ui/modal"; +import { NumberInput, NumberInputField, NumberInputStepper, NumberIncrementStepper, NumberDecrementStepper } from "@chakra-ui/number-input"; +import { useToast } from "@chakra-ui/toast"; +import { useGetAccountInfo, useGetNetworkConfig, useGetPendingTransactions } from "@multiversx/sdk-dapp/hooks"; +import { contractsForChain } from "libs/config"; +import { labels } from "libs/language"; +import { DataNftMintContract } from "libs/MultiversX/dataNftMint"; +import { DataNftType } from "libs/MultiversX/types"; +import { isValidNumericCharacter } from "libs/utils"; + +type BurnDataNFTModalPropType = { + isOpen: boolean; + onClose: () => void; + selectedDataNft: DataNftType; +}; + +export default function BurnDataNFTModal(props: BurnDataNFTModalPropType) { + const { isOpen, onClose, selectedDataNft } = props; + const { chainID } = useGetNetworkConfig(); + const { colorMode } = useColorMode(); + const [burnNFTModalState, setBurnNFTModalState] = useState(1); // 1 and 2 + const [dataNftBurnAmountError, setDataNftBurnAmountError] = useState(""); + const mintContract = new DataNftMintContract(chainID); + const [dataNftBurnAmount, setDataNftBurnAmount] = useState(selectedDataNft.balance); + const toast = useToast(); + const { address } = useGetAccountInfo(); + const { hasPendingTransactions } = useGetPendingTransactions(); + + const onChangeDataNftBurnAmount = (valueAsString: string) => { + let error = ""; + const valueAsNumber = Number(valueAsString); + if (valueAsNumber < 1) { + error = "Burn amount cannot be zero or negative"; + } else if (selectedDataNft && valueAsNumber > Number(selectedDataNft.balance)) { + error = "Data NFT balance exceeded"; + } + + setDataNftBurnAmountError(error); + setDataNftBurnAmount(valueAsNumber); + }; + + const showErrorToast = (title: string) => { + toast({ + title, + status: "error", + isClosable: true, + }); + }; + + const onBurn = () => { + const errorMessages = { + noWalletConn: labels.ERR_BURN_NO_WALLET_CONN, + noNFTSelected: labels.ERR_BURN_NO_NFT_SELECTED, + }; + + const conditions = [ + { + condition: !address, + errorMessage: errorMessages.noWalletConn, + }, + { + condition: !selectedDataNft, + errorMessage: errorMessages.noNFTSelected, + }, + ]; + + const shouldReturn = conditions.some(({ condition, errorMessage }) => { + if (condition) { + showErrorToast(errorMessage); + return true; + } + return false; + }); + + if (shouldReturn || !selectedDataNft) { + return; + } + + mintContract.sendBurnTransaction( + address, + selectedDataNft.collection, + selectedDataNft.nonce, + dataNftBurnAmount, + contractsForChain(chainID).dataNftTokens.find((t) => t.id === selectedDataNft.collection)?.contract + ); + + onClose(); + }; + + return ( + + + + {burnNFTModalState === 1 ? ( + <> + Burn Supply from my Data NFT + + + + + + + {selectedDataNft.tokenName} + + + + + + You have ownership of {selectedDataNft.balance} Data NFTs (out of a total of {selectedDataNft.supply}). You can burn these{" "} + {selectedDataNft.balance} Data NFTs and remove them from your wallet. + {selectedDataNft.supply - selectedDataNft.balance > 0 && + ` The remaining ${selectedDataNft.supply - selectedDataNft.balance} ${ + selectedDataNft.supply - selectedDataNft.balance > 1 ? "are" : "is" + } not under your ownership.`} + + + + + + Please note that Data NFTs not listed in the Data NFT marketplace are "NOT public" and are "Private" to only you so no one + can see or access them. So only burn Data NFTs if you are sure you want to destroy your Data NFTs for good. Once burned you will not be able to + recover them again. + + + + How many do you want to burn? + + + + + + + + + {dataNftBurnAmountError && ( + + {dataNftBurnAmountError} + + )} + + + + + + + + ) : ( + <> + Are you sure? + + + + Data NFT Title:   + + + {selectedDataNft.title} + + + + + Burn Amount:    + + + {dataNftBurnAmount} + + + + Are you sure you want to proceed with burning the Data NFTs? You cannot undo this action. + + + + + + + + )} + + + ); +} diff --git a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx index 121553be..d941d45b 100644 --- a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx +++ b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx @@ -8,11 +8,6 @@ import { HStack, Image, Link, - Modal, - ModalBody, - ModalContent, - ModalHeader, - ModalOverlay, NumberDecrementStepper, NumberIncrementStepper, NumberInput, @@ -47,7 +42,6 @@ import { useLocalStorage } from "libs/hooks"; import { labels } from "libs/language"; import { getApi } from "libs/MultiversX/api"; import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; -import { DataNftMintContract } from "libs/MultiversX/dataNftMint"; import { DataNftType } from "libs/MultiversX/types"; import { backendApi, @@ -61,6 +55,7 @@ import { } from "libs/utils"; import { useMarketStore, useMintStore } from "store"; import AccessDataStreamModal from "./AccessDatastreamModal"; +import BurnDataNFTModal from "./BurnDataNFTModal"; import ListDataNFTModal from "../ListDataNFTModal"; export type WalletDataNFTMxPropType = { @@ -92,11 +87,7 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { s3: 0, }); const [errUnlockAccessGeneric, setErrUnlockAccessGeneric] = useState(""); - const [burnNFTModalState, setBurnNFTModalState] = useState(1); // 1 and 2 - const mintContract = new DataNftMintContract(chainID); const marketContract = new DataNftMarketContract(chainID); - const [dataNftBurnAmount, setDataNftBurnAmount] = useState(1); - const [dataNftBurnAmountError, setDataNftBurnAmountError] = useState(""); const [selectedDataNft, setSelectedDataNft] = useState(); const { isOpen: isBurnNFTOpen, onOpen: onBurnNFTOpen, onClose: onBurnNFTClose } = useDisclosure(); const { isOpen: isListNFTOpen, onOpen: onListNFTOpen, onClose: onListNFTClose } = useDisclosure(); @@ -239,54 +230,6 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { } } - const showErrorToast = (title: string) => { - toast({ - title, - status: "error", - isClosable: true, - }); - }; - - const onBurn = () => { - const errorMessages = { - noWalletConn: labels.ERR_BURN_NO_WALLET_CONN, - noNFTSelected: labels.ERR_BURN_NO_NFT_SELECTED, - }; - - const conditions = [ - { - condition: !address, - errorMessage: errorMessages.noWalletConn, - }, - { - condition: !selectedDataNft, - errorMessage: errorMessages.noNFTSelected, - }, - ]; - - const shouldReturn = conditions.some(({ condition, errorMessage }) => { - if (condition) { - showErrorToast(errorMessage); - return true; - } - return false; - }); - - if (shouldReturn || !selectedDataNft) { - return; - } - - mintContract.sendBurnTransaction( - address, - selectedDataNft.collection, - selectedDataNft.nonce, - dataNftBurnAmount, - contractsForChain(chainID).dataNftTokens.find((t) => t.id === selectedDataNft.collection)?.contract - ); - - onBurnNFTClose(); - }; - async function accessDataStream(tokenIdentifier: string, nonce: number) { try { onAccessProgressModalOpen(); @@ -341,8 +284,6 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { const onBurnButtonClick = (nft: DataNftType) => { setSelectedDataNft(nft); - setDataNftBurnAmount(Number(nft.balance)); - setBurnNFTModalState(1); onBurnNFTOpen(); }; @@ -360,19 +301,6 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { } }; - const onChangeDataNftBurnAmount = (valueAsString: string) => { - let error = ""; - const valueAsNumber = Number(valueAsString); - if (valueAsNumber < 1) { - error = "Burn amount cannot be zero or negative"; - } else if (selectedDataNft && valueAsNumber > Number(selectedDataNft.balance)) { - error = "Data NFT balance exceeded"; - } - - setDataNftBurnAmountError(error); - setDataNftBurnAmount(valueAsNumber); - }; - const formatButtonNumber = (_price: number, _amount: number) => { if (_price > 0) { if (_price >= item.maxPayment) { @@ -690,120 +618,7 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { - {selectedDataNft && ( - - - - {burnNFTModalState === 1 ? ( - <> - Burn Supply from my Data NFT - - - - - - - {selectedDataNft.tokenName} - - - - - - You have ownership of {selectedDataNft.balance} Data NFTs (out of a total of {selectedDataNft.supply}). You can burn these{" "} - {selectedDataNft.balance} Data NFTs and remove them from your wallet. - {selectedDataNft.supply - selectedDataNft.balance > 0 && - ` The remaining ${selectedDataNft.supply - selectedDataNft.balance} ${ - selectedDataNft.supply - selectedDataNft.balance > 1 ? "are" : "is" - } not under your ownership.`} - - - - - - Please note that Data NFTs not listed in the Data NFT marketplace are "NOT public" and are "Private" to only you so no - one can see or access them. So only burn Data NFTs if you are sure you want to destroy your Data NFTs for good. Once burned you will not - be able to recover them again. - - - - How many do you want to burn? - - - - - - - - - {dataNftBurnAmountError && ( - - {dataNftBurnAmountError} - - )} - - - - - - - - ) : ( - <> - Are you sure? - - - - Data NFT Title:   - - - {selectedDataNft.title} - - - - - Burn Amount:    - - - {dataNftBurnAmount} - - - - Are you sure you want to proceed with burning the Data NFTs? You cannot undo this action. - - - - - - - - )} - - - )} + {selectedDataNft && } {selectedDataNft && ( Date: Thu, 11 Jan 2024 10:31:53 +0200 Subject: [PATCH 16/46] refactor frozenoverlay --- src/components/FrozenOverlay.tsx | 32 +++++++++++++++++++ src/components/MyListedDataNFT.tsx | 26 +++------------ .../UtilComps/UpperCardComponent.tsx | 28 +++------------- src/components/WalletDataNFTMX.tsx | 24 ++------------ .../WalletDataNFTMX/WalletDataNFTMX.tsx | 24 ++------------ 5 files changed, 45 insertions(+), 89 deletions(-) create mode 100644 src/components/FrozenOverlay.tsx diff --git a/src/components/FrozenOverlay.tsx b/src/components/FrozenOverlay.tsx new file mode 100644 index 00000000..e1c9c368 --- /dev/null +++ b/src/components/FrozenOverlay.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import { Box, Text } from "@chakra-ui/layout"; + +type FrozenOverlayPropType = { + isVisible: boolean | undefined; +}; + +export default function FrozenOverlay(props: FrozenOverlayPropType) { + const { isVisible } = props; + return ( + + + - FROZEN -{" "} + + Data NFT is under investigation by the DAO as there was a complaint received against it + + + + ); +} diff --git a/src/components/MyListedDataNFT.tsx b/src/components/MyListedDataNFT.tsx index 23310fcf..0f763382 100644 --- a/src/components/MyListedDataNFT.tsx +++ b/src/components/MyListedDataNFT.tsx @@ -38,6 +38,7 @@ import { viewDataDisabledMessage, } from "libs/utils"; import { useMarketStore, useMintStore } from "store"; +import FrozenOverlay from "./FrozenOverlay"; type MyListedDataNFTProps = { offer: OfferType; @@ -273,28 +274,9 @@ const MyListedDataNFT: FC = (props) => { )}
- - - - FROZEN -{" "} - - Data NFT is under investigation by the DAO as there was a complaint received against it - - - +
diff --git a/src/components/UtilComps/UpperCardComponent.tsx b/src/components/UtilComps/UpperCardComponent.tsx index 1762ffe0..c8bdcb40 100644 --- a/src/components/UtilComps/UpperCardComponent.tsx +++ b/src/components/UtilComps/UpperCardComponent.tsx @@ -30,6 +30,7 @@ import { DEFAULT_NFT_IMAGE } from "libs/mxConstants"; import { convertToLocalString, convertWeiToEsdt, getTokenWantedRepresentation, printPrice, tokenDecimals, transformDescription } from "libs/utils"; import { useMarketStore, useMintStore } from "store"; import ShortAddress from "./ShortAddress"; +import FrozenOverlay from "components/FrozenOverlay"; type UpperCardComponentProps = { nftImageLoading: boolean; @@ -247,19 +248,8 @@ const UpperCardComponent: FC = ({ )} - = ({ (userData.frozenNonces && offer && (userData.frozenNonces.includes(offer.offered_token_nonce) || marketFreezedNonces.includes(offer.offered_token_nonce)))) - ? "visible" - : "collapse" - }> - - - FROZEN -{" "} - - Data NFT is under investigation by the DAO as there was a complaint received against it - - - + } + /> ); diff --git a/src/components/WalletDataNFTMX.tsx b/src/components/WalletDataNFTMX.tsx index e35d41d9..484dd25b 100644 --- a/src/components/WalletDataNFTMX.tsx +++ b/src/components/WalletDataNFTMX.tsx @@ -69,6 +69,7 @@ import { } from "libs/utils"; import { useMarketStore, useMintStore } from "store"; import ListDataNFTModal from "./ListDataNFTModal"; +import FrozenOverlay from "./FrozenOverlay"; export type WalletDataNFTMxPropType = { hasLoaded: boolean; @@ -675,28 +676,7 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { - - - - FROZEN -{" "} - - Data NFT is under investigation by the DAO as there was a complaint received against it - - - + {selectedDataNft && ( diff --git a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx index d941d45b..ade5ddbb 100644 --- a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx +++ b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx @@ -57,6 +57,7 @@ import { useMarketStore, useMintStore } from "store"; import AccessDataStreamModal from "./AccessDatastreamModal"; import BurnDataNFTModal from "./BurnDataNFTModal"; import ListDataNFTModal from "../ListDataNFTModal"; +import FrozenOverlay from "components/FrozenOverlay"; export type WalletDataNFTMxPropType = { hasLoaded: boolean; @@ -596,28 +597,7 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { - - - - FROZEN -{" "} - - Data NFT is under investigation by the DAO as there was a complaint received against it - - - + {selectedDataNft && } {selectedDataNft && ( Date: Thu, 11 Jan 2024 11:04:07 +0200 Subject: [PATCH 17/46] refactor previewdatabutton --- src/components/MarketplaceLowerCard.tsx | 24 +--------- src/components/MyListedDataLowerCard.tsx | 22 +--------- src/components/MyListedDataNFT.tsx | 20 +-------- src/components/PreviewDataButton.tsx | 44 +++++++++++++++++++ src/components/WalletDataNFTMX.tsx | 21 +-------- .../WalletDataNFTMX/WalletDataNFTMX.tsx | 23 ++-------- src/pages/DataNFT/DataNFTDetails.tsx | 24 +++------- 7 files changed, 61 insertions(+), 117 deletions(-) create mode 100644 src/components/PreviewDataButton.tsx diff --git a/src/components/MarketplaceLowerCard.tsx b/src/components/MarketplaceLowerCard.tsx index 762a2e2f..9659805b 100644 --- a/src/components/MarketplaceLowerCard.tsx +++ b/src/components/MarketplaceLowerCard.tsx @@ -24,6 +24,7 @@ import { useLocalStorage } from "libs/hooks"; import { DataNftMetadataType, OfferType } from "libs/MultiversX/types"; import { isValidNumericCharacter, shouldPreviewDataBeEnabled, viewDataDisabledMessage } from "libs/utils"; import { useMarketStore } from "store"; +import PreviewDataButton from "./PreviewDataButton"; type MarketplaceLowerCardProps = { offer: OfferType; @@ -44,31 +45,10 @@ const MarketplaceLowerCard: FC = ({ offer, nftMetadat const isMyNft = offer.owner === address; const maxBuyLimit = process.env.REACT_APP_MAX_BUY_LIMIT_PER_SFT ? Number(process.env.REACT_APP_MAX_BUY_LIMIT_PER_SFT) : 0; const maxBuyNumber = maxBuyLimit > 0 ? Math.min(maxBuyLimit, offer.quantity) : offer.quantity; - const [previewDataOnDevnetSession] = useLocalStorage(PREVIEW_DATA_ON_DEVNET_SESSION_KEY, null); return ( <> - - - + diff --git a/src/components/MyListedDataLowerCard.tsx b/src/components/MyListedDataLowerCard.tsx index 9faf9c10..36f9f995 100644 --- a/src/components/MyListedDataLowerCard.tsx +++ b/src/components/MyListedDataLowerCard.tsx @@ -41,6 +41,7 @@ import { viewDataDisabledMessage, } from "libs/utils"; import { useMarketStore } from "store"; +import PreviewDataButton from "./PreviewDataButton"; type MyListedDataLowerCardProps = { offer: OfferType; @@ -264,26 +265,7 @@ const MyListedDataLowerCard: FC = ({ offer, nftMetad return ( <> - - - + - + {address && ( <> diff --git a/src/components/PreviewDataButton.tsx b/src/components/PreviewDataButton.tsx new file mode 100644 index 00000000..59cd9079 --- /dev/null +++ b/src/components/PreviewDataButton.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import { Button } from "@chakra-ui/button"; +import { useColorMode } from "@chakra-ui/color-mode"; +import { Text } from "@chakra-ui/layout"; +import { Tooltip } from "@chakra-ui/tooltip"; +import { useGetLoginInfo, useGetNetworkConfig } from "@multiversx/sdk-dapp/hooks"; +import { PREVIEW_DATA_ON_DEVNET_SESSION_KEY } from "libs/config"; +import { useLocalStorage } from "libs/hooks"; +import { shouldPreviewDataBeEnabled, viewDataDisabledMessage } from "libs/utils"; + +type PreviewDataButtonPropType = { + previewDataURL: string; + buttonSize?: any; + buttonWidth?: string; +}; + +export default function PreviewDataButton(props: PreviewDataButtonPropType) { + const { loginMethod } = useGetLoginInfo(); + const { chainID } = useGetNetworkConfig(); + const [previewDataOnDevnetSession] = useLocalStorage(PREVIEW_DATA_ON_DEVNET_SESSION_KEY, null); + const { colorMode } = useColorMode(); + const { previewDataURL, buttonSize = "sm", buttonWidth = "full" } = props; + return ( + + + + ); +} diff --git a/src/components/WalletDataNFTMX.tsx b/src/components/WalletDataNFTMX.tsx index 484dd25b..2d95fe12 100644 --- a/src/components/WalletDataNFTMX.tsx +++ b/src/components/WalletDataNFTMX.tsx @@ -70,6 +70,7 @@ import { import { useMarketStore, useMintStore } from "store"; import ListDataNFTModal from "./ListDataNFTModal"; import FrozenOverlay from "./FrozenOverlay"; +import PreviewDataButton from "./PreviewDataButton"; export type WalletDataNFTMxPropType = { hasLoaded: boolean; @@ -544,25 +545,7 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { - - - + diff --git a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx index ade5ddbb..df9b7a8f 100644 --- a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx +++ b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx @@ -35,6 +35,7 @@ import { motion } from "framer-motion"; import moment from "moment"; import { MdOutlineInfo } from "react-icons/md"; import { useNavigate } from "react-router-dom"; +import FrozenOverlay from "components/FrozenOverlay"; import ExploreAppButton from "components/UtilComps/ExploreAppButton"; import ShortAddress from "components/UtilComps/ShortAddress"; import { CHAIN_TX_VIEWER, PREVIEW_DATA_ON_DEVNET_SESSION_KEY, contractsForChain, uxConfig } from "libs/config"; @@ -57,7 +58,7 @@ import { useMarketStore, useMintStore } from "store"; import AccessDataStreamModal from "./AccessDatastreamModal"; import BurnDataNFTModal from "./BurnDataNFTModal"; import ListDataNFTModal from "../ListDataNFTModal"; -import FrozenOverlay from "components/FrozenOverlay"; +import PreviewDataButton from "components/PreviewDataButton"; export type WalletDataNFTMxPropType = { hasLoaded: boolean; @@ -465,25 +466,7 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { - - - + diff --git a/src/pages/DataNFT/DataNFTDetails.tsx b/src/pages/DataNFT/DataNFTDetails.tsx index a7053f4d..05a0ee77 100644 --- a/src/pages/DataNFT/DataNFTDetails.tsx +++ b/src/pages/DataNFT/DataNFTDetails.tsx @@ -58,6 +58,7 @@ import { } from "libs/utils"; import { shouldPreviewDataBeEnabled, viewDataDisabledMessage } from "libs/utils/util"; import { useMarketStore } from "store"; +import PreviewDataButton from "components/PreviewDataButton"; type DataNFTDetailsProps = { owner?: string; @@ -407,24 +408,11 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { - - - + Date: Thu, 11 Jan 2024 11:08:26 +0200 Subject: [PATCH 18/46] remove old walletdatanftmx file --- src/components/WalletDataNFTMX.tsx | 831 ----------------------------- 1 file changed, 831 deletions(-) delete mode 100644 src/components/WalletDataNFTMX.tsx diff --git a/src/components/WalletDataNFTMX.tsx b/src/components/WalletDataNFTMX.tsx deleted file mode 100644 index 2d95fe12..00000000 --- a/src/components/WalletDataNFTMX.tsx +++ /dev/null @@ -1,831 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { CheckCircleIcon, ExternalLinkIcon, InfoIcon } from "@chakra-ui/icons"; -import { - Alert, - AlertDescription, - AlertIcon, - AlertTitle, - Badge, - Box, - Button, - CloseButton, - Flex, - HStack, - Image, - Link, - Modal, - ModalBody, - ModalCloseButton, - ModalContent, - ModalHeader, - ModalOverlay, - NumberDecrementStepper, - NumberIncrementStepper, - NumberInput, - NumberInputField, - NumberInputStepper, - Popover, - PopoverArrow, - PopoverBody, - PopoverCloseButton, - PopoverContent, - PopoverHeader, - PopoverTrigger, - Skeleton, - Spinner, - Stack, - Text, - Tooltip, - useColorMode, - useDisclosure, - useToast, -} from "@chakra-ui/react"; -import { DataNft } from "@itheum/sdk-mx-data-nft/out"; -import { useGetAccountInfo, useGetLoginInfo, useGetNetworkConfig, useGetPendingTransactions, useGetSignedTransactions } from "@multiversx/sdk-dapp/hooks"; -import axios from "axios"; -import { motion } from "framer-motion"; -import moment from "moment"; -import { MdOutlineInfo } from "react-icons/md"; -import { useNavigate } from "react-router-dom"; -import imgGuidePopup from "assets/img/guide-unblock-popups.png"; -import ExploreAppButton from "components/UtilComps/ExploreAppButton"; -import ShortAddress from "components/UtilComps/ShortAddress"; -import { CHAIN_TX_VIEWER, PREVIEW_DATA_ON_DEVNET_SESSION_KEY, contractsForChain, uxConfig } from "libs/config"; -import { useLocalStorage } from "libs/hooks"; -import { labels } from "libs/language"; -import { getApi } from "libs/MultiversX/api"; -import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; -import { DataNftMintContract } from "libs/MultiversX/dataNftMint"; -import { DataNftType } from "libs/MultiversX/types"; -import { - backendApi, - convertToLocalString, - decodeNativeAuthToken, - isValidNumericCharacter, - shouldPreviewDataBeEnabled, - sleep, - transformDescription, - viewDataDisabledMessage, -} from "libs/utils"; -import { useMarketStore, useMintStore } from "store"; -import ListDataNFTModal from "./ListDataNFTModal"; -import FrozenOverlay from "./FrozenOverlay"; -import PreviewDataButton from "./PreviewDataButton"; - -export type WalletDataNFTMxPropType = { - hasLoaded: boolean; - maxPayment: number; - setHasLoaded: (hasLoaded: boolean) => void; - sellerFee: number; - openNftDetailsDrawer: (e: number) => void; - isProfile?: boolean; -} & DataNftType; - -export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { - const { chainID, network } = useGetNetworkConfig(); - const { loginMethod, tokenLogin } = useGetLoginInfo(); - const { colorMode } = useColorMode(); - const { address } = useGetAccountInfo(); - const { hasPendingTransactions } = useGetPendingTransactions(); - const toast = useToast(); - const navigate = useNavigate(); - const isWebWallet = loginMethod == "wallet"; - const userData = useMintStore((state) => state.userData); - const isMarketPaused = useMarketStore((state) => state.isMarketPaused); - const marketRequirements = useMarketStore((state) => state.marketRequirements); - - const { isOpen: isAccessProgressModalOpen, onOpen: onAccessProgressModalOpen, onClose: onAccessProgressModalClose } = useDisclosure(); - const [unlockAccessProgress, setUnlockAccessProgress] = useState({ - s1: 0, - s2: 0, - s3: 0, - }); - const [errUnlockAccessGeneric, setErrUnlockAccessGeneric] = useState(""); - const [burnNFTModalState, setBurnNFTModalState] = useState(1); // 1 and 2 - const mintContract = new DataNftMintContract(chainID); - const marketContract = new DataNftMarketContract(chainID); - const [dataNftBurnAmount, setDataNftBurnAmount] = useState(1); - const [dataNftBurnAmountError, setDataNftBurnAmountError] = useState(""); - const [selectedDataNft, setSelectedDataNft] = useState(); - const { isOpen: isBurnNFTOpen, onOpen: onBurnNFTOpen, onClose: onBurnNFTClose } = useDisclosure(); - const { isOpen: isListNFTOpen, onOpen: onListNFTOpen, onClose: onListNFTClose } = useDisclosure(); - const [amount, setAmount] = useState(1); - const [amountError, setAmountError] = useState(""); - const [price, setPrice] = useState(10); - const [priceError, setPriceError] = useState(""); - const [previewDataOnDevnetSession] = useLocalStorage(PREVIEW_DATA_ON_DEVNET_SESSION_KEY, null); - const [webWalletListTxHash, setWebWalletListTxHash] = useState(""); - const maxListLimit = process.env.REACT_APP_MAX_LIST_LIMIT_PER_SFT ? Number(process.env.REACT_APP_MAX_LIST_LIMIT_PER_SFT) : 0; - const maxListNumber = maxListLimit > 0 ? Math.min(maxListLimit, item.balance) : item.balance; - const backendUrl = backendApi(chainID); - const { signedTransactionsArray, hasSignedTransactions } = useGetSignedTransactions(); - - useEffect(() => { - if (!isWebWallet) return; - if (!hasSignedTransactions) return; - - const [, sessionInfo] = signedTransactionsArray[0]; - try { - const txHash = sessionInfo.transactions[0].hash; - - if (webWalletListTxHash == "") { - setWebWalletListTxHash(txHash); - } - } catch (e) { - sessionStorage.removeItem("web-wallet-tx"); - } - }, [hasSignedTransactions]); - - useEffect(() => { - if (!isWebWallet) return; - if (!webWalletListTxHash) return; - const data = sessionStorage.getItem("web-wallet-tx"); - - if (!data) return; - - const txData = JSON.parse(data); - - if (txData) { - if (txData.type === "add-offer-tx") { - addOfferBackend( - webWalletListTxHash, - txData.offered_token_identifier, - txData.offered_token_nonce, - txData.offered_token_amount, - txData.title, - txData.description, - txData.wanted_token_identifier, - txData.wanted_token_nonce, - txData.wanted_token_amount, - txData.quantity, - txData.owner - ); - } - sessionStorage.removeItem("web-wallet-tx"); - } - }, [webWalletListTxHash]); - - async function addOfferBackend( - txHash: string, - offered_token_identifier: string, - offered_token_nonce: string, - offered_token_amount: string, - title: string, - description: string, - wanted_token_identifier: string, - wanted_token_nonce: string, - wanted_token_amount: string, - quantity: number, - owner: string - ) { - try { - let indexResponse; - let success = false; - - // Use a loop with a boolean condition - while (!success) { - indexResponse = await axios.get( - `https://${getApi(chainID)}/accounts/${contractsForChain(chainID).market}/transactions?hashes=${txHash}&withScResults=true&withLogs=true` - ); - - if (indexResponse.data[0].status === "success" && typeof indexResponse.data[0].pendingResults === "undefined") { - success = true; - break; - } - - await new Promise((resolve) => setTimeout(resolve, 4000)); - } - - if (indexResponse) { - const results = indexResponse.data[0].results; - const txLogs = indexResponse.data[0].logs.events; - - const allLogs = []; - - for (const result of results) { - if (result.logs && result.logs.events) { - const events = result.logs.events; - allLogs.push(...events); - } - } - - allLogs.push(...txLogs); - - const addOfferEvent = allLogs.find((log: any) => log.identifier === "addOffer"); - - const indexFound = addOfferEvent.topics[1]; - const index = parseInt(Buffer.from(indexFound, "base64").toString("hex"), 16); - const headers = { - Authorization: `Bearer ${tokenLogin?.nativeAuthToken}`, - "Content-Type": "application/json", - }; - - const requestBody = { - index: index, - offered_token_identifier: offered_token_identifier, - offered_token_nonce: offered_token_nonce, - offered_token_amount: offered_token_amount, - title: title, - description: description, - wanted_token_identifier: wanted_token_identifier, - wanted_token_nonce: wanted_token_nonce, - wanted_token_amount: wanted_token_amount, - quantity: quantity, - owner: owner, - }; - - const response = await fetch(`${backendUrl}/addOffer`, { - method: "POST", - headers: headers, - body: JSON.stringify(requestBody), - }); - - const data = await response.json(); - console.log("Response:", data); - } - } catch (error) { - console.log("Error:", error); - } - } - - const showErrorToast = (title: string) => { - toast({ - title, - status: "error", - isClosable: true, - }); - }; - - const onBurn = () => { - const errorMessages = { - noWalletConn: labels.ERR_BURN_NO_WALLET_CONN, - noNFTSelected: labels.ERR_BURN_NO_NFT_SELECTED, - }; - - const conditions = [ - { - condition: !address, - errorMessage: errorMessages.noWalletConn, - }, - { - condition: !selectedDataNft, - errorMessage: errorMessages.noNFTSelected, - }, - ]; - - const shouldReturn = conditions.some(({ condition, errorMessage }) => { - if (condition) { - showErrorToast(errorMessage); - return true; - } - return false; - }); - - if (shouldReturn || !selectedDataNft) { - return; - } - - mintContract.sendBurnTransaction( - address, - selectedDataNft.collection, - selectedDataNft.nonce, - dataNftBurnAmount, - contractsForChain(chainID).dataNftTokens.find((t) => t.id === selectedDataNft.collection)?.contract - ); - - onBurnNFTClose(); - }; - - async function accessDataStream(tokenIdentifier: string, nonce: number) { - try { - onAccessProgressModalOpen(); - - setUnlockAccessProgress((prevProgress) => ({ - ...prevProgress, - s1: 1, - s2: 1, - })); - await sleep(3); - - // auto download the file without ever exposing the url - if (!(tokenLogin && tokenLogin.nativeAuthToken)) { - throw Error(labels.NATIVE_AUTH_TOKEN_MISSING); - } - - DataNft.setNetworkConfig(network.id); - const dataNft = await DataNft.createFromApi({ tokenIdentifier, nonce }); - const arg = { - mvxNativeAuthOrigins: [decodeNativeAuthToken(tokenLogin.nativeAuthToken).origin], - mvxNativeAuthMaxExpirySeconds: 3600, - fwdHeaderMapLookup: { - "authorization": `Bearer ${tokenLogin.nativeAuthToken}`, - }, - }; - const res = await dataNft.viewDataViaMVXNativeAuth(arg); - - if (!res.error) { - const link = document.createElement("a"); - link.target = "_blank"; - link.download = `DataNFT-${nonce}`; - link.href = window.URL.createObjectURL(new Blob([res.data], { type: res.contentType })); - link.click(); - } else { - throw Error(res.error); - } - - setUnlockAccessProgress((prevProgress) => ({ - ...prevProgress, - s3: 1, - })); - } catch (e: any) { - setErrUnlockAccessGeneric(e.toString()); - } - } - - const cleanupAccessDataStreamProcess = () => { - setUnlockAccessProgress({ s1: 0, s2: 0, s3: 0 }); - setErrUnlockAccessGeneric(""); - onAccessProgressModalClose(); - }; - - const onBurnButtonClick = (nft: DataNftType) => { - setSelectedDataNft(nft); - setDataNftBurnAmount(Number(nft.balance)); - setBurnNFTModalState(1); - onBurnNFTOpen(); - }; - - const onListButtonClick = (nft: DataNftType) => { - if (isMarketPaused) { - toast({ - title: "Marketplace is paused", - status: "error", - duration: 9000, - isClosable: true, - }); - } else { - setSelectedDataNft(nft); - onListNFTOpen(); - } - }; - - const onChangeDataNftBurnAmount = (valueAsString: string) => { - let error = ""; - const valueAsNumber = Number(valueAsString); - if (valueAsNumber < 1) { - error = "Burn amount cannot be zero or negative"; - } else if (selectedDataNft && valueAsNumber > Number(selectedDataNft.balance)) { - error = "Data NFT balance exceeded"; - } - - setDataNftBurnAmountError(error); - setDataNftBurnAmount(valueAsNumber); - }; - - const formatButtonNumber = (_price: number, _amount: number) => { - if (_price > 0) { - if (_price >= item.maxPayment) { - return item.maxPayment.toString() + " ITHEUM " + (_amount > 1 ? "each" : ""); - } else { - return _price.toString() + " ITHEUM " + (_amount > 1 ? "each" : ""); - } - } else { - return "Free"; - } - }; - - return ( - - - - item.setHasLoaded(true)} - onClick={() => item.openNftDetailsDrawer(item.index)} - /> - item.setHasLoaded(true)} - onClick={() => item.openNftDetailsDrawer(item.index)} - whileHover={{ opacity: 1, backdropFilter: "blur(1px)", backgroundColor: "#1b1b1ba0" }}> - - - Details - - - - - - - - - {item.tokenName} - - - - -
- - {item.title} - - - - - {transformDescription(item.description)} - - -
-
- - - {item.title} - - - - - - {transformDescription(item.description)} - - - -
- - - Creator:  - navigate(`/profile/${item.creator}`)}> - - - - - - - {`Creation time: ${moment(item.creationTime).format(uxConfig.dateStr)}`} - - - - - - You are the {item.creator !== address ? "Owner" : "Creator"} - - - - - - Fully Transferable License - - - - - - - - - - - {`Balance: ${item.balance}`}
- {`Total supply: ${item.supply}`}
- {`Royalty: ${convertToLocalString(item.royalties * 100)}%`} -
- - - - - - - - - - - - How many to list:{" "} - - { - let error = ""; - const valueAsNumber = Number(value); - if (valueAsNumber <= 0) { - error = "Cannot be zero or negative"; - } else if (valueAsNumber > item.balance) { - error = "Not enough balance"; - } else if (maxListLimit > 0 && valueAsNumber > maxListLimit) { - error = "Cannot exceed max list limit"; - } - - setAmountError(error); - setAmount(valueAsNumber); - }}> - - - - - - - - - - {amountError && ( - - {amountError} - - )} - - - - - - Access fee for each: - - - { - let error = ""; - const valueAsNumber = Number(valueString); - if (valueAsNumber < 0) { - error = "Cannot be negative"; - } else if (valueAsNumber > item.maxPayment ? item.maxPayment : 0) { - error = "Maximum listing fee is" + " " + item.maxPayment; - } - setPriceError(error); - setPrice(valueAsNumber); - }} - keepWithinRange={false}> - - - - - - - - - {priceError && ( - - {priceError} - - )} - - - - - -
-
- - - {selectedDataNft && ( - - - - {burnNFTModalState === 1 ? ( - <> - Burn Supply from my Data NFT - - - - - - - {selectedDataNft.tokenName} - - - - - - You have ownership of {selectedDataNft.balance} Data NFTs (out of a total of {selectedDataNft.supply}). You can burn these{" "} - {selectedDataNft.balance} Data NFTs and remove them from your wallet. - {selectedDataNft.supply - selectedDataNft.balance > 0 && - ` The remaining ${selectedDataNft.supply - selectedDataNft.balance} ${ - selectedDataNft.supply - selectedDataNft.balance > 1 ? "are" : "is" - } not under your ownership.`} - - - - - - Please note that Data NFTs not listed in the Data NFT marketplace are "NOT public" and are "Private" to only you so no - one can see or access them. So only burn Data NFTs if you are sure you want to destroy your Data NFTs for good. Once burned you will not - be able to recover them again. - - - - How many do you want to burn? - - - - - - - - - {dataNftBurnAmountError && ( - - {dataNftBurnAmountError} - - )} - - - - - - - - ) : ( - <> - Are you sure? - - - - Data NFT Title:   - - - {selectedDataNft.title} - - - - - Burn Amount:    - - - {dataNftBurnAmount} - - - - Are you sure you want to proceed with burning the Data NFTs? You cannot undo this action. - - - - - - - - )} - - - )} - {selectedDataNft && ( - - )} - - - - - Data Access Unlock Progress - - - - - {(!unlockAccessProgress.s1 && ) || } - Initiating handshake with Data Marshal - - - - {(!unlockAccessProgress.s3 && ) || } - Verifying data access rights to unlock Data Stream - - - {errUnlockAccessGeneric && ( - - - - - Process Error - - {errUnlockAccessGeneric && {errUnlockAccessGeneric}} - - - - )} - {unlockAccessProgress.s1 && unlockAccessProgress.s2 && unlockAccessProgress.s3 && ( - - )} - - - - -
-
- ); -} From 956588b260a3f361a0f035d68b07fd4bda560434 Mon Sep 17 00:00:00 2001 From: Benedek Robert George Date: Thu, 11 Jan 2024 20:53:54 +0200 Subject: [PATCH 19/46] fix: remove comments & solve display error --- .../DataNFT/DataNFTMarketplaceMultiversX.tsx | 24 ++++--------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx index 9fbab268..c6291632 100644 --- a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx +++ b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx @@ -78,6 +78,7 @@ export const Marketplace: FC = ({ tabState }) => { const updateOffers = useMarketStore((state) => state.updateOffers); const loadingOffers = useMarketStore((state) => state.loadingOffers); const updateLoadingOffers = useMarketStore((state) => state.updateLoadingOffers); + // pagination const pageCount = useMarketStore((state) => state.pageCount); const updatePageCount = useMarketStore((state) => state.updatePageCount); @@ -123,7 +124,6 @@ export const Marketplace: FC = ({ tabState }) => { // start loading offers updateLoadingOffers(true); - ///TODO CHECK IF COLLECTIONS AND MAP IS THE SAME let _offers: OfferType[] = []; const start = 0; if (isApiUp && isMarketplaceApiUp) { @@ -144,16 +144,8 @@ export const Marketplace: FC = ({ tabState }) => { _nonceOfferMap.set(offer.offered_token_nonce, offer); } }); - // if (_nonceOfferMap !== undefined) { - // Array.from(_nonceOfferMap.entries()) - // .slice(0, 20) - // .map(([nonce, offer]) => { - // console.log(nonce, offer); - // }); - // } - setNonceOfferMap(_nonceOfferMap); - //TODO make pagination + setNonceOfferMap(_nonceOfferMap); ///get nftMetadatas for the grouped offers setNftMetadatasLoading(true); @@ -226,10 +218,8 @@ export const Marketplace: FC = ({ tabState }) => { let _offers: OfferType[] = []; const start = pageIndex * pageSize; if (isApiUp && isMarketplaceApiUp) { - // console.log('Api Up'); _offers = await getOffersFromBackendApi(chainID, start, pageSize, tabState === 1 ? undefined : address); } else { - // console.log('Api Down'); _offers = await marketContract.viewPagedOffers(start, start + pageSize - 1, tabState === 1 ? "" : address); } @@ -316,9 +306,6 @@ export const Marketplace: FC = ({ tabState }) => { } }, [pendingTransactions]); - //todo pagination, - // refresh the page when somebody buys something (Haspending transaction) - return ( <> @@ -398,15 +385,14 @@ export const Marketplace: FC = ({ tabState }) => {
- {/* */} {!window.location.href.includes("my") && ( Group by collection - + + + From ec0a3975343ad438d5a3c022f9e454d7bb565e8a Mon Sep 17 00:00:00 2001 From: Enciusan Date: Fri, 12 Jan 2024 11:18:30 +0200 Subject: [PATCH 20/46] #1140 done - freeze data from itheum-enterpirse fixed, started trending/favourite integration --- package-lock.json | 23 ++++-------------- package.json | 2 +- .../DataNftCollection/CurateNfts.tsx | 24 +++++++++++-------- src/pages/Home/HomeMultiversX.tsx | 8 ++++--- src/pages/Home/components/TrendingData.tsx | 18 ++++++++++++++ 5 files changed, 42 insertions(+), 33 deletions(-) create mode 100644 src/pages/Home/components/TrendingData.tsx diff --git a/package-lock.json b/package-lock.json index ae9efa1b..d16e1b40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", "@hookform/resolvers": "3.3.2", - "@itheum/sdk-mx-data-nft": "2.5.0", + "@itheum/sdk-mx-data-nft": "2.6.0", "@itheum/sdk-mx-enterprise": "0.1.0", "@multiversx/sdk-core": "12.17.0", "@multiversx/sdk-dapp": "2.26.0", @@ -29,7 +29,6 @@ "bignumber.js": "9.1.2", "dotenv": "16.3.1", "framer-motion": "10.16.16", - "mime": "4.0.0", "moment": "2.29.4", "nft.storage": "7.1.1", "react": "18.2.0", @@ -4066,9 +4065,9 @@ } }, "node_modules/@itheum/sdk-mx-data-nft": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@itheum/sdk-mx-data-nft/-/sdk-mx-data-nft-2.5.0.tgz", - "integrity": "sha512-horIw/8/1EAuII6uN+fGkePwJ8u4t52MvjJGo/YBSFpujyvJ6i6JbAXaqyVYMWY3GkWnNTTQMblii0dgZ32FWw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@itheum/sdk-mx-data-nft/-/sdk-mx-data-nft-2.6.0.tgz", + "integrity": "sha512-uJY+6Tk6tNq+F2W0QfhwpCMVAZWg57Uo0SwPooKnO7tpXAN3L5m1BPFojKHHra0ZqZTkfRe6eToUVGX+3+rHNA==", "dependencies": { "@multiversx/sdk-core": "12.17.0", "@multiversx/sdk-network-providers": "2.2.0", @@ -22531,20 +22530,6 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.0.tgz", - "integrity": "sha512-pzhgdeqU5pJ9t5WK9m4RT4GgGWqYJylxUf62Yb9datXRwdcw5MjiD1BYI5evF8AgTXN9gtKX3CFLvCUL5fAhEA==", - "funding": [ - "https://github.com/sponsors/broofa" - ], - "bin": { - "mime": "bin/cli.js" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", diff --git a/package.json b/package.json index 8875a752..1096bb9f 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", "@hookform/resolvers": "3.3.2", - "@itheum/sdk-mx-data-nft": "2.5.0", + "@itheum/sdk-mx-data-nft": "2.6.0", "@itheum/sdk-mx-enterprise": "0.1.0", "@multiversx/sdk-core": "12.17.0", "@multiversx/sdk-dapp": "2.26.0", diff --git a/src/pages/Enterprise/components/DataNftCollection/CurateNfts.tsx b/src/pages/Enterprise/components/DataNftCollection/CurateNfts.tsx index cf2272df..166c8e6a 100644 --- a/src/pages/Enterprise/components/DataNftCollection/CurateNfts.tsx +++ b/src/pages/Enterprise/components/DataNftCollection/CurateNfts.tsx @@ -70,11 +70,11 @@ export const CurateNfts: React.FC = (props) => { }); }; - const frozenNoncesAddresses = async () => { - const viewAddressFrozenNonces = await nftMinter.viewAddressFrozenNonces(new Address(address)); - // console.log(viewAddressFrozenNonces); - setAddressFrozenNonces(viewAddressFrozenNonces); - }; + // const frozenNoncesAddresses = async () => { + // // const viewAddressFrozenNonces = await nftMinter.viewAddressFrozenNonces(new Address(address)); + // // console.log(viewAddressFrozenNonces); + // // setAddressFrozenNonces(viewAddressFrozenNonces); + // }; useEffect(() => { getCreatedDataNftsFromAPI(); @@ -82,7 +82,11 @@ export const CurateNfts: React.FC = (props) => { }, [paginationFromNft]); useEffect(() => { - frozenNoncesAddresses(); + (async () => { + const viewAddressFrozenNonces = await nftMinter.viewFrozenNonces(); + console.log(viewAddressFrozenNonces); + setAddressFrozenNonces(viewAddressFrozenNonces); + })(); }, [hasPendingTransactions]); // console.log(addressFrozenNonces); @@ -150,7 +154,7 @@ export const CurateNfts: React.FC = (props) => { return ( {addressFrozenNonces.includes(dataNfts.nonce) && ( - + Frozen @@ -170,7 +174,7 @@ export const CurateNfts: React.FC = (props) => {