diff --git a/package-lock.json b/package-lock.json index 8d577ee..5639f96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.16.4", "@mui/material": "^5.15.14", "@testing-library/jest-dom": "^6.4.6", "@testing-library/user-event": "^14.5.2", @@ -1221,6 +1222,31 @@ "url": "https://opencollective.com/mui-org" } }, + "node_modules/@mui/icons-material": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.4.tgz", + "integrity": "sha512-j9/CWctv6TH6Dou2uR2EH7UOgu79CW/YcozxCYVLJ7l03pCsiOlJ5sBArnWJxJ+nGkFwyL/1d1k8JEPMDR125A==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material": { "version": "5.15.14", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.14.tgz", diff --git a/package.json b/package.json index 67930ed..72083a2 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.16.4", "@mui/material": "^5.15.14", "@testing-library/jest-dom": "^6.4.6", "@testing-library/user-event": "^14.5.2", diff --git a/src/App.tsx b/src/App.tsx index ad40f94..77ff7b1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,14 +3,16 @@ import reactLogo from "./assets/react.svg"; import viteLogo from "/vite.svg"; import "./App.css"; import { useDropzone } from "react-dropzone"; -import { Box, Input, InputLabel, Tooltip, Typography } from "@mui/material"; +import { Box, CircularProgress, Input, InputLabel, Tooltip, Typography } from "@mui/material"; import { decryptStoredWallet } from "./utils/decryptWallet"; import { CountdownCircleTimer } from "react-countdown-circle-timer"; import Logo1 from "./assets/svgs/Logo1.svg"; import Logo1Dark from "./assets/svgs/Logo1Dark.svg"; - +import RefreshIcon from '@mui/icons-material/Refresh'; import Logo2 from "./assets/svgs/Logo2.svg"; import Copy from "./assets/svgs/Copy.svg"; +import ltcLogo from './assets/ltc.png'; +import qortLogo from './assets/qort.png' import { CopyToClipboard } from "react-copy-to-clipboard"; import Download from "./assets/svgs/Download.svg"; import Logout from "./assets/svgs/Logout.svg"; @@ -63,13 +65,16 @@ function App() { const [extState, setExtstate] = useState("not-authenticated"); const [backupjson, setBackupjson] = useState(null); const [rawWallet, setRawWallet] = useState(null); + const [ltcBalanceLoading, setLtcBalanceLoading] = useState(false); + const [qortBalanceLoading, setQortBalanceLoading] = useState(false) const [decryptedWallet, setdecryptedWallet] = useState(null); const [requestConnection, setRequestConnection] = useState(null); const [requestBuyOrder, setRequestBuyOrder] = useState(null); - + const [authenticatedMode, setAuthenticatedMode] = useState('qort') const [requestAuthentication, setRequestAuthentication] = useState(null); const [userInfo, setUserInfo] = useState(null); const [balance, setBalance] = useState(null); + const [ltcBalance, setLtcBalance] = useState(null) const [paymentTo, setPaymentTo] = useState(""); const [paymentAmount, setPaymentAmount] = useState(0); const [paymentPassword, setPaymentPassword] = useState(""); @@ -79,7 +84,7 @@ function App() { const [walletToBeDownloaded, setWalletToBeDownloaded] = useState(null); const [walletToBeDownloadedPassword, setWalletToBeDownloadedPassword] = useState(""); - const [authenticatePassword, setAuthenticatePassword] = + const [authenticatePassword, setAuthenticatePassword] = useState(""); const [sendqortState, setSendqortState] = useState(null); const [isLoading, setIsLoading] = useState(false) @@ -89,11 +94,11 @@ function App() { ] = useState(""); const [walletToBeDownloadedError, setWalletToBeDownloadedError] = useState(""); - const [walletToBeDecryptedError, setWalletToBeDecryptedError] = + const [walletToBeDecryptedError, setWalletToBeDecryptedError] = useState(""); - const holdRefExtState = useRef("not-authenticated") - useEffect(()=> { - if(extState){ + const holdRefExtState = useRef("not-authenticated") + useEffect(() => { + if (extState) { holdRefExtState.current = extState } }, [extState]) @@ -122,14 +127,14 @@ function App() { // Read the file as text reader.readAsText(file); }); - + let error: any = null; let pf: any; try { if (typeof fileContents !== "string") return; pf = JSON.parse(fileContents); - } catch (e) {} + } catch (e) { } try { const requiredFields = [ @@ -157,7 +162,7 @@ function App() { }, }); - + const saveWalletFunc = async (password: string) => { let wallet = structuredClone(rawWallet); @@ -167,7 +172,7 @@ function App() { wallet = await wallet2.generateSaveWalletData( password, crypto.kdfThreads, - () => {} + () => { } ); setWalletToBeDownloaded({ @@ -196,19 +201,30 @@ function App() { tabs[0].id, { from: "popup", subject: "anySubject" }, function (response) { - + } ); } ); }; - - + + const getBalanceFunc = () => { + setQortBalanceLoading(true) chrome.runtime.sendMessage({ action: "balance" }, (response) => { if (response && !response?.error) { setBalance(response); } + setQortBalanceLoading(false) + }); + }; + const getLtcBalanceFunc = () => { + setLtcBalanceLoading(true) + chrome.runtime.sendMessage({ action: "ltcBalance" }, (response) => { + if (response && !response?.error) { + setLtcBalance(response); + } + setLtcBalanceLoading(false) }); }; const sendCoinFunc = () => { @@ -257,7 +273,7 @@ function App() { useEffect(() => { // Listen for messages from the background script chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { - + // Check if the message is to update the state if (message.action === "UPDATE_STATE_CONFIRM_SEND_QORT") { // Update the component state with the received 'sendqort' state @@ -284,7 +300,7 @@ function App() { }); }, []); - + //param = isDecline const confirmPayment = (isDecline: boolean) => { if (isDecline) { @@ -327,7 +343,7 @@ function App() { setExtstate("transfer-success-request"); setCountdown(null); } else { - + setSendPaymentError( response?.error || "Unable to perform payment. Please try again." ); @@ -349,7 +365,7 @@ function App() { }, }, (response) => { - window.close(); + window.close(); } ); return; @@ -361,8 +377,8 @@ function App() { action: "buyOrderConfirmation", payload: { crosschainAtInfo: requestBuyOrder?.crosschainAtInfo, - interactionId: requestBuyOrder?.interactionId, - isDecline: false, + interactionId: requestBuyOrder?.interactionId, + isDecline: false, }, }, (response) => { @@ -370,7 +386,7 @@ function App() { setExtstate("buy-order-submitted"); setCountdown(null); } else { - + setSendPaymentError( response?.error || "Unable to perform payment. Please try again." ); @@ -402,18 +418,18 @@ function App() { // useEffect(()=> { // rawWalletRef.current = rawWallet // }, [rawWallet]) - + useEffect(() => { try { setIsLoading(true) chrome.runtime.sendMessage({ action: "getWalletInfo" }, (response) => { if (response && response?.walletInfo) { setRawWallet(response?.walletInfo); - if(holdRefExtState.current === 'web-app-request-payment' || holdRefExtState.current === 'web-app-request-connection' || holdRefExtState.current === 'web-app-request-buy-order') return + if (holdRefExtState.current === 'web-app-request-payment' || holdRefExtState.current === 'web-app-request-connection' || holdRefExtState.current === 'web-app-request-buy-order') return setExtstate("authenticated"); } }); - } catch (error) {} finally { + } catch (error) { } finally { setIsLoading(false) } }, []); @@ -427,7 +443,8 @@ function App() { } }); getBalanceFunc(); - } catch (error) {} + getLtcBalanceFunc() + } catch (error) { } }, [address]); useEffect(() => { @@ -444,8 +461,8 @@ function App() { return; } setIsLoading(true) - await new Promise((res)=> { - setTimeout(()=> { + await new Promise((res) => { + setTimeout(() => { res() }, 250) }) @@ -487,8 +504,8 @@ function App() { return; } setIsLoading(true) - await new Promise((res)=> { - setTimeout(()=> { + await new Promise((res) => { + setTimeout(() => { res() }, 250) }) @@ -496,12 +513,14 @@ function App() { const wallet = await res.generateSaveWalletData( walletToBeDownloadedPassword, crypto.kdfThreads, - () => {} + () => { } ); - chrome.runtime.sendMessage({ action: "decryptWallet", payload: { - password: walletToBeDownloadedPassword, - wallet - } }, (response) => { + chrome.runtime.sendMessage({ + action: "decryptWallet", payload: { + password: walletToBeDownloadedPassword, + wallet + } + }, (response) => { if (response && !response?.error) { setRawWallet(wallet); setWalletToBeDownloaded({ @@ -515,18 +534,18 @@ function App() { } }); getBalanceFunc(); - } else if(response?.error){ + } else if (response?.error) { setIsLoading(false) setWalletToBeDecryptedError(response.error) } }); - - + + } catch (error: any) { setWalletToBeDownloadedError(error?.message); setIsLoading(false) - } + } }; const logoutFunc = () => { @@ -536,7 +555,7 @@ function App() { resetAllStates(); } }); - } catch (error) {} + } catch (error) { } }; const returnToMain = () => { @@ -561,6 +580,7 @@ function App() { setRequestAuthentication(null); setUserInfo(null); setBalance(null); + setLtcBalance(null) setPaymentTo(""); setPaymentAmount(0); setPaymentPassword(""); @@ -574,19 +594,21 @@ function App() { setSendqortState(null); }; - const authenticateWallet = async()=> { + const authenticateWallet = async () => { try { setIsLoading(true) setWalletToBeDecryptedError('') - await new Promise((res)=> { - setTimeout(()=> { + await new Promise((res) => { + setTimeout(() => { res() }, 250) }) - chrome.runtime.sendMessage({ action: "decryptWallet", payload: { - password: authenticatePassword, - wallet: rawWallet - } }, (response) => { + chrome.runtime.sendMessage({ + action: "decryptWallet", payload: { + password: authenticatePassword, + wallet: rawWallet + } + }, (response) => { if (response && !response?.error) { setAuthenticatePassword(""); setExtstate("authenticated"); @@ -598,14 +620,14 @@ function App() { } }); getBalanceFunc(); - } else if(response?.error){ + } else if (response?.error) { setIsLoading(false) setWalletToBeDecryptedError(response.error) } }); } catch (error) { setWalletToBeDecryptedError('Unable to authenticate. Wrong password') - } + } } return ( @@ -684,55 +706,91 @@ function App() { - - - - {userInfo?.name} - - - - - {rawWallet?.address0?.slice(0, 6)}... - {rawWallet?.address0?.slice(-4)} - - - - {balance && ( - - {balance?.toFixed(2)} QORT - - )} - - {/*

balance: {balance}

*/} - - {/* { - setExtstate("download-wallet"); - }} - > - Download Wallet - */} - { - setExtstate("send-qort"); - }} - > - Transfer QORT - + {authenticatedMode === 'ltc' ? ( + <> + + + + + {rawWallet?.ltcAddress?.slice(0, 6)}... + {rawWallet?.ltcAddress?.slice(-4)} + + + + {ltcBalanceLoading && } + {ltcBalance && !ltcBalanceLoading && ( + + + {ltcBalance?.toFixed(5)} LTC + + + + + )} + + + ) : ( + <> + + + + {userInfo?.name} + + + + + {rawWallet?.address0?.slice(0, 6)}... + {rawWallet?.address0?.slice(-4)} + + + + {qortBalanceLoading && } + {balance && ( + + {balance?.toFixed(2)} QORT + + )} + + + { + setExtstate("send-qort"); + }} + > + Transfer QORT + + + )} +
@@ -753,6 +811,25 @@ function App() { cursor: "pointer", }} /> + + {authenticatedMode === 'qort' && ( + { + setAuthenticatedMode('ltc') + }} src={ltcLogo} style={{ + cursor: "pointer", + width: '20px', + height: 'auto' + }} /> + )} + {authenticatedMode === 'ltc' && ( + { + setAuthenticatedMode('qort') + }} src={qortLogo} style={{ + cursor: "pointer", + width: '20px', + height: 'auto' + }} /> + )}
)} @@ -865,7 +942,7 @@ function App() { )} - {extState === "web-app-request-buy-order" && ( + {extState === "web-app-request-buy-order" && ( <> @@ -1143,7 +1220,7 @@ function App() { style={{ cursor: "pointer", }} - onClick={()=> { + onClick={() => { setRawWallet(null); setExtstate("not-authenticated"); }} @@ -1178,32 +1255,32 @@ function App() { - - <> - - Wallet Password - - - - setAuthenticatePassword(e.target.value) + + <> + + Wallet Password + + + + setAuthenticatePassword(e.target.value) + } + onKeyDown={(e) => { + if (e.key === "Enter") { + authenticateWallet(); } - onKeyDown={(e) => { - if (e.key === "Enter") { - authenticateWallet(); - } - }} - /> - - - Authenticate - - - {walletToBeDecryptedError} - - + }} + /> + + + Authenticate + + + {walletToBeDecryptedError} + + )} {extState === "download-wallet" && ( @@ -1290,34 +1367,34 @@ function App() { <> {!walletToBeDownloaded && ( <> - - - { - setExtstate("not-authenticated") - }} - src={Return} - /> - + + + { + setExtstate("not-authenticated") + }} + src={Return} + /> +
- - -
+ width: '136px', + height: '154px' + }}> + + + { chrome.storage.local.set({ walletInfo: newWallet }, () => { @@ -322,7 +322,6 @@ async function decryptWallet({ password, wallet, walletVersion }) { } async function signChatFunc(chatBytesArray, chatNonce, validApi, keyPair) { - console.log({ chatBytesArray, chatNonce, validApi, keyPair }) let response try { const signedChatBytes = signChat( @@ -569,7 +568,6 @@ async function fetchMessagesForBuyOrders(apiCall, signature, senderPublicKey) { const response = await fetch(apiCall); let data = await response.json(); data = data.filter((item) => !triedChatMessage.includes(item.signature)) - console.log({data}) if (data && data.length > 0) { const encodedMessageObj = data[0] const resKeyPair = await getKeyPair() @@ -583,7 +581,6 @@ async function fetchMessagesForBuyOrders(apiCall, signature, senderPublicKey) { const decodedMessage = decryptChatMessage(encodedMessageObj.data, keyPair.privateKey, senderPublicKey, encodedMessageObj.reference) const parsedMessage = JSON.parse(decodedMessage) - console.log({parsedMessage}) if (parsedMessage?.extra?.chatRequestSignature === signature) { resolve(parsedMessage); } else {