diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz
index 824f0da6..78f57b7b 100644
Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ
diff --git a/src/components/Modals/ImportNFTModal/ImportNFTModal.jsx b/src/components/Modals/ImportNFTModal/ImportNFTModal.jsx
index 174758a1..d4f36ae8 100755
--- a/src/components/Modals/ImportNFTModal/ImportNFTModal.jsx
+++ b/src/components/Modals/ImportNFTModal/ImportNFTModal.jsx
@@ -3,19 +3,25 @@ import { Modal } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import {
setImportModal,
- addImportedNFTtoNFTlist,
+ setPreloadNFTs,
+ setNFTList,
} from "../../../store/reducers/generalSlice";
import { validateFunctions } from "../../../services/addressValidators";
-
-import axios from "axios";
import "./importNFTModal.css";
-import EVMBody from "./EVMBody";
+import EVMBody from "./importBodies/EVMBody";
+import { withServices } from "../../App/hocs/withServices";
+import {
+ checkNFTExist,
+ importNFTURI,
+ validForm,
+} from "../../../utils/importNFTUtility";
-export default function ImportNFTModal() {
+function ImportNFTModal({ serviceContainer }) {
const dispatch = useDispatch();
const from = useSelector((state) => state.general.from);
const account = useSelector((state) => state.general.account);
+ const NFTList = useSelector((state) => state.general.NFTList);
const [validContract, setValidContract] = useState(true);
const [contract, setContract] = useState();
@@ -23,8 +29,6 @@ export default function ImportNFTModal() {
const [tokenId, setTokenId] = useState();
const [importBlocked, setImportBlocked] = useState(false);
const [error, setError] = useState("");
- const validForm = contract?.length === 42 && tokenId;
- const chainNonce = from.nonce;
const handleClose = () => {
dispatch(setImportModal(false));
@@ -36,51 +40,52 @@ export default function ImportNFTModal() {
// setValidContract(true);
// } else setValidContract(false);
- if(value.length > 0){
- setValidContract(validateFunctions.EVM(value))
- }
- else{
- setValidContract(true)
+ if (value.length > 0 && from.type === "EVM") {
+ setValidContract(validateFunctions.EVM(value));
+ } else if (from.type === "Elrond") {
+ console.log("Elrond");
+ setValidContract(validateFunctions.Elrond(value));
+ } else {
+ setValidContract(true);
}
};
- //" ";
- //"http://192.168.129.241:3000/nfts/nftCheck";
+ /**
+ *
+ * IMPORTING TOKEN
+ */
const handleImport = async () => {
- const baseURL = "https://indexnft.herokuapp.com/nfts/nftCheck";
- const _headers = {
- Accept: "*",
- "Content-Type": "application/json",
- // Authorization: `Bearer ${process.env.REACT_APP_BEARER}`,
- };
try {
setImportBlocked(true);
- setTimeout(() => {
- setImportBlocked(false);
- }, 10000);
- const imported = await axios({
- method: "post",
- url: baseURL,
- headers: _headers,
- data: JSON.stringify({
- chainNonce,
- tokenId,
- contract,
- address: account,
- }),
- });
- setImportBlocked(false);
- if (typeof imported.data === "object") {
- dispatch(addImportedNFTtoNFTlist(imported.data));
- } else setError(imported.data);
+
+ const fromChain = await serviceContainer.bridge.getChain(from.nonce);
+ const signer = fromChain.signer;
+
+ if (checkNFTExist(NFTList, contract, tokenId, from))
+ throw new Error("NFT already imported!");
+
+ const formattedData = await importNFTURI(
+ contract,
+ tokenId,
+ account,
+ signer,
+ from
+ );
+
+ dispatch(setPreloadNFTs(NFTList ? NFTList.length + 1 : 1));
+ dispatch(setNFTList(NFTList ? [...NFTList, formattedData] : [formattedData]));
dispatch(setImportModal(false));
- } catch (error) {
- setError(error.message);
setImportBlocked(false);
- console.error(error);
+ setError('');
+
+ } catch (err) {
+ console.log(err);
+ setImportBlocked(false);
+ setError(err.message || "You don't own this NFT!");
}
};
+
return (
@@ -98,7 +103,7 @@ export default function ImportNFTModal() {
setTokenId={setTokenId}
importBlocked={importBlocked}
error={error}
- validForm={validForm}
+ validForm={validForm(from, contract, tokenId)}
// OFF={OFF}
handleClose={handleClose}
handleContractChange={handleContractChange}
@@ -107,3 +112,7 @@ export default function ImportNFTModal() {
);
}
+
+
+
+export default withServices(ImportNFTModal)
\ No newline at end of file
diff --git a/src/components/Modals/ImportNFTModal/importBodies/EVMBody.jsx b/src/components/Modals/ImportNFTModal/importBodies/EVMBody.jsx
new file mode 100755
index 00000000..be6292af
--- /dev/null
+++ b/src/components/Modals/ImportNFTModal/importBodies/EVMBody.jsx
@@ -0,0 +1,100 @@
+import React from "react";
+import { Modal } from "react-bootstrap";
+import PropTypes from "prop-types";
+import { useSelector } from "react-redux";
+import { importInputs } from "../../../../utils/importNFTUtility";
+
+export default function EVMBody({
+ error,
+ tokenId,
+ handleImport,
+ handleClose,
+ validForm,
+ importBlocked,
+ validContract,
+ setTokenId,
+ setContractOnBlur,
+ contract,
+ contractOnBlur,
+ handleContractChange,
+}) {
+ const from = useSelector((state) => state.general.from);
+ const OFF = { opacity: 0.6, pointerEvents: "none" };
+ return (
+
+ {error && {error}
}
+
+
+ );
+}
+EVMBody.propTypes = {
+ error: PropTypes.string,
+ tokenId: PropTypes.string,
+ handleImport: PropTypes.any,
+ handleClose: PropTypes.any,
+ validForm: PropTypes.bool,
+ importBlocked: PropTypes.bool,
+ validContract: PropTypes.bool,
+ setTokenId: PropTypes.any,
+ setContractOnBlur: PropTypes.any,
+ contract: PropTypes.string,
+ contractOnBlur: PropTypes.string,
+ handleContractChange: PropTypes.any,
+};
diff --git a/src/components/Modals/ImportNFTModal/EVMBody.jsx b/src/components/Modals/ImportNFTModal/importBodies/HederaBody.jsx
old mode 100755
new mode 100644
similarity index 89%
rename from src/components/Modals/ImportNFTModal/EVMBody.jsx
rename to src/components/Modals/ImportNFTModal/importBodies/HederaBody.jsx
index fc377bbc..4d34f1a4
--- a/src/components/Modals/ImportNFTModal/EVMBody.jsx
+++ b/src/components/Modals/ImportNFTModal/importBodies/HederaBody.jsx
@@ -2,7 +2,7 @@ import React from "react";
import { Modal } from "react-bootstrap";
import PropTypes from "prop-types";
-export default function EVMBody({
+export default function HederaBody({
error,
tokenId,
handleImport,
@@ -23,7 +23,7 @@ export default function EVMBody({
+
- {from.type === "EVM" && nfts?.length < 1 && }
+ {
+ // from.type === "EVM" &&
+ nfts?.length < 1 && }
{NFTListTopButton && NFTListTopButton()}
{(nfts?.length > 0 || from?.type === "Cosmos") && (
- {from.type === "EVM" && (
- // ||
- // from?.type !== "Cosmos"
+ {/* {from.type === "EVM" && ( */}
+ {/* // ||
+ // from?.type !== "Cosmos" */}
- )}
+ {/* )} */}
{/* {onlyWhiteListedNFTs?.length === selectedNFTs?.length &&
selectedNFTs?.length ? (
diff --git a/src/components/NFTsBoard/NFTmobileView.jsx b/src/components/NFTsBoard/NFTmobileView.jsx
index 10993f5d..b0fa195f 100755
--- a/src/components/NFTsBoard/NFTmobileView.jsx
+++ b/src/components/NFTsBoard/NFTmobileView.jsx
@@ -12,7 +12,6 @@ import { useDispatch, useSelector } from "react-redux";
import MobileDestinationAddressBar from "../MobileOnly/MobileDestinationAddressBar";
import "./NFTsBoard.css";
-import Refresh from "../Buttons/Refresh";
import ChainSwitch from "../Buttons/ChainSwitch";
import SelectedNFTs from "../Buttons/SelectedNFTs";
import ViewButton from "../Buttons/ViewButton";
@@ -71,7 +70,6 @@ const NFTmobileView = ({ selectedNFTs, _from, nfts }) => {
@@ -89,7 +87,7 @@ const NFTmobileView = ({ selectedNFTs, _from, nfts }) => {
showSelected={showSelected}
setOff={setShowSelected}
/>
- {_from.type === "EVM" && nfts?.length < 1 && (
+ {_from.type === "EVM" && (nfts?.length === undefined || nfts?.length < 1) && (
)}
{nfts?.length > 0 && (
diff --git a/src/event/assets/abi/erc1155Abi.json b/src/event/assets/abi/erc1155Abi.json
new file mode 100644
index 00000000..16d6bf6f
--- /dev/null
+++ b/src/event/assets/abi/erc1155Abi.json
@@ -0,0 +1,25 @@
+[
+ {
+ "inputs": [
+ { "internalType": "address", "name": "account", "type": "address" },
+ { "internalType": "uint256", "name": "id", "type": "uint256" }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ { "internalType": "uint256", "name": "", "type": "uint256" }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "uint256", "name": "id", "type": "uint256" }
+ ],
+ "name": "uri",
+ "outputs": [
+ { "internalType": "string", "name": "", "type": "string" }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ]
\ No newline at end of file
diff --git a/src/event/assets/abi/mintAbi.json b/src/event/assets/abi/mintAbi.json
index 8ddca462..bbe876e8 100644
--- a/src/event/assets/abi/mintAbi.json
+++ b/src/event/assets/abi/mintAbi.json
@@ -325,6 +325,25 @@
"stateMutability": "view",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "id",
+ "type": "uint256"
+ }
+ ],
+ "name": "uri",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
{
"inputs": [],
"name": "baseUri",
@@ -786,4 +805,4 @@
"stateMutability": "view",
"type": "function"
}
-]
+]
\ No newline at end of file
diff --git a/src/models/chains.js b/src/models/chains.js
index 67ed0141..48dd6dca 100755
--- a/src/models/chains.js
+++ b/src/models/chains.js
@@ -782,8 +782,8 @@ class TON extends AbstractChain {
async preParse(nft) {
const _contract = nft.collectionIdent || "SingleNFt";
- const withMetadata = Object.keys(nft.native?.metadata).length > 0;
- let uri = "";
+ const withMetadata = Object.keys(nft.native?.metaData ?? {}).length > 0;
+ let uri = nft?.uri ?? "";
let native_metadata = {};
if (withMetadata) {
const data = JSON.stringify(nft.native.metadata);
@@ -799,6 +799,7 @@ class TON extends AbstractChain {
return {
collectionIdent: _contract,
uri,
+ image: nft.image,
metaData: withMetadata
? {
...nft.native.metadata,
@@ -808,7 +809,7 @@ class TON extends AbstractChain {
native: {
...nft.native,
- tokenId: nft.native.nftItemAddr,
+ tokenId: nft?.native?.nftItemAddr ?? nft.native.name?.split("#")?.[1],
contract: _contract,
},
};
diff --git a/src/utils/chainsTypes.js b/src/utils/chainsTypes.js
index 88df786a..603ea36b 100644
--- a/src/utils/chainsTypes.js
+++ b/src/utils/chainsTypes.js
@@ -129,6 +129,7 @@ export const v3_ChainId = {
7: {name: 'MATIC', type: "EVM"},
18: {name: 'TEZOS', type: "TEZOS"},
24: {name: 'SECRET', type: "COSMOS"},
+ 26: {name: 'SOLANA', type: "SOLANA"},
27: {name: 'TON', type: "TON"},
29: {name: 'HEDERA', type: "HEDERA"},
}
diff --git a/src/utils/importNFTUtility.js b/src/utils/importNFTUtility.js
new file mode 100755
index 00000000..a630fa1e
--- /dev/null
+++ b/src/utils/importNFTUtility.js
@@ -0,0 +1,504 @@
+import axios from "axios";
+import { ethers } from "ethers";
+
+import store from "../store/store";
+import ABI from "../event/assets/abi/mintAbi.json";
+import ABI1155 from "../event/assets/abi/erc1155Abi.json";
+import { setupURI } from "../utils";
+
+// ----------------------------
+
+// ----------------------------
+
+/**
+ * FORMAT DATA
+ */
+const formatData = (
+ contractAddress,
+ uri,
+ owner,
+ tokenId,
+ contractType,
+ chainId,
+ native
+) => {
+ const obj = {
+ collectionIdent: contractAddress,
+ uri,
+ native: {
+ owner,
+ tokenId,
+ uri,
+ contract: contractAddress,
+ chainId,
+ contractType,
+ ...native,
+ },
+ };
+
+ if (native?.image) {
+ obj.image = native.image;
+ }
+
+ return obj;
+};
+
+/**
+ * CHECK VALID FORM
+ */
+export const validForm = (from, contract, tokenId) => {
+ switch (from.type) {
+ case "EVM":
+ return contract?.length === 42 && tokenId;
+ case "Elrond":
+ return tokenId;
+ case "Hedera":
+ case "Tezos":
+ return contract && tokenId;
+ case "TON":
+ return contract && contract.length > 10;
+ default:
+ return true;
+ }
+};
+
+/**
+ * IMPORT INPUTS
+ */
+export const importInputs = (from) => {
+ switch (from.type) {
+ case "EVM":
+ return {
+ contract: {
+ label: "1. Paste contract address",
+ placeholder: "0x...",
+ },
+ tokenId: {
+ label: "2. Paste Token ID",
+ placeholder: "Enter Token ID",
+ },
+ };
+ case "Elrond":
+ return {
+ contract: {
+ label: "1. Paste Collection address",
+ placeholder: "0x...",
+ },
+ tokenId: {
+ label: "2. Paste Token ID",
+ placeholder: "Enter Token ID",
+ },
+ };
+ case "Hedera":
+ return {
+ contract: {
+ label: "1. Paste contract address",
+ placeholder: "EBSD-...",
+ },
+ tokenId: {
+ label: "2. Paste Token ID",
+ placeholder: "01",
+ },
+ };
+ case "Tezos":
+ return {
+ contract: {
+ label: "1. Paste contract address",
+ placeholder: "0x...",
+ },
+ tokenId: {
+ label: "2. Paste Token ID",
+ placeholder: "Enter Token ID",
+ },
+ };
+ case "TON":
+ return {
+ contract: {
+ label: "1. Paste item address",
+ placeholder: "EQD...",
+ },
+ tokenId: {
+ label: "",
+ placeholder: "",
+ },
+ };
+ case "Solana":
+ return {
+ contract: {
+ label: "1. Paste Token address",
+ placeholder: "D0...",
+ },
+ tokenId: {
+ label: "",
+ placeholder: "",
+ },
+ };
+
+ default:
+ return {
+ contract: {
+ label: "1. Paste contract address",
+ placeholder: "0x...",
+ },
+ tokenId: {
+ label: "2. Paste Token ID",
+ placeholder: "Enter Token ID",
+ },
+ };
+ }
+};
+
+/**
+ * CHECK NFT EXIST
+ */
+export const checkNFTExist = (NFTList, contractAddress, tokenId, from) => {
+ switch (from.type) {
+ case "Elrond":
+ return NFTList.find((n) =>
+ n.native.contract === contractAddress &&
+ n.native.tokenId == tokenId.toString().length < 2
+ ? "0" + tokenId.toString()
+ : tokenId.toString()
+ );
+ case "TON":
+ case "Solana":
+ return NFTList.find((n) => n.native.contract === contractAddress);
+ default:
+ return NFTList.find(
+ (n) =>
+ n.native.contract === contractAddress &&
+ n.native.tokenId == tokenId?.toString()
+ );
+ }
+};
+
+/**
+ * IMPORT NFT URI
+ */
+export const importNFTURI = async (
+ contract,
+ tokenId,
+ account,
+ signer,
+ from
+) => {
+ switch (from.type) {
+ case "EVM":
+ return await importNFTURI_EVM(contract, tokenId, account, signer, from);
+ case "Elrond":
+ return await importNFTURI_Elrond(contract, tokenId, account, from);
+ case "Hedera":
+ return await importNFTURI_Hedera(contract, tokenId, account, from);
+ case "Tezos":
+ return await importNFTURI_Tezos(contract, tokenId, account, from);
+ case "TON":
+ return await importNFTURI_TON(contract, account, from);
+ case "Solana":
+ return await importNFTURI_Solana(contract, account, from);
+ default:
+ throw new Error("Invalid chain");
+ }
+};
+
+/**
+ * IMPORT NFT URI FROM EVM CHAIN
+ */
+export const importNFTURI_EVM = async (
+ contract,
+ tokenId,
+ account,
+ signer,
+ from
+) => {
+ const Contract721 = new ethers.Contract(contract, ABI, signer);
+ const Contract1155 = new ethers.Contract(contract, ABI1155, signer);
+
+ try {
+ // EVM CHAIN for ERC721
+ const owner721 = await Contract721.ownerOf(tokenId);
+ if (owner721 !== account) throw new Error("You don't own this NFT!");
+
+ const tokenURI = await Contract721.tokenURI(tokenId);
+ return formatData(
+ contract,
+ tokenURI,
+ account,
+ tokenId,
+ "ERC721",
+ from.chainId
+ );
+ } catch (error) {
+ console.log("Error 721", error);
+ try {
+ // CHECK IF THE USER HAS THE NFT ON ERC1155 CHAIN
+ const balance1155 = await Contract1155.balanceOf(account, tokenId);
+ if (balance1155 <= 0) throw new Error("You don't own this NFT!");
+
+ const tokenURI = await Contract1155.uri(tokenId);
+ return formatData(
+ contract,
+ tokenURI,
+ account,
+ tokenId,
+ "ERC1155",
+ from.chainId
+ );
+ } catch (error) {
+ console.log({ error });
+ throw new Error("You don't own this NFT!");
+ }
+ }
+};
+
+/**
+ * IMPORT NFT URI FROM ELROND CHAIN
+ */
+export const importNFTURI_Elrond = async (contract, tokenId, account, from) => {
+ try {
+ const {
+ general: { testNet },
+ } = store.getState();
+ const id = tokenId.toString();
+ const fomatedID = id.length < 2 ? "0" + id : id;
+ const tokenIdentifier = `${contract}-${fomatedID}`;
+ const { data } = await axios.get(
+ testNet
+ ? `https://devnet-api.multiversx.com/nfts/${tokenIdentifier}`
+ : `https://api.multiversx.com/nfts/${tokenIdentifier}`
+ );
+
+ if (data.owner !== account) {
+ return Promise.reject(new Error("You don't own this NFT!"));
+ }
+
+ return formatData(contract, data.url, account, fomatedID, "", from.nonce, {
+ ...data,
+ image: data.url,
+ });
+ } catch (error) {
+ console.log({ error });
+ throw new Error(
+ error.response?.data?.message ||
+ error.message ||
+ "An error occurred while importing the NFT!"
+ );
+ }
+};
+
+/**
+ * IMPORT NFT FROM HEDERA CHAIN
+ */
+export const importNFTURI_Hedera = async (
+ tokenId,
+ serialNumber,
+ account,
+ from
+) => {
+ try {
+ const {
+ general: { testNet },
+ } = store.getState();
+ const { data } = await axios.get(
+ testNet
+ ? `https://testnet.mirrornode.hedera.com/api/v1/tokens/${tokenId}/nfts/${serialNumber}`
+ : `https://mainnet.mirrornode.hedera.com/api/v1/tokens/${tokenId}/nfts/${serialNumber}`
+ );
+
+ if (data.account_id !== account) {
+ return Promise.reject(new Error("You don't own this NFT!"));
+ }
+
+ const decodeMetadata = await Buffer.from(
+ data.metadata,
+ "base64"
+ ).toLocaleString();
+
+ const { data: metadata } = await axios.get(setupURI(decodeMetadata));
+
+ return formatData(
+ tokenId,
+ metadata.imageUrl,
+ account,
+ serialNumber,
+ "",
+ from.nonce,
+ metadata
+ );
+ } catch (error) {
+ console.log({ error });
+ throw new Error(
+ error.response?.data?.message ||
+ error.message ||
+ "An error occurred while importing the NFT!"
+ );
+ }
+};
+
+/**
+ * IMPORT NFT FROM TEZOS CHAIN
+ */
+export const importNFTURI_Tezos = async (contract, tokenId, account, from) => {
+ try {
+ const {
+ general: { testNet },
+ } = store.getState();
+ const { data } = await axios.get(
+ testNet
+ ? `https://api.ghostnet.tzkt.io/v1/tokens/balances?account=${account}&token.tokenId=${tokenId}&token.contract=${contract}&token.standard=fa2&limit=10000`
+ : `https://api.tzkt.io/v1/tokens/balances?account=${account}&token.tokenId=${tokenId}&token.contract=${contract}&token.standard=fa2&limit=10000`
+ );
+
+ const { token } = data.find((t) => t.token.tokenId === tokenId);
+
+ if (data.length <= 0 || !token) {
+ return Promise.reject(new Error("You don't own this NFT!"));
+ }
+
+ return formatData(
+ contract,
+ setupURI(token.metadata?.artifactUri),
+ account,
+ tokenId,
+ "FA2",
+ from.nonce,
+ {
+ ...token.metadata,
+ image: setupURI(
+ token.metadata?.displayUri ?? token.metadata?.artifactUri
+ ),
+ animation_url: setupURI(token.metadata?.artifactUri),
+ }
+ );
+ } catch (error) {
+ console.log({ error });
+ throw new Error(
+ error.response?.data?.message ||
+ error.message ||
+ "An error occurred while importing the NFT!"
+ );
+ }
+};
+
+/**
+ * IMPORT NFT FROM TON CHAIN
+ */
+export const importNFTURI_TON = async (contract, account, from) => {
+ try {
+ const {
+ general: { testNet },
+ } = store.getState();
+ const { data } = await axios.get(
+ testNet
+ ? `https://testnet.toncenter.com/api/v3/nft/items?address=${contract}`
+ : `https://toncenter.com/api/v3/nft/items?address=${contract}`
+ );
+
+ if (data.nft_items?.length === 0) {
+ return Promise.reject(new Error("Invalid item address!"));
+ }
+
+ const item = data.nft_items[0];
+
+ if (item.owner_address !== account) {
+ return Promise.reject(new Error("You don't own this NFT!"));
+ }
+
+ const metadata = await axios.get(setupURI(item.content.uri));
+
+ return formatData(
+ contract,
+ setupURI(item.content.uri),
+ account,
+ contract,
+ "TON",
+ from.nonce,
+ {
+ ...metadata.data,
+ image: metadata.data.image,
+ }
+ );
+ } catch (error) {
+ console.log({ error });
+ throw new Error(
+ error.response?.data?.message ||
+ error.message ||
+ "An error occurred while importing the NFT!"
+ );
+ }
+};
+
+/**
+ * IMPORT NFT FROM SOLANA CHAIN
+ */
+export const importNFTURI_Solana = async (contract, account, from) => {
+ try {
+ const {
+ general: { testNet },
+ } = store.getState();
+ const { data } = await axios.post(
+ testNet
+ ? "https://explorer-api.devnet.solana.com/"
+ : "https://explorer-api.mainnet-beta.solana.com/",
+ {
+ id: contract,
+ jsonrpc: "2.0",
+ method: "getAsset",
+ params: {
+ id: contract,
+ },
+ }
+ );
+
+ if (data.error) {
+ return Promise.reject(
+ new Error(
+ data.error.code === -32000
+ ? "Invalid contract address!"
+ : "An error occurred while importing the NFT!"
+ )
+ );
+ }
+
+ if (data?.result?.authorities?.[0]?.address !== account) {
+ return Promise.reject(new Error("You don't own this NFT!"));
+ }
+
+ const { data: metadata } = await axios.get(data.result.content.json_uri);
+
+ console.log(
+ formatData(
+ contract,
+ metadata.image,
+ account,
+ contract,
+ "SPL",
+ from.nonce,
+ {
+ ...metadata,
+ image: metadata.image,
+ }
+ )
+ );
+
+ return formatData(
+ contract,
+ metadata.image,
+ account,
+ contract,
+ "SPL",
+ from.nonce,
+ {
+ ...metadata,
+ image: metadata.image,
+ nftMint: contract,
+ }
+ );
+ } catch (error) {
+ console.log({ error });
+ throw new Error(
+ error.response?.data?.message ||
+ error.message ||
+ "An error occurred while importing the NFT!"
+ );
+ }
+};