From 0e6705596eef7763fbe47f74350c0b557ad222a3 Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 8 Feb 2024 10:48:31 +0200 Subject: [PATCH 1/9] wip: refactor marketplace to use sdk --- src/components/MarketplaceLowerCard.tsx | 7 +- src/components/MyListedDataLowerCard.tsx | 19 +- src/components/MyListedDataNFT.tsx | 13 +- src/components/ProcureDataNFTModal.tsx | 53 +-- src/components/Sections/RecentDataNFTs.tsx | 14 +- .../UtilComps/UpperCardComponent.tsx | 13 +- src/libs/MultiversX/backend-api.ts | 18 +- src/libs/MultiversX/dataNftMarket.ts | 318 ++++-------------- src/libs/MultiversX/types.ts | 31 +- src/libs/language.ts | 1 + src/pages/DataNFT/DataNFTDetails.tsx | 14 +- .../DataNFT/DataNFTMarketplaceMultiversX.tsx | 21 +- .../Profile/components/DataCreatorTabs.tsx | 9 +- src/store/market.ts | 7 +- 14 files changed, 182 insertions(+), 356 deletions(-) diff --git a/src/components/MarketplaceLowerCard.tsx b/src/components/MarketplaceLowerCard.tsx index d3dc729e..f39da3d9 100644 --- a/src/components/MarketplaceLowerCard.tsx +++ b/src/components/MarketplaceLowerCard.tsx @@ -21,13 +21,14 @@ import ProcureDataNFTModal from "components/ProcureDataNFTModal"; import ExploreAppButton from "components/UtilComps/ExploreAppButton"; import { PREVIEW_DATA_ON_DEVNET_SESSION_KEY } from "libs/config"; import { useLocalStorage } from "libs/hooks"; -import { DataNftMetadataType, OfferType } from "libs/MultiversX/types"; +import { DataNftMetadataType } from "libs/MultiversX/types"; import { isValidNumericCharacter, shouldPreviewDataBeEnabled, viewDataDisabledMessage } from "libs/utils"; import { useMarketStore } from "store"; import PreviewDataButton from "./PreviewDataButton"; +import { Offer } from "@itheum/sdk-mx-data-nft/out"; type MarketplaceLowerCardProps = { - offer: OfferType; + offer: Offer; nftMetadata: DataNftMetadataType; }; @@ -50,7 +51,7 @@ const MarketplaceLowerCard: FC = ({ offer, nftMetadat - + {!isMyNft ? ( diff --git a/src/components/MyListedDataLowerCard.tsx b/src/components/MyListedDataLowerCard.tsx index 36f9f995..45ee225c 100644 --- a/src/components/MyListedDataLowerCard.tsx +++ b/src/components/MyListedDataLowerCard.tsx @@ -27,7 +27,7 @@ import BigNumber from "bignumber.js"; import { PREVIEW_DATA_ON_DEVNET_SESSION_KEY, contractsForChain } from "libs/config"; import { useLocalStorage } from "libs/hooks"; import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; -import { DataNftMetadataType, OfferType } from "libs/MultiversX/types"; +import { DataNftMetadataType } from "libs/MultiversX/types"; import { convertToLocalString, convertEsdtToWei, @@ -42,9 +42,10 @@ import { } from "libs/utils"; import { useMarketStore } from "store"; import PreviewDataButton from "./PreviewDataButton"; +import { Offer } from "@itheum/sdk-mx-data-nft/out"; type MyListedDataLowerCardProps = { - offer: OfferType; + offer: Offer; nftMetadata: DataNftMetadataType; }; @@ -137,7 +138,7 @@ const MyListedDataLowerCard: FC = ({ offer, nftMetad const price = newPrice + (newPrice * (marketRequirements.buyerTaxPercentage ?? 200)) / 10000; - const requestBody = { price: convertEsdtToWei(price, tokenDecimals(offer.wanted_token_identifier)).toFixed() }; + const requestBody = { price: convertEsdtToWei(price, tokenDecimals(offer.wantedTokenIdentifier)).toFixed() }; const response = await fetch(`${backendUrl}/updateOffer/${index}`, { method: "POST", headers: headers, @@ -185,8 +186,8 @@ const MyListedDataLowerCard: FC = ({ offer, nftMetad const fee = marketRequirements && offer ? convertWeiToEsdt( - new BigNumber(offer.wanted_token_amount).multipliedBy(10000).div(10000 + (marketRequirements.buyerTaxPercentage as number)), - tokenDecimals(offer.wanted_token_identifier) + new BigNumber(offer.wantedTokenAmount).multipliedBy(10000).div(10000 + (marketRequirements.buyerTaxPercentage as number)), + tokenDecimals(offer.wantedTokenIdentifier) ).toNumber() : 0; @@ -250,7 +251,7 @@ const MyListedDataLowerCard: FC = ({ offer, nftMetad const { sessionId: sessionIdTemp } = await contract.updateOfferPrice( offer.index, - convertEsdtToWei(newListingPrice, tokenDecimals(offer.wanted_token_identifier)).toFixed(), + convertEsdtToWei(newListingPrice, tokenDecimals(offer.wantedTokenIdentifier)).toFixed(), address ); if (isWebWallet) { @@ -290,8 +291,8 @@ const MyListedDataLowerCard: FC = ({ offer, nftMetad if (marketRequirements) { setNewListingPrice( convertWeiToEsdt( - new BigNumber(offer.wanted_token_amount).multipliedBy(10000).div(10000 + marketRequirements.buyerTaxPercentage), - tokenDecimals(offer.wanted_token_identifier) + new BigNumber(offer.wantedTokenAmount).multipliedBy(10000).div(10000 + marketRequirements.buyerTaxPercentage), + tokenDecimals(offer.wantedTokenIdentifier) ).toNumber() ); } else { @@ -455,7 +456,7 @@ const MyListedDataLowerCard: FC = ({ offer, nftMetad Current Fee per Data NFT - : {fee} {getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)}{" "} + : {fee} {getTokenWantedRepresentation(offer.wantedTokenIdentifier, offer.wantedTokenNonce)}{" "} {fee && itheumPrice ? `(~${convertToLocalString(fee * itheumPrice, 2)} USD)` : ""} diff --git a/src/components/MyListedDataNFT.tsx b/src/components/MyListedDataNFT.tsx index 84f2e0c5..0e0ab8c1 100644 --- a/src/components/MyListedDataNFT.tsx +++ b/src/components/MyListedDataNFT.tsx @@ -27,7 +27,7 @@ import ShortAddress from "components/UtilComps/ShortAddress"; import { CHAIN_TX_VIEWER, uxConfig, PREVIEW_DATA_ON_DEVNET_SESSION_KEY } from "libs/config"; import { useLocalStorage } from "libs/hooks"; import { getApi } from "libs/MultiversX/api"; -import { DataNftMetadataType, OfferType } from "libs/MultiversX/types"; +import { DataNftMetadataType } from "libs/MultiversX/types"; import { convertWeiToEsdt, convertToLocalString, @@ -40,9 +40,10 @@ import { import { useMarketStore, useMintStore } from "store"; import FrozenOverlay from "./FrozenOverlay"; import PreviewDataButton from "./PreviewDataButton"; +import { Offer } from "@itheum/sdk-mx-data-nft/out"; type MyListedDataNFTProps = { - offer: OfferType; + offer: Offer; offers: Record; nftImageLoading: boolean; setNftImageLoading: Dispatch>; @@ -93,7 +94,7 @@ const MyListedDataNFT: FC = (props) => { {"item.dataPreview"} = (props) => { Unlock from: {` `} {printPrice( - convertWeiToEsdt(offer.wanted_token_amount, tokenDecimals(offer.wanted_token_identifier)).toNumber(), - getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce) + convertWeiToEsdt(offer.wantedTokenAmount, tokenDecimals(offer.wantedTokenIdentifier)).toNumber(), + getTokenWantedRepresentation(offer.wantedTokenIdentifier, offer.wantedTokenNonce) )} @@ -259,7 +260,7 @@ const MyListedDataNFT: FC = (props) => { diff --git a/src/components/ProcureDataNFTModal.tsx b/src/components/ProcureDataNFTModal.tsx index 6c6b12ef..c3b74c3d 100644 --- a/src/components/ProcureDataNFTModal.tsx +++ b/src/components/ProcureDataNFTModal.tsx @@ -19,7 +19,7 @@ import { useGetAccountInfo, useGetLoginInfo, useGetNetworkConfig, useGetSignedTr import BigNumber from "bignumber.js"; import DataNFTLiveUptime from "components/UtilComps/DataNFTLiveUptime"; import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; -import { DataNftMetadataType, OfferType } from "libs/MultiversX/types"; +import { DataNftMetadataType } from "libs/MultiversX/types"; import { convertEsdtToWei, convertWeiToEsdt, @@ -31,13 +31,14 @@ import { backendApi, } from "libs/utils"; import { useAccountStore, useMarketStore } from "store"; +import { Offer } from "@itheum/sdk-mx-data-nft/out"; export interface ProcureAccessModalProps { isOpen: boolean; onClose: () => void; buyerFee: number; nftData: DataNftMetadataType; - offer: OfferType; + offer: Offer; amount: number; setSessionId?: (e: any) => void; } @@ -60,10 +61,10 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData const backendUrl = backendApi(chainID); const feePrice = printPrice( - convertWeiToEsdt(Number(offer.wanted_token_amount) * amount, tokenDecimals(offer.wanted_token_identifier)).toNumber(), - getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce) + convertWeiToEsdt(Number(offer.wantedTokenAmount) * amount, tokenDecimals(offer.wantedTokenIdentifier)).toNumber(), + getTokenWantedRepresentation(offer.wantedTokenIdentifier, offer.wantedTokenNonce) ); - const fee = convertWeiToEsdt(offer.wanted_token_amount, tokenDecimals(offer.wanted_token_identifier)).toNumber(); + const fee = convertWeiToEsdt(offer.wantedTokenAmount, tokenDecimals(offer.wantedTokenIdentifier)).toNumber(); const [readTermsChecked, setReadTermsChecked] = useState(false); const [liveUptimeFAIL, setLiveUptimeFAIL] = useState(true); const [isLiveUptimeSuccessful, setIsLiveUptimeSuccessful] = useState(false); @@ -172,12 +173,12 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData } } - const paymentAmount = new BigNumber(offer.wanted_token_amount).multipliedBy(amount); + const paymentAmount = new BigNumber(offer.wantedTokenAmount).multipliedBy(amount); - if (offer.wanted_token_identifier == "EGLD") { + if (offer.wantedTokenIdentifier == "EGLD") { marketContract.sendAcceptOfferEgldTransaction(offer.index, paymentAmount.toFixed(), amount, address); } else { - if (offer.wanted_token_nonce === 0) { + if (offer.wantedTokenNonce === 0) { //Check if we buy all quantity, use web wallet and are on that offer's details page and thus should use callback route const isOnOfferPage = window.location.pathname.includes("/offer-"); const shouldUseCallbackRoute = isWebWallet && amount == offer.quantity && isOnOfferPage; @@ -186,7 +187,7 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData const { sessionId } = await marketContract.sendAcceptOfferEsdtTransaction( offer.index, paymentAmount.toFixed(), - offer.wanted_token_identifier, + offer.wantedTokenIdentifier, amount as never, address, shouldUseCallbackRoute ? callbackRoute : undefined @@ -203,8 +204,8 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData const { sessionId } = await marketContract.sendAcceptOfferNftEsdtTransaction( offer.index, paymentAmount.toFixed(), - offer.wanted_token_identifier, - offer.wanted_token_nonce, + offer.wantedTokenIdentifier, + offer.wantedTokenNonce, amount as never, address ); @@ -264,10 +265,10 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData <> {printPrice( convertWeiToEsdt( - new BigNumber(offer.wanted_token_amount).multipliedBy(10000).div(10000 + buyerFee), - tokenDecimals(offer.wanted_token_identifier) + new BigNumber(offer.wantedTokenAmount).multipliedBy(10000).div(10000 + buyerFee), + tokenDecimals(offer.wantedTokenIdentifier) ).toNumber(), - getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce) + getTokenWantedRepresentation(offer.wantedTokenIdentifier, offer.wantedTokenNonce) )} ) : ( @@ -276,7 +277,7 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData - {new BigNumber(offer.wanted_token_amount).multipliedBy(amount).comparedTo(convertEsdtToWei(itheumBalance)) > 0 && ( + {new BigNumber(offer.wantedTokenAmount).multipliedBy(amount).comparedTo(convertEsdtToWei(itheumBalance)) > 0 && ( Your wallet token balance is too low to proceed @@ -288,9 +289,9 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData :{" "} {buyerFee ? `${buyerFee / 100}% (${convertWeiToEsdt( - new BigNumber(offer.wanted_token_amount).multipliedBy(buyerFee).div(10000 + buyerFee), - tokenDecimals(offer.wanted_token_identifier) - ).toNumber()} ${getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)})` + new BigNumber(offer.wantedTokenAmount).multipliedBy(buyerFee).div(10000 + buyerFee), + tokenDecimals(offer.wantedTokenIdentifier) + ).toNumber()} ${getTokenWantedRepresentation(offer.wantedTokenIdentifier, offer.wantedTokenNonce)})` : "-"} @@ -312,29 +313,29 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData {buyerFee ? ( <> - {new BigNumber(offer.wanted_token_amount).comparedTo(0) <= 0 ? ( + {new BigNumber(offer.wantedTokenAmount).comparedTo(0) <= 0 ? ( "" ) : ( <> {" " + convertWeiToEsdt( - new BigNumber(offer.wanted_token_amount) + new BigNumber(offer.wantedTokenAmount) .multipliedBy(amount) .multipliedBy(10000) .div(10000 + buyerFee), - tokenDecimals(offer.wanted_token_identifier) + tokenDecimals(offer.wantedTokenIdentifier) ).toNumber() + " "} - {getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)} + {getTokenWantedRepresentation(offer.wantedTokenIdentifier, offer.wantedTokenNonce)} {" + "} {convertWeiToEsdt( - new BigNumber(offer.wanted_token_amount) + new BigNumber(offer.wantedTokenAmount) .multipliedBy(amount) .multipliedBy(buyerFee) .div(10000 + buyerFee), - tokenDecimals(offer.wanted_token_identifier) + tokenDecimals(offer.wantedTokenIdentifier) ).toNumber()} - {" " + getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)} + {" " + getTokenWantedRepresentation(offer.wantedTokenIdentifier, offer.wantedTokenNonce)} )} @@ -375,7 +376,7 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData isDisabled={ !readTermsChecked || liveUptimeFAIL || - new BigNumber(offer.wanted_token_amount).multipliedBy(amount).comparedTo(convertEsdtToWei(itheumBalance)) > 0 || + new BigNumber(offer.wantedTokenAmount).multipliedBy(amount).comparedTo(convertEsdtToWei(itheumBalance)) > 0 || !isLiveUptimeSuccessful }> Proceed diff --git a/src/components/Sections/RecentDataNFTs.tsx b/src/components/Sections/RecentDataNFTs.tsx index b76845c3..79b701b8 100644 --- a/src/components/Sections/RecentDataNFTs.tsx +++ b/src/components/Sections/RecentDataNFTs.tsx @@ -122,28 +122,28 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea const offers = await marketContract.viewOffers(startIndex, stopIndex); const slicedOffers = offers.slice(0, 10); // get these offers metadata from the API - const nftIds = slicedOffers.map((offer) => `${offer.offered_token_identifier}-${hexZero(offer.offered_token_nonce)}`); + const nftIds = slicedOffers.map((offer) => `${offer.offeredTokenIdentifier}-${hexZero(offer.offeredTokenNonce)}`); const dataNfts = await getNftsByIds(nftIds, chainID); // merge the offer data and meta data const _latestOffers: DataNftCondensedView[] = []; slicedOffers.forEach((offer, idx) => { - const _nft = dataNfts.find((nft) => `${offer.offered_token_identifier}-${hexZero(offer.offered_token_nonce)}` === nft.identifier); + const _nft = dataNfts.find((nft) => `${offer.offeredTokenIdentifier}-${hexZero(offer.offeredTokenNonce)}` === nft.identifier); if (_nft !== undefined) { const _nftMetaData = mintContract.decodeNftAttributes(_nft, idx); - const tokenAmount = convertWeiToEsdt(new BigNumber(offer.wanted_token_amount)).toNumber(); + const tokenAmount = convertWeiToEsdt(new BigNumber(offer.wantedTokenAmount)).toNumber(); _latestOffers.push({ data_nft_id: _nftMetaData.id, - offered_token_identifier: offer.offered_token_identifier, - offered_token_nonce: offer.offered_token_nonce, + offered_token_identifier: offer.offeredTokenIdentifier, + offered_token_nonce: offer.offeredTokenNonce, offer_index: offer.index, - offered_token_amount: offer.offered_token_amount, + offered_token_amount: offer.offeredTokenAmount, quantity: offer.quantity, - wanted_token_amount: offer.wanted_token_amount, + wanted_token_amount: offer.wantedTokenAmount, creator: _nftMetaData.creator, tokenName: _nftMetaData.tokenName, title: _nftMetaData.title, diff --git a/src/components/UtilComps/UpperCardComponent.tsx b/src/components/UtilComps/UpperCardComponent.tsx index 10be372d..d0b70fea 100644 --- a/src/components/UtilComps/UpperCardComponent.tsx +++ b/src/components/UtilComps/UpperCardComponent.tsx @@ -28,18 +28,19 @@ import { MdOutlineInfo } from "react-icons/md"; import { useNavigate } from "react-router-dom"; import FrozenOverlay from "components/FrozenOverlay"; import { CHAIN_TX_VIEWER, uxConfig } from "libs/config"; -import { DataNftMetadataType, OfferType } from "libs/MultiversX/types"; +import { DataNftMetadataType } from "libs/MultiversX/types"; 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 { Offer } from "@itheum/sdk-mx-data-nft/out"; type UpperCardComponentProps = { nftImageLoading: boolean; setNftImageLoaded: Dispatch>; imageUrl: string; nftMetadata: DataNftMetadataType; - offer: OfferType; + offer: Offer; index: number; marketFreezedNonces: number[]; children?: React.ReactNode; @@ -71,11 +72,11 @@ const UpperCardComponent: FC = ({ const feePrice = offer ? printPrice( - convertWeiToEsdt(offer.wanted_token_amount as BigNumber.Value, tokenDecimals(offer.wanted_token_identifier)).toNumber(), - getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce) + convertWeiToEsdt(offer.wantedTokenAmount as BigNumber.Value, tokenDecimals(offer.wantedTokenIdentifier)).toNumber(), + getTokenWantedRepresentation(offer.wantedTokenIdentifier, offer.wantedTokenNonce) ) : ""; - const fee = offer ? convertWeiToEsdt(offer.wanted_token_amount as BigNumber.Value, tokenDecimals(offer.wanted_token_identifier)).toNumber() : 0; + const fee = offer ? convertWeiToEsdt(offer.wantedTokenAmount as BigNumber.Value, tokenDecimals(offer.wantedTokenIdentifier)).toNumber() : 0; const isMobile = window.innerWidth <= 480; return ( @@ -259,7 +260,7 @@ const UpperCardComponent: FC = ({ (userData.addressFrozen || (userData.frozenNonces && offer && - (userData.frozenNonces.includes(offer.offered_token_nonce) || marketFreezedNonces.includes(offer.offered_token_nonce)))) + (userData.frozenNonces.includes(offer.offeredTokenNonce) || marketFreezedNonces.includes(offer.offeredTokenNonce)))) } /> diff --git a/src/libs/MultiversX/backend-api.ts b/src/libs/MultiversX/backend-api.ts index 126953c2..f3e80532 100644 --- a/src/libs/MultiversX/backend-api.ts +++ b/src/libs/MultiversX/backend-api.ts @@ -1,8 +1,8 @@ -import { MarketplaceRequirements } from "@itheum/sdk-mx-data-nft/out"; +import { MarketplaceRequirements, Offer } from "@itheum/sdk-mx-data-nft/out"; import axios from "axios"; import { backendApi } from "libs/utils"; import { uxConfig } from "."; -import { DataNftCollectionType, Favorite, OfferType, TrendingNft } from "./types"; +import { DataNftCollectionType, Favorite, TrendingNft } from "./types"; export async function getHealthCheckFromBackendApi(chainID: string): Promise { try { @@ -119,13 +119,13 @@ export async function getOffersCountFromBackendApi(chainID: string, address?: st } } -export async function getOffersFromBackendApi(chainID: string, from: number, size: number, address?: string): Promise { +export async function getOffersFromBackendApi(chainID: string, from: number, size: number, address?: string): Promise { try { let url = `${backendApi(chainID)}/offers?from=${from}&size=${size}`; if (address) { url += `&address=${address}`; } - const { data } = await axios.get(url, { + const { data } = await axios.get(url, { timeout: uxConfig.mxAPITimeoutMs, }); return data; @@ -137,7 +137,7 @@ export async function getOffersFromBackendApi(chainID: string, from: number, siz export async function getOfersAsCollectionFromBackendApi(chainID: string): Promise { try { - let url = `${backendApi(chainID)}/data-nfts`; + const url = `${backendApi(chainID)}/data-nfts`; const { data } = await axios.get(url, { timeout: uxConfig.mxAPITimeoutMs, @@ -149,10 +149,10 @@ export async function getOfersAsCollectionFromBackendApi(chainID: string): Promi } } -export async function getRecentOffersFromBackendApi(chainID: string): Promise { +export async function getRecentOffersFromBackendApi(chainID: string): Promise { try { const url = `${backendApi(chainID)}/offers/recent`; - const { data } = await axios.get(url, { + const { data } = await axios.get(url, { timeout: uxConfig.mxAPITimeoutMs, }); @@ -169,7 +169,7 @@ export async function getOffersByIdAndNoncesFromBackendApi( nonces: number[], from?: number, size?: number -): Promise { +): Promise { if (nonces.length === 0) { throw Error("getOffersByIdAndNoncesFromBackendApi: nonces must not be empty."); } @@ -182,7 +182,7 @@ export async function getOffersByIdAndNoncesFromBackendApi( url += `&size=${size}`; } - const { data } = await axios.get(url, { + const { data } = await axios.get(url, { timeout: uxConfig.mxAPITimeoutMs, }); diff --git a/src/libs/MultiversX/dataNftMarket.ts b/src/libs/MultiversX/dataNftMarket.ts index cdafef21..74c0c2a0 100644 --- a/src/libs/MultiversX/dataNftMarket.ts +++ b/src/libs/MultiversX/dataNftMarket.ts @@ -1,4 +1,5 @@ import { useToast } from "@chakra-ui/react"; +import { DataNftMarket, Offer } from "@itheum/sdk-mx-data-nft/out"; import { AbiRegistry, SmartContract, @@ -20,91 +21,33 @@ import { import { sendTransactions } from "@multiversx/sdk-dapp/services"; import { refreshAccount } from "@multiversx/sdk-dapp/utils/account"; import BigNumber from "bignumber.js"; -import { uxConfig } from "libs/config"; +import { contractsForChain, uxConfig } from "libs/config"; import { labels } from "libs/language"; -import jsonData from "./ABIs/data_market.abi.json"; import { getNetworkProvider } from "./api"; -import { MarketplaceRequirementsType, OfferType } from "./types"; -import { contractsForChain } from "../config"; +import { MarketplaceRequirementsType } from "./types"; export class DataNftMarketContract { - timeout: number; - dataNftMarketContractAddress: any; - chainID: string; - contract: SmartContract; + contract: DataNftMarket; itheumToken: string; toast = useToast(); constructor(chainID: string) { - this.timeout = uxConfig.mxAPITimeoutMs; - this.dataNftMarketContractAddress = contractsForChain(chainID).market; - this.chainID = chainID; - - const json = JSON.parse(JSON.stringify(jsonData)); - const abiRegistry = AbiRegistry.create(json); - - this.contract = new SmartContract({ - address: new Address(this.dataNftMarketContractAddress), - abi: abiRegistry, - }); - - this.itheumToken = contractsForChain(chainID).itheumToken as unknown as string; - } - - async viewNumberOfOffers() { - const interaction = this.contract.methods.viewNumberOfOffers([]); - const query = interaction.buildQuery(); - - try { - const networkProvider = getNetworkProvider(this.chainID); - - const res = await networkProvider.queryContract(query); - const endpointDefinition = interaction.getEndpoint(); - - const { firstValue, returnCode } = new ResultsParser().parseQueryResponse(res, endpointDefinition); - - if (returnCode && returnCode.isSuccess()) { - const firstValueAsStruct = firstValue as U32Value; - return firstValueAsStruct.valueOf().toNumber(); - } else { - const nonOKErr = new Error("viewNumberOfOffers returnCode returned a non OK value"); - console.error(nonOKErr); - - return 0; - } - } catch (error) { - console.error(error); - - return 0; + let env = "devnet"; + if (chainID === "1") { + env = "mainnet"; } + this.contract = new DataNftMarket(env, uxConfig.mxAPITimeoutMs); + this.itheumToken = contractsForChain(chainID).itheumToken as unknown as string; // TODO: check if working without last part } - async sendAcceptOfferEsdtTransaction(index: number, paymentAmount: string, tokenId: string, amount: number, sender: string, callbackRoute?: string) { - const data = - new BigNumber(paymentAmount).comparedTo(0) > 0 - ? new ContractCallPayloadBuilder() - .setFunction(new ContractFunction("ESDTTransfer")) - .addArg(new TokenIdentifierValue(tokenId)) - .addArg(new BigUIntValue(paymentAmount)) - .addArg(new StringValue("acceptOffer")) - .addArg(new U64Value(index)) - .addArg(new BigUIntValue(amount)) - .build() - : new ContractCallPayloadBuilder() - .setFunction(new ContractFunction("acceptOffer")) - .addArg(new U64Value(index)) - .addArg(new BigUIntValue(amount)) - .build(); - - const offerEsdtTx = new Transaction({ - value: 0, - data, - receiver: new Address(this.dataNftMarketContractAddress), - sender: new Address(sender), - gasLimit: 20000000, - chainID: this.chainID, - }); + async sendAcceptOfferEsdtTransaction(index: number, paymentAmount: string, tokenId: string, amount: BigNumber.Value, sender: string, callbackRoute?: string) { + let offerEsdtTx; + if (new BigNumber(paymentAmount).comparedTo(0) > 0) { + offerEsdtTx = this.contract.acceptOfferWithESDT(new Address(sender), index, amount, new BigNumber(paymentAmount), tokenId); + } else { + offerEsdtTx = this.contract.acceptOfferWithNoPayment(new Address(sender), index, amount); + } await refreshAccount(); @@ -138,7 +81,7 @@ export class DataNftMarketContract { .addArg(new TokenIdentifierValue(tokenId)) .addArg(new U64Value(nonce)) .addArg(new BigUIntValue(paymentAmount)) - .addArg(new AddressValue(new Address(this.dataNftMarketContractAddress))) + .addArg(new AddressValue(this.contract.getContractAddress())) .addArg(new StringValue("acceptOffer")) .addArg(new U64Value(index)) .addArg(new BigUIntValue(amount)) @@ -146,7 +89,7 @@ export class DataNftMarketContract { receiver: new Address(senderAddress), sender: new Address(senderAddress), gasLimit: 20000000, - chainID: this.chainID, + chainID: this.contract.chainID, }); await refreshAccount(); @@ -165,19 +108,8 @@ export class DataNftMarketContract { return { sessionId, error }; } - async sendAcceptOfferEgldTransaction(index: number, paymentAmount: string, amount: number, senderAddress: string) { - const offerEgldTx = new Transaction({ - value: paymentAmount, - data: new ContractCallPayloadBuilder() - .setFunction(new ContractFunction("acceptOffer")) - .addArg(new U64Value(index)) - .addArg(new BigUIntValue(amount)) - .build(), - receiver: new Address(this.dataNftMarketContractAddress), - gasLimit: 20000000, - sender: new Address(senderAddress), - chainID: this.chainID, - }); + async sendAcceptOfferEgldTransaction(index: number, paymentAmount: string, amount: BigNumber.Value, senderAddress: string) { + const offerEgldTx = this.contract.acceptOfferWithEGLD(new Address(senderAddress), index, amount, new BigNumber(paymentAmount)); await refreshAccount(); @@ -195,18 +127,7 @@ export class DataNftMarketContract { } async sendCancelOfferTransaction(index: number, senderAddress: string) { - const cancelTx = new Transaction({ - value: 0, - data: new ContractCallPayloadBuilder() - .setFunction(new ContractFunction("cancelOffer")) - .addArg(new U64Value(index)) - .addArg(new BooleanValue(true)) - .build(), - receiver: new Address(this.dataNftMarketContractAddress), - gasLimit: 20000000, - sender: new Address(senderAddress), - chainID: this.chainID, - }); + const cancelTx = this.contract.cancelOffer(new Address(senderAddress), index); await refreshAccount(); @@ -223,30 +144,22 @@ export class DataNftMarketContract { return { sessionId, error }; } - async addToMarket(addTokenCollection: string, addTokenNonce: number, addTokenQuantity: number, price: number, addressOfSender: string) { - const addERewTx = new Transaction({ - value: 0, - data: new ContractCallPayloadBuilder() - .setFunction(new ContractFunction("ESDTNFTTransfer")) //method - .addArg(new TokenIdentifierValue(addTokenCollection)) //what token id to send - .addArg(new U64Value(addTokenNonce)) //what token nonce to send - .addArg(new BigUIntValue(addTokenQuantity)) //how many tokens to send - .addArg(new AddressValue(new Address(this.dataNftMarketContractAddress))) //address to send to - .addArg(new StringValue("addOffer")) //what method to call on the contract - .addArg(new TokenIdentifierValue(this.itheumToken)) //what token id to ask for - .addArg(new U64Value(0)) //what nonce to ask for - .addArg(new BigUIntValue(price * 10 ** 18)) //how much to ask for - .addArg(new BigUIntValue(0)) // minimum amount for seller - setting will be introduced in the future - .addArg(new BigUIntValue(addTokenQuantity)) //how many times to divide the amount of tokens sent into - .build(), - receiver: new Address(addressOfSender), - sender: new Address(addressOfSender), - gasLimit: 20000000, - chainID: this.chainID, - }); + async addToMarket(addTokenCollection: string, addTokenNonce: number, addTokenQuantity: number, price: BigNumber.Value, addressOfSender: string) { + const addToMarketTx = this.contract.addOffer( + new Address(addressOfSender), + addTokenCollection, + addTokenNonce, + addTokenQuantity, + this.itheumToken, + 0, + new BigNumber(price).multipliedBy(10 ** 18), + 0 + ); + await refreshAccount(); + const { sessionId, error } = await sendTransactions({ - transactions: addERewTx, + transactions: addToMarketTx, transactionsDisplayInfo: { processingMessage: "Adding Data NFT to marketplace", errorMessage: "Error occurred", @@ -259,26 +172,12 @@ export class DataNftMarketContract { } async delistDataNft(index: number, delistAmount: number, senderAddress: string) { - const data = new ContractCallPayloadBuilder() - .setFunction(new ContractFunction("cancelOffer")) - .addArg(new U64Value(index)) - .addArg(new BigUIntValue(delistAmount)) - .addArg(new BooleanValue(true)) - .build(); - - const tx = new Transaction({ - value: "0", - data, - receiver: new Address(this.dataNftMarketContractAddress), - gasLimit: 20000000, - sender: new Address(senderAddress), - chainID: this.chainID, - }); + const cancelOfferTx = this.contract.cancelOffer(new Address(senderAddress), index); await refreshAccount(); const { sessionId, error } = await sendTransactions({ - transactions: tx, + transactions: cancelOfferTx, transactionsDisplayInfo: { processingMessage: "De-Listing offer", errorMessage: "Error occurred during de-listing offer", @@ -291,38 +190,30 @@ export class DataNftMarketContract { return { sessionId, error }; } - async viewRequirements(): Promise { - const interaction = this.contract.methodsExplicit.viewRequirements(); - const query = interaction.buildQuery(); - + async viewNumberOfOffers() { try { - const networkProvider = getNetworkProvider(this.chainID); - - const res = await networkProvider.queryContract(query); - const endpointDefinition = interaction.getEndpoint(); - const { firstValue, returnCode, returnMessage } = new ResultsParser().parseQueryResponse(res, endpointDefinition); - - if (!firstValue || !returnCode.isSuccess()) { - console.error(returnMessage); - return undefined; - } + const numberOfOffers = await this.contract.viewNumberOfOffers(); + return numberOfOffers; + } catch (e) { + console.error(e); + this.toast({ + title: labels.ERR_MARKET_NR_OFFERS_FAIL, + status: "error", + isClosable: true, + duration: 20000, + }); + return undefined; + } + } - const value = firstValue.valueOf(); - const decoded = { - accepted_tokens: value.accepted_tokens.map((v: any) => v.toString()), - accepted_payments: value.accepted_payments.map((v: any) => v.toString()), - maximum_payment_fees: value.maximum_payment_fees.map((v: any) => v.toFixed()), - discount_fee_percentage_buyer: value.discount_fee_percentage_buyer.toNumber(), - discount_fee_percentage_seller: value.discount_fee_percentage_seller.toNumber(), - percentage_cut_from_buyer: value.percentage_cut_from_buyer.toNumber(), - percentage_cut_from_seller: value.percentage_cut_from_seller.toNumber(), - buyer_fee: 0, - seller_fee: 0, + async viewRequirements(): Promise { + try { + const marketplaceRequirements = await this.contract.viewRequirements(); + return { + ...marketplaceRequirements, + buyerFee: marketplaceRequirements.buyerTaxPercentage - marketplaceRequirements.buyerTaxPercentageDiscount, + sellerFee: marketplaceRequirements.sellerTaxPercentage - marketplaceRequirements.sellerTaxPercentageDiscount, }; - decoded.buyer_fee = decoded.percentage_cut_from_buyer - decoded.discount_fee_percentage_buyer; - decoded.seller_fee = decoded.percentage_cut_from_seller - decoded.discount_fee_percentage_seller; - - return decoded; } catch (e) { console.error(e); this.toast({ @@ -335,7 +226,8 @@ export class DataNftMarketContract { } } - async viewOffers(startIndex: number, stopIndex: number): Promise { + //TODO: change to SDK + async viewOffers(startIndex: number, stopIndex: number): Promise { // this will spread out a new array from startIndex to stopIndex e.g. startIndex=0, stopIndex=5 : you get [1,2,3,4,5] const indexRange = Array.from({ length: stopIndex - startIndex }, (_, i) => new U64Value(startIndex + 1 + i)); @@ -380,13 +272,9 @@ export class DataNftMarketContract { } } - async viewPagedOffers(startIndex: number, stopIndex: number, userAddress?: string): Promise { - const interaction = this.contract.methodsExplicit.viewPagedOffers([ - new U64Value(startIndex), - new U64Value(stopIndex), - userAddress ? new OptionalValue(new AddressType(), new AddressValue(new Address(userAddress))) : OptionalValue.newMissing(), - ]); - const query = interaction.buildQuery(); + //TODO: add user address when SDK supports it + async viewPagedOffers(startIndex: number, stopIndex: number, userAddress?: string): Promise { + const pagedOffers = await this.contract.viewPagedOffers(startIndex, stopIndex); try { const networkProvider = getNetworkProvider(this.chainID); @@ -426,7 +314,8 @@ export class DataNftMarketContract { } } - async viewOffer(index: number): Promise { + //TODO: change this to SDK when it supports it + async viewOffer(index: number): Promise { const interaction = this.contract.methodsExplicit.viewOffer([new U64Value(index)]); const query = interaction.buildQuery(); @@ -469,25 +358,9 @@ export class DataNftMarketContract { } async viewUserTotalOffers(userAddress: string): Promise { - const interaction = this.contract.methodsExplicit.viewUserTotalOffers([new AddressValue(new Address(userAddress))]); - const query = interaction.buildQuery(); - try { - const networkProvider = getNetworkProvider(this.chainID); - - const res = await networkProvider.queryContract(query); - const endpointDefinition = interaction.getEndpoint(); - const { firstValue, returnCode, returnMessage } = new ResultsParser().parseQueryResponse(res, endpointDefinition); - - if (!firstValue || !returnCode.isSuccess()) { - console.error(returnMessage); - return 0; - } - - const value = firstValue.valueOf(); - const decoded = value.toNumber(); - - return decoded; + const userTotalOffers = await this.contract.viewAddressTotalOffers(new Address(userAddress)); + return userTotalOffers; } catch (e) { console.error(e); this.toast({ @@ -501,26 +374,12 @@ export class DataNftMarketContract { } async updateOfferPrice(index: number, newPrice: string, senderAddress: string) { - const data = new ContractCallPayloadBuilder() - .setFunction(new ContractFunction("changeOfferPrice")) - .addArg(new U64Value(index)) - .addArg(new BigUIntValue(newPrice)) - .addArg(new BigUIntValue(0)) - .build(); - - const tx = new Transaction({ - value: "0", - data, - receiver: new Address(this.dataNftMarketContractAddress), - gasLimit: 20000000, - sender: new Address(senderAddress), - chainID: this.chainID, - }); + const changeOfferPriceTx = await this.contract.changeOfferPrice(new Address(senderAddress), index, new BigNumber(newPrice), 0); await refreshAccount(); const { sessionId, error } = await sendTransactions({ - transactions: tx, + transactions: changeOfferPriceTx, transactionsDisplayInfo: { processingMessage: "Updating price", errorMessage: "Error occurred during updating price", @@ -534,25 +393,11 @@ export class DataNftMarketContract { } async getLastValidOfferId(): Promise { - const interaction = this.contract.methodsExplicit.getLastValidOfferId(); - const query = interaction.buildQuery(); + const lastValidOfferId = await this.contract.viewLastValidOfferId(); try { - const networkProvider = getNetworkProvider(this.chainID); - - const res = await networkProvider.queryContract(query); - const endpointDefinition = interaction.getEndpoint(); - const { firstValue, returnCode, returnMessage } = new ResultsParser().parseQueryResponse(res, endpointDefinition); - - if (!firstValue || !returnCode.isSuccess()) { - console.error(returnMessage); - return 0; - } - - const value = firstValue.valueOf(); - const decoded = value.toNumber(); - - return decoded; + lastValidOfferId; + return lastValidOfferId; } catch (e) { console.error(e); this.toast({ @@ -566,24 +411,9 @@ export class DataNftMarketContract { } async getIsPaused(): Promise { - const interaction = this.contract.methodsExplicit.getIsPaused(); - const query = interaction.buildQuery(); - try { - const networkProvider = getNetworkProvider(this.chainID); - - const res = await networkProvider.queryContract(query); - const endpointDefinition = interaction.getEndpoint(); - const { firstValue, returnCode, returnMessage } = new ResultsParser().parseQueryResponse(res, endpointDefinition); - - if (!firstValue || !returnCode.isSuccess()) { - throw Error(returnMessage); - } - - const value = firstValue.valueOf(); - const decoded = value; - - return decoded; + const isPaused = await this.contract.viewContractPauseState(); + return isPaused; } catch (e) { console.error(e); this.toast({ diff --git a/src/libs/MultiversX/types.ts b/src/libs/MultiversX/types.ts index 8e0572c1..5a417963 100644 --- a/src/libs/MultiversX/types.ts +++ b/src/libs/MultiversX/types.ts @@ -39,28 +39,17 @@ export interface DataNftCondensedView { } export interface MarketplaceRequirementsType { - accepted_tokens: string[]; - accepted_payments: string[]; - maximum_payment_fees: string[]; - discount_fee_percentage_buyer: number; - discount_fee_percentage_seller: number; - percentage_cut_from_buyer: number; - percentage_cut_from_seller: number; - buyer_fee: number; - seller_fee: number; + acceptedTokens: string[]; + acceptedPayments: string[]; + maximumPaymentFees: string[]; + buyerTaxPercentageDiscount: number; + sellerTaxPercentageDiscount: number; + buyerTaxPercentage: number; + sellerTaxPercentage: number; + buyerFee: number; + sellerFee: number; } -export interface OfferType { - index: number; - owner: string; - offered_token_identifier: string; - offered_token_nonce: number; - offered_token_amount: string; - wanted_token_identifier: string; - wanted_token_nonce: number; - wanted_token_amount: string; - quantity: number; -} export interface DataNftCollectionType { tokenIdentifier: string; nftImgUrl: string; @@ -76,7 +65,7 @@ export interface DataNftCollectionType { royalties: string; nonce: number; collection: string; - minOffer: OfferType; + minOffer: Offer; } export interface Favorite { diff --git a/src/libs/language.ts b/src/libs/language.ts index bf4e4401..35fa1e7e 100644 --- a/src/libs/language.ts +++ b/src/libs/language.ts @@ -41,4 +41,5 @@ export const labels = { "MINT_FORM_POPUP_INFO_ROYALTY": 'The "Creator Royalty" you will earn each time a copy is re-traded in the Data NFT Marketplace', "ADD_FAVORITE_FAILS": "Could not add to favorites. (ER-27)", "REMOVE_FAVORITE_FAILS": "Could not remove from favorites. (ER-28)", + "ERR_MARKET_NR_OFFERS_FAIL": "Could not fetch number of marketplace offers. (ER-29)", }; diff --git a/src/pages/DataNFT/DataNFTDetails.tsx b/src/pages/DataNFT/DataNFTDetails.tsx index fe96c9b5..76b8be83 100644 --- a/src/pages/DataNFT/DataNFTDetails.tsx +++ b/src/pages/DataNFT/DataNFTDetails.tsx @@ -47,7 +47,6 @@ import { getFavoritesFromBackendApi, getOffersByIdAndNoncesFromBackendApi } from import { getApi } from "libs/MultiversX/api"; import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; import { DataNftMintContract } from "libs/MultiversX/dataNftMint"; -import { OfferType } from "libs/MultiversX/types"; import { convertToLocalString, convertWeiToEsdt, @@ -59,6 +58,7 @@ import { } from "libs/utils"; import { useMarketStore } from "store"; import { Favourite } from "../../components/Favourite/Favourite"; +import { Offer } from "@itheum/sdk-mx-data-nft/out"; type DataNFTDetailsProps = { owner?: string; @@ -97,7 +97,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { const marketContract = new DataNftMarketContract(chainID); const { onCopy } = useClipboard(`${window.location.protocol + "//" + window.location.host}/datanfts/marketplace/${tokenId}/offer-${offerId}`); - const [offer, setOffer] = useState(); + const [offer, setOffer] = useState(); const [totalOffers, setTotalOffers] = useState>({}); const [amount, setAmount] = useState(1); const [amountError, setAmountError] = useState(""); @@ -373,7 +373,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { {!offer && getListingText(priceFromApi)} - {offer && getListingText(Number(offer.wanted_token_amount))} + {offer && getListingText(Number(offer.wantedTokenAmount))} {showConnectWallet && ( diff --git a/src/components/MyListedDataNFT.tsx b/src/components/MyListedDataNFT.tsx index 4dcce605..8c95c619 100644 --- a/src/components/MyListedDataNFT.tsx +++ b/src/components/MyListedDataNFT.tsx @@ -144,13 +144,13 @@ const MyListedDataNFT: FC = (props) => { {address && address == nftMetadata[index].creator && ( - You are the Creator + You Created this )} {address && address == offer.owner && ( - You are Owner + You Own this )} @@ -174,7 +174,7 @@ const MyListedDataNFT: FC = (props) => { <> - Unlock from: {` `} + Get from: {` `} {printPrice( convertWeiToEsdt(offer.wanted_token_amount, tokenDecimals(offer.wanted_token_identifier)).toNumber(), getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce) diff --git a/src/components/ProcureDataNFTModal.tsx b/src/components/ProcureDataNFTModal.tsx index 6c6b12ef..687b94b3 100644 --- a/src/components/ProcureDataNFTModal.tsx +++ b/src/components/ProcureDataNFTModal.tsx @@ -40,25 +40,20 @@ export interface ProcureAccessModalProps { offer: OfferType; amount: number; setSessionId?: (e: any) => void; + showCustomMintMsg?: boolean; } -export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData, offer, amount, setSessionId }: ProcureAccessModalProps) { +export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData, offer, amount, setSessionId, showCustomMintMsg }: ProcureAccessModalProps) { const { chainID } = useGetNetworkConfig(); const { address } = useGetAccountInfo(); const toast = useToast(); - const { colorMode } = useColorMode(); - const itheumPrice = useMarketStore((state) => state.itheumPrice); const itheumBalance = useAccountStore((state) => state.itheumBalance); const marketContract = new DataNftMarketContract(chainID); - const { tokenLogin, loginMethod } = useGetLoginInfo(); - const isWebWallet = loginMethod === "wallet"; - const backendUrl = backendApi(chainID); - const feePrice = printPrice( convertWeiToEsdt(Number(offer.wanted_token_amount) * amount, tokenDecimals(offer.wanted_token_identifier)).toNumber(), getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce) @@ -67,14 +62,11 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData const [readTermsChecked, setReadTermsChecked] = useState(false); const [liveUptimeFAIL, setLiveUptimeFAIL] = useState(true); const [isLiveUptimeSuccessful, setIsLiveUptimeSuccessful] = useState(false); - const [purchaseSessionId, setPurchaseSessionId] = useState(""); const [purchaseTxStatus, setPurchaseTxStatus] = useState(false); - const trackPurchaseTxStatus = useTrackTransactionStatus({ transactionId: purchaseSessionId, }); - const { hasSignedTransactions, signedTransactionsArray } = useGetSignedTransactions(); useEffect(() => { @@ -175,7 +167,7 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData const paymentAmount = new BigNumber(offer.wanted_token_amount).multipliedBy(amount); if (offer.wanted_token_identifier == "EGLD") { - marketContract.sendAcceptOfferEgldTransaction(offer.index, paymentAmount.toFixed(), amount, address); + marketContract.sendAcceptOfferEgldTransaction(offer.index, paymentAmount.toFixed(), amount, address, showCustomMintMsg); } else { if (offer.wanted_token_nonce === 0) { //Check if we buy all quantity, use web wallet and are on that offer's details page and thus should use callback route @@ -189,7 +181,8 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData offer.wanted_token_identifier, amount as never, address, - shouldUseCallbackRoute ? callbackRoute : undefined + shouldUseCallbackRoute ? callbackRoute : undefined, + showCustomMintMsg ); setPurchaseSessionId(sessionId); if (isWebWallet) { @@ -206,7 +199,9 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData offer.wanted_token_identifier, offer.wanted_token_nonce, amount as never, - address + address, + "", + showCustomMintMsg ); setPurchaseSessionId(sessionId); if (isWebWallet) { @@ -232,7 +227,7 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData - Procure Access to Data NFTs + {showCustomMintMsg ? "Mint Data NFTs" : "Procure Access to Data NFTs"} { return ( + + { imgLink="https://images.cointelegraph.com/images/1434_aHR0cHM6Ly9zMy5jb2ludGVsZWdyYXBoLmNvbS9zdG9yYWdlL3VwbG9hZHMvdmlldy8yMzQwMTg1MzQ5Njk5M2U0ZmY5OGU0NTUwMTE0N2I3Yy5qcGc=.jpg" /> - - formatNumberRoundFloor(row.amount / Math.pow(10, 18)), - header: "Amount", + header: "Quantity", footer: (footerProps) => footerProps.column.id, }, ], diff --git a/src/components/Tables/TokenTxTable.tsx b/src/components/Tables/TokenTxTable.tsx index 482d2a51..9ec1a4d0 100644 --- a/src/components/Tables/TokenTxTable.tsx +++ b/src/components/Tables/TokenTxTable.tsx @@ -72,7 +72,7 @@ export default function TokenTxTable(props: TokenTableProps) { { id: "amount", accessorFn: (row) => row.value, - header: "Amount", + header: "Quantity", footer: (footerProps) => footerProps.column.id, }, { diff --git a/src/components/UtilComps/UpperCardComponent.tsx b/src/components/UtilComps/UpperCardComponent.tsx index 10be372d..00995421 100644 --- a/src/components/UtilComps/UpperCardComponent.tsx +++ b/src/components/UtilComps/UpperCardComponent.tsx @@ -199,7 +199,7 @@ const UpperCardComponent: FC = ({ {address && address == nftMetadata.creator && ( - You are the Creator + You Created this )} @@ -207,7 +207,7 @@ const UpperCardComponent: FC = ({ {address && address == offer?.owner && ( - You are Owner + You Own this )} @@ -236,7 +236,7 @@ const UpperCardComponent: FC = ({ <> - Unlock from: {` `} + Get from: {` `} { <> {feePrice} {fee && itheumPrice ? `(~${convertToLocalString(fee * itheumPrice, 2)} USD)` : ""} diff --git a/src/components/WalletDataNFTMX/BurnDataNFTModal.tsx b/src/components/WalletDataNFTMX/BurnDataNFTModal.tsx index f120b539..6b4628c0 100644 --- a/src/components/WalletDataNFTMX/BurnDataNFTModal.tsx +++ b/src/components/WalletDataNFTMX/BurnDataNFTModal.tsx @@ -183,7 +183,7 @@ export default function BurnDataNFTModal(props: BurnDataNFTModalPropType) { - Burn Amount:    + Burn Quantity:    {dataNftBurnAmount} diff --git a/src/libs/MultiversX/custom.css b/src/libs/MultiversX/custom.css index 1a768e39..fad1b0ac 100644 --- a/src/libs/MultiversX/custom.css +++ b/src/libs/MultiversX/custom.css @@ -361,6 +361,29 @@ body { } } +@keyframes Shake { + 10%, + 90% { + transform: translate3d(-0.5px, 0, 0); + } + + 20%, + 80% { + transform: translate3d(0.5px, 0, 0); + } + + 30%, + 50%, + 70% { + transform: translate3d(-1px, 0, 0); + } + + 40%, + 60% { + transform: translate3d(1px, 0, 0); + } +} + .dapp-core-component__dappModalStyles__dappModalContent.dapp-modal-dialog-content { margin-top: 0px !important; margin-bottom: 4rem !important; diff --git a/src/libs/MultiversX/dataNftMarket.ts b/src/libs/MultiversX/dataNftMarket.ts index cdafef21..df035e27 100644 --- a/src/libs/MultiversX/dataNftMarket.ts +++ b/src/libs/MultiversX/dataNftMarket.ts @@ -80,7 +80,15 @@ export class DataNftMarketContract { } } - async sendAcceptOfferEsdtTransaction(index: number, paymentAmount: string, tokenId: string, amount: number, sender: string, callbackRoute?: string) { + async sendAcceptOfferEsdtTransaction( + index: number, + paymentAmount: string, + tokenId: string, + amount: number, + sender: string, + callbackRoute?: string, + showCustomMintMsg?: boolean + ) { const data = new BigNumber(paymentAmount).comparedTo(0) > 0 ? new ContractCallPayloadBuilder() @@ -108,12 +116,14 @@ export class DataNftMarketContract { await refreshAccount(); + const actionMsg = showCustomMintMsg ? "Minting Data NFT" : "Accepting offer"; + const { sessionId, error } = await sendTransactions({ transactions: offerEsdtTx, transactionsDisplayInfo: { - processingMessage: "Accepting offer", - errorMessage: "Error occurred during accepting offer", - successMessage: "Offer accepted successfully", + processingMessage: actionMsg, + errorMessage: `${actionMsg} failed :(`, + successMessage: `${actionMsg} successful!`, }, redirectAfterSign: callbackRoute ? true : false, callbackRoute: callbackRoute ?? window.location.pathname, @@ -129,7 +139,8 @@ export class DataNftMarketContract { nonce: number, amount: number, senderAddress: string, - callbackRoute?: string + callbackRoute?: string, + showCustomMintMsg?: boolean ) { const offerEsdtTx = new Transaction({ value: 0, @@ -151,12 +162,14 @@ export class DataNftMarketContract { await refreshAccount(); + const actionMsg = showCustomMintMsg ? "Minting Data NFT" : "Accepting offer"; + const { sessionId, error } = await sendTransactions({ transactions: offerEsdtTx, transactionsDisplayInfo: { - processingMessage: "Accepting offer", - errorMessage: "Error occurred during accepting offer", - successMessage: "Offer accepted successfully", + processingMessage: actionMsg, + errorMessage: `${actionMsg} failed :(`, + successMessage: `${actionMsg} successful!`, }, redirectAfterSign: callbackRoute ? true : false, callbackRoute: callbackRoute ?? window.location.pathname, @@ -165,7 +178,7 @@ export class DataNftMarketContract { return { sessionId, error }; } - async sendAcceptOfferEgldTransaction(index: number, paymentAmount: string, amount: number, senderAddress: string) { + async sendAcceptOfferEgldTransaction(index: number, paymentAmount: string, amount: number, senderAddress: string, showCustomMintMsg?: boolean) { const offerEgldTx = new Transaction({ value: paymentAmount, data: new ContractCallPayloadBuilder() @@ -181,12 +194,14 @@ export class DataNftMarketContract { await refreshAccount(); + const actionMsg = showCustomMintMsg ? "Minting Data NFT" : "Accepting Offer"; + const { sessionId, error } = await sendTransactions({ transactions: offerEgldTx, transactionsDisplayInfo: { - processingMessage: "Accepting offer", - errorMessage: "Error occurred during accepting offer", - successMessage: "Offer accepted successfully", + processingMessage: actionMsg, + errorMessage: `${actionMsg} failed :(`, + successMessage: `${actionMsg} successful!`, }, redirectAfterSign: false, }); @@ -214,7 +229,7 @@ export class DataNftMarketContract { transactions: cancelTx, transactionsDisplayInfo: { processingMessage: "Cancelling offer", - errorMessage: "Error occurred during offer cancellation", + errorMessage: "Cancelling offer failed :(", successMessage: "Offer cancelled successfully", }, redirectAfterSign: false, @@ -249,7 +264,7 @@ export class DataNftMarketContract { transactions: addERewTx, transactionsDisplayInfo: { processingMessage: "Adding Data NFT to marketplace", - errorMessage: "Error occurred", + errorMessage: "Adding Data NFT to marketplace failed :(", successMessage: "Data NFT added to marketplace", }, redirectAfterSign: false, @@ -280,8 +295,8 @@ export class DataNftMarketContract { const { sessionId, error } = await sendTransactions({ transactions: tx, transactionsDisplayInfo: { - processingMessage: "De-Listing offer", - errorMessage: "Error occurred during de-listing offer", + processingMessage: "De-listing offer", + errorMessage: "De-listing offer failed :(", successMessage: "Offer de-listed successfully", }, redirectAfterSign: false, @@ -523,7 +538,7 @@ export class DataNftMarketContract { transactions: tx, transactionsDisplayInfo: { processingMessage: "Updating price", - errorMessage: "Error occurred during updating price", + errorMessage: "Updating price failed :(", successMessage: "Fee updated successfully", }, redirectAfterSign: false, diff --git a/src/libs/MultiversX/dataNftMint.ts b/src/libs/MultiversX/dataNftMint.ts index 361f2c4d..a180a6fe 100644 --- a/src/libs/MultiversX/dataNftMint.ts +++ b/src/libs/MultiversX/dataNftMint.ts @@ -122,9 +122,9 @@ export class DataNftMintContract { const { sessionId, error } = await sendTransactions({ transactions: mintTransaction, transactionsDisplayInfo: { - processingMessage: "Minting Data NFT", - errorMessage: "Data NFT minting error", - successMessage: "Data NFT minted successfully", + processingMessage: "Minting Data NFT Collection", + errorMessage: "Collection minting failed :(", + successMessage: "Collection minted successfully!", }, redirectAfterSign: false, }); @@ -152,7 +152,7 @@ export class DataNftMintContract { transactions: tx, transactionsDisplayInfo: { processingMessage: "Burning Data NFT", - errorMessage: "Error occurred during burning NFT", + errorMessage: "Burning Data NFT failed :(", successMessage: "Data NFT burnt", }, redirectAfterSign: false, diff --git a/src/pages/AdvertiseData/TradeData.tsx b/src/pages/AdvertiseData/TradeData.tsx index d6f708e1..9164ebad 100644 --- a/src/pages/AdvertiseData/TradeData.tsx +++ b/src/pages/AdvertiseData/TradeData.tsx @@ -17,7 +17,7 @@ export const TradeData: React.FC = () => { Mint Data - Connect, mint and trade your datasets as Data NFTs in our Data NFT Marketplace + Connect, mint and trade your Data Streams as Data NFTs in our Data NFT Marketplace diff --git a/src/pages/AdvertiseData/components/MintingModal.tsx b/src/pages/AdvertiseData/components/MintingModal.tsx index 587bf661..628fd61e 100644 --- a/src/pages/AdvertiseData/components/MintingModal.tsx +++ b/src/pages/AdvertiseData/components/MintingModal.tsx @@ -47,7 +47,7 @@ export const MintingModal: React.FC = (props) => { - Data NFT Minting Progress + Data NFT Collection Minting Progress {!!errDataNFTStreamGeneric && } diff --git a/src/pages/DataNFT/DataNFTDetails.tsx b/src/pages/DataNFT/DataNFTDetails.tsx index 2c1b0177..cbc1b24e 100644 --- a/src/pages/DataNFT/DataNFTDetails.tsx +++ b/src/pages/DataNFT/DataNFTDetails.tsx @@ -109,7 +109,6 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { const { pathname } = useLocation(); const [previewDataOnDevnetSession] = useLocalStorage(PREVIEW_DATA_ON_DEVNET_SESSION_KEY, null); const [favouriteItems, setFavouriteItems] = React.useState>([]); - const maxBuyLimit = import.meta.env.VITE_MAX_BUY_LIMIT_PER_SFT ? Number(import.meta.env.VITE_MAX_BUY_LIMIT_PER_SFT) : 0; const maxBuyNumber = offer && maxBuyLimit > 0 ? Math.min(maxBuyLimit, offer.quantity) : offer?.quantity; @@ -185,6 +184,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { })(); } }, [offerId, hasPendingTransactions]); + function getTokenDetails() { const apiLink = getApi(chainID); const nftApiLink = `https://${apiLink}/nfts/${tokenId}`; @@ -287,12 +287,17 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { }; const [searchParams, setSearchParams] = useSearchParams(); + useEffect(() => { if (tokenId && offerId && location.pathname === "/datanfts/marketplace/market") { setSearchParams({ tokenId: tokenId, offerId: String(offerId) }); } }, []); + const isCreatorListing = () => { + return nftData.attributes?.creator === offer?.owner; + }; + return ( {!isLoadingNftData() ? ( @@ -385,7 +390,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { {offer && address && address != offer.owner && ( - How many to procure + How many to {isCreatorListing() ? "mint" : "procure"} )} @@ -709,6 +723,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { offer={offer} amount={amount} setSessionId={setSessionId} + showCustomMintMsg={isCreatorListing()} /> )} diff --git a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx index f8aa37db..549e8ad9 100644 --- a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx +++ b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx @@ -303,7 +303,7 @@ export const Marketplace: FC = ({ tabState }) => { Data NFT Marketplace - Explore and discover new Data NFTs direct from Data Creators and peer-to-peer traders + Explore and discover new Data NFTs direct from Data Creators and peer-to-peer data traders diff --git a/src/pages/DataNFT/MyDataNFTsMultiversX.tsx b/src/pages/DataNFT/MyDataNFTsMultiversX.tsx index aed8acc5..57eea50b 100644 --- a/src/pages/DataNFT/MyDataNFTsMultiversX.tsx +++ b/src/pages/DataNFT/MyDataNFTsMultiversX.tsx @@ -170,7 +170,7 @@ export default function MyDataNFTsMx({ tabState }: { tabState: number }) { Data NFT Wallet - Below are the Data NFTs you created or purchased on the current blockchain + Below are the Data NFTs you created or purchased from the peer-to-peer Data NFT Marketplace diff --git a/src/pages/GetWhitelist/LandingPage/LandingPage.tsx b/src/pages/GetWhitelist/LandingPage/LandingPage.tsx index 85fd8eb9..98316470 100644 --- a/src/pages/GetWhitelist/LandingPage/LandingPage.tsx +++ b/src/pages/GetWhitelist/LandingPage/LandingPage.tsx @@ -42,8 +42,8 @@ export const LandingPage: React.FC = () => { It’s time to own and trade your data. - Whether you’re a data creator, researcher, content creator, analyst, gamer, or a pioneering project - you have the power to redefine the value of - your data. Transform your unique datasets into a new asset class by minting your very own Data NFTs. + Whether you’re a data creator, musician, researcher, content creator, analyst, gamer, or a pioneering project - you have the power to redefine the + value of your data. Transform your unique datasets into a new asset class by minting your very own Data NFTs. Don’t just be a part of the change, lead it. diff --git a/src/pages/GetWhitelist/TrendingData/TrendingData.tsx b/src/pages/GetWhitelist/TrendingData/TrendingData.tsx index 50c6827b..215d81d4 100644 --- a/src/pages/GetWhitelist/TrendingData/TrendingData.tsx +++ b/src/pages/GetWhitelist/TrendingData/TrendingData.tsx @@ -3,11 +3,20 @@ import { Box, Flex, Text, useColorMode } from "@chakra-ui/react"; import bubbleImage from "assets/img/whitelist/BubbleImage.png"; import infographicsImage from "assets/img/whitelist/InfographicsImage.png"; import trailblazerImage from "assets/img/whitelist/TrailblazerImage.png"; +import nftunesImage from "assets/img/whitelist/NFTuneApp.png"; +import timecapsuleImage from "assets/img/whitelist/TimeCapsuleApp.png"; import { TrendingDataCards } from "./components/TrendingDataCards"; const cardContent = [ { id: 1, + headerImage: nftunesImage, + title: "NF-Tunes", + description: "Empowering Indie musicians to engage with a fresh fan community and discover alternative avenues for music distribution", + url: "https://explorer.itheum.io/nftunes", + }, + { + id: 2, headerImage: infographicsImage, title: "MultiversX Infographics", description: @@ -15,7 +24,7 @@ const cardContent = [ url: "https://explorer.itheum.io/multiversx-infographics", }, { - id: 2, + id: 3, headerImage: bubbleImage, title: "MultiversX ESDT Bubbles", description: @@ -23,12 +32,19 @@ const cardContent = [ url: "https://explorer.itheum.io/multiversx-bubbles", }, { - id: 3, + id: 4, headerImage: trailblazerImage, title: "Trailblazer", - description: "Hardcore community members unlock Project Alpha by owning their favourite project's TrailBlazer Data NFTs.", + description: "Hardcore community members unlock Project Alpha by owning their favorite project's TrailBlazer Data NFTs.", url: "https://explorer.itheum.io/project-trailblazer", }, + { + id: 5, + headerImage: timecapsuleImage, + title: "Time Capsule", + description: "Capture, archive, and relive historic social media events through media, preserving memories for future generations.", + url: "https://explorer.itheum.io/timecapsule", + }, ]; export const TrendingData: React.FC = () => { const { colorMode } = useColorMode(); diff --git a/src/pages/Home/HomeMultiversX.tsx b/src/pages/Home/HomeMultiversX.tsx index f225cc94..e0db4af4 100644 --- a/src/pages/Home/HomeMultiversX.tsx +++ b/src/pages/Home/HomeMultiversX.tsx @@ -421,7 +421,7 @@ export default function HomeMultiversX({ - Data DEX 101 Guides + Get Started diff --git a/src/pages/LandingPage/index.tsx b/src/pages/LandingPage/index.tsx index c30137ad..334f48d2 100644 --- a/src/pages/LandingPage/index.tsx +++ b/src/pages/LandingPage/index.tsx @@ -40,7 +40,7 @@ const LandingPage = () => { your data {" "} - in the Web3 Multiverse + as Data NFTs @@ -63,7 +63,7 @@ const LandingPage = () => { - Data DEX 101 Guides + Get Started From 64b5544b368a8e663e9aefcba3124766506752f5 Mon Sep 17 00:00:00 2001 From: Damian Date: Tue, 20 Feb 2024 20:14:23 +0200 Subject: [PATCH 3/9] fix: correct marshal uptime check --- package-lock.json | 4 ++-- src/components/ListDataNFTModal.tsx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7f882c17..b3451e60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "data-dex", - "version": "1.11.1", + "version": "1.11.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-dex", - "version": "1.11.1", + "version": "1.11.2", "dependencies": { "@chakra-ui/icons": "2.1.1", "@chakra-ui/react": "2.8.2", diff --git a/src/components/ListDataNFTModal.tsx b/src/components/ListDataNFTModal.tsx index 0e2b3b4c..ca3f1a07 100644 --- a/src/components/ListDataNFTModal.tsx +++ b/src/components/ListDataNFTModal.tsx @@ -15,6 +15,7 @@ import { useToast, useColorMode, } from "@chakra-ui/react"; +import { DataNft } from "@itheum/sdk-mx-data-nft/out"; import { useGetAccountInfo, useGetLoginInfo, useGetNetworkConfig, useGetPendingTransactions, useTrackTransactionStatus } from "@multiversx/sdk-dapp/hooks"; import axios from "axios"; @@ -22,7 +23,7 @@ import BigNumber from "bignumber.js"; import DataNFTLiveUptime from "components/UtilComps/DataNFTLiveUptime"; import { contractsForChain } from "libs/config"; import { getApi } from "libs/MultiversX/api"; -import { sleep, printPrice, convertToLocalString, getTokenWantedRepresentation, backendApi } from "libs/utils"; +import { sleep, printPrice, convertToLocalString, getTokenWantedRepresentation, backendApi, getApiDataMarshal } from "libs/utils"; import { useMarketStore } from "store"; export type ListModalProps = { @@ -40,7 +41,6 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, const { chainID } = useGetNetworkConfig(); const { address } = useGetAccountInfo(); const marketRequirements = useMarketStore((state) => state.marketRequirements); - const toast = useToast(); const fullPrice = amount * offer.wanted_token_amount; const priceWithSellerFee = fullPrice - (fullPrice * sellerFee) / 10000; @@ -337,7 +337,7 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, setLiveUptimeFAIL(hasFailed)} isLiveUptimeSuccessful={isLiveUptimeSuccessful} From db39f41445bfa7edbfd7fc0e20783a6e4e3f7a61 Mon Sep 17 00:00:00 2001 From: Damian Date: Tue, 20 Feb 2024 20:14:34 +0200 Subject: [PATCH 4/9] fix: correct marshal uptime check --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5455f28c..94fd79c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "data-dex", - "version": "1.11.2", + "version": "1.11.3", "description": "The Itheum Data DEX enables you to trade your data using web3 tech", "dependencies": { "@chakra-ui/icons": "2.1.1", From 825ecdd3f2fa4e8f93fbe1452e7a31df92062a98 Mon Sep 17 00:00:00 2001 From: Damian Date: Tue, 20 Feb 2024 20:49:01 +0200 Subject: [PATCH 5/9] fix: correct marshal uptime check --- src/components/ProcureDataNFTModal.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ProcureDataNFTModal.tsx b/src/components/ProcureDataNFTModal.tsx index 687b94b3..9710a4fd 100644 --- a/src/components/ProcureDataNFTModal.tsx +++ b/src/components/ProcureDataNFTModal.tsx @@ -29,6 +29,7 @@ import { tokenDecimals, getTokenWantedRepresentation, backendApi, + getApiDataMarshal, } from "libs/utils"; import { useAccountStore, useMarketStore } from "store"; @@ -341,7 +342,7 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData setLiveUptimeFAIL(hasFailed)} isLiveUptimeSuccessful={isLiveUptimeSuccessful} From 823499e35c6cfadbea1a5d6e8dcd9e926a225136 Mon Sep 17 00:00:00 2001 From: Damian Date: Tue, 20 Feb 2024 20:49:43 +0200 Subject: [PATCH 6/9] fix: correct marshal uptime check --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 94fd79c1..cadd3e33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "data-dex", - "version": "1.11.3", + "version": "1.11.4", "description": "The Itheum Data DEX enables you to trade your data using web3 tech", "dependencies": { "@chakra-ui/icons": "2.1.1", From 0753a3455ec80e93a7575da4b5ed20eb2ef8d888 Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 22 Feb 2024 10:42:41 +0200 Subject: [PATCH 7/9] chore: refactor dataNftMarket --- package-lock.json | 12 ++-- package.json | 2 +- src/libs/MultiversX/dataNftMarket.ts | 95 +++------------------------- 3 files changed, 16 insertions(+), 93 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3451e60..fe654154 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "data-dex", - "version": "1.11.2", + "version": "1.11.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-dex", - "version": "1.11.2", + "version": "1.11.4", "dependencies": { "@chakra-ui/icons": "2.1.1", "@chakra-ui/react": "2.8.2", "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", "@hookform/resolvers": "3.3.4", - "@itheum/sdk-mx-data-nft": "2.6.2", + "@itheum/sdk-mx-data-nft": "2.6.3", "@itheum/sdk-mx-enterprise": "0.2.0", "@multiversx/sdk-core": "12.18.0", "@multiversx/sdk-dapp": "2.28.0", @@ -4151,9 +4151,9 @@ } }, "node_modules/@itheum/sdk-mx-data-nft": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@itheum/sdk-mx-data-nft/-/sdk-mx-data-nft-2.6.2.tgz", - "integrity": "sha512-kgfD6IQZV01PmA5/eBjM1vRPsZHm8jEzQD1JwNy6GNygCxGpmkDsQNYOW7PpeiTdGLE4Bq4bbkUaS6/z1XkTuA==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@itheum/sdk-mx-data-nft/-/sdk-mx-data-nft-2.6.3.tgz", + "integrity": "sha512-iDpACWuNlrBuW41/GDre2sabZ6/7OQQZmXDXVGdw2lqN5JFdFqYDneNbiVZpgjFFYHtykjE75USwEOkGjfp8kw==", "dependencies": { "@multiversx/sdk-core": "12.18.0", "@multiversx/sdk-network-providers": "2.2.1", diff --git a/package.json b/package.json index cadd3e33..d9a6b0e4 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", "@hookform/resolvers": "3.3.4", - "@itheum/sdk-mx-data-nft": "2.6.2", + "@itheum/sdk-mx-data-nft": "2.6.3", "@itheum/sdk-mx-enterprise": "0.2.0", "@multiversx/sdk-core": "12.18.0", "@multiversx/sdk-dapp": "2.28.0", diff --git a/src/libs/MultiversX/dataNftMarket.ts b/src/libs/MultiversX/dataNftMarket.ts index bc10da62..b83e2ff9 100644 --- a/src/libs/MultiversX/dataNftMarket.ts +++ b/src/libs/MultiversX/dataNftMarket.ts @@ -241,40 +241,15 @@ export class DataNftMarketContract { } } - //TODO: change to SDK async viewOffers(startIndex: number, stopIndex: number): Promise { - // this will spread out a new array from startIndex to stopIndex e.g. startIndex=0, stopIndex=5 : you get [1,2,3,4,5] - const indexRange = Array.from({ length: stopIndex - startIndex }, (_, i) => new U64Value(startIndex + 1 + i)); - - const interaction = this.contract.methodsExplicit.viewOffers(indexRange); - const query = interaction.buildQuery(); - try { - const networkProvider = getNetworkProvider(this.chainID); - - const res = await networkProvider.queryContract(query); - const endpointDefinition = interaction.getEndpoint(); - const { firstValue, returnCode, returnMessage } = new ResultsParser().parseQueryResponse(res, endpointDefinition); - - if (!firstValue || !returnCode.isSuccess()) { - console.error(returnMessage); - return []; + const indexRange = []; + for (let i = startIndex; i < stopIndex; i++) { + indexRange.push(i + 1); } + const offers = this.contract.viewOffers(indexRange); - const values = firstValue.valueOf(); - const decoded = values.map((value: any) => ({ - index: value.offer_id.toNumber(), - owner: value.owner.toString(), - offered_token_identifier: value.offered_token_identifier.toString(), - offered_token_nonce: value.offered_token_nonce.toNumber(), - offered_token_amount: value.offered_token_amount.toFixed(), - wanted_token_identifier: value.wanted_token_identifier.toString(), - wanted_token_nonce: value.wanted_token_nonce.toNumber(), - wanted_token_amount: value.wanted_token_amount.toFixed(), - quantity: value.quantity.toNumber(), - })); - - return decoded; + return offers; } catch (e) { console.error(e); this.toast({ @@ -287,36 +262,11 @@ export class DataNftMarketContract { } } - //TODO: add user address when SDK supports it async viewPagedOffers(startIndex: number, stopIndex: number, userAddress?: string): Promise { - const pagedOffers = await this.contract.viewPagedOffers(startIndex, stopIndex); - try { - const networkProvider = getNetworkProvider(this.chainID); - - const res = await networkProvider.queryContract(query); - const endpointDefinition = interaction.getEndpoint(); - const { firstValue, returnCode, returnMessage } = new ResultsParser().parseQueryResponse(res, endpointDefinition); - - if (!firstValue || !returnCode.isSuccess()) { - console.error(returnMessage); - return []; - } + const pagedOffers = await this.contract.viewPagedOffers(startIndex, stopIndex, userAddress); - const values = firstValue.valueOf(); - const decoded = values.map((value: any) => ({ - index: value.offer_id.toNumber(), - owner: value.owner.toString(), - offered_token_identifier: value.offered_token_identifier.toString(), - offered_token_nonce: value.offered_token_nonce.toNumber(), - offered_token_amount: value.offered_token_amount.toFixed(), - wanted_token_identifier: value.wanted_token_identifier.toString(), - wanted_token_nonce: value.wanted_token_nonce.toNumber(), - wanted_token_amount: value.wanted_token_amount.toFixed(), - quantity: value.quantity.toNumber(), - })); - - return decoded; + return pagedOffers; } catch (e) { console.error(e); this.toast({ @@ -329,37 +279,10 @@ export class DataNftMarketContract { } } - //TODO: change this to SDK when it supports it async viewOffer(index: number): Promise { - const interaction = this.contract.methodsExplicit.viewOffer([new U64Value(index)]); - const query = interaction.buildQuery(); - try { - const networkProvider = getNetworkProvider(this.chainID); - - const res = await networkProvider.queryContract(query); - const endpointDefinition = interaction.getEndpoint(); - const { firstValue, returnCode, returnMessage } = new ResultsParser().parseQueryResponse(res, endpointDefinition); - - if (!firstValue || !returnCode.isSuccess()) { - console.error(returnMessage); - return undefined; - } - - const value = firstValue.valueOf(); - const decoded = { - index: value.offer_id.toNumber(), - owner: value.owner.toString(), - offered_token_identifier: value.offered_token_identifier.toString(), - offered_token_nonce: value.offered_token_nonce.toNumber(), - offered_token_amount: value.offered_token_amount.toFixed(), - wanted_token_identifier: value.wanted_token_identifier.toString(), - wanted_token_nonce: value.wanted_token_nonce.toNumber(), - wanted_token_amount: value.wanted_token_amount.toFixed(), - quantity: value.quantity.toNumber(), - }; - - return decoded; + const offer = this.contract.viewOffer(index); + return offer; } catch (e) { console.error(e); this.toast({ From b17006970b51c797548587441fcfb7bb49f0345c Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 22 Feb 2024 11:30:02 +0200 Subject: [PATCH 8/9] fix: recent data nfts refactoring --- package-lock.json | 8 +- package.json | 2 +- src/components/Sections/RecentDataNFTs.tsx | 96 +++++++++++----------- src/libs/MultiversX/dataNftMarket.ts | 10 +-- src/libs/MultiversX/types.ts | 16 ---- src/libs/types.ts | 28 ++++++- 6 files changed, 80 insertions(+), 80 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe654154..9b84106e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", "@hookform/resolvers": "3.3.4", - "@itheum/sdk-mx-data-nft": "2.6.3", + "@itheum/sdk-mx-data-nft": "2.7.0-alpha.2", "@itheum/sdk-mx-enterprise": "0.2.0", "@multiversx/sdk-core": "12.18.0", "@multiversx/sdk-dapp": "2.28.0", @@ -4151,9 +4151,9 @@ } }, "node_modules/@itheum/sdk-mx-data-nft": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@itheum/sdk-mx-data-nft/-/sdk-mx-data-nft-2.6.3.tgz", - "integrity": "sha512-iDpACWuNlrBuW41/GDre2sabZ6/7OQQZmXDXVGdw2lqN5JFdFqYDneNbiVZpgjFFYHtykjE75USwEOkGjfp8kw==", + "version": "2.7.0-alpha.2", + "resolved": "https://registry.npmjs.org/@itheum/sdk-mx-data-nft/-/sdk-mx-data-nft-2.7.0-alpha.2.tgz", + "integrity": "sha512-jORhgT0Pv/ha77D/oM9BAim36dqsh9XMK0a07kC1I0HnKSn/RDEUFsRAEOA5vABShlxbW2jN5uTaHOGm9A9txw==", "dependencies": { "@multiversx/sdk-core": "12.18.0", "@multiversx/sdk-network-providers": "2.2.1", diff --git a/package.json b/package.json index d9a6b0e4..dfd8df51 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", "@hookform/resolvers": "3.3.4", - "@itheum/sdk-mx-data-nft": "2.6.3", + "@itheum/sdk-mx-data-nft": "2.7.0-alpha.2", "@itheum/sdk-mx-enterprise": "0.2.0", "@multiversx/sdk-core": "12.18.0", "@multiversx/sdk-dapp": "2.28.0", diff --git a/src/components/Sections/RecentDataNFTs.tsx b/src/components/Sections/RecentDataNFTs.tsx index 79b701b8..2f4d807d 100644 --- a/src/components/Sections/RecentDataNFTs.tsx +++ b/src/components/Sections/RecentDataNFTs.tsx @@ -1,38 +1,39 @@ import React, { useEffect, useState } from "react"; import { Card, CardBody, Heading, Image, Link, SimpleGrid, Skeleton, Stack, Text } from "@chakra-ui/react"; -import { DataNft } from "@itheum/sdk-mx-data-nft/out"; +import { DataNft, Offer, createTokenIdentifier } from "@itheum/sdk-mx-data-nft/out"; +import { Address } from "@multiversx/sdk-core/out"; import { useGetNetworkConfig } from "@multiversx/sdk-dapp/hooks"; import { useGetLoginInfo } from "@multiversx/sdk-dapp/hooks/account"; -import BigNumber from "bignumber.js"; import { Link as ReactRouterLink } from "react-router-dom"; import { getFavoritesFromBackendApi, getHealthCheckFromBackendApi, getRecentOffersFromBackendApi } from "libs/MultiversX"; import { getNftsByIds } from "libs/MultiversX/api"; import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; import { DataNftMintContract } from "libs/MultiversX/dataNftMint"; -import { DataNftCondensedView } from "libs/MultiversX/types"; +import { RecentDataNFTType } from "libs/types"; import { convertWeiToEsdt, hexZero, sleep } from "libs/utils"; import { useAccountStore, useMarketStore } from "store"; import { NoDataHere } from "./NoDataHere"; import { Favourite } from "../Favourite/Favourite"; -const latestOffersSkeleton: DataNftCondensedView[] = []; +const latestOffersSkeleton: RecentDataNFTType[] = []; // create the placeholder offers for skeleton loading for (let i = 0; i < 10; i++) { latestOffersSkeleton.push({ - data_nft_id: "", - offered_token_identifier: "", - offered_token_nonce: 0, - offer_index: 0, - offered_token_amount: "", + offeredTokenIdentifier: "", + offeredTokenNonce: 0, + offeredTokenAmount: 0, + index: 0, quantity: 0, - wanted_token_amount: "", - creator: "", + wantedTokenIdentifier: "", + wantedTokenNonce: 0, + wantedTokenAmount: 0, + creator: new Address(), + owner: new Address(), tokenName: "", title: "", nftImgUrl: "", royalties: 0, - feePerSFT: 0, }); } @@ -40,7 +41,7 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea const { isLoggedIn: isMxLoggedIn } = useGetLoginInfo(); const { chainID } = useGetNetworkConfig(); const [loadedOffers, setLoadedOffers] = useState(false); - const [latestOffers, setLatestOffers] = useState(latestOffersSkeleton); + const [latestOffers, setLatestOffers] = useState(latestOffersSkeleton); const { tokenLogin } = useGetLoginInfo(); // console.log(latestOffers); const marketRequirements = useMarketStore((state) => state.marketRequirements); @@ -79,31 +80,31 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea if (isApiUp) { const offers = await getRecentOffersFromBackendApi(chainID); - const recentNonces = offers.map((nft: any) => ({ nonce: nft.offered_token_nonce })); + const recentNonces = offers.map((nft: any) => ({ nonce: nft.offeredTokenNonce })); const dataNfts: DataNft[] = await DataNft.createManyFromApi(recentNonces); - const _latestOffers: DataNftCondensedView[] = []; + const _latestOffers: RecentDataNFTType[] = []; - offers.forEach((offer: any) => { + offers.forEach((offer: Offer) => { const matchingDataNft = dataNfts.find( - (dataNft: DataNft) => dataNft.nonce === offer.offered_token_nonce && dataNft.collection === offer.offered_token_identifier + (dataNft: DataNft) => dataNft.nonce === offer.offeredTokenNonce && dataNft.collection === offer.offeredTokenIdentifier ); if (matchingDataNft) { - const tokenAmount = convertWeiToEsdt(new BigNumber(offer.wanted_token_amount)).toNumber(); _latestOffers.push({ - data_nft_id: matchingDataNft?.tokenIdentifier, - offered_token_identifier: offer.offered_token_identifier, - offered_token_nonce: offer.offered_token_nonce, - offer_index: offer.index, - offered_token_amount: offer.offered_token_amount, + index: offer.index, + owner: new Address(offer.owner), + creator: new Address(matchingDataNft?.owner), + offeredTokenIdentifier: offer.offeredTokenIdentifier, + offeredTokenNonce: offer.offeredTokenNonce, + offeredTokenAmount: offer.offeredTokenAmount, + wantedTokenIdentifier: offer.wantedTokenIdentifier, + wantedTokenNonce: offer.wantedTokenNonce, + wantedTokenAmount: offer.wantedTokenAmount, quantity: offer.quantity, - wanted_token_amount: offer.wanted_token_amount, - creator: offer?.creator, tokenName: matchingDataNft?.tokenName, - title: offer?.title, + title: matchingDataNft?.title, nftImgUrl: matchingDataNft?.nftImgUrl, royalties: matchingDataNft?.royalties, - feePerSFT: tokenAmount, }); } }); @@ -126,30 +127,29 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea const dataNfts = await getNftsByIds(nftIds, chainID); // merge the offer data and meta data - const _latestOffers: DataNftCondensedView[] = []; + const _latestOffers: RecentDataNFTType[] = []; slicedOffers.forEach((offer, idx) => { - const _nft = dataNfts.find((nft) => `${offer.offeredTokenIdentifier}-${hexZero(offer.offeredTokenNonce)}` === nft.identifier); + const _nft = dataNfts.find((nft) => createTokenIdentifier(nft.collection, nft.nonce) === nft.identifier); if (_nft !== undefined) { - const _nftMetaData = mintContract.decodeNftAttributes(_nft, idx); - - const tokenAmount = convertWeiToEsdt(new BigNumber(offer.wantedTokenAmount)).toNumber(); + const _nftMetaData = DataNft.decodeAttributes(_nft); _latestOffers.push({ - data_nft_id: _nftMetaData.id, - offered_token_identifier: offer.offeredTokenIdentifier, - offered_token_nonce: offer.offeredTokenNonce, - offer_index: offer.index, - offered_token_amount: offer.offeredTokenAmount, + creator: new Address(_nftMetaData.creator), + owner: new Address(offer.owner), + offeredTokenIdentifier: offer.offeredTokenIdentifier, + offeredTokenNonce: offer.offeredTokenNonce, + offeredTokenAmount: offer.offeredTokenAmount, + index: idx, + wantedTokenIdentifier: offer.wantedTokenIdentifier, + wantedTokenNonce: offer.wantedTokenNonce, + wantedTokenAmount: offer.wantedTokenAmount, quantity: offer.quantity, - wanted_token_amount: offer.wantedTokenAmount, - creator: _nftMetaData.creator, tokenName: _nftMetaData.tokenName, title: _nftMetaData.title, nftImgUrl: _nftMetaData.nftImgUrl, royalties: _nftMetaData.royalties, - feePerSFT: tokenAmount, }); } }); @@ -164,7 +164,7 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea if (isMxLoggedIn) { skeletonHeight = { base: "240px", md: "170px", "2xl": "190px" }; } - + console.log(latestOffers, "latestOffers"); return ( <> @@ -174,12 +174,14 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea {loadedOffers && latestOffers.length === 0 && } - {latestOffers.map((item: DataNftCondensedView, idx: number) => { + {latestOffers.map((item: RecentDataNFTType, idx: number) => { return ( - + Data NFT Image @@ -188,11 +190,13 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea {item.title} - Supply Available : {item.quantity} - Unlock for {item.feePerSFT === 0 ? "Free" : `${item.feePerSFT} ITHEUM/NFT`} + Supply Available : {Number(item.quantity)} + + Unlock for {item.wantedTokenAmount === 0 ? "Free" : `${Number(convertWeiToEsdt(item.wantedTokenAmount))} ITHEUM/NFT`} + { try { - const pagedOffers = await this.contract.viewPagedOffers(startIndex, stopIndex, userAddress); + const pagedOffers = await this.contract.viewPagedOffers(startIndex, stopIndex, new Address(userAddress)); return pagedOffers; } catch (e) { diff --git a/src/libs/MultiversX/types.ts b/src/libs/MultiversX/types.ts index 5a417963..85baf467 100644 --- a/src/libs/MultiversX/types.ts +++ b/src/libs/MultiversX/types.ts @@ -22,22 +22,6 @@ export interface DataNftMetadataType { collection: string; } -export interface DataNftCondensedView { - data_nft_id: string; // API (as id) - offered_token_identifier: string; // SC - offered_token_nonce: number; // SC - offer_index: number; // SC - offered_token_amount: string; // SC - quantity: number; // SC - wanted_token_amount: string; // SC - creator: string; // api - tokenName: string; // api - title: string; // api - nftImgUrl?: string; // api - royalties: number; // api, - feePerSFT: number; // calculation, -} - export interface MarketplaceRequirementsType { acceptedTokens: string[]; acceptedPayments: string[]; diff --git a/src/libs/types.ts b/src/libs/types.ts index 40768052..04459953 100644 --- a/src/libs/types.ts +++ b/src/libs/types.ts @@ -1,12 +1,32 @@ +import { IAddress } from "@multiversx/sdk-core/out"; +import BigNumber from "bignumber.js"; + export interface ContractsType { itheumToken: string; - claims: string; - faucet: string; - market: string; + claims: IAddress; + faucet: IAddress; + market: IAddress; dataNftTokens: DataNFTToken[]; } +export interface RecentDataNFTType { + index: BigNumber.Value; + owner: IAddress; + creator: IAddress; + offeredTokenIdentifier: string; + offeredTokenNonce: BigNumber.Value; + offeredTokenAmount: BigNumber.Value; + wantedTokenIdentifier: string; + wantedTokenNonce: BigNumber.Value; + wantedTokenAmount: BigNumber.Value; + quantity: BigNumber.Value; + tokenName?: string; + title?: string; + nftImgUrl?: string; + royalties?: BigNumber.Value; +} + export interface DataNFTToken { id: string; - contract: string; + contract: IAddress; } From 7ebc126e4e28ce5813c724cc465fe63fbc5c2b00 Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 22 Feb 2024 12:18:13 +0200 Subject: [PATCH 9/9] chore: use Offer from SDK in the whole Data Dex --- package-lock.json | 134 ++++++++++-------- src/components/ListDataNFTModal.tsx | 95 +++++++------ src/components/MyListedDataNFT.tsx | 6 +- src/components/ProcureDataNFTModal.tsx | 7 +- src/components/Sections/RecentDataNFTs.tsx | 6 +- .../WalletDataNFTMX/WalletDataNFTMX.tsx | 42 +++--- src/libs/MultiversX/dataNftMarket.ts | 1 + src/pages/DataNFT/DataNFTDetails.tsx | 10 +- .../DataNFT/DataNFTMarketplaceMultiversX.tsx | 4 +- 9 files changed, 163 insertions(+), 142 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9b84106e..111ad18b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7406,9 +7406,12 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -7933,9 +7936,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001588", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", - "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", + "version": "1.0.30001589", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", + "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", "dev": true, "funding": [ { @@ -8544,9 +8547,9 @@ } }, "node_modules/destr": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.2.tgz", - "integrity": "sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz", + "integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==" }, "node_modules/detect-browser": { "version": "5.3.0", @@ -8714,9 +8717,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.674", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.674.tgz", - "integrity": "sha512-jZtIZxv9FlwTLX5kVZStUtXZywhEi3vqvY6iEzJnc57cNgHFQ5JCczElTs/062v6ODTT7eX8ZOTqQcxa3nMUWQ==", + "version": "1.4.679", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.679.tgz", + "integrity": "sha512-NhQMsz5k0d6m9z3qAxnsOR/ebal4NAGsrNVRwcDo4Kc/zQ7KdsTKZUxZoygHcVRb0QDW3waEDIcE3isZ79RP6g==", "dev": true }, "node_modules/elliptic": { @@ -8953,14 +8956,14 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -10446,15 +10449,15 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/focus-lock": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.2.tgz", - "integrity": "sha512-kFI92jZVqa8rP4Yer2sLNlUDcOdEFxYum2tIIr4eCH0XF+pOmlg0xiY4tkbDmHJXt3phtbJoWs1L6PgUVk97rA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.3.tgz", + "integrity": "sha512-hfXkZha7Xt4RQtrL1HBfspAuIj89Y0fb6GX0dfJilb8S2G/lvL4akPAcHq6xoD2NuZnDMCnZL/zQesMyeu6Psg==", "dependencies": { "tslib": "^2.0.3" }, @@ -11837,12 +11840,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -13193,9 +13199,9 @@ } }, "node_modules/mlly": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.5.0.tgz", - "integrity": "sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.0.tgz", + "integrity": "sha512-YOvg9hfYQmnaB56Yb+KrJE2u0Yzz5zR+sLejEvF4fzwzV1Al6hkf2vyHTwqCRyv0hCi9rVCqVoXpyYevQIRwLQ==", "dependencies": { "acorn": "^8.11.3", "pathe": "^1.1.2", @@ -14044,6 +14050,14 @@ "node": ">=10.13.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.4.35", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", @@ -15312,14 +15326,15 @@ } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -16190,12 +16205,12 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", - "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" }, @@ -16204,15 +16219,16 @@ } }, "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -16222,16 +16238,16 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz", - "integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.6", + "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.1", + "has-proto": "^1.0.3", "is-typed-array": "^1.1.13" }, "engines": { @@ -16242,14 +16258,20 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" diff --git a/src/components/ListDataNFTModal.tsx b/src/components/ListDataNFTModal.tsx index ca3f1a07..c283b388 100644 --- a/src/components/ListDataNFTModal.tsx +++ b/src/components/ListDataNFTModal.tsx @@ -15,7 +15,7 @@ import { useToast, useColorMode, } from "@chakra-ui/react"; -import { DataNft } from "@itheum/sdk-mx-data-nft/out"; +import { Offer } from "@itheum/sdk-mx-data-nft/out"; import { useGetAccountInfo, useGetLoginInfo, useGetNetworkConfig, useGetPendingTransactions, useTrackTransactionStatus } from "@multiversx/sdk-dapp/hooks"; import axios from "axios"; @@ -23,6 +23,7 @@ import BigNumber from "bignumber.js"; import DataNFTLiveUptime from "components/UtilComps/DataNFTLiveUptime"; import { contractsForChain } from "libs/config"; import { getApi } from "libs/MultiversX/api"; +import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; import { sleep, printPrice, convertToLocalString, getTokenWantedRepresentation, backendApi, getApiDataMarshal } from "libs/utils"; import { useMarketStore } from "store"; @@ -31,8 +32,8 @@ export type ListModalProps = { onClose: () => void; sellerFee: number; nftData: any; - offer: any; - marketContract: any; + offer: Partial; + marketContract: DataNftMarketContract; amount: number; setAmount: (amount: number) => void; }; @@ -42,14 +43,14 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, const { address } = useGetAccountInfo(); const marketRequirements = useMarketStore((state) => state.marketRequirements); const toast = useToast(); - const fullPrice = amount * offer.wanted_token_amount; + const fullPrice = amount * Number(offer.wantedTokenAmount); const priceWithSellerFee = fullPrice - (fullPrice * sellerFee) / 10000; const priceWithSellerFeeAndRoyalties = priceWithSellerFee - priceWithSellerFee * nftData.royalties; const feePrice = address !== nftData.creator - ? printPrice(priceWithSellerFeeAndRoyalties, getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)) - : printPrice(priceWithSellerFee, getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)); - const fee = offer.wanted_token_amount; + ? printPrice(priceWithSellerFeeAndRoyalties, getTokenWantedRepresentation(offer.wantedTokenIdentifier ?? "", offer.wantedTokenNonce ?? 0)) + : printPrice(priceWithSellerFee, getTokenWantedRepresentation(offer.wantedTokenIdentifier ?? "", offer.wantedTokenNonce ?? 0)); + const fee = offer.wantedTokenAmount; const [readTermsChecked, setReadTermsChecked] = useState(false); const [liveUptimeFAIL, setLiveUptimeFAIL] = useState(true); const [isLiveUptimeSuccessful, setIsLiveUptimeSuccessful] = useState(false); @@ -92,15 +93,15 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, async function addOfferBackend( txHash = listTxHash, - offered_token_identifier = nftData.collection, - offered_token_nonce = nftData.nonce, - offered_token_amount = 1, + offeredTokenIdentifier = nftData.collection, + offeredTokenNonce = nftData.nonce, + offeredTokenAmount = 1, title = nftData.title, description = nftData.description, - wanted_token_identifier = offer.wanted_token_identifier, - wanted_token_nonce = offer.wanted_token_nonce, - wanted_token_amount = Number( - (Number(offer.wanted_token_amount) + (Number(offer.wanted_token_amount) * (marketRequirements.buyerTaxPercentage ?? 200)) / 10000) * Number(10 ** 18) + wantedTokenIdentifier = offer.wantedTokenIdentifier, + wantedTokenNonce = offer.wantedTokenNonce, + wantedTokenAmount = Number( + (Number(offer.wantedTokenAmount) + (Number(offer.wantedTokenAmount) * (marketRequirements.buyerTaxPercentage ?? 200)) / 10000) * Number(10 ** 18) ).toString(), quantity = amount * 1, owner = address @@ -135,17 +136,17 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, }; 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, + index, + offeredTokenIdentifier, + offeredTokenNonce, + offeredTokenAmount, + title, + description, + wantedTokenIdentifier, + wantedTokenNonce, + wantedTokenAmount, + quantity, + owner, }; const response = await fetch(`${backendUrl}/addOffer`, { @@ -196,21 +197,21 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, } } - const { sessionId } = await marketContract.addToMarket(nftData.collection, nftData.nonce, amount, offer.wanted_token_amount, address); + const { sessionId } = await marketContract.addToMarket(nftData.collection, nftData.nonce, amount, offer.wantedTokenAmount ?? 0, address); if (isWebWallet) { - const price = Number(offer.wanted_token_amount) + (Number(offer.wanted_token_amount) * (marketRequirements.buyerTaxPercentage ?? 200)) / 10000; + const price = Number(offer.wantedTokenAmount) + (Number(offer.wantedTokenAmount) * (marketRequirements.buyerTaxPercentage ?? 200)) / 10000; sessionStorage.setItem( "web-wallet-tx", JSON.stringify({ type: "add-offer-tx", - offered_token_identifier: nftData.collection, - offered_token_nonce: nftData.nonce, - offered_token_amount: 1, + offeredTokenIdentifier: nftData.collection, + offeredTokenNonce: nftData.nonce, + offeredTokenAmount: 1, title: nftData.title, description: nftData.description, - wanted_token_identifier: offer.wanted_token_identifier, - wanted_token_nonce: offer.wanted_token_nonce, - wanted_token_amount: Number(price * Number(10 ** 18)).toString(), + wantedTokenIdentifier: offer.wantedTokenIdentifier, + wantedTokenNonce: offer.wantedTokenNonce, + wantedTokenAmount: Number(price * Number(10 ** 18)).toString(), quantity: amount * 1, owner: address, }) @@ -263,8 +264,8 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, <> {": "} {printPrice( - new BigNumber(offer.wanted_token_amount).toNumber(), - getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce) + new BigNumber(offer.wantedTokenAmount ?? 0).toNumber(), + getTokenWantedRepresentation(offer.wantedTokenIdentifier ?? "", offer.wantedTokenNonce ?? 0) )} ) : ( @@ -277,10 +278,10 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, Seller Tax (per NFT) :{" "} - {`${sellerFee / 100}% (${new BigNumber(offer.wanted_token_amount) + {`${sellerFee / 100}% (${new BigNumber(offer.wantedTokenAmount ?? 0) .multipliedBy(sellerFee) .div(10000) - .toNumber()} ${getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)})`} + .toNumber()} ${getTokenWantedRepresentation(offer.wantedTokenIdentifier ?? "", offer.wantedTokenNonce ?? 0)})`} @@ -290,8 +291,8 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, :{" "} {`${convertToLocalString(nftData.royalties * 100)}% (${convertToLocalString( - new BigNumber(offer.wanted_token_amount).multipliedBy((1 - sellerFee / 10000) * nftData.royalties) - )} ${getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)})`} + new BigNumber(offer.wantedTokenAmount ?? 0).multipliedBy((1 - sellerFee / 10000) * nftData.royalties) + )} ${getTokenWantedRepresentation(offer.wantedTokenIdentifier ?? "", offer.wantedTokenNonce ?? 0)})`} )} @@ -302,7 +303,7 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, {": "} { <> - {feePrice} {fee && itheumPrice ? `(~${convertToLocalString(fee * itheumPrice * amount, 2)} USD)` : ""} + {feePrice} {fee && itheumPrice ? `(~${convertToLocalString(Number(fee) * itheumPrice * amount, 2)} USD)` : ""} } @@ -312,20 +313,20 @@ export default function ListDataNFTModal({ isOpen, onClose, sellerFee, nftData, { <> - {new BigNumber(offer.wanted_token_amount).comparedTo(0) <= 0 ? ( + {new BigNumber(offer.wantedTokenAmount ?? 0).comparedTo(0) <= 0 ? ( "" ) : ( <> - {" " + convertToLocalString(new BigNumber(offer.wanted_token_amount).multipliedBy(amount)) + " "} - {getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)} + {" " + convertToLocalString(new BigNumber(offer.wantedTokenAmount ?? 0).multipliedBy(amount)) + " "} + {getTokenWantedRepresentation(offer.wantedTokenIdentifier ?? "", offer.wantedTokenNonce ?? 0)} {" - "} - {convertToLocalString(new BigNumber(offer.wanted_token_amount).multipliedBy(amount).multipliedBy(sellerFee).div(10000))} - {" " + getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)} + {convertToLocalString(new BigNumber(offer.wantedTokenAmount ?? 0).multipliedBy(amount).multipliedBy(sellerFee).div(10000))} + {" " + getTokenWantedRepresentation(offer.wantedTokenIdentifier ?? "", offer.wantedTokenNonce ?? 0)} {address != nftData.creator && ( <> {" - "} - {convertToLocalString(new BigNumber(offer.wanted_token_amount).multipliedBy((1 - sellerFee / 10000) * nftData.royalties))} - {" " + getTokenWantedRepresentation(offer.wanted_token_identifier, offer.wanted_token_nonce)} + {convertToLocalString(new BigNumber(offer.wantedTokenAmount ?? 0).multipliedBy((1 - sellerFee / 10000) * nftData.royalties))} + {" " + getTokenWantedRepresentation(offer.wantedTokenIdentifier ?? "", offer.wantedTokenNonce ?? 0)} )} diff --git a/src/components/MyListedDataNFT.tsx b/src/components/MyListedDataNFT.tsx index d25cfae5..8f9020c9 100644 --- a/src/components/MyListedDataNFT.tsx +++ b/src/components/MyListedDataNFT.tsx @@ -34,7 +34,7 @@ import PreviewDataButton from "./PreviewDataButton"; type MyListedDataNFTProps = { offer: Offer; - offers: Record; + offers: Record; nftImageLoading: boolean; setNftImageLoading: Dispatch>; nftMetadataLoading: boolean; @@ -226,11 +226,11 @@ const MyListedDataNFT: FC = (props) => { if (marketRequirements) { setNewListingPrice( convertWeiToEsdt( - new BigNumber(offers[index].wanted_token_amount) + new BigNumber(offers[index].wantedTokenAmount) .multipliedBy(amountOfTokens[index]) .multipliedBy(10000) .div(10000 + marketRequirements.buyerTaxPercentage), - tokenDecimals(offers[index].wanted_token_identifier) + tokenDecimals(offers[index].wantedTokenIdentifier) ).toNumber() ); } else { diff --git a/src/components/ProcureDataNFTModal.tsx b/src/components/ProcureDataNFTModal.tsx index d35fb468..105c01f5 100644 --- a/src/components/ProcureDataNFTModal.tsx +++ b/src/components/ProcureDataNFTModal.tsx @@ -168,7 +168,7 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData const paymentAmount = new BigNumber(offer.wantedTokenAmount).multipliedBy(amount); - if (offer.wanted_token_identifier == "EGLD") { + if (offer.wantedTokenIdentifier == "EGLD") { marketContract.sendAcceptOfferEgldTransaction(offer.index, paymentAmount.toFixed(), amount, address, showCustomMintMsg); } else { if (offer.wantedTokenNonce === 0) { @@ -195,12 +195,11 @@ export default function ProcureDataNFTModal({ isOpen, onClose, buyerFee, nftData setSessionId(sessionId); } } else { - const { sessionId } = await marketContract.sendAcceptOfferNftEsdtTransaction( + const { sessionId } = await marketContract.sendAcceptOfferEsdtTransaction( offer.index, paymentAmount.toFixed(), offer.wantedTokenIdentifier, - offer.wantedTokenNonce, - amount as never, + amount, address, "", showCustomMintMsg diff --git a/src/components/Sections/RecentDataNFTs.tsx b/src/components/Sections/RecentDataNFTs.tsx index 2f4d807d..57d0a4e0 100644 --- a/src/components/Sections/RecentDataNFTs.tsx +++ b/src/components/Sections/RecentDataNFTs.tsx @@ -8,7 +8,6 @@ import { Link as ReactRouterLink } from "react-router-dom"; import { getFavoritesFromBackendApi, getHealthCheckFromBackendApi, getRecentOffersFromBackendApi } from "libs/MultiversX"; import { getNftsByIds } from "libs/MultiversX/api"; import { DataNftMarketContract } from "libs/MultiversX/dataNftMarket"; -import { DataNftMintContract } from "libs/MultiversX/dataNftMint"; import { RecentDataNFTType } from "libs/types"; import { convertWeiToEsdt, hexZero, sleep } from "libs/utils"; import { useAccountStore, useMarketStore } from "store"; @@ -43,13 +42,12 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea const [loadedOffers, setLoadedOffers] = useState(false); const [latestOffers, setLatestOffers] = useState(latestOffersSkeleton); const { tokenLogin } = useGetLoginInfo(); - // console.log(latestOffers); + const marketRequirements = useMarketStore((state) => state.marketRequirements); const favoriteNfts = useAccountStore((state) => state.favoriteNfts); const updateFavoriteNfts = useAccountStore((state) => state.updateFavoriteNfts); const marketContract = new DataNftMarketContract(chainID); - const mintContract = new DataNftMintContract(chainID); useEffect(() => { apiWrapper(); @@ -67,7 +65,6 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea if (tokenLogin?.nativeAuthToken) { const bearerToken = tokenLogin?.nativeAuthToken; const getFavourites = await getFavoritesFromBackendApi(chainID, bearerToken); - // console.log(getFavourites, "FAVO"); updateFavoriteNfts(getFavourites); } }; @@ -164,7 +161,6 @@ const RecentDataNFTs = ({ headingText, headingSize }: { headingText: string; hea if (isMxLoggedIn) { skeletonHeight = { base: "240px", md: "170px", "2xl": "190px" }; } - console.log(latestOffers, "latestOffers"); return ( <> diff --git a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx index cbfb748b..001c3453 100644 --- a/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx +++ b/src/components/WalletDataNFTMX/WalletDataNFTMX.tsx @@ -133,14 +133,14 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { if (txData.type === "add-offer-tx") { addOfferBackend( webWalletListTxHash, - txData.offered_token_identifier, - txData.offered_token_nonce, - txData.offered_token_amount, + txData.offeredTokenIdentifier, + txData.offeredTokenNonce, + txData.offeredTokenAmount, txData.title, txData.description, - txData.wanted_token_identifier, - txData.wanted_token_nonce, - txData.wanted_token_amount, + txData.wantedTokenIdentifier, + txData.wantedTokenNonce, + txData.wantedTokenAmount, txData.quantity, txData.owner ); @@ -151,14 +151,14 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { async function addOfferBackend( txHash: string, - offered_token_identifier: string, - offered_token_nonce: string, - offered_token_amount: string, + offeredTokenIdentifier: string, + offeredTokenNonce: string, + offeredTokenAmount: string, title: string, description: string, - wanted_token_identifier: string, - wanted_token_nonce: string, - wanted_token_amount: string, + wantedTokenIdentifier: string, + wantedTokenNonce: string, + wantedTokenAmount: string, quantity: number, owner: string ) { @@ -206,14 +206,14 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { const requestBody = { index: index, - offered_token_identifier: offered_token_identifier, - offered_token_nonce: offered_token_nonce, - offered_token_amount: offered_token_amount, + offeredTokenIdentifier: offeredTokenIdentifier, + offeredTokenNonce: offeredTokenNonce, + offeredTokenAmount: offeredTokenAmount, title: title, description: description, - wanted_token_identifier: wanted_token_identifier, - wanted_token_nonce: wanted_token_nonce, - wanted_token_amount: wanted_token_amount, + wantedTokenIdentifier: wantedTokenIdentifier, + wantedTokenNonce: wantedTokenNonce, + wantedTokenAmount: wantedTokenAmount, quantity: quantity, owner: owner, }; @@ -589,7 +589,11 @@ export default function WalletDataNFTMX(item: WalletDataNFTMxPropType) { nftData={selectedDataNft} marketContract={marketContract} sellerFee={item.sellerFee || 0} - offer={{ wanted_token_identifier: contractsForChain(chainID).itheumToken, wanted_token_amount: price, wanted_token_nonce: 0 }} + offer={{ + wantedTokenIdentifier: contractsForChain(chainID).itheumToken, + wantedTokenAmount: price.toString(), + wantedTokenNonce: 0, + }} amount={amount} setAmount={setAmount} /> diff --git a/src/libs/MultiversX/dataNftMarket.ts b/src/libs/MultiversX/dataNftMarket.ts index ead97e73..874c0da7 100644 --- a/src/libs/MultiversX/dataNftMarket.ts +++ b/src/libs/MultiversX/dataNftMarket.ts @@ -48,6 +48,7 @@ export class DataNftMarketContract { } else { offerEsdtTx = this.contract.acceptOfferWithNoPayment(new Address(sender), index, amount); } + offerEsdtTx.setGasLimit(20000000); await refreshAccount(); diff --git a/src/pages/DataNFT/DataNFTDetails.tsx b/src/pages/DataNFT/DataNFTDetails.tsx index a4886fa2..30f30fe6 100644 --- a/src/pages/DataNFT/DataNFTDetails.tsx +++ b/src/pages/DataNFT/DataNFTDetails.tsx @@ -25,6 +25,7 @@ import { useToast, VStack, } from "@chakra-ui/react"; +import { Offer } from "@itheum/sdk-mx-data-nft/out"; import { useGetAccountInfo, useGetNetworkConfig, useGetPendingTransactions, useTrackTransactionStatus } from "@multiversx/sdk-dapp/hooks"; import { useGetLoginInfo } from "@multiversx/sdk-dapp/hooks/account"; import axios from "axios"; @@ -40,8 +41,7 @@ import TokenTxTable from "components/Tables/TokenTxTable"; import ConditionalRender from "components/UtilComps/ApiWrapper"; import ExploreAppButton from "components/UtilComps/ExploreAppButton"; import ShortAddress from "components/UtilComps/ShortAddress"; -import { CHAIN_TX_VIEWER, PREVIEW_DATA_ON_DEVNET_SESSION_KEY, uxConfig } from "libs/config"; -import { useLocalStorage } from "libs/hooks"; +import { CHAIN_TX_VIEWER, uxConfig } from "libs/config"; import { labels } from "libs/language"; import { getFavoritesFromBackendApi, getOffersByIdAndNoncesFromBackendApi } from "libs/MultiversX"; import { getApi } from "libs/MultiversX/api"; @@ -58,7 +58,6 @@ import { } from "libs/utils"; import { useMarketStore } from "store"; import { Favourite } from "../../components/Favourite/Favourite"; -import { Offer } from "@itheum/sdk-mx-data-nft/out"; type DataNFTDetailsProps = { owner?: string; @@ -107,7 +106,6 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { const marketplaceDrawer = "/datanfts/marketplace/market"; const walletDrawer = "/datanfts/wallet"; const { pathname } = useLocation(); - const [previewDataOnDevnetSession] = useLocalStorage(PREVIEW_DATA_ON_DEVNET_SESSION_KEY, null); const [favouriteItems, setFavouriteItems] = React.useState>([]); const maxBuyLimit = import.meta.env.VITE_MAX_BUY_LIMIT_PER_SFT ? Number(import.meta.env.VITE_MAX_BUY_LIMIT_PER_SFT) : 0; const maxBuyNumber = offer && maxBuyLimit > 0 ? Math.min(maxBuyLimit, offer.quantity) : offer?.quantity; @@ -232,7 +230,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { const _offers = await getOffersByIdAndNoncesFromBackendApi(chainID, identifier, [nonceDec]); setTotalOffers(_offers); - const price = Math.min(..._offers.map((offerArg: any) => offerArg.wanted_token_amount)); + const price = Math.min(..._offers.map((offerArg: any) => offerArg.wantedTokenAmount)); if (price !== Infinity) { setPriceFromApi(price); } else { @@ -671,7 +669,7 @@ export default function DataNFTDetails(props: DataNFTDetailsProps) { .map((to: any, index: number) => ( - {marketRequirements && getOfferPrice(Number(to.wanted_token_amount))} + {marketRequirements && getOfferPrice(Number(to.wantedTokenAmount))} {to.quantity} diff --git a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx index 6c0f1be7..f90f7482 100644 --- a/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx +++ b/src/pages/DataNFT/DataNFTMarketplaceMultiversX.tsx @@ -126,7 +126,7 @@ export const Marketplace: FC = ({ tabState }) => { useEffect(() => { (async () => { - const _marketFreezedNonces = await mintContract.getSftsFrozenForAddress(marketContract.dataNftMarketContractAddress); + const _marketFreezedNonces = await mintContract.getSftsFrozenForAddress(marketContract.contract.getContractAddress().bech32()); setMarketFreezedNonces(_marketFreezedNonces); })(); }, []); @@ -155,7 +155,7 @@ export const Marketplace: FC = ({ tabState }) => { let _numberOfOffers = 0; if (tabState === 1) { // global offers - _numberOfOffers = await marketContract.viewNumberOfOffers(); + _numberOfOffers = (await marketContract.viewNumberOfOffers()) ?? 0; } else { // offers of User _numberOfOffers = await marketContract.viewUserTotalOffers(address);