From cbf4afe8c043aeda2a93aea50e7018267224185f Mon Sep 17 00:00:00 2001 From: jwst9 Date: Thu, 31 Aug 2023 09:08:55 -0600 Subject: [PATCH 1/4] make client choose proper wallet from given telegram user id parameter --- client/src/pages/TgRouter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/pages/TgRouter.tsx b/client/src/pages/TgRouter.tsx index 385ab39..3b3f6f6 100644 --- a/client/src/pages/TgRouter.tsx +++ b/client/src/pages/TgRouter.tsx @@ -11,7 +11,7 @@ const TgRouter = (): React.JSX.Element => { const wallet = useSelector(state => state.wallet || {}) const qs = querystring.parse(location.search) as Record const { userId, sessionId } = qs - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) + const address = Object.keys(wallet).find(addr => wallet[addr].phone === userId && apis.web3.isValidAddress(addr)) const state = wallet[address ?? ''] const pk = state?.pk const phone = state?.phone From 761d5a7d1275e9b3390dab7c117e75da1d2653e9 Mon Sep 17 00:00:00 2001 From: jwst9 Date: Thu, 31 Aug 2023 19:38:01 -0600 Subject: [PATCH 2/4] add useMultipleWallet hook --- client/src/components/Container.tsx | 14 ++--- client/src/hooks/useMultipleWallet.tsx | 59 +++++++++++++++++++++ client/src/index.tsx | 5 +- client/src/pages/ApproveTransaction.tsx | 20 +++---- client/src/pages/NFT.tsx | 19 +++---- client/src/pages/Request.tsx | 11 ++-- client/src/pages/SaveRecoverySecret.tsx | 26 +++++---- client/src/pages/SignMessage.tsx | 12 ++--- client/src/pages/Signup.tsx | 8 +-- client/src/pages/TgRouter.tsx | 33 ++++++------ client/src/pages/TgSignup.tsx | 16 ++++-- client/src/pages/Wallet.tsx | 10 ++-- client/src/state/modules/wallet/reducers.ts | 6 ++- 13 files changed, 151 insertions(+), 88 deletions(-) create mode 100644 client/src/hooks/useMultipleWallet.tsx diff --git a/client/src/components/Container.tsx b/client/src/components/Container.tsx index c3020cb..9eb9388 100644 --- a/client/src/components/Container.tsx +++ b/client/src/components/Container.tsx @@ -5,25 +5,21 @@ import MenuIcon from '../../assets/menu.svg' import { Col, Main, Modal, Row } from './Layout' import { Button, LinkWrarpper } from './Controls' import { walletActions } from '../state/modules/wallet' -import { useDispatch, useSelector } from 'react-redux' +import { useDispatch } from 'react-redux' import paths from '../pages/paths' -import apis from '../api/index' import { useNavigate } from 'react-router' -import { type RootState } from '../state/rootReducer' -import { type WalletState } from '../state/modules/wallet/reducers' import config from '../config' +import useMultipleWallet from '../hooks/useMultipleWallet' const MainContainer = ({ children, withMenu = false }): React.JSX.Element => { const navigate = useNavigate() const dispatch = useDispatch() - const wallet = useSelector(state => state.wallet ?? {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) + const { wallet } = useMultipleWallet() const [menuVisible, setMenuVisible] = useState(false) const [logoutModalVisible, setLogoutModalVisible] = useState(false) - const state = wallet[address ?? ''] - const p = state?.p + const p = wallet?.p const logout = (): void => { dispatch(walletActions.deleteAllWallet()) setLogoutModalVisible(false) @@ -44,7 +40,7 @@ const MainContainer = ({ children, withMenu = false }): React.JSX.Element => { { setMenuVisible(!menuVisible) }} src={MenuIcon as string} /> {menuVisible && - {wallet && { navigate(paths.wallet) }}>{wallet[address ?? ''].phone}} + {wallet && { navigate(paths.wallet) }}>{wallet.phone}} { setLogoutModalVisible(true) }}>Logout } } diff --git a/client/src/hooks/useMultipleWallet.tsx b/client/src/hooks/useMultipleWallet.tsx new file mode 100644 index 0000000..f7dec3d --- /dev/null +++ b/client/src/hooks/useMultipleWallet.tsx @@ -0,0 +1,59 @@ +import React, { useCallback, useContext, useState } from "react" +import { useSelector } from "react-redux" +import { RootState } from "../state/rootReducer" +import { WalletState, Wallet } from "../state/modules/wallet/reducers" +import apis from '../api' + +type WalletType = { + wallet?: Wallet + switchWallet: (phone: string) => Wallet | undefined + containWallet: (phone: string) => boolean +} + +const WalletContext = React.createContext({ + switchWallet: () => undefined, + containWallet: () => true +}) + +type MultipleWalletProviderProps = { + children: React.ReactNode +} + +export const MultipleWalletProvider = ({ children }: MultipleWalletProviderProps) => { + const wallets = useSelector(state => state.wallet || {}) + + const [address, setAddress] = useState() + + const containWallet = useCallback((phone: string) => + Object.keys(wallets).some(e => wallets[e].phone === phone && apis.web3.isValidAddress(e)), + [wallets] + ) + + const switchWallet = useCallback((phone: string) => { + const address = Object.keys(wallets).find(e => wallets[e].phone === phone && apis.web3.isValidAddress(e)) + + if (!address) { + return undefined + } + + setAddress(address) + + return wallets[address] + }, [wallets]) + + return ( + + {children} + + ) +} + +const useWalletAddress = () => useContext(WalletContext) + +export default useWalletAddress diff --git a/client/src/index.tsx b/client/src/index.tsx index cddb3a8..b6564f0 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -12,6 +12,7 @@ import 'react-phone-number-input/style.css' import { HistoryRouter } from 'redux-first-history/rr6' import { PersistGate } from 'redux-persist/es/integration/react' import { Loading } from './components/Misc' +import { MultipleWalletProvider } from './hooks/useMultipleWallet' // eslint-disable-next-line @typescript-eslint/no-empty-function document.body.ontouchstart = function (): void {} @@ -26,7 +27,9 @@ if (container != null) { } persistor={persistor}> - + + + diff --git a/client/src/pages/ApproveTransaction.tsx b/client/src/pages/ApproveTransaction.tsx index 1abd433..7adf5d6 100644 --- a/client/src/pages/ApproveTransaction.tsx +++ b/client/src/pages/ApproveTransaction.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react' -import { useDispatch, useSelector } from 'react-redux' +import { useDispatch } from 'react-redux' import paths from './paths' import MainContainer from '../components/Container' import querystring from 'query-string' @@ -11,10 +11,9 @@ import { Row } from '../components/Layout' import { utils } from '../utils' import { pick } from 'lodash' import { globalActions } from '../state/modules/global' -import { type RootState } from '../state/rootReducer' -import { type WalletState } from '../state/modules/wallet/reducers' import { type TransactionReceipt } from 'ethers' import { Navigate, useNavigate } from 'react-router' +import useMultipleWallet from '../hooks/useMultipleWallet' export interface CallData { method?: string @@ -43,16 +42,15 @@ export interface ApproveTransactionParams { } export const ApproveTransaction = ({ calldata, caller, callback, comment, inputAmount, dest, onComplete }: ApproveTransactionParams): React.JSX.Element => { - const wallet = useSelector((state: RootState) => state.wallet || {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) + const { wallet } = useMultipleWallet() const [showDetails, setShowDetails] = useState(false) const { balance: amount, formatted: amountFormatted } = utils.toBalance(inputAmount ?? '0') - if (!address || !wallet[address]?.pk) { + if (wallet?.pk === undefined) { return } - const pk = wallet[address]?.pk + const pk = wallet.pk const execute = async (): Promise => { if (!calldata) { @@ -97,7 +95,7 @@ export const ApproveTransaction = ({ calldata, caller, callback, comment, inputA const returnUrl = new URL(callback) returnUrl.searchParams.append('success', 'true') returnUrl.searchParams.append('hash', receipt.hash) - returnUrl.searchParams.append('address', address) + returnUrl.searchParams.append('address', wallet.address) toast.success(`Returning to app at ${returnUrl.hostname}`) setTimeout(() => { location.href = returnUrl.href @@ -185,10 +183,8 @@ const ApproveTransactionPage = (): React.JSX.Element => { const callback = utils.safeURL(Buffer.from(decodeURIComponent(callbackEncoded ?? ''), 'base64').toString()) const calldata = decodeCalldata(calldataB64Encoded) - - const wallet = useSelector(state => state.wallet ?? {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) ?? '' - const pk = wallet[address]?.pk + const { wallet } = useMultipleWallet() + const pk = wallet?.pk useEffect(() => { if (phone) { diff --git a/client/src/pages/NFT.tsx b/client/src/pages/NFT.tsx index bd536e0..b71b9a5 100644 --- a/client/src/pages/NFT.tsx +++ b/client/src/pages/NFT.tsx @@ -23,6 +23,7 @@ import { type UseMetadataParams, type UseMetadataResult } from './types' +import useMultipleWallet from '../hooks/useMultipleWallet' export const MetadataURITransformer = (url?: string): string | undefined => { const IPFSIO = /https:\/\/ipfs\.io\/ipfs\/(.+)/ @@ -352,9 +353,9 @@ const NFTSendModal = ({ modelVisible, setModelVisible, maxQuantity, contractAddr const [to, setTo] = useState('') const [amount, setAmount] = useState('1') const [isSending, setIsSending] = useState(false) - const wallet = useSelector(state => state.wallet || {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) - const pk = wallet[address ?? '']?.pk + const { wallet } = useMultipleWallet() + const pk = wallet?.pk + const address = wallet?.address const send = async (): Promise => { if (!address || !pk) { @@ -489,9 +490,9 @@ const NFTViewer = ({ visible, setVisible, onClose, contractAddress, resolvedImag const [sendModelVisible, setSendModalVisible] = useState(false) const [managementVisible, setManagementVisible] = useState(false) const [isTracking, setIsTracking] = useState(false) - const wallet = useSelector(state => state.wallet || {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) - const pk = wallet[address ?? '']?.pk + const { wallet } = useMultipleWallet() + const address = wallet?.address + const pk = wallet?.pk const key = utils.computeTokenKey({ contractAddress, tokenId, tokenType }).string const balance = BigInt(useSelector(state => state.balance?.[address ?? '']?.tokenBalances?.[key] || '')) @@ -611,9 +612,9 @@ const NFTTracker = ({ visible, setVisible }: NFTTrackerParams): React.JSX.Elemen const [contract, setContract] = useState('') const [tokenId, setTokenId] = useState('') const [isTracking, setIsTracking] = useState(false) - const wallet = useSelector(state => state.wallet || {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) - const pk = wallet[address ?? '']?.pk + const { wallet } = useMultipleWallet() + const address = wallet?.address + const pk = wallet?.pk const track = async (): Promise => { if (!address || !pk) { diff --git a/client/src/pages/Request.tsx b/client/src/pages/Request.tsx index 40f6ae5..06c75eb 100644 --- a/client/src/pages/Request.tsx +++ b/client/src/pages/Request.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' +import { useDispatch } from 'react-redux' import { Navigate, useNavigate, useParams } from 'react-router' import paths from './paths' import MainContainer from '../components/Container' @@ -11,15 +11,15 @@ import { ApproveTransaction, decodeCalldata } from './ApproveTransaction' import { Button } from '../components/Controls' import { TailSpin } from 'react-loading-icons' import { globalActions } from '../state/modules/global' -import { type RootState } from '../state/rootReducer' -import { type WalletState } from '../state/modules/wallet/reducers' import querystring from 'query-string' +import useMultipleWallet from '../hooks/useMultipleWallet' const Request = (): React.JSX.Element => { const dispatch = useDispatch() const navigate = useNavigate() - const wallet = useSelector(state => state.wallet || {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) + const { wallet } = useMultipleWallet() + const address = wallet?.address + const pk = wallet?.pk const match = useParams() const { id } = match ?? {} const qs = querystring.parse(location.search) as Record @@ -33,7 +33,6 @@ const Request = (): React.JSX.Element => { } = request ?? {} const calldata = decodeCalldata(calldataB64Encoded) const callback = utils.safeURL(callbackURL ?? '') - const pk = wallet[address ?? '']?.pk useEffect(() => { if (phone) { diff --git a/client/src/pages/SaveRecoverySecret.tsx b/client/src/pages/SaveRecoverySecret.tsx index fe65097..8d0d011 100644 --- a/client/src/pages/SaveRecoverySecret.tsx +++ b/client/src/pages/SaveRecoverySecret.tsx @@ -1,31 +1,25 @@ import React, { useEffect, useState } from 'react' import MainContainer from '../components/Container' -import { useDispatch, useSelector } from 'react-redux' -import { type RootState } from '../state/rootReducer' -import { type WalletState } from '../state/modules/wallet/reducers' -import apis from '../api' +import { useDispatch } from 'react-redux' import { Navigate, useNavigate } from 'react-router' import paths from './paths' import { BaseText, DescLeft, LinkText, SmallText } from '../components/Text' import { Col, Row } from '../components/Layout' import { Button, LinkWrarpper } from '../components/Controls' -import { globalActions } from '../state/modules/global' -import { utils } from '../utils' import { walletActions } from '../state/modules/wallet' import { toast } from 'react-toastify' +import useMultipleWallet from '../hooks/useMultipleWallet' const SaveRecoverySecret = (): React.JSX.Element => { const [tgDest, setTgDest] = useState('') const [emailDest, setEmailDest] = useState('') const navigate = useNavigate() const dispatch = useDispatch() - const wallet = useSelector(state => state.wallet || {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) - - const state = wallet[address ?? ''] - const pk = state?.pk - const phone = state?.phone - const p = state?.p + const { wallet } = useMultipleWallet() + const address = wallet?.address + const pk = wallet?.pk + const phone = wallet?.phone + const p = wallet?.p useEffect(() => { if (!pk || !p || !phone) { @@ -41,7 +35,11 @@ const SaveRecoverySecret = (): React.JSX.Element => { }, [phone, p, pk, address]) const cleanup = (): void => { - dispatch(walletActions.updateWallet({ ...state, p: '' })) + if (!wallet) { + return + } + + dispatch(walletActions.updateWallet({ ...wallet, p: '' })) toast.info('Recovery secret is cleaned up') navigate(paths.wallet) } diff --git a/client/src/pages/SignMessage.tsx b/client/src/pages/SignMessage.tsx index 545fbb7..1755925 100644 --- a/client/src/pages/SignMessage.tsx +++ b/client/src/pages/SignMessage.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react' -import { useDispatch, useSelector } from 'react-redux' +import { useDispatch } from 'react-redux' import paths from './paths' import MainContainer from '../components/Container' import querystring from 'query-string' @@ -10,15 +10,12 @@ import { toast } from 'react-toastify' import { Row } from '../components/Layout' import { utils } from '../utils' import { globalActions } from '../state/modules/global' -import { type RootState } from '../state/rootReducer' -import { type WalletState } from '../state/modules/wallet/reducers' import { Navigate, useNavigate } from 'react-router' +import useMultipleWallet from '../hooks/useMultipleWallet' const SignMessage = (): React.JSX.Element => { const dispatch = useDispatch() const navigate = useNavigate() - const wallet = useSelector(state => state.wallet || {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) const qs = querystring.parse(location.search) as Record const callback = utils.safeURL(Buffer.from(decodeURIComponent(qs.callback ?? ''), 'base64').toString()) const { caller, message, comment, phone } = qs @@ -29,7 +26,10 @@ const SignMessage = (): React.JSX.Element => { } }, [dispatch, phone]) - const pk = wallet[address ?? '']?.pk + const { wallet } = useMultipleWallet() + const pk = wallet?.pk + const address = wallet?.address + if (!pk) { dispatch(globalActions.setNextAction({ path: paths.sign, query: location.search })) return diff --git a/client/src/pages/Signup.tsx b/client/src/pages/Signup.tsx index b516aa8..39cf4b1 100644 --- a/client/src/pages/Signup.tsx +++ b/client/src/pages/Signup.tsx @@ -18,8 +18,9 @@ import styled from 'styled-components' import { Navigate, useNavigate } from 'react-router' import { type RootState } from '../state/rootReducer' import { type NextAction } from '../state/modules/global/actions' -import { type WalletState } from '../state/modules/wallet/reducers' import config from "../config"; +import useMultipleWallet from '../hooks/useMultipleWallet' + const randomSeed = (): Uint8Array => { const otpSeedBuffer = new Uint8Array(32) return window.crypto.getRandomValues(otpSeedBuffer) @@ -45,7 +46,6 @@ const Signup = (): React.JSX.Element => { const [qrCodeData, setQrCodeData] = useState('') const next = useSelector(state => state.global.next || {}) const prefilledPhone = useSelector(state => state.global.prefilledPhone ?? '') - const wallet = useSelector(state => state.wallet || {}) const [triedSave, setTriedSave] = useState(false) const [useQR, setUseQR] = useState(false) @@ -146,7 +146,9 @@ const Signup = (): React.JSX.Element => { // onDone && onDone() } - const existingAddress = !hash && Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) + const { wallet } = useMultipleWallet() + const existingAddress = !hash && wallet?.address + if (existingAddress) { console.log('redirecting because wallet exists:', existingAddress) return diff --git a/client/src/pages/TgRouter.tsx b/client/src/pages/TgRouter.tsx index 3b3f6f6..13494ba 100644 --- a/client/src/pages/TgRouter.tsx +++ b/client/src/pages/TgRouter.tsx @@ -1,29 +1,26 @@ -import React from 'react' -import apis from '../api' -import { useSelector } from 'react-redux' +import React, { useEffect } from 'react' import paths from './paths' -import { Navigate } from 'react-router' -import { type RootState } from '../state/rootReducer' -import { type WalletState } from '../state/modules/wallet/reducers' +import { useNavigate } from 'react-router' import querystring from 'query-string' +import useMultipleWallet from '../hooks/useMultipleWallet' const TgRouter = (): React.JSX.Element => { - const wallet = useSelector(state => state.wallet || {}) const qs = querystring.parse(location.search) as Record const { userId, sessionId } = qs - const address = Object.keys(wallet).find(addr => wallet[addr].phone === userId && apis.web3.isValidAddress(addr)) - const state = wallet[address ?? ''] - const pk = state?.pk - const phone = state?.phone + const { wallet, containWallet, switchWallet } = useMultipleWallet() + const navigate = useNavigate() - if (address && pk && phone) { - console.log('redirecting to existing wallet', address) - return - } + useEffect(() => { + if (wallet?.address && wallet.pk && wallet.phone === userId) { + navigate(paths.wallet) + } else if (containWallet(userId)) { + switchWallet(userId) + } else { + navigate({ pathname: paths.tgSignup, search: `?userId=${userId}&sessionId=${sessionId}` }) + } + }, [wallet, switchWallet, containWallet, navigate, sessionId, userId]) - // TODO: delete address if pk and phone are not present - - return + return <> } export default TgRouter diff --git a/client/src/pages/TgSignup.tsx b/client/src/pages/TgSignup.tsx index 20caae5..2191a30 100644 --- a/client/src/pages/TgSignup.tsx +++ b/client/src/pages/TgSignup.tsx @@ -12,9 +12,9 @@ import { globalActions } from '../state/modules/global' import { Navigate, useNavigate } from 'react-router' import { type RootState } from '../state/rootReducer' import { type NextAction } from '../state/modules/global/actions' -import { type WalletState } from '../state/modules/wallet/reducers' import querystring from 'query-string' import { Button } from '../components/Controls' +import useMultipleWallet from '../hooks/useMultipleWallet' const randomSeed = (): Uint8Array => { const otpSeedBuffer = new Uint8Array(32) @@ -29,7 +29,6 @@ const TgSignup = (): React.JSX.Element => { const [accountExists, setAccountExists] = useState(false) const [invalidSession, setInvalidSession] = useState(false) const [signedUp, setSignedup] = useState(false) - const wallet = useSelector(state => state.wallet || {}) const qs = querystring.parse(location.search) as Record const { userId, sessionId } = qs const fullUserId = `tg:${userId}` @@ -64,6 +63,14 @@ const TgSignup = (): React.JSX.Element => { signup().catch(console.error) }, [navigate, sessionId, userId, fullUserId, p, pk]) + const { wallet, switchWallet, containWallet } = useMultipleWallet() + + useEffect(() => { + if (containWallet(fullUserId)) { + switchWallet(fullUserId) + } + }, [containWallet, switchWallet]) + useEffect(() => { if (!signedUp) { return @@ -86,8 +93,9 @@ const TgSignup = (): React.JSX.Element => { navigate({ pathname: paths.tgRecover, search: `?userId=${userId}&sessionId=${sessionId}` }) } - const existingAddress = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) - if (existingAddress) { + const existingAddress = wallet?.address + + if (existingAddress && wallet?.phone === fullUserId) { console.log('redirecting because wallet exists:', existingAddress) return } diff --git a/client/src/pages/Wallet.tsx b/client/src/pages/Wallet.tsx index cebc58d..3cd466a 100644 --- a/client/src/pages/Wallet.tsx +++ b/client/src/pages/Wallet.tsx @@ -17,12 +17,14 @@ import { walletActions } from '../state/modules/wallet' import { type RootState } from '../state/rootReducer' import { type WalletState } from '../state/modules/wallet/reducers' import { Navigate } from 'react-router' +import useMultipleWallet from '../hooks/useMultipleWallet' const Wallet = (): React.JSX.Element => { // const history = useHistory() const dispatch = useDispatch() - const wallet = useSelector(state => state.wallet || {}) - const address = Object.keys(wallet).find(e => apis.web3.isValidAddress(e)) + const wallets = useSelector(state => state.wallet || {}) + const { wallet } = useMultipleWallet() + const address = wallet?.address const balance = useSelector(state => state.balance[address ?? '']?.balance || '0') const [to, setTo] = useState('') @@ -48,7 +50,7 @@ const Wallet = (): React.JSX.Element => { }, [dispatch, address]) useEffect(() => { - const keys = Object.keys(wallet) + const keys = Object.keys(wallets) for (const k of keys) { if (k.startsWith('_')) { continue @@ -60,7 +62,7 @@ const Wallet = (): React.JSX.Element => { } }, [wallet, dispatch]) - const pk = wallet[address ?? '']?.pk + const pk = wallet?.pk if (!pk || !address) { return diff --git a/client/src/state/modules/wallet/reducers.ts b/client/src/state/modules/wallet/reducers.ts index f5309c8..c58033e 100644 --- a/client/src/state/modules/wallet/reducers.ts +++ b/client/src/state/modules/wallet/reducers.ts @@ -3,7 +3,7 @@ import walletActions, { type TrackedToken } from './actions' import uniq from 'lodash/fp/uniq' import omit from 'lodash/fp/omit' -export type WalletState = Record +} + +export type WalletState = Record export const initialState: WalletState = {} From 5c9087fab0e0dce595195abdbaa67ff906b24a4b Mon Sep 17 00:00:00 2001 From: jwst9 Date: Thu, 31 Aug 2023 19:54:02 -0600 Subject: [PATCH 3/4] fix navigate from signup & recover --- client/src/pages/TgRecover.tsx | 16 +++++++++++++--- client/src/pages/TgSignup.tsx | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/client/src/pages/TgRecover.tsx b/client/src/pages/TgRecover.tsx index 9eb70ec..ea554b0 100644 --- a/client/src/pages/TgRecover.tsx +++ b/client/src/pages/TgRecover.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import { BaseText, Desc, Title } from '../components/Text' import { toast } from 'react-toastify' import { Button, Input } from '../components/Controls' @@ -13,6 +13,7 @@ import { globalActions } from '../state/modules/global' import { type RootState } from '../state/rootReducer' import { type NextAction } from '../state/modules/global/actions' import querystring from 'query-string' +import useMultipleWallet from '../hooks/useMultipleWallet' const TgRecover = (): React.JSX.Element => { const navigate = useNavigate() @@ -22,6 +23,7 @@ const TgRecover = (): React.JSX.Element => { const [password, setPassword] = useState('') const qs = querystring.parse(location.search) as Record const { userId, sessionId } = qs + const fullId = `tg:${userId}` const restore = async (): Promise => { let p: undefined | Uint8Array @@ -35,7 +37,7 @@ const TgRecover = (): React.JSX.Element => { return } setVerifying(true) - const fullId = `tg:${userId}` + try { const eseed = utils.computePartialParameters({ phone: fullId, p }) const { success, ekey, address, error } = await apis.server.tgRestore({ userId, eseed, sessionId }) @@ -62,7 +64,6 @@ const TgRecover = (): React.JSX.Element => { navigate({ pathname: next.path, search: next.query }) return } - navigate(paths.wallet) }, 1000) } catch (ex: any) { console.error(ex) @@ -72,6 +73,15 @@ const TgRecover = (): React.JSX.Element => { } } + const { switchWallet, containWallet } = useMultipleWallet() + + useEffect(() => { + if (containWallet(fullId)) { + switchWallet(fullId) + navigate(paths.wallet) + } + }, [containWallet, switchWallet, navigate]) + return ( Recover your wallet diff --git a/client/src/pages/TgSignup.tsx b/client/src/pages/TgSignup.tsx index 2191a30..36fba75 100644 --- a/client/src/pages/TgSignup.tsx +++ b/client/src/pages/TgSignup.tsx @@ -68,8 +68,9 @@ const TgSignup = (): React.JSX.Element => { useEffect(() => { if (containWallet(fullUserId)) { switchWallet(fullUserId) + navigate(paths.wallet) } - }, [containWallet, switchWallet]) + }, [containWallet, switchWallet, navigate]) useEffect(() => { if (!signedUp) { @@ -85,7 +86,6 @@ const TgSignup = (): React.JSX.Element => { navigate({ pathname: next.path, search: next.query }) return } - navigate(paths.wallet) }, 2000) }, [dispatch, navigate, fullUserId, next.path, next.query, p, pk, signedUp]) From 3351eb4cda01e677037b3329d58bdf24a6f20264 Mon Sep 17 00:00:00 2001 From: jwst9 Date: Wed, 6 Sep 2023 01:08:42 -0600 Subject: [PATCH 4/4] add UserIdHandler --- client/src/AppRoutes.tsx | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/client/src/AppRoutes.tsx b/client/src/AppRoutes.tsx index b1f5efa..93cebc8 100644 --- a/client/src/AppRoutes.tsx +++ b/client/src/AppRoutes.tsx @@ -1,5 +1,5 @@ -import React from 'react' -import { Route, Routes } from 'react-router-dom' +import React, { useEffect } from 'react' +import { Outlet, Route, Routes } from 'react-router-dom' import Signup from './pages/Signup' import Wallet from './pages/Wallet' import Recover from './pages/Recover' @@ -11,10 +11,34 @@ import Archive from './pages/Archive' import TgSignup from './pages/TgSignup' import TgRecover from './pages/TgRecover' import SaveRecoverySecret from './pages/SaveRecoverySecret' +import querystring from 'query-string' import TgRouter from './pages/TgRouter' +import useMultipleWallet from './hooks/useMultipleWallet' + +const UserIdHandler = () => { + const qs = querystring.parse(location.search) as Record + const { userId } = qs + + const { wallet, containWallet, switchWallet } = useMultipleWallet() + + useEffect(() => { + if (wallet?.address && wallet.pk && wallet.phone === userId) { + return + } else if (containWallet(userId)) { + switchWallet(userId) + } + }, [wallet, switchWallet, containWallet, userId]) + + return ( + + ) +} + const AppRoutes = (): React.JSX.Element => { return ( + } /> + {/* } /> */} } /> } />