2024-09-09 20:36:39 +03:00
|
|
|
|
import {
|
|
|
|
|
createContext,
|
|
|
|
|
useCallback,
|
|
|
|
|
useEffect,
|
|
|
|
|
useMemo,
|
|
|
|
|
useRef,
|
|
|
|
|
useState,
|
|
|
|
|
} from "react";
|
2024-04-14 14:57:30 +03:00
|
|
|
|
import reactLogo from "./assets/react.svg";
|
|
|
|
|
import viteLogo from "/vite.svg";
|
|
|
|
|
import "./App.css";
|
|
|
|
|
import { useDropzone } from "react-dropzone";
|
2024-09-09 20:36:39 +03:00
|
|
|
|
import {
|
|
|
|
|
Box,
|
|
|
|
|
Button,
|
|
|
|
|
Checkbox,
|
|
|
|
|
CircularProgress,
|
|
|
|
|
Dialog,
|
|
|
|
|
DialogActions,
|
|
|
|
|
DialogContent,
|
|
|
|
|
DialogContentText,
|
|
|
|
|
DialogTitle,
|
|
|
|
|
Input,
|
|
|
|
|
InputLabel,
|
|
|
|
|
Popover,
|
|
|
|
|
Tooltip,
|
|
|
|
|
Typography,
|
|
|
|
|
} from "@mui/material";
|
2024-04-14 14:57:30 +03:00
|
|
|
|
import { decryptStoredWallet } from "./utils/decryptWallet";
|
|
|
|
|
import { CountdownCircleTimer } from "react-countdown-circle-timer";
|
2024-04-14 21:14:13 +03:00
|
|
|
|
import Logo1 from "./assets/svgs/Logo1.svg";
|
2024-04-15 22:30:49 +03:00
|
|
|
|
import Logo1Dark from "./assets/svgs/Logo1Dark.svg";
|
2024-09-09 20:36:39 +03:00
|
|
|
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
2024-04-14 21:14:13 +03:00
|
|
|
|
import Logo2 from "./assets/svgs/Logo2.svg";
|
|
|
|
|
import Copy from "./assets/svgs/Copy.svg";
|
2024-09-09 20:36:39 +03:00
|
|
|
|
import ltcLogo from "./assets/ltc.png";
|
|
|
|
|
import qortLogo from "./assets/qort.png";
|
2024-04-14 21:14:13 +03:00
|
|
|
|
import { CopyToClipboard } from "react-copy-to-clipboard";
|
|
|
|
|
import Download from "./assets/svgs/Download.svg";
|
|
|
|
|
import Logout from "./assets/svgs/Logout.svg";
|
|
|
|
|
import Return from "./assets/svgs/Return.svg";
|
2024-04-14 23:01:28 +03:00
|
|
|
|
import Success from "./assets/svgs/Success.svg";
|
2024-04-15 22:30:49 +03:00
|
|
|
|
import Info from "./assets/svgs/Info.svg";
|
2024-04-14 14:57:30 +03:00
|
|
|
|
import {
|
|
|
|
|
createAccount,
|
|
|
|
|
generateRandomSentence,
|
|
|
|
|
saveFileToDisk,
|
|
|
|
|
} from "./utils/generateWallet/generateWallet";
|
|
|
|
|
import { kdf } from "./deps/kdf";
|
|
|
|
|
import { generateSaveWalletData } from "./utils/generateWallet/storeWallet";
|
|
|
|
|
import { crypto, walletVersion } from "./constants/decryptWallet";
|
|
|
|
|
import PhraseWallet from "./utils/generateWallet/phrase-wallet";
|
2024-04-14 21:14:13 +03:00
|
|
|
|
import {
|
|
|
|
|
AddressBox,
|
|
|
|
|
AppContainer,
|
|
|
|
|
AuthenticatedContainer,
|
|
|
|
|
AuthenticatedContainerInnerLeft,
|
|
|
|
|
AuthenticatedContainerInnerRight,
|
|
|
|
|
CustomButton,
|
|
|
|
|
CustomInput,
|
|
|
|
|
CustomLabel,
|
|
|
|
|
TextItalic,
|
|
|
|
|
TextP,
|
|
|
|
|
TextSpan,
|
|
|
|
|
} from "./App-styles";
|
|
|
|
|
import { Spacer } from "./common/Spacer";
|
2024-04-15 22:30:49 +03:00
|
|
|
|
import { Loader } from "./components/Loader";
|
2024-07-10 10:23:45 -04:00
|
|
|
|
import { PasswordField, ErrorText } from "./components";
|
2024-09-09 20:36:39 +03:00
|
|
|
|
import { ChatGroup } from "./components/Chat/ChatGroup";
|
|
|
|
|
import { Group, requestQueueMemberNames } from "./components/Group/Group";
|
|
|
|
|
import { TaskManger } from "./components/TaskManager/TaskManger";
|
|
|
|
|
import { useModal } from "./common/useModal";
|
|
|
|
|
import { LoadingButton } from "@mui/lab";
|
|
|
|
|
import { Label } from "./components/Group/AddGroup";
|
|
|
|
|
import { CustomizedSnackbars } from "./components/Snackbar/Snackbar";
|
|
|
|
|
import {
|
|
|
|
|
getFee,
|
|
|
|
|
groupApi,
|
|
|
|
|
groupApiLocal,
|
|
|
|
|
groupApiSocket,
|
|
|
|
|
groupApiSocketLocal,
|
|
|
|
|
} from "./background";
|
|
|
|
|
import { executeEvent } from "./utils/events";
|
|
|
|
|
import { requestQueueCommentCount, requestQueuePublishedAccouncements } from "./components/Chat/GroupAnnouncements";
|
|
|
|
|
import { requestQueueGroupJoinRequests } from "./components/Group/GroupJoinRequests";
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
|
|
|
|
type extStates =
|
|
|
|
|
| "not-authenticated"
|
|
|
|
|
| "authenticated"
|
|
|
|
|
| "send-qort"
|
|
|
|
|
| "web-app-request-connection"
|
|
|
|
|
| "web-app-request-payment"
|
|
|
|
|
| "web-app-request-authentication"
|
|
|
|
|
| "download-wallet"
|
2024-04-15 22:30:49 +03:00
|
|
|
|
| "create-wallet"
|
|
|
|
|
| "transfer-success-regular"
|
2024-07-09 00:44:02 +03:00
|
|
|
|
| "transfer-success-request"
|
|
|
|
|
| "wallet-dropped"
|
2024-07-12 23:44:21 -04:00
|
|
|
|
| "web-app-request-buy-order"
|
2024-07-17 17:00:43 -04:00
|
|
|
|
| "buy-order-submitted"
|
2024-09-09 20:36:39 +03:00
|
|
|
|
| "group";
|
|
|
|
|
|
|
|
|
|
interface MyContextInterface {
|
|
|
|
|
txList: any[];
|
|
|
|
|
memberGroups: any[];
|
|
|
|
|
setTxList: (val) => void;
|
|
|
|
|
setMemberGroups: (val) => void;
|
|
|
|
|
isShow: boolean;
|
|
|
|
|
onCancel: () => void;
|
|
|
|
|
onOk: () => void;
|
|
|
|
|
show: () => void;
|
|
|
|
|
message: any;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const defaultValues: MyContextInterface = {
|
|
|
|
|
txList: [],
|
|
|
|
|
memberGroups: [],
|
|
|
|
|
setTxList: () => {},
|
|
|
|
|
setMemberGroups: () => {},
|
|
|
|
|
isShow: false,
|
|
|
|
|
onCancel: () => {},
|
|
|
|
|
onOk: () => {},
|
|
|
|
|
show: () => {},
|
|
|
|
|
message: {
|
|
|
|
|
publishFee: "",
|
|
|
|
|
message: "",
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const allQueues = {
|
|
|
|
|
requestQueueCommentCount: requestQueueCommentCount,
|
|
|
|
|
requestQueuePublishedAccouncements: requestQueuePublishedAccouncements,
|
|
|
|
|
requestQueueMemberNames: requestQueueMemberNames,
|
|
|
|
|
requestQueueGroupJoinRequests: requestQueueGroupJoinRequests
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const controlAllQueues = (action) => {
|
|
|
|
|
Object.keys(allQueues).forEach((key) => {
|
|
|
|
|
const val = allQueues[key];
|
|
|
|
|
try {
|
|
|
|
|
if (typeof val[action] === 'function') {
|
|
|
|
|
val[action]();
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const clearAllQueues = () => {
|
|
|
|
|
Object.keys(allQueues).forEach((key) => {
|
|
|
|
|
const val = allQueues[key];
|
|
|
|
|
try {
|
|
|
|
|
val.clear();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const pauseAllQueues = () => controlAllQueues('pause');
|
|
|
|
|
export const resumeAllQueues = () => controlAllQueues('resume');
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
export const MyContext = createContext<MyContextInterface>(defaultValues);
|
|
|
|
|
|
|
|
|
|
export let globalApiKey: string | null = null;
|
|
|
|
|
|
|
|
|
|
export const getBaseApiReact = (customApi?: string) => {
|
|
|
|
|
|
|
|
|
|
if (customApi) {
|
|
|
|
|
return customApi;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (globalApiKey) {
|
|
|
|
|
return groupApiLocal;
|
|
|
|
|
} else {
|
|
|
|
|
return groupApi;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
export const getBaseApiReactSocket = (customApi?: string) => {
|
|
|
|
|
|
|
|
|
|
if (customApi) {
|
|
|
|
|
return customApi;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (globalApiKey) {
|
|
|
|
|
return groupApiSocketLocal;
|
|
|
|
|
} else {
|
|
|
|
|
return groupApiSocket;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
export const isMainWindow = window?.location?.href?.includes("?main=true");
|
2024-04-14 14:57:30 +03:00
|
|
|
|
function App() {
|
|
|
|
|
const [extState, setExtstate] = useState<extStates>("not-authenticated");
|
|
|
|
|
const [backupjson, setBackupjson] = useState<any>(null);
|
|
|
|
|
const [rawWallet, setRawWallet] = useState<any>(null);
|
2024-07-17 20:53:38 -04:00
|
|
|
|
const [ltcBalanceLoading, setLtcBalanceLoading] = useState<boolean>(false);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const [qortBalanceLoading, setQortBalanceLoading] = useState<boolean>(false);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const [decryptedWallet, setdecryptedWallet] = useState<any>(null);
|
|
|
|
|
const [requestConnection, setRequestConnection] = useState<any>(null);
|
2024-07-12 23:44:21 -04:00
|
|
|
|
const [requestBuyOrder, setRequestBuyOrder] = useState<any>(null);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const [authenticatedMode, setAuthenticatedMode] = useState("qort");
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const [requestAuthentication, setRequestAuthentication] = useState<any>(null);
|
|
|
|
|
const [userInfo, setUserInfo] = useState<any>(null);
|
|
|
|
|
const [balance, setBalance] = useState<any>(null);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const [ltcBalance, setLtcBalance] = useState<any>(null);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const [paymentTo, setPaymentTo] = useState<string>("");
|
|
|
|
|
const [paymentAmount, setPaymentAmount] = useState<number>(0);
|
|
|
|
|
const [paymentPassword, setPaymentPassword] = useState<string>("");
|
|
|
|
|
const [sendPaymentError, setSendPaymentError] = useState<string>("");
|
|
|
|
|
const [sendPaymentSuccess, setSendPaymentSuccess] = useState<string>("");
|
|
|
|
|
const [countdown, setCountdown] = useState<null | number>(null);
|
|
|
|
|
const [walletToBeDownloaded, setWalletToBeDownloaded] = useState<any>(null);
|
|
|
|
|
const [walletToBeDownloadedPassword, setWalletToBeDownloadedPassword] =
|
|
|
|
|
useState<string>("");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const [isMain, setIsMain] = useState<boolean>(
|
|
|
|
|
window?.location?.href?.includes("?main=true")
|
|
|
|
|
);
|
|
|
|
|
const isMainRef = useRef(false);
|
|
|
|
|
const [authenticatePassword, setAuthenticatePassword] = useState<string>("");
|
2024-04-15 22:30:49 +03:00
|
|
|
|
const [sendqortState, setSendqortState] = useState<any>(null);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
2024-04-14 21:14:13 +03:00
|
|
|
|
const [
|
|
|
|
|
walletToBeDownloadedPasswordConfirm,
|
|
|
|
|
setWalletToBeDownloadedPasswordConfirm,
|
|
|
|
|
] = useState<string>("");
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const [walletToBeDownloadedError, setWalletToBeDownloadedError] =
|
|
|
|
|
useState<string>("");
|
2024-07-17 20:53:38 -04:00
|
|
|
|
const [walletToBeDecryptedError, setWalletToBeDecryptedError] =
|
2024-07-09 00:44:02 +03:00
|
|
|
|
useState<string>("");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const [txList, setTxList] = useState([]);
|
|
|
|
|
const [memberGroups, setMemberGroups] = useState([]);
|
|
|
|
|
const [isFocused, setIsFocused] = useState(true);
|
|
|
|
|
|
|
|
|
|
const holdRefExtState = useRef<extStates>("not-authenticated");
|
|
|
|
|
const isFocusedRef = useRef<boolean>(true);
|
|
|
|
|
const { isShow, onCancel, onOk, show, message } = useModal();
|
|
|
|
|
const [openRegisterName, setOpenRegisterName] = useState(false);
|
|
|
|
|
const registerNamePopoverRef = useRef(null);
|
|
|
|
|
const [isLoadingRegisterName, setIsLoadingRegisterName] = useState(false);
|
|
|
|
|
const [registerNameValue, setRegisterNameValue] = useState("");
|
|
|
|
|
const [infoSnack, setInfoSnack] = useState(null);
|
|
|
|
|
const [openSnack, setOpenSnack] = useState(false);
|
|
|
|
|
const [hasLocalNode, setHasLocalNode] = useState(false);
|
|
|
|
|
const [openAdvancedSettings, setOpenAdvancedSettings] = useState(false);
|
|
|
|
|
const [useLocalNode, setUseLocalNode] = useState(false);
|
|
|
|
|
const [confirmUseOfLocal, setConfirmUseOfLocal] = useState(false);
|
|
|
|
|
|
|
|
|
|
const [apiKey, setApiKey] = useState("");
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
chrome.runtime.sendMessage({ action: "getApiKey" }, (response) => {
|
|
|
|
|
if (response) {
|
|
|
|
|
|
|
|
|
|
globalApiKey = response;
|
|
|
|
|
setApiKey(response);
|
|
|
|
|
setUseLocalNode(true)
|
|
|
|
|
setConfirmUseOfLocal(true)
|
|
|
|
|
setOpenAdvancedSettings(true)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}, []);
|
2024-07-17 20:53:38 -04:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (extState) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
holdRefExtState.current = extState;
|
2024-04-25 12:48:26 +03:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}, [extState]);
|
2024-04-25 12:48:26 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
isFocusedRef.current = isFocused;
|
|
|
|
|
}, [isFocused]);
|
|
|
|
|
|
|
|
|
|
// Handler for file selection
|
|
|
|
|
const handleFileChangeApiKey = (event) => {
|
|
|
|
|
const file = event.target.files[0]; // Get the selected file
|
|
|
|
|
if (file) {
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
reader.onload = (e) => {
|
|
|
|
|
const text = e.target.result; // Get the file content
|
|
|
|
|
setApiKey(text); // Store the file content in the state
|
|
|
|
|
};
|
|
|
|
|
reader.readAsText(file); // Read the file as text
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const checkIfUserHasLocalNode = useCallback(async () => {
|
|
|
|
|
try {
|
|
|
|
|
const url = `http://127.0.0.1:12391/admin/status`;
|
|
|
|
|
const response = await fetch(url, {
|
|
|
|
|
method: "GET",
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
if (data?.isSynchronizing === false && data?.syncPercent === 100) {
|
|
|
|
|
setHasLocalNode(true);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {}
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
checkIfUserHasLocalNode();
|
|
|
|
|
}, [extState]);
|
2024-07-18 12:26:13 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const address = useMemo(() => {
|
|
|
|
|
if (!rawWallet?.address0) return "";
|
|
|
|
|
return rawWallet.address0;
|
|
|
|
|
}, [rawWallet]);
|
|
|
|
|
const { getRootProps, getInputProps } = useDropzone({
|
|
|
|
|
accept: {
|
|
|
|
|
"application/json": [".json"], // Only accept JSON files
|
|
|
|
|
},
|
|
|
|
|
maxFiles: 1,
|
|
|
|
|
onDrop: async (acceptedFiles) => {
|
|
|
|
|
const file: any = acceptedFiles[0];
|
|
|
|
|
const fileContents = await new Promise((resolve, reject) => {
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
|
|
|
|
|
reader.onabort = () => reject("File reading was aborted");
|
|
|
|
|
reader.onerror = () => reject("File reading has failed");
|
|
|
|
|
reader.onload = () => {
|
|
|
|
|
// Resolve the promise with the reader result when reading completes
|
|
|
|
|
resolve(reader.result);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Read the file as text
|
|
|
|
|
reader.readAsText(file);
|
|
|
|
|
});
|
2024-07-17 20:53:38 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
let error: any = null;
|
|
|
|
|
let pf: any;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (typeof fileContents !== "string") return;
|
|
|
|
|
pf = JSON.parse(fileContents);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (e) {}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const requiredFields = [
|
|
|
|
|
"address0",
|
|
|
|
|
"salt",
|
|
|
|
|
"iv",
|
|
|
|
|
"version",
|
|
|
|
|
"encryptedSeed",
|
|
|
|
|
"mac",
|
|
|
|
|
"kdfThreads",
|
|
|
|
|
];
|
|
|
|
|
for (const field of requiredFields) {
|
|
|
|
|
if (!(field in pf)) throw new Error(field + " not found in JSON");
|
|
|
|
|
}
|
2024-07-09 00:44:02 +03:00
|
|
|
|
// storeWalletInfo(pf);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
setRawWallet(pf);
|
2024-07-09 00:44:02 +03:00
|
|
|
|
// setExtstate("authenticated");
|
|
|
|
|
setExtstate("wallet-dropped");
|
2024-04-14 14:57:30 +03:00
|
|
|
|
setdecryptedWallet(null);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log(e);
|
|
|
|
|
|
|
|
|
|
error = e;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const saveWalletFunc = async (password: string) => {
|
|
|
|
|
let wallet = structuredClone(rawWallet);
|
2024-04-14 21:14:13 +03:00
|
|
|
|
|
|
|
|
|
const res = await decryptStoredWallet(password, wallet);
|
|
|
|
|
const wallet2 = new PhraseWallet(res, walletVersion);
|
|
|
|
|
wallet = await wallet2.generateSaveWalletData(
|
|
|
|
|
password,
|
|
|
|
|
crypto.kdfThreads,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
() => {}
|
2024-04-14 21:14:13 +03:00
|
|
|
|
);
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
setWalletToBeDownloaded({
|
|
|
|
|
wallet,
|
|
|
|
|
qortAddress: rawWallet.address0,
|
|
|
|
|
});
|
|
|
|
|
return {
|
|
|
|
|
wallet,
|
|
|
|
|
qortAddress: rawWallet.address0,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const storeWalletInfo = (wallet: any) => {
|
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{ action: "storeWalletInfo", wallet },
|
|
|
|
|
(response) => {
|
|
|
|
|
if (response) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
chrome.tabs.query(
|
|
|
|
|
{ active: true, currentWindow: true },
|
|
|
|
|
function (tabs: any[]) {
|
|
|
|
|
chrome.tabs.sendMessage(
|
|
|
|
|
tabs[0].id,
|
|
|
|
|
{ from: "popup", subject: "anySubject" },
|
2024-09-09 20:36:39 +03:00
|
|
|
|
function (response) {}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
};
|
2024-07-17 20:53:38 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const getBalanceFunc = () => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setQortBalanceLoading(true);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
chrome.runtime.sendMessage({ action: "balance" }, (response) => {
|
2024-07-18 12:26:13 -04:00
|
|
|
|
if (!response?.error && !isNaN(+response)) {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
setBalance(response);
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setQortBalanceLoading(false);
|
2024-07-17 20:53:38 -04:00
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const getLtcBalanceFunc = () => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setLtcBalanceLoading(true);
|
2024-07-17 20:53:38 -04:00
|
|
|
|
chrome.runtime.sendMessage({ action: "ltcBalance" }, (response) => {
|
2024-07-18 12:26:13 -04:00
|
|
|
|
if (!response?.error && !isNaN(+response)) {
|
2024-07-17 20:53:38 -04:00
|
|
|
|
setLtcBalance(response);
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setLtcBalanceLoading(false);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const sendCoinFunc = () => {
|
|
|
|
|
setSendPaymentError("");
|
|
|
|
|
setSendPaymentSuccess("");
|
|
|
|
|
if (!paymentTo) {
|
|
|
|
|
setSendPaymentError("Please enter a recipient");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!paymentAmount) {
|
|
|
|
|
setSendPaymentError("Please enter an amount greater than 0");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!paymentPassword) {
|
|
|
|
|
setSendPaymentError("Please enter your wallet password");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(true);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "sendCoin",
|
|
|
|
|
payload: {
|
|
|
|
|
amount: Number(paymentAmount),
|
|
|
|
|
receiver: paymentTo.trim(),
|
|
|
|
|
password: paymentPassword,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
(response) => {
|
|
|
|
|
if (response?.error) {
|
|
|
|
|
setSendPaymentError(response.error);
|
|
|
|
|
} else {
|
2024-04-15 22:30:49 +03:00
|
|
|
|
setExtstate("transfer-success-regular");
|
|
|
|
|
// setSendPaymentSuccess("Payment successfully sent");
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(false);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const clearAllStates = () => {
|
|
|
|
|
setRequestConnection(null);
|
|
|
|
|
setRequestAuthentication(null);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
// Listen for messages from the background script
|
|
|
|
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
|
|
// Check if the message is to update the state
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (
|
|
|
|
|
message.action === "UPDATE_STATE_CONFIRM_SEND_QORT" &&
|
|
|
|
|
!isMainWindow
|
|
|
|
|
) {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
// Update the component state with the received 'sendqort' state
|
|
|
|
|
setSendqortState(message.payload);
|
|
|
|
|
setExtstate("web-app-request-payment");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else if (message.action === "closePopup" && !isMainWindow) {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
// Update the component state with the received 'sendqort' state
|
|
|
|
|
window.close();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else if (
|
|
|
|
|
message.action === "UPDATE_STATE_REQUEST_CONNECTION" &&
|
|
|
|
|
!isMainWindow
|
|
|
|
|
) {
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
// Update the component state with the received 'sendqort' state
|
|
|
|
|
setRequestConnection(message.payload);
|
|
|
|
|
setExtstate("web-app-request-connection");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else if (
|
|
|
|
|
message.action === "UPDATE_STATE_REQUEST_BUY_ORDER" &&
|
|
|
|
|
!isMainWindow
|
|
|
|
|
) {
|
2024-07-12 23:44:21 -04:00
|
|
|
|
// Update the component state with the received 'sendqort' state
|
|
|
|
|
setRequestBuyOrder(message.payload);
|
|
|
|
|
setExtstate("web-app-request-buy-order");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else if (
|
|
|
|
|
message.action === "UPDATE_STATE_REQUEST_AUTHENTICATION" &&
|
|
|
|
|
!isMainWindow
|
|
|
|
|
) {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
// Update the component state with the received 'sendqort' state
|
|
|
|
|
setRequestAuthentication(message.payload);
|
|
|
|
|
setExtstate("web-app-request-authentication");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else if (message.action === "SET_COUNTDOWN" && !isMainWindow) {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
setCountdown(message.payload);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else if (message.action === "INITIATE_MAIN") {
|
|
|
|
|
// Update the component state with the received 'sendqort' state
|
|
|
|
|
setIsMain(true);
|
|
|
|
|
isMainRef.current = true;
|
|
|
|
|
} else if (message.action === "CHECK_FOCUS" && isMainWindow) {
|
|
|
|
|
|
|
|
|
|
sendResponse(isFocusedRef.current);
|
|
|
|
|
} else if (
|
|
|
|
|
message.action === "NOTIFICATION_OPEN_DIRECT" &&
|
|
|
|
|
isMainWindow
|
|
|
|
|
) {
|
|
|
|
|
executeEvent("openDirectMessage", {
|
|
|
|
|
from: message.payload.from,
|
|
|
|
|
});
|
|
|
|
|
} else if (message.action === "NOTIFICATION_OPEN_GROUP" && isMainWindow) {
|
|
|
|
|
executeEvent("openGroupMessage", {
|
|
|
|
|
from: message.payload.from,
|
|
|
|
|
});
|
|
|
|
|
} else if (
|
|
|
|
|
message.action === "NOTIFICATION_OPEN_ANNOUNCEMENT_GROUP" &&
|
|
|
|
|
isMainWindow
|
|
|
|
|
) {
|
|
|
|
|
executeEvent("openGroupAnnouncement", {
|
|
|
|
|
from: message.payload.from,
|
|
|
|
|
});
|
|
|
|
|
} else if (
|
|
|
|
|
message.action === "NOTIFICATION_OPEN_THREAD_NEW_POST" &&
|
|
|
|
|
isMainWindow
|
|
|
|
|
) {
|
|
|
|
|
executeEvent("openThreadNewPost", {
|
|
|
|
|
data: message.payload.data,
|
|
|
|
|
});
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
|
|
|
|
});
|
2024-04-14 21:14:13 +03:00
|
|
|
|
}, []);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
2024-07-17 20:53:38 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
//param = isDecline
|
|
|
|
|
const confirmPayment = (isDecline: boolean) => {
|
|
|
|
|
if (isDecline) {
|
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "sendQortConfirmation",
|
|
|
|
|
payload: {
|
|
|
|
|
amount: sendqortState?.amount,
|
|
|
|
|
receiver: sendqortState?.address,
|
|
|
|
|
password: paymentPassword,
|
|
|
|
|
interactionId: sendqortState?.interactionId,
|
|
|
|
|
isDecline: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
(response) => {
|
|
|
|
|
if (response) {
|
|
|
|
|
setSendPaymentSuccess("Payment successfully sent");
|
|
|
|
|
} else {
|
|
|
|
|
window.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-07-12 23:44:21 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(true);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "sendQortConfirmation",
|
|
|
|
|
payload: {
|
|
|
|
|
amount: sendqortState.amount,
|
|
|
|
|
receiver: sendqortState.address,
|
|
|
|
|
password: paymentPassword,
|
|
|
|
|
interactionId: sendqortState.interactionId,
|
|
|
|
|
isDecline: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
(response) => {
|
2024-04-15 22:30:49 +03:00
|
|
|
|
if (response === true) {
|
|
|
|
|
setExtstate("transfer-success-request");
|
|
|
|
|
setCountdown(null);
|
2024-07-12 23:44:21 -04:00
|
|
|
|
} else {
|
|
|
|
|
setSendPaymentError(
|
|
|
|
|
response?.error || "Unable to perform payment. Please try again."
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(false);
|
2024-07-12 23:44:21 -04:00
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const confirmBuyOrder = (isDecline: boolean) => {
|
|
|
|
|
if (isDecline) {
|
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "buyOrderConfirmation",
|
|
|
|
|
payload: {
|
|
|
|
|
crosschainAtInfo: requestBuyOrder?.crosschainAtInfo,
|
|
|
|
|
interactionId: requestBuyOrder?.interactionId,
|
|
|
|
|
isDecline: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
(response) => {
|
2024-07-17 20:53:38 -04:00
|
|
|
|
window.close();
|
2024-07-12 23:44:21 -04:00
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(true);
|
2024-07-12 23:44:21 -04:00
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "buyOrderConfirmation",
|
|
|
|
|
payload: {
|
|
|
|
|
crosschainAtInfo: requestBuyOrder?.crosschainAtInfo,
|
2024-07-17 20:53:38 -04:00
|
|
|
|
interactionId: requestBuyOrder?.interactionId,
|
|
|
|
|
isDecline: false,
|
2024-07-12 23:44:21 -04:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
(response) => {
|
|
|
|
|
if (response === true) {
|
2024-07-17 17:00:43 -04:00
|
|
|
|
setExtstate("buy-order-submitted");
|
2024-07-12 23:44:21 -04:00
|
|
|
|
setCountdown(null);
|
2024-04-15 22:30:49 +03:00
|
|
|
|
} else {
|
|
|
|
|
setSendPaymentError(
|
|
|
|
|
response?.error || "Unable to perform payment. Please try again."
|
|
|
|
|
);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(false);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
const responseToConnectionRequest = (
|
|
|
|
|
isOkay: boolean,
|
|
|
|
|
hostname: string,
|
|
|
|
|
interactionId: string
|
|
|
|
|
) => {
|
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "responseToConnectionRequest",
|
|
|
|
|
payload: { isOkay, hostname, interactionId },
|
|
|
|
|
},
|
|
|
|
|
(response) => {
|
|
|
|
|
if (response === false || response === true) {
|
|
|
|
|
window.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-14 23:01:28 +03:00
|
|
|
|
// const rawWalletRef = useRef(null)
|
|
|
|
|
|
|
|
|
|
// useEffect(()=> {
|
|
|
|
|
// rawWalletRef.current = rawWallet
|
|
|
|
|
// }, [rawWallet])
|
2024-07-17 20:53:38 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
try {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(true);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
chrome.runtime.sendMessage({ action: "getWalletInfo" }, (response) => {
|
|
|
|
|
if (response && response?.walletInfo) {
|
|
|
|
|
setRawWallet(response?.walletInfo);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (
|
|
|
|
|
holdRefExtState.current === "web-app-request-payment" ||
|
|
|
|
|
holdRefExtState.current === "web-app-request-connection" ||
|
|
|
|
|
holdRefExtState.current === "web-app-request-buy-order"
|
|
|
|
|
)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
setExtstate("authenticated");
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (error) {
|
|
|
|
|
} finally {
|
|
|
|
|
setIsLoading(false);
|
2024-04-16 13:25:36 +03:00
|
|
|
|
}
|
2024-04-14 23:01:28 +03:00
|
|
|
|
}, []);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const getUserInfo = useCallback(async (useTimer?: boolean) => {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
try {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (useTimer) {
|
|
|
|
|
await new Promise((res) => {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
res(null);
|
|
|
|
|
}, 10000);
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
chrome.runtime.sendMessage({ action: "userInfo" }, (response) => {
|
|
|
|
|
if (response && !response.error) {
|
|
|
|
|
setUserInfo(response);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
getBalanceFunc();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (error) {}
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!address) return;
|
|
|
|
|
getUserInfo();
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}, [address]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
return () => {
|
|
|
|
|
console.log("exit");
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (
|
|
|
|
|
authenticatedMode === "ltc" &&
|
|
|
|
|
!ltcBalanceLoading &&
|
|
|
|
|
ltcBalance === null
|
|
|
|
|
) {
|
|
|
|
|
getLtcBalanceFunc();
|
2024-07-18 11:22:51 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}, [authenticatedMode]);
|
2024-07-18 11:22:51 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const confirmPasswordToDownload = async () => {
|
|
|
|
|
try {
|
|
|
|
|
setWalletToBeDownloadedError("");
|
|
|
|
|
if (!walletToBeDownloadedPassword) {
|
|
|
|
|
setSendPaymentError("Please enter your password");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(true);
|
2024-07-17 20:53:38 -04:00
|
|
|
|
await new Promise<void>((res) => {
|
|
|
|
|
setTimeout(() => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
res();
|
|
|
|
|
}, 250);
|
|
|
|
|
});
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const res = await saveWalletFunc(walletToBeDownloadedPassword);
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
setWalletToBeDownloadedError(error?.message);
|
2024-04-15 22:30:49 +03:00
|
|
|
|
} finally {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(false);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const saveFileToDiskFunc = async () => {
|
|
|
|
|
try {
|
|
|
|
|
await saveFileToDisk(
|
|
|
|
|
walletToBeDownloaded.wallet,
|
|
|
|
|
walletToBeDownloaded.qortAddress
|
|
|
|
|
);
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
setWalletToBeDownloadedError(error?.message);
|
2024-04-15 22:30:49 +03:00
|
|
|
|
} finally {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const createAccountFunc = async () => {
|
|
|
|
|
try {
|
|
|
|
|
if (!walletToBeDownloadedPassword) {
|
|
|
|
|
setWalletToBeDownloadedError("Please enter a password");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!walletToBeDownloadedPasswordConfirm) {
|
|
|
|
|
setWalletToBeDownloadedError("Please confirm your password");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-04-14 21:14:13 +03:00
|
|
|
|
if (
|
|
|
|
|
walletToBeDownloadedPasswordConfirm !== walletToBeDownloadedPassword
|
|
|
|
|
) {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
setWalletToBeDownloadedError("Password fields do not match!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(true);
|
2024-07-17 20:53:38 -04:00
|
|
|
|
await new Promise<void>((res) => {
|
|
|
|
|
setTimeout(() => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
res();
|
|
|
|
|
}, 250);
|
|
|
|
|
});
|
2024-04-14 21:14:13 +03:00
|
|
|
|
const res = await createAccount();
|
|
|
|
|
const wallet = await res.generateSaveWalletData(
|
|
|
|
|
walletToBeDownloadedPassword,
|
|
|
|
|
crypto.kdfThreads,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
() => {}
|
2024-04-14 21:14:13 +03:00
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "decryptWallet",
|
|
|
|
|
payload: {
|
|
|
|
|
password: walletToBeDownloadedPassword,
|
2024-07-09 00:44:02 +03:00
|
|
|
|
wallet,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
(response) => {
|
|
|
|
|
if (response && !response?.error) {
|
|
|
|
|
setRawWallet(wallet);
|
|
|
|
|
setWalletToBeDownloaded({
|
|
|
|
|
wallet,
|
|
|
|
|
qortAddress: wallet.address0,
|
|
|
|
|
});
|
|
|
|
|
chrome.runtime.sendMessage({ action: "userInfo" }, (response2) => {
|
|
|
|
|
setIsLoading(false);
|
|
|
|
|
if (response2 && !response2.error) {
|
|
|
|
|
setUserInfo(response);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
getBalanceFunc();
|
|
|
|
|
} else if (response?.error) {
|
|
|
|
|
setIsLoading(false);
|
|
|
|
|
setWalletToBeDecryptedError(response.error);
|
|
|
|
|
}
|
2024-07-09 00:44:02 +03:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
} catch (error: any) {
|
|
|
|
|
setWalletToBeDownloadedError(error?.message);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(false);
|
2024-07-17 20:53:38 -04:00
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
};
|
|
|
|
|
|
2024-04-14 21:14:13 +03:00
|
|
|
|
const logoutFunc = () => {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
try {
|
|
|
|
|
chrome.runtime.sendMessage({ action: "logout" }, (response) => {
|
|
|
|
|
if (response) {
|
2024-04-15 22:30:49 +03:00
|
|
|
|
resetAllStates();
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (error) {}
|
2024-04-14 21:14:13 +03:00
|
|
|
|
};
|
|
|
|
|
|
2024-04-14 23:01:28 +03:00
|
|
|
|
const returnToMain = () => {
|
2024-04-14 21:14:13 +03:00
|
|
|
|
setPaymentTo("");
|
|
|
|
|
setPaymentAmount(0);
|
|
|
|
|
setPaymentPassword("");
|
|
|
|
|
setSendPaymentError("");
|
|
|
|
|
setSendPaymentSuccess("");
|
|
|
|
|
setCountdown(null);
|
|
|
|
|
setWalletToBeDownloaded(null);
|
|
|
|
|
setWalletToBeDownloadedPassword("");
|
2024-04-14 23:01:28 +03:00
|
|
|
|
setExtstate("authenticated");
|
|
|
|
|
};
|
2024-04-15 22:30:49 +03:00
|
|
|
|
|
|
|
|
|
const resetAllStates = () => {
|
|
|
|
|
setExtstate("not-authenticated");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setAuthenticatedMode("qort");
|
2024-04-15 22:30:49 +03:00
|
|
|
|
setBackupjson(null);
|
|
|
|
|
setRawWallet(null);
|
|
|
|
|
setdecryptedWallet(null);
|
|
|
|
|
setRequestConnection(null);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setRequestBuyOrder(null);
|
2024-04-15 22:30:49 +03:00
|
|
|
|
setRequestAuthentication(null);
|
|
|
|
|
setUserInfo(null);
|
|
|
|
|
setBalance(null);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setLtcBalance(null);
|
2024-04-15 22:30:49 +03:00
|
|
|
|
setPaymentTo("");
|
|
|
|
|
setPaymentAmount(0);
|
|
|
|
|
setPaymentPassword("");
|
|
|
|
|
setSendPaymentError("");
|
|
|
|
|
setSendPaymentSuccess("");
|
|
|
|
|
setCountdown(null);
|
|
|
|
|
setWalletToBeDownloaded(null);
|
|
|
|
|
setWalletToBeDownloadedPassword("");
|
|
|
|
|
setWalletToBeDownloadedPasswordConfirm("");
|
|
|
|
|
setWalletToBeDownloadedError("");
|
|
|
|
|
setSendqortState(null);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
globalApiKey = null;
|
|
|
|
|
setApiKey("");
|
|
|
|
|
setUseLocalNode(false);
|
|
|
|
|
setHasLocalNode(false);
|
|
|
|
|
setOpenAdvancedSettings(false);
|
|
|
|
|
setConfirmUseOfLocal(false)
|
2024-04-15 22:30:49 +03:00
|
|
|
|
};
|
|
|
|
|
|
2024-07-17 20:53:38 -04:00
|
|
|
|
const authenticateWallet = async () => {
|
2024-07-09 00:44:02 +03:00
|
|
|
|
try {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setIsLoading(true);
|
|
|
|
|
setWalletToBeDecryptedError("");
|
2024-07-17 20:53:38 -04:00
|
|
|
|
await new Promise<void>((res) => {
|
|
|
|
|
setTimeout(() => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
res();
|
|
|
|
|
}, 250);
|
|
|
|
|
});
|
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "decryptWallet",
|
|
|
|
|
payload: {
|
|
|
|
|
password: authenticatePassword,
|
|
|
|
|
wallet: rawWallet,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
(response) => {
|
|
|
|
|
if (response && !response?.error) {
|
|
|
|
|
setAuthenticatePassword("");
|
|
|
|
|
setExtstate("authenticated");
|
|
|
|
|
setWalletToBeDecryptedError("");
|
|
|
|
|
chrome.runtime.sendMessage({ action: "userInfo" }, (response) => {
|
|
|
|
|
setIsLoading(false);
|
|
|
|
|
if (response && !response.error) {
|
|
|
|
|
setUserInfo(response);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
getBalanceFunc();
|
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{ action: "getWalletInfo" },
|
|
|
|
|
(response) => {
|
|
|
|
|
if (response && response?.walletInfo) {
|
|
|
|
|
setRawWallet(response?.walletInfo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else if (response?.error) {
|
|
|
|
|
setIsLoading(false);
|
|
|
|
|
setWalletToBeDecryptedError(response.error);
|
|
|
|
|
}
|
2024-07-17 20:53:38 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
setWalletToBeDecryptedError("Unable to authenticate. Wrong password");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// const handleBeforeUnload = (e)=> {
|
|
|
|
|
// const shouldClose = confirm('Are you sure you want to close this window? You may have unsaved changes.');
|
|
|
|
|
|
|
|
|
|
// if (!shouldClose) {
|
|
|
|
|
// // Prevent the window from closing
|
|
|
|
|
// e.preventDefault();
|
|
|
|
|
// e.returnValue = ''; // Required for Chrome
|
|
|
|
|
// } else {
|
|
|
|
|
// // Allow the window to close
|
|
|
|
|
// // No need to call preventDefault here; returnValue must be left empty
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// useEffect(()=> {
|
|
|
|
|
// window.addEventListener('beforeunload', handleBeforeUnload);
|
|
|
|
|
|
|
|
|
|
// return ()=> {
|
|
|
|
|
// window.removeEventListener('beforeunload', handleBeforeUnload);
|
|
|
|
|
// }
|
|
|
|
|
// }, [])
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!isMainWindow) return;
|
|
|
|
|
const handleBeforeUnload = (e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.returnValue = ""; // This is required for Chrome to display the confirmation dialog.
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Add the event listener when the component mounts
|
|
|
|
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
|
|
|
|
|
|
|
|
// Clean up the event listener when the component unmounts
|
|
|
|
|
return () => {
|
|
|
|
|
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!isMainWindow) return;
|
|
|
|
|
// Handler for when the window gains focus
|
|
|
|
|
const handleFocus = () => {
|
|
|
|
|
setIsFocused(true);
|
|
|
|
|
console.log("Webview is focused");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Handler for when the window loses focus
|
|
|
|
|
const handleBlur = () => {
|
|
|
|
|
setIsFocused(false);
|
|
|
|
|
console.log("Webview is not focused");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Attach the event listeners
|
|
|
|
|
window.addEventListener("focus", handleFocus);
|
|
|
|
|
window.addEventListener("blur", handleBlur);
|
|
|
|
|
|
|
|
|
|
// Optionally, listen for visibility changes
|
|
|
|
|
const handleVisibilityChange = () => {
|
|
|
|
|
if (document.visibilityState === "visible") {
|
|
|
|
|
setIsFocused(true);
|
|
|
|
|
console.log("Webview is visible");
|
|
|
|
|
} else {
|
|
|
|
|
setIsFocused(false);
|
|
|
|
|
console.log("Webview is hidden");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
|
|
|
|
|
|
|
|
// Cleanup the event listeners on component unmount
|
|
|
|
|
return () => {
|
|
|
|
|
window.removeEventListener("focus", handleFocus);
|
|
|
|
|
window.removeEventListener("blur", handleBlur);
|
|
|
|
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const registerName = async () => {
|
|
|
|
|
try {
|
|
|
|
|
if (!userInfo?.address) throw new Error("Your address was not found");
|
|
|
|
|
const fee = await getFee("REGISTER_NAME");
|
|
|
|
|
await show({
|
|
|
|
|
message: "Would you like to register this name?",
|
|
|
|
|
publishFee: fee.fee + " QORT",
|
|
|
|
|
});
|
|
|
|
|
setIsLoadingRegisterName(true);
|
|
|
|
|
new Promise((res, rej) => {
|
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "registerName",
|
|
|
|
|
payload: {
|
|
|
|
|
name: registerNameValue,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
(response) => {
|
|
|
|
|
|
|
|
|
|
if (!response?.error) {
|
|
|
|
|
res(response);
|
|
|
|
|
setIsLoadingRegisterName(false);
|
|
|
|
|
setInfoSnack({
|
|
|
|
|
type: "success",
|
|
|
|
|
message:
|
|
|
|
|
"Successfully registered. It may take a couple of minutes for the changes to propagate",
|
|
|
|
|
});
|
|
|
|
|
setOpenRegisterName(false);
|
|
|
|
|
setRegisterNameValue("");
|
|
|
|
|
setOpenSnack(true);
|
|
|
|
|
setTxList((prev) => [
|
|
|
|
|
{
|
|
|
|
|
...response,
|
|
|
|
|
type: "register-name",
|
|
|
|
|
label: `Registered name: awaiting confirmation. This may take a couple minutes.`,
|
|
|
|
|
labelDone: `Registered name: success!`,
|
|
|
|
|
done: false,
|
|
|
|
|
},
|
|
|
|
|
...prev.filter((item) => !item.done),
|
|
|
|
|
]);
|
|
|
|
|
return;
|
2024-07-18 12:26:13 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setInfoSnack({
|
|
|
|
|
type: "error",
|
|
|
|
|
message: response?.error,
|
|
|
|
|
});
|
|
|
|
|
setOpenSnack(true);
|
|
|
|
|
rej(response.error);
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-07-09 00:44:02 +03:00
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (error?.message) {
|
|
|
|
|
setInfoSnack({
|
|
|
|
|
type: "error",
|
|
|
|
|
message: error?.message,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
setIsLoadingRegisterName(false);
|
2024-07-17 20:53:38 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
};
|
2024-07-09 00:44:02 +03:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
return (
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<AppContainer>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{/* {extState === 'group' && (
|
|
|
|
|
<Group myAddress={userInfo?.address} />
|
|
|
|
|
)} */}
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
{extState === "not-authenticated" && (
|
|
|
|
|
<>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<Spacer height="48px" />
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<div
|
|
|
|
|
className="image-container"
|
|
|
|
|
style={{
|
|
|
|
|
width: "136px",
|
|
|
|
|
height: "154px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<img src={Logo1} className="base-image" />
|
|
|
|
|
<img src={Logo1Dark} className="hover-image" />
|
|
|
|
|
</div>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<Spacer height="38px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
WELCOME TO <TextItalic>YOUR</TextItalic> <br></br>
|
|
|
|
|
<TextSpan> QORTAL WALLET</TextSpan>
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="38px" />
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
gap: "10px",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
marginLeft: "28px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<CustomButton {...getRootProps()}>
|
|
|
|
|
<input {...getInputProps()} />
|
|
|
|
|
Authenticate
|
|
|
|
|
</CustomButton>
|
|
|
|
|
<Tooltip
|
|
|
|
|
title="Authenticate by importing your Qortal JSON file"
|
|
|
|
|
arrow
|
|
|
|
|
>
|
|
|
|
|
<img src={Info} />
|
|
|
|
|
</Tooltip>
|
|
|
|
|
</Box>
|
|
|
|
|
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<Spacer height="6px" />
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
gap: "10px",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
marginLeft: "28px",
|
2024-04-14 21:14:13 +03:00
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<CustomButton
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setExtstate("create-wallet");
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Create account
|
|
|
|
|
</CustomButton>
|
|
|
|
|
|
|
|
|
|
<img
|
|
|
|
|
src={Info}
|
|
|
|
|
style={{
|
|
|
|
|
visibility: "hidden",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{hasLocalNode && (
|
|
|
|
|
<>
|
|
|
|
|
<Spacer height="15px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
gap: "10px",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
flexDirection: "column",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
<Typography
|
|
|
|
|
sx={{
|
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
fontSize: '14px'
|
|
|
|
|
}}
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setOpenAdvancedSettings(true);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Advanced settings
|
|
|
|
|
</Typography>
|
|
|
|
|
|
|
|
|
|
{openAdvancedSettings && (
|
|
|
|
|
<>
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
gap: "10px",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
width: '100%'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Checkbox
|
|
|
|
|
edge="start"
|
|
|
|
|
checked={useLocalNode}
|
|
|
|
|
tabIndex={-1}
|
|
|
|
|
disableRipple
|
|
|
|
|
onChange={(event) => {
|
|
|
|
|
setUseLocalNode(event.target.checked);
|
|
|
|
|
}}
|
|
|
|
|
disabled={confirmUseOfLocal}
|
|
|
|
|
sx={{
|
|
|
|
|
"&.Mui-checked": {
|
|
|
|
|
color: "white", // Customize the color when checked
|
|
|
|
|
},
|
|
|
|
|
"& .MuiSvgIcon-root": {
|
|
|
|
|
color: "white",
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<Typography>Use local node</Typography>
|
|
|
|
|
</Box>
|
|
|
|
|
{useLocalNode && (
|
|
|
|
|
<>
|
|
|
|
|
<Button disabled={confirmUseOfLocal} variant="contained" component="label">
|
|
|
|
|
Select apiKey.txt
|
|
|
|
|
<input
|
|
|
|
|
type="file"
|
|
|
|
|
accept=".txt"
|
|
|
|
|
hidden
|
|
|
|
|
onChange={handleFileChangeApiKey} // File input handler
|
|
|
|
|
/>
|
|
|
|
|
</Button>
|
|
|
|
|
<Spacer height="5px" />
|
|
|
|
|
<Typography
|
|
|
|
|
sx={{
|
|
|
|
|
fontSize: "12px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{apiKey}
|
|
|
|
|
</Typography>
|
|
|
|
|
<Spacer height="5px" />
|
|
|
|
|
<Button
|
|
|
|
|
onClick={() => {
|
|
|
|
|
const valueToSet = !confirmUseOfLocal
|
|
|
|
|
const payload = valueToSet ? apiKey : null
|
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{ action: "setApiKey", payload },
|
|
|
|
|
(response) => {
|
|
|
|
|
if (response) {
|
|
|
|
|
globalApiKey = payload;
|
|
|
|
|
|
|
|
|
|
setConfirmUseOfLocal(valueToSet)
|
|
|
|
|
if(!globalApiKey){
|
|
|
|
|
setUseLocalNode(false)
|
|
|
|
|
setOpenAdvancedSettings(false)
|
|
|
|
|
setApiKey('')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
variant="contained"
|
|
|
|
|
sx={{
|
|
|
|
|
color: "white",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{!confirmUseOfLocal ? 'Confirm use of local node' : 'Switch back to gateway'}
|
|
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</Box>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</>
|
|
|
|
|
)}
|
2024-04-14 21:14:13 +03:00
|
|
|
|
{/* {extState !== "not-authenticated" && (
|
2024-04-14 14:57:30 +03:00
|
|
|
|
<button onClick={logoutFunc}>logout</button>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
)} */}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{extState === "authenticated" && isMainWindow && (
|
|
|
|
|
<MyContext.Provider
|
|
|
|
|
value={{
|
|
|
|
|
txList,
|
|
|
|
|
setTxList,
|
|
|
|
|
memberGroups,
|
|
|
|
|
setMemberGroups,
|
|
|
|
|
isShow,
|
|
|
|
|
onCancel,
|
|
|
|
|
onOk,
|
|
|
|
|
show,
|
|
|
|
|
message,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
width: "100vw",
|
|
|
|
|
height: "100vh",
|
|
|
|
|
display: "flex",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Group
|
|
|
|
|
balance={balance}
|
|
|
|
|
userInfo={userInfo}
|
|
|
|
|
myAddress={userInfo?.address}
|
|
|
|
|
isFocused={isFocused}
|
|
|
|
|
isMain={isMain}
|
|
|
|
|
/>
|
|
|
|
|
<AuthenticatedContainer sx={{ width: "350px" }}>
|
|
|
|
|
<AuthenticatedContainerInnerLeft>
|
|
|
|
|
<Spacer height="48px" />
|
|
|
|
|
|
|
|
|
|
{authenticatedMode === "ltc" ? (
|
|
|
|
|
<>
|
|
|
|
|
<img src={ltcLogo} />
|
|
|
|
|
<Spacer height="32px" />
|
|
|
|
|
<CopyToClipboard text={rawWallet?.ltcAddress}>
|
|
|
|
|
<AddressBox>
|
|
|
|
|
{rawWallet?.ltcAddress?.slice(0, 6)}...
|
|
|
|
|
{rawWallet?.ltcAddress?.slice(-4)} <img src={Copy} />
|
|
|
|
|
</AddressBox>
|
|
|
|
|
</CopyToClipboard>
|
|
|
|
|
<Spacer height="10px" />
|
|
|
|
|
{ltcBalanceLoading && (
|
|
|
|
|
<CircularProgress color="success" size={16} />
|
|
|
|
|
)}
|
|
|
|
|
{!isNaN(+ltcBalance) && !ltcBalanceLoading && (
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
gap: "10px",
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 700,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{ltcBalance} LTC
|
|
|
|
|
</TextP>
|
|
|
|
|
<RefreshIcon
|
|
|
|
|
onClick={getLtcBalanceFunc}
|
|
|
|
|
sx={{
|
|
|
|
|
fontSize: "16px",
|
|
|
|
|
color: "white",
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
<img src={Logo2} />
|
|
|
|
|
<Spacer height="32px" />
|
2024-07-17 20:53:38 -04:00
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{userInfo?.name}
|
2024-07-17 20:53:38 -04:00
|
|
|
|
</TextP>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<Spacer height="10px" />
|
|
|
|
|
<CopyToClipboard text={rawWallet?.address0}>
|
|
|
|
|
<AddressBox>
|
|
|
|
|
{rawWallet?.address0?.slice(0, 6)}...
|
|
|
|
|
{rawWallet?.address0?.slice(-4)} <img src={Copy} />
|
|
|
|
|
</AddressBox>
|
|
|
|
|
</CopyToClipboard>
|
|
|
|
|
<Spacer height="10px" />
|
|
|
|
|
{qortBalanceLoading && (
|
|
|
|
|
<CircularProgress color="success" size={16} />
|
|
|
|
|
)}
|
|
|
|
|
{!qortBalanceLoading && balance >= 0 && (
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
gap: "10px",
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 700,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{balance?.toFixed(2)} QORT
|
|
|
|
|
</TextP>
|
|
|
|
|
<RefreshIcon
|
|
|
|
|
onClick={getBalanceFunc}
|
|
|
|
|
sx={{
|
|
|
|
|
fontSize: "16px",
|
|
|
|
|
color: "white",
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<Spacer height="35px" />
|
|
|
|
|
{userInfo && !userInfo?.name && (
|
|
|
|
|
<TextP
|
|
|
|
|
ref={registerNamePopoverRef}
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: 1.2,
|
|
|
|
|
fontSize: "16px",
|
|
|
|
|
fontWeight: 500,
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
marginTop: "10px",
|
|
|
|
|
color: "red",
|
|
|
|
|
textDecoration: "underline",
|
|
|
|
|
}}
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setOpenRegisterName(true);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
REGISTER NAME
|
|
|
|
|
</TextP>
|
|
|
|
|
)}
|
|
|
|
|
<Spacer height="20px" />
|
|
|
|
|
<CustomButton
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setExtstate("send-qort");
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Transfer QORT
|
|
|
|
|
</CustomButton>
|
|
|
|
|
</>
|
2024-07-17 20:53:38 -04:00
|
|
|
|
)}
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "24px",
|
2024-09-09 20:36:39 +03:00
|
|
|
|
fontSize: "12px",
|
|
|
|
|
fontWeight: 500,
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
marginTop: "10px",
|
|
|
|
|
textDecoration: "underline",
|
|
|
|
|
}}
|
|
|
|
|
onClick={() => {
|
|
|
|
|
chrome.tabs.create({ url: "https://www.qort.trade" });
|
2024-07-17 20:53:38 -04:00
|
|
|
|
}}
|
|
|
|
|
>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
Get QORT at qort.trade
|
2024-07-17 20:53:38 -04:00
|
|
|
|
</TextP>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
</AuthenticatedContainerInnerLeft>
|
|
|
|
|
<AuthenticatedContainerInnerRight>
|
|
|
|
|
<Spacer height="20px" />
|
|
|
|
|
<img
|
2024-07-17 20:53:38 -04:00
|
|
|
|
onClick={() => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setExtstate("download-wallet");
|
2024-07-17 20:53:38 -04:00
|
|
|
|
}}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
src={Download}
|
|
|
|
|
style={{
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Spacer height="20px" />
|
|
|
|
|
<img
|
|
|
|
|
src={Logout}
|
|
|
|
|
onClick={logoutFunc}
|
|
|
|
|
style={{
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Spacer height="20px" />
|
|
|
|
|
{authenticatedMode === "qort" && (
|
|
|
|
|
<img
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setAuthenticatedMode("ltc");
|
|
|
|
|
}}
|
|
|
|
|
src={ltcLogo}
|
|
|
|
|
style={{
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
width: "20px",
|
|
|
|
|
height: "auto",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{authenticatedMode === "ltc" && (
|
|
|
|
|
<img
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setAuthenticatedMode("qort");
|
|
|
|
|
}}
|
|
|
|
|
src={qortLogo}
|
|
|
|
|
style={{
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
width: "20px",
|
|
|
|
|
height: "auto",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</AuthenticatedContainerInnerRight>
|
|
|
|
|
</AuthenticatedContainer>
|
|
|
|
|
</Box>
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
position: "fixed",
|
|
|
|
|
right: "25px",
|
|
|
|
|
bottom: "25px",
|
|
|
|
|
width: "350px",
|
|
|
|
|
zIndex: 100000,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<TaskManger getUserInfo={getUserInfo} />
|
|
|
|
|
</Box>
|
|
|
|
|
</MyContext.Provider>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
)}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{extState === "send-qort" && isMainWindow && (
|
2024-04-14 14:57:30 +03:00
|
|
|
|
<>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<Spacer height="22px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
width: "100%",
|
|
|
|
|
justifyContent: "flex-start",
|
2024-04-14 23:01:28 +03:00
|
|
|
|
paddingLeft: "22px",
|
|
|
|
|
boxSizing: "border-box",
|
2024-04-14 21:14:13 +03:00
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<img
|
|
|
|
|
style={{
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
}}
|
|
|
|
|
onClick={returnToMain}
|
|
|
|
|
src={Return}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
<Spacer height="35px" />
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Box
|
2024-04-14 21:14:13 +03:00
|
|
|
|
sx={{
|
2024-04-14 23:01:28 +03:00
|
|
|
|
display: "flex",
|
|
|
|
|
flexDirection: "column",
|
|
|
|
|
alignItems: "flex-start",
|
2024-04-14 21:14:13 +03:00
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "start",
|
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Transfer QORT
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="35px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "start",
|
|
|
|
|
lineHeight: "16px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
color: "rgba(255, 255, 255, 0.5)",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Balance:
|
|
|
|
|
</TextP>
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "start",
|
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 700,
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-07-18 12:26:13 -04:00
|
|
|
|
{balance?.toFixed(2)} QORT
|
2024-04-14 23:01:28 +03:00
|
|
|
|
</TextP>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
</Box>
|
|
|
|
|
<Spacer height="35px" />
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
<Box>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<CustomLabel htmlFor="standard-adornment-name">To</CustomLabel>
|
|
|
|
|
<Spacer height="5px" />
|
|
|
|
|
<CustomInput
|
2024-04-14 14:57:30 +03:00
|
|
|
|
id="standard-adornment-name"
|
|
|
|
|
value={paymentTo}
|
|
|
|
|
onChange={(e) => setPaymentTo(e.target.value)}
|
2024-04-14 21:14:13 +03:00
|
|
|
|
autoComplete="off"
|
2024-04-14 14:57:30 +03:00
|
|
|
|
/>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<Spacer height="6px" />
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<CustomLabel htmlFor="standard-adornment-amount">
|
|
|
|
|
Amount
|
|
|
|
|
</CustomLabel>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<Spacer height="5px" />
|
|
|
|
|
<CustomInput
|
2024-04-14 14:57:30 +03:00
|
|
|
|
id="standard-adornment-amount"
|
|
|
|
|
type="number"
|
|
|
|
|
value={paymentAmount}
|
|
|
|
|
onChange={(e) => setPaymentAmount(+e.target.value)}
|
2024-04-14 21:14:13 +03:00
|
|
|
|
autoComplete="off"
|
2024-04-14 14:57:30 +03:00
|
|
|
|
/>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<Spacer height="6px" />
|
|
|
|
|
<CustomLabel htmlFor="standard-adornment-password">
|
2024-04-15 22:30:49 +03:00
|
|
|
|
Confirm Wallet Password
|
2024-04-14 21:14:13 +03:00
|
|
|
|
</CustomLabel>
|
|
|
|
|
<Spacer height="5px" />
|
2024-07-02 19:02:02 -04:00
|
|
|
|
<PasswordField
|
2024-04-14 14:57:30 +03:00
|
|
|
|
id="standard-adornment-password"
|
|
|
|
|
value={paymentPassword}
|
|
|
|
|
onChange={(e) => setPaymentPassword(e.target.value)}
|
2024-04-14 21:14:13 +03:00
|
|
|
|
autoComplete="off"
|
2024-04-14 14:57:30 +03:00
|
|
|
|
/>
|
|
|
|
|
</Box>
|
2024-04-16 13:25:36 +03:00
|
|
|
|
<Spacer height="10px" />
|
2024-07-10 10:23:45 -04:00
|
|
|
|
<ErrorText>{sendPaymentError}</ErrorText>
|
2024-04-16 13:25:36 +03:00
|
|
|
|
{/* <Typography>{sendPaymentSuccess}</Typography> */}
|
2024-04-14 21:14:13 +03:00
|
|
|
|
<Spacer height="25px" />
|
|
|
|
|
<CustomButton
|
2024-04-14 14:57:30 +03:00
|
|
|
|
onClick={() => {
|
|
|
|
|
sendCoinFunc();
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
Send
|
|
|
|
|
</CustomButton>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</>
|
2024-07-12 23:44:21 -04:00
|
|
|
|
)}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{extState === "web-app-request-buy-order" && !isMainWindow && (
|
2024-07-12 23:44:21 -04:00
|
|
|
|
<>
|
|
|
|
|
<Spacer height="100px" />
|
|
|
|
|
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
The Application <br></br>{" "}
|
|
|
|
|
<TextItalic>{requestBuyOrder?.hostname}</TextItalic> <br></br>
|
|
|
|
|
<TextSpan>is requesting a buy order</TextSpan>
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="10px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
2024-07-18 00:05:45 -04:00
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 700,
|
2024-07-12 23:44:21 -04:00
|
|
|
|
}}
|
|
|
|
|
>
|
2024-07-18 00:05:45 -04:00
|
|
|
|
{+requestBuyOrder?.crosschainAtInfo?.qortAmount} QORT
|
2024-07-12 23:44:21 -04:00
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="15px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
2024-07-18 00:05:45 -04:00
|
|
|
|
fontSize: "14px",
|
2024-07-12 23:44:21 -04:00
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
FOR
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="15px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 700,
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{requestBuyOrder?.crosschainAtInfo?.expectedForeignAmount}{" "}
|
|
|
|
|
{requestBuyOrder?.crosschainAtInfo?.foreignBlockchain}
|
2024-07-12 23:44:21 -04:00
|
|
|
|
</TextP>
|
|
|
|
|
{/* <Spacer height="29px" />
|
|
|
|
|
|
|
|
|
|
<CustomLabel htmlFor="standard-adornment-password">
|
|
|
|
|
Confirm Wallet Password
|
|
|
|
|
</CustomLabel>
|
|
|
|
|
<Spacer height="5px" />
|
|
|
|
|
<PasswordField
|
|
|
|
|
id="standard-adornment-password"
|
|
|
|
|
value={paymentPassword}
|
|
|
|
|
onChange={(e) => setPaymentPassword(e.target.value)}
|
|
|
|
|
/> */}
|
|
|
|
|
<Spacer height="29px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "14px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<CustomButton
|
|
|
|
|
sx={{
|
|
|
|
|
minWidth: "102px",
|
|
|
|
|
}}
|
|
|
|
|
onClick={() => confirmBuyOrder(false)}
|
|
|
|
|
>
|
|
|
|
|
accept
|
|
|
|
|
</CustomButton>
|
|
|
|
|
<CustomButton
|
|
|
|
|
sx={{
|
|
|
|
|
minWidth: "102px",
|
|
|
|
|
}}
|
|
|
|
|
onClick={() => confirmBuyOrder(true)}
|
|
|
|
|
>
|
|
|
|
|
decline
|
|
|
|
|
</CustomButton>
|
|
|
|
|
</Box>
|
|
|
|
|
<ErrorText>{sendPaymentError}</ErrorText>
|
|
|
|
|
</>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
)}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{extState === "web-app-request-payment" && !isMainWindow && (
|
2024-04-14 14:57:30 +03:00
|
|
|
|
<>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<Spacer height="100px" />
|
2024-04-14 23:19:55 +03:00
|
|
|
|
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<TextP
|
2024-04-14 23:19:55 +03:00
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
The Application <br></br>{" "}
|
|
|
|
|
<TextItalic>{sendqortState?.hostname}</TextItalic> <br></br>
|
|
|
|
|
<TextSpan>is requesting a payment</TextSpan>
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="10px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
2024-04-15 22:30:49 +03:00
|
|
|
|
fontSize: "10px",
|
2024-04-14 23:19:55 +03:00
|
|
|
|
}}
|
2024-04-15 22:30:49 +03:00
|
|
|
|
>
|
|
|
|
|
{sendqortState?.description}
|
|
|
|
|
</TextP>
|
2024-04-14 23:19:55 +03:00
|
|
|
|
<Spacer height="15px" />
|
|
|
|
|
<TextP
|
2024-04-15 22:30:49 +03:00
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 700,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{sendqortState?.amount} QORT
|
|
|
|
|
</TextP>
|
2024-07-09 00:44:02 +03:00
|
|
|
|
{/* <Spacer height="29px" />
|
2024-04-14 23:19:55 +03:00
|
|
|
|
|
|
|
|
|
<CustomLabel htmlFor="standard-adornment-password">
|
2024-04-15 22:30:49 +03:00
|
|
|
|
Confirm Wallet Password
|
2024-04-14 23:19:55 +03:00
|
|
|
|
</CustomLabel>
|
|
|
|
|
<Spacer height="5px" />
|
2024-07-02 19:02:02 -04:00
|
|
|
|
<PasswordField
|
2024-04-14 14:57:30 +03:00
|
|
|
|
id="standard-adornment-password"
|
|
|
|
|
value={paymentPassword}
|
|
|
|
|
onChange={(e) => setPaymentPassword(e.target.value)}
|
2024-07-09 00:44:02 +03:00
|
|
|
|
/> */}
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<Spacer height="29px" />
|
|
|
|
|
<Box
|
2024-04-14 23:19:55 +03:00
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "14px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<CustomButton
|
|
|
|
|
sx={{
|
|
|
|
|
minWidth: "102px",
|
|
|
|
|
}}
|
|
|
|
|
onClick={() => confirmPayment(false)}
|
|
|
|
|
>
|
|
|
|
|
accept
|
|
|
|
|
</CustomButton>
|
|
|
|
|
<CustomButton
|
|
|
|
|
sx={{
|
|
|
|
|
minWidth: "102px",
|
|
|
|
|
}}
|
|
|
|
|
onClick={() => confirmPayment(true)}
|
|
|
|
|
>
|
|
|
|
|
decline
|
|
|
|
|
</CustomButton>
|
|
|
|
|
</Box>
|
2024-07-10 10:23:45 -04:00
|
|
|
|
<ErrorText>{sendPaymentError}</ErrorText>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</>
|
|
|
|
|
)}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{extState === "web-app-request-connection" && !isMainWindow && (
|
2024-04-14 14:57:30 +03:00
|
|
|
|
<>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Spacer height="48px" />
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<div
|
|
|
|
|
className="image-container"
|
|
|
|
|
style={{
|
|
|
|
|
width: "136px",
|
|
|
|
|
height: "154px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<img src={Logo1} className="base-image" />
|
|
|
|
|
<img src={Logo1Dark} className="hover-image" />
|
|
|
|
|
</div>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Spacer height="38px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
The Application <br></br>{" "}
|
|
|
|
|
<TextItalic>{requestConnection?.hostname}</TextItalic> <br></br>
|
|
|
|
|
<TextSpan>is requestion a connection</TextSpan>
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="38px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "14px",
|
|
|
|
|
}}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<CustomButton
|
|
|
|
|
sx={{
|
|
|
|
|
minWidth: "102px",
|
|
|
|
|
}}
|
|
|
|
|
onClick={() =>
|
|
|
|
|
responseToConnectionRequest(
|
|
|
|
|
true,
|
|
|
|
|
requestConnection?.hostname,
|
|
|
|
|
requestConnection.interactionId
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
accept
|
|
|
|
|
</CustomButton>
|
|
|
|
|
<CustomButton
|
|
|
|
|
sx={{
|
|
|
|
|
minWidth: "102px",
|
|
|
|
|
}}
|
|
|
|
|
onClick={() =>
|
|
|
|
|
responseToConnectionRequest(
|
|
|
|
|
false,
|
|
|
|
|
requestConnection?.hostname,
|
|
|
|
|
requestConnection.interactionId
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
decline
|
|
|
|
|
</CustomButton>
|
|
|
|
|
</Box>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</>
|
|
|
|
|
)}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{extState === "web-app-request-authentication" && !isMainWindow && (
|
2024-04-14 14:57:30 +03:00
|
|
|
|
<>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Spacer height="48px" />
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<div
|
|
|
|
|
className="image-container"
|
|
|
|
|
style={{
|
|
|
|
|
width: "136px",
|
|
|
|
|
height: "154px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<img src={Logo1} className="base-image" />
|
|
|
|
|
<img src={Logo1Dark} className="hover-image" />
|
|
|
|
|
</div>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Spacer height="38px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
The Application <br></br>{" "}
|
|
|
|
|
<TextItalic>{requestConnection?.hostname}</TextItalic> <br></br>
|
|
|
|
|
<TextSpan>requests authentication</TextSpan>
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="38px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "14px",
|
|
|
|
|
}}
|
|
|
|
|
></Box>
|
|
|
|
|
<Spacer height="38px" />
|
|
|
|
|
<CustomButton {...getRootProps()}>
|
|
|
|
|
<input {...getInputProps()} />
|
|
|
|
|
Authenticate
|
|
|
|
|
</CustomButton>
|
|
|
|
|
<Spacer height="6px" />
|
|
|
|
|
<CustomButton
|
2024-04-14 21:14:13 +03:00
|
|
|
|
onClick={() => {
|
|
|
|
|
setExtstate("create-wallet");
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Create account
|
2024-04-14 23:01:28 +03:00
|
|
|
|
</CustomButton>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</>
|
|
|
|
|
)}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{rawWallet && extState === "wallet-dropped" && (
|
2024-07-09 00:44:02 +03:00
|
|
|
|
<>
|
|
|
|
|
<Spacer height="22px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
width: "100%",
|
|
|
|
|
justifyContent: "flex-start",
|
|
|
|
|
paddingLeft: "22px",
|
|
|
|
|
boxSizing: "border-box",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<img
|
|
|
|
|
style={{
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
}}
|
2024-07-17 20:53:38 -04:00
|
|
|
|
onClick={() => {
|
2024-07-09 00:44:02 +03:00
|
|
|
|
setRawWallet(null);
|
|
|
|
|
setExtstate("not-authenticated");
|
|
|
|
|
}}
|
|
|
|
|
src={Return}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
<Spacer height="10px" />
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<div
|
|
|
|
|
className="image-container"
|
|
|
|
|
style={{
|
|
|
|
|
width: "136px",
|
|
|
|
|
height: "154px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-07-09 00:44:02 +03:00
|
|
|
|
<img src={Logo1} className="base-image" />
|
|
|
|
|
<img src={Logo1Dark} className="hover-image" />
|
|
|
|
|
</div>
|
|
|
|
|
<Spacer height="35px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
flexDirection: "column",
|
|
|
|
|
alignItems: "flex-start",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "start",
|
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Authenticate
|
|
|
|
|
</TextP>
|
|
|
|
|
</Box>
|
|
|
|
|
<Spacer height="35px" />
|
2024-07-17 20:53:38 -04:00
|
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
<CustomLabel htmlFor="standard-adornment-password">
|
|
|
|
|
Wallet Password
|
|
|
|
|
</CustomLabel>
|
|
|
|
|
<Spacer height="5px" />
|
|
|
|
|
<PasswordField
|
|
|
|
|
id="standard-adornment-password"
|
|
|
|
|
value={authenticatePassword}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
onChange={(e) => setAuthenticatePassword(e.target.value)}
|
2024-07-17 20:53:38 -04:00
|
|
|
|
onKeyDown={(e) => {
|
|
|
|
|
if (e.key === "Enter") {
|
|
|
|
|
authenticateWallet();
|
2024-07-09 00:44:02 +03:00
|
|
|
|
}
|
2024-07-17 20:53:38 -04:00
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Spacer height="20px" />
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<CustomButton onClick={authenticateWallet}>
|
2024-07-17 20:53:38 -04:00
|
|
|
|
Authenticate
|
|
|
|
|
</CustomButton>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<ErrorText>{walletToBeDecryptedError}</ErrorText>
|
2024-07-17 20:53:38 -04:00
|
|
|
|
</>
|
2024-07-09 00:44:02 +03:00
|
|
|
|
</>
|
|
|
|
|
)}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
{extState === "download-wallet" && (
|
|
|
|
|
<>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<Spacer height="22px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
width: "100%",
|
|
|
|
|
justifyContent: "flex-start",
|
|
|
|
|
paddingLeft: "22px",
|
|
|
|
|
boxSizing: "border-box",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<img
|
|
|
|
|
style={{
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
}}
|
|
|
|
|
onClick={returnToMain}
|
|
|
|
|
src={Return}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
<Spacer height="10px" />
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<div
|
|
|
|
|
className="image-container"
|
|
|
|
|
style={{
|
|
|
|
|
width: "136px",
|
|
|
|
|
height: "154px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<img src={Logo1} className="base-image" />
|
|
|
|
|
<img src={Logo1Dark} className="hover-image" />
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</div>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<Spacer height="35px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
flexDirection: "column",
|
|
|
|
|
alignItems: "flex-start",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "start",
|
|
|
|
|
lineHeight: "24px",
|
|
|
|
|
fontSize: "20px",
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Download Wallet
|
|
|
|
|
</TextP>
|
|
|
|
|
</Box>
|
|
|
|
|
<Spacer height="35px" />
|
2024-04-14 14:57:30 +03:00
|
|
|
|
{!walletToBeDownloaded && (
|
|
|
|
|
<>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<CustomLabel htmlFor="standard-adornment-password">
|
|
|
|
|
Confirm Wallet Password
|
|
|
|
|
</CustomLabel>
|
|
|
|
|
<Spacer height="5px" />
|
2024-07-02 19:02:02 -04:00
|
|
|
|
<PasswordField
|
2024-04-14 14:57:30 +03:00
|
|
|
|
id="standard-adornment-password"
|
|
|
|
|
value={walletToBeDownloadedPassword}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setWalletToBeDownloadedPassword(e.target.value)
|
|
|
|
|
}
|
|
|
|
|
/>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<Spacer height="20px" />
|
|
|
|
|
<CustomButton onClick={confirmPasswordToDownload}>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
Confirm password
|
2024-04-15 22:30:49 +03:00
|
|
|
|
</CustomButton>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<ErrorText>{walletToBeDownloadedError}</ErrorText>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{walletToBeDownloaded && (
|
|
|
|
|
<>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<CustomButton onClick={saveFileToDiskFunc}>
|
|
|
|
|
Download wallet
|
|
|
|
|
</CustomButton>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
{extState === "create-wallet" && (
|
|
|
|
|
<>
|
|
|
|
|
{!walletToBeDownloaded && (
|
|
|
|
|
<>
|
2024-07-17 20:53:38 -04:00
|
|
|
|
<Spacer height="22px" />
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
width: "100%",
|
|
|
|
|
justifyContent: "flex-start",
|
|
|
|
|
paddingLeft: "22px",
|
|
|
|
|
boxSizing: "border-box",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<img
|
|
|
|
|
style={{
|
|
|
|
|
cursor: "pointer",
|
|
|
|
|
}}
|
|
|
|
|
onClick={() => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setExtstate("not-authenticated");
|
2024-07-17 20:53:38 -04:00
|
|
|
|
}}
|
|
|
|
|
src={Return}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<Spacer height="15px" />
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<div
|
|
|
|
|
className="image-container"
|
|
|
|
|
style={{
|
|
|
|
|
width: "136px",
|
|
|
|
|
height: "154px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-07-17 20:53:38 -04:00
|
|
|
|
<img src={Logo1} className="base-image" />
|
|
|
|
|
<img src={Logo1Dark} className="hover-image" />
|
|
|
|
|
</div>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Spacer height="38px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Set up your Qortal account
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="14px" />
|
|
|
|
|
<CustomLabel htmlFor="standard-adornment-password">
|
2024-04-15 22:30:49 +03:00
|
|
|
|
Wallet Password
|
2024-04-14 23:01:28 +03:00
|
|
|
|
</CustomLabel>
|
|
|
|
|
<Spacer height="5px" />
|
2024-07-02 19:02:02 -04:00
|
|
|
|
<PasswordField
|
2024-04-14 14:57:30 +03:00
|
|
|
|
id="standard-adornment-password"
|
|
|
|
|
value={walletToBeDownloadedPassword}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setWalletToBeDownloadedPassword(e.target.value)
|
|
|
|
|
}
|
|
|
|
|
/>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Spacer height="6px" />
|
|
|
|
|
<CustomLabel htmlFor="standard-adornment-password">
|
2024-04-15 22:30:49 +03:00
|
|
|
|
Confirm Wallet Password
|
2024-04-14 23:01:28 +03:00
|
|
|
|
</CustomLabel>
|
|
|
|
|
<Spacer height="5px" />
|
2024-07-02 19:02:02 -04:00
|
|
|
|
<PasswordField
|
2024-04-14 14:57:30 +03:00
|
|
|
|
id="standard-adornment-password"
|
|
|
|
|
value={walletToBeDownloadedPasswordConfirm}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setWalletToBeDownloadedPasswordConfirm(e.target.value)
|
|
|
|
|
}
|
|
|
|
|
/>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Spacer height="17px" />
|
|
|
|
|
|
|
|
|
|
<CustomButton onClick={createAccountFunc}>
|
|
|
|
|
Create Account
|
|
|
|
|
</CustomButton>
|
2024-09-09 20:36:39 +03:00
|
|
|
|
<ErrorText>{walletToBeDownloadedError}</ErrorText>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{walletToBeDownloaded && (
|
|
|
|
|
<>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Spacer height="48px" />
|
|
|
|
|
<img src={Success} />
|
|
|
|
|
<Spacer height="45px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Congrats, you’re all set up!
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="100px" />
|
2024-04-15 22:30:49 +03:00
|
|
|
|
<CustomButton
|
|
|
|
|
onClick={() => {
|
|
|
|
|
saveFileToDiskFunc();
|
|
|
|
|
returnToMain();
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
Backup Account
|
|
|
|
|
</CustomButton>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
)}
|
2024-04-15 22:30:49 +03:00
|
|
|
|
{extState === "transfer-success-regular" && (
|
|
|
|
|
<>
|
|
|
|
|
<Spacer height="48px" />
|
|
|
|
|
<img src={Success} />
|
|
|
|
|
<Spacer height="45px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
The transfer was succesful!
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="100px" />
|
|
|
|
|
<CustomButton
|
|
|
|
|
onClick={() => {
|
|
|
|
|
returnToMain();
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Continue
|
|
|
|
|
</CustomButton>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
{extState === "transfer-success-request" && (
|
|
|
|
|
<>
|
|
|
|
|
<Spacer height="48px" />
|
|
|
|
|
<img src={Success} />
|
|
|
|
|
<Spacer height="45px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
The transfer was succesful!
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="100px" />
|
|
|
|
|
<CustomButton
|
|
|
|
|
onClick={() => {
|
|
|
|
|
window.close();
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Continue
|
|
|
|
|
</CustomButton>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
2024-07-17 17:00:43 -04:00
|
|
|
|
{extState === "buy-order-submitted" && (
|
|
|
|
|
<>
|
|
|
|
|
<Spacer height="48px" />
|
|
|
|
|
<img src={Success} />
|
|
|
|
|
<Spacer height="45px" />
|
|
|
|
|
<TextP
|
|
|
|
|
sx={{
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: "15px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Your buy order was submitted
|
|
|
|
|
</TextP>
|
|
|
|
|
<Spacer height="100px" />
|
|
|
|
|
<CustomButton
|
|
|
|
|
onClick={() => {
|
|
|
|
|
window.close();
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Close
|
|
|
|
|
</CustomButton>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
{countdown && (
|
2024-04-14 23:01:28 +03:00
|
|
|
|
<Box
|
|
|
|
|
style={{
|
|
|
|
|
position: "absolute",
|
|
|
|
|
top: "20px",
|
|
|
|
|
left: "20px",
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-14 23:01:28 +03:00
|
|
|
|
{/* <Spacer height="25px"/> */}
|
|
|
|
|
<CountdownCircleTimer
|
|
|
|
|
isPlaying
|
|
|
|
|
duration={countdown}
|
|
|
|
|
colors={["#004777", "#F7B801", "#A30000", "#A30000"]}
|
|
|
|
|
colorsTime={[7, 5, 2, 0]}
|
|
|
|
|
onComplete={() => {
|
|
|
|
|
window.close();
|
|
|
|
|
}}
|
|
|
|
|
size={75}
|
|
|
|
|
strokeWidth={8}
|
|
|
|
|
>
|
|
|
|
|
{({ remainingTime }) => <TextP>{remainingTime}</TextP>}
|
|
|
|
|
</CountdownCircleTimer>
|
|
|
|
|
</Box>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
)}
|
2024-04-15 22:30:49 +03:00
|
|
|
|
{isLoading && <Loader />}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{isShow && (
|
|
|
|
|
<Dialog
|
|
|
|
|
open={isShow}
|
|
|
|
|
aria-labelledby="alert-dialog-title"
|
|
|
|
|
aria-describedby="alert-dialog-description"
|
|
|
|
|
>
|
|
|
|
|
<DialogTitle id="alert-dialog-title">{"Publish"}</DialogTitle>
|
|
|
|
|
<DialogContent>
|
|
|
|
|
<DialogContentText id="alert-dialog-description">
|
|
|
|
|
{message.message}
|
|
|
|
|
</DialogContentText>
|
|
|
|
|
<DialogContentText id="alert-dialog-description2">
|
|
|
|
|
publish fee: {message.publishFee}
|
|
|
|
|
</DialogContentText>
|
|
|
|
|
</DialogContent>
|
|
|
|
|
<DialogActions>
|
|
|
|
|
<Button variant="contained" onClick={onCancel}>
|
|
|
|
|
Disagree
|
|
|
|
|
</Button>
|
|
|
|
|
<Button variant="contained" onClick={onOk} autoFocus>
|
|
|
|
|
Agree
|
|
|
|
|
</Button>
|
|
|
|
|
</DialogActions>
|
|
|
|
|
</Dialog>
|
|
|
|
|
)}
|
|
|
|
|
<Popover
|
|
|
|
|
open={openRegisterName}
|
|
|
|
|
anchorEl={registerNamePopoverRef.current}
|
|
|
|
|
onClose={() => {
|
|
|
|
|
setOpenRegisterName(false);
|
|
|
|
|
setRegisterNameValue("");
|
|
|
|
|
}}
|
|
|
|
|
anchorOrigin={{
|
|
|
|
|
vertical: "bottom",
|
|
|
|
|
horizontal: "center",
|
|
|
|
|
}}
|
|
|
|
|
transformOrigin={{
|
|
|
|
|
vertical: "top",
|
|
|
|
|
horizontal: "center",
|
|
|
|
|
}}
|
|
|
|
|
style={{ marginTop: "8px" }}
|
|
|
|
|
>
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
width: "325px",
|
|
|
|
|
height: "250px",
|
|
|
|
|
display: "flex",
|
|
|
|
|
flexDirection: "column",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "10px",
|
|
|
|
|
padding: "10px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Label>Choose a name</Label>
|
|
|
|
|
<Input
|
|
|
|
|
onChange={(e) => setRegisterNameValue(e.target.value)}
|
|
|
|
|
value={registerNameValue}
|
|
|
|
|
placeholder="Choose a name"
|
|
|
|
|
/>
|
|
|
|
|
<Spacer height="25px" />
|
|
|
|
|
<LoadingButton
|
|
|
|
|
loading={isLoadingRegisterName}
|
|
|
|
|
loadingPosition="start"
|
|
|
|
|
variant="contained"
|
|
|
|
|
disabled={!registerNameValue}
|
|
|
|
|
onClick={registerName}
|
|
|
|
|
>
|
|
|
|
|
Register Name
|
|
|
|
|
</LoadingButton>
|
|
|
|
|
</Box>
|
|
|
|
|
</Popover>
|
|
|
|
|
<CustomizedSnackbars
|
|
|
|
|
open={openSnack}
|
|
|
|
|
setOpen={setOpenSnack}
|
|
|
|
|
info={infoSnack}
|
|
|
|
|
setInfo={setInfoSnack}
|
|
|
|
|
/>
|
2024-04-14 21:14:13 +03:00
|
|
|
|
</AppContainer>
|
2024-04-14 14:57:30 +03:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default App;
|