import React, { useEffect, useRef, useState } from "react"; import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; import Divider from "@mui/material/Divider"; import ListItemText from "@mui/material/ListItemText"; import ListItemAvatar from "@mui/material/ListItemAvatar"; import Avatar from "@mui/material/Avatar"; import Typography from "@mui/material/Typography"; import { Box, Button, ButtonBase, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Input } from "@mui/material"; import { CustomButton } from "./App-styles"; import { useDropzone } from "react-dropzone"; import EditIcon from "@mui/icons-material/Edit"; import { Label } from "./components/Group/AddGroup"; import { Spacer } from "./common/Spacer"; import { getWallets, storeWallets, walletVersion } from "./background"; import { useModal } from "./common/useModal"; import PhraseWallet from "./utils/generateWallet/phrase-wallet"; import { decryptStoredWalletFromSeedPhrase } from "./utils/decryptWallet"; import { crypto } from "./constants/decryptWallet"; import { LoadingButton } from "@mui/lab"; import { PasswordField } from "./components"; const parsefilenameQortal = (filename)=> { return filename.startsWith("qortal_backup_") ? filename.slice(14) : filename; } export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => { const [wallets, setWallets] = useState([]); const [isLoading, setIsLoading] = useState(true); const [seedValue, setSeedValue] = useState(""); const [seedName, setSeedName] = useState(""); const [seedError, setSeedError] = useState(""); const [password, setPassword] = useState(""); const [isOpenSeedModal, setIsOpenSeedModal] = useState(false); const [isLoadingEncryptSeed, setIsLoadingEncryptSeed] = useState(false); const { isShow, onCancel, onOk, show, } = useModal(); const { getRootProps, getInputProps } = useDropzone({ accept: { "application/json": [".json"], // Only accept JSON files }, onDrop: async (acceptedFiles) => { const files: any = acceptedFiles; let importedWallets: any = []; for (const file of files) { try { 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); }); if (typeof fileContents !== "string") continue; const parsedData = JSON.parse(fileContents) importedWallets.push({...parsedData, filename: file?.name}); } catch (error) { console.error(error); } } let error: any = null; let uniqueInitialMap = new Map(); // Only add a message if it doesn't already exist in the Map importedWallets.forEach((wallet) => { if (!wallet?.address0) return; if (!uniqueInitialMap.has(wallet?.address0)) { uniqueInitialMap.set(wallet?.address0, wallet); } }); const data = Array.from(uniqueInitialMap.values()); if (data && data?.length > 0) { const uniqueNewWallets = data.filter( (newWallet) => !wallets.some( (existingWallet) => existingWallet?.address0 === newWallet?.address0 ) ); setWallets([...wallets, ...uniqueNewWallets]); } }, }); const updateWalletItem = (idx, wallet) => { setWallets((prev) => { let copyPrev = [...prev]; if (wallet === null) { copyPrev.splice(idx, 1); // Use splice to remove the item return copyPrev; } else { copyPrev[idx] = wallet; // Update the wallet at the specified index return copyPrev; } }); }; const handleSetSeedValue = async ()=> { try { setIsOpenSeedModal(true) const {seedValue, seedName, password} = await show({ message: "", publishFee: "", }); setIsLoadingEncryptSeed(true) const res = await decryptStoredWalletFromSeedPhrase(seedValue) const wallet2 = new PhraseWallet(res, walletVersion); const wallet = await wallet2.generateSaveWalletData( password, crypto.kdfThreads, () => {} ); if(wallet?.address0){ setWallets([...wallets, { ...wallet, name: seedName }]); setIsOpenSeedModal(false) setSeedValue('') setSeedName('') setPassword('') setSeedError('') } else { setSeedError('Could not create wallet.') } } catch (error) { setSeedError(error?.message || 'Could not create wallet.') } finally { setIsLoadingEncryptSeed(false) } } const selectedWalletFunc = (wallet) => { setRawWallet(wallet); setExtState("wallet-dropped"); }; useEffect(()=> { setIsLoading(true) getWallets().then((res)=> { if(res && Array.isArray(res)){ setWallets(res) } setIsLoading(false) }).catch((error)=> { console.error(error) setIsLoading(false) }) }, []) useEffect(()=> { if(!isLoading && wallets && Array.isArray(wallets)){ storeWallets(wallets) } }, [wallets, isLoading]) if(isLoading) return null return (
{(wallets?.length === 0 || !wallets) ? ( <> No wallets saved ): ( <> Your saved wallets )} {rawWallet && ( Selected Wallet: {rawWallet?.name && {rawWallet.name}} {rawWallet?.address0 && ( {rawWallet?.address0} )} )} {wallets?.length > 0 && ( {wallets?.map((wallet, idx) => { return ( <> ); })} )} Add seed-phrase Add wallets { if (e.key === 'Enter' && seedValue && seedName && password) { onOk({seedValue, seedName, password}); } }} > Type or paste in your seed-phrase setSeedName(e.target.value)} /> setSeedValue(e.target.value)} /> setPassword(e.target.value)} autoComplete="off" /> { if(!seedValue || !seedName || !password) return onOk({seedValue, seedName, password}); }} autoFocus > Add {seedError}
); }; const WalletItem = ({ wallet, updateWalletItem, idx, setSelectedWallet }) => { const [name, setName] = useState(""); const [note, setNote] = useState(""); const [isEdit, setIsEdit] = useState(false); useEffect(() => { if (wallet?.name) { setName(wallet.name); } if (wallet?.note) { setNote(wallet.note); } }, [wallet]); return ( <> { setSelectedWallet(wallet); }} sx={{ width: '100%' }} > { e.stopPropagation(); setIsEdit(true); }} edge="end" aria-label="edit" > } alignItems="flex-start" > {wallet?.address0} {wallet?.note} } /> {isEdit && ( setName(e.target.value)} sx={{ width: "100%", }} /> setNote(e.target.value)} inputProps={{ maxLength: 100, }} sx={{ width: "100%", }} /> )} ); };