From 3ab0390ab57917fd2bcd12aa59a4db6d6dceb421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Tue, 3 Dec 2024 09:23:14 -0300 Subject: [PATCH 1/4] feat: remember selected address --- src/context/walletContext/walletContext.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/context/walletContext/walletContext.tsx b/src/context/walletContext/walletContext.tsx index a7ad52464..66d7db9c6 100644 --- a/src/context/walletContext/walletContext.tsx +++ b/src/context/walletContext/walletContext.tsx @@ -51,7 +51,9 @@ export const WalletProvider = ({ children }: { children: ReactNode }) => { ////// User props const { addAccount, user } = useAuth() - const [selectedAddress, setSelectedAddress] = useState(undefined) + const [selectedAddress, setSelectedAddress] = useState( + localStorage.getItem('selectedAddress') ?? undefined + ) const isWalletConnected = useCallback( (wallet: interfaces.IDBWallet): boolean => { @@ -151,6 +153,13 @@ export const WalletProvider = ({ children }: { children: ReactNode }) => { } }, [wallets, selectedAddress]) + // Remember selected address + useEffect(() => { + if (selectedAddress) { + localStorage.setItem('selectedAddress', selectedAddress) + } + }, [selectedAddress]) + // Add new BYOW wallet when connected useEffect(() => { if (!user || !wagmiAddress || !wallets.length) return From 2a75a4edf2a608550330354c3f2e96ebf45965f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Tue, 3 Dec 2024 12:20:09 -0300 Subject: [PATCH 2/4] fix: handle local storage undefined --- src/context/walletContext/walletContext.tsx | 12 +++++++++--- src/utils/general.utils.ts | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/context/walletContext/walletContext.tsx b/src/context/walletContext/walletContext.tsx index 66d7db9c6..5ae29111c 100644 --- a/src/context/walletContext/walletContext.tsx +++ b/src/context/walletContext/walletContext.tsx @@ -8,7 +8,13 @@ import { useQuery, useQueryClient } from '@tanstack/react-query' import { PEANUT_WALLET_CHAIN, PEANUT_WALLET_TOKEN } from '@/constants' import { Chain, erc20Abi, getAddress, parseUnits } from 'viem' import { useAuth } from '../authContext' -import { backgroundColorFromAddress, areEvmAddressesEqual, fetchWalletBalances } from '@/utils' +import { + backgroundColorFromAddress, + areEvmAddressesEqual, + fetchWalletBalances, + getFromLocalStorage, + saveToLocalStorage, +} from '@/utils' import { peanutPublicClient } from '@/constants/viem.consts' interface WalletContextType { @@ -52,7 +58,7 @@ export const WalletProvider = ({ children }: { children: ReactNode }) => { const { addAccount, user } = useAuth() const [selectedAddress, setSelectedAddress] = useState( - localStorage.getItem('selectedAddress') ?? undefined + getFromLocalStorage('selectedAddress') ?? undefined ) const isWalletConnected = useCallback( @@ -156,7 +162,7 @@ export const WalletProvider = ({ children }: { children: ReactNode }) => { // Remember selected address useEffect(() => { if (selectedAddress) { - localStorage.setItem('selectedAddress', selectedAddress) + saveToLocalStorage('selectedAddress', selectedAddress) } }, [selectedAddress]) diff --git a/src/utils/general.utils.ts b/src/utils/general.utils.ts index 44853c9d9..046837376 100644 --- a/src/utils/general.utils.ts +++ b/src/utils/general.utils.ts @@ -83,7 +83,7 @@ function waitForPromise(promise: Promise, timeoutTime: number = 30000): Pr }) } -const saveToLocalStorage = (key: string, data: any) => { +export const saveToLocalStorage = (key: string, data: any) => { try { // Convert the data to a string before storing it in localStorage const serializedData = JSON.stringify(data) @@ -95,7 +95,7 @@ const saveToLocalStorage = (key: string, data: any) => { } } -const getFromLocalStorage = (key: string) => { +export const getFromLocalStorage = (key: string) => { try { if (typeof localStorage === 'undefined') return const data = localStorage.getItem(key) From c88869d32acf20af1aa7b033ba3e6362cbc9c6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Wed, 4 Dec 2024 08:26:51 -0300 Subject: [PATCH 3/4] feat: store user preferences in local storage --- src/components/Create/Link/Confirm.view.tsx | 16 +++--- src/context/tokenSelector.context.tsx | 28 +++++----- src/context/walletContext/walletContext.tsx | 10 ++-- src/utils/general.utils.ts | 57 +++++++++------------ 4 files changed, 52 insertions(+), 59 deletions(-) diff --git a/src/components/Create/Link/Confirm.view.tsx b/src/components/Create/Link/Confirm.view.tsx index 2cebf1dc6..393c26292 100644 --- a/src/components/Create/Link/Confirm.view.tsx +++ b/src/components/Create/Link/Confirm.view.tsx @@ -10,7 +10,7 @@ import { saveCreatedLinkToLocalStorage, shareToEmail, shareToSms, - updatePeanutPreferences, + updateUserPreferences, ErrorHandler, printableAddress, formatTokenAmount, @@ -210,11 +210,15 @@ export const CreateLinkConfirmView = ({ if (createType === 'sms_link') shareToSms(recipient.name ?? '', link[0], usdValue) } - updatePeanutPreferences({ - chainId: selectedChainID, - tokenAddress: selectedTokenAddress, - decimals: selectedTokenDecimals, - }) + if (selectedChainID && selectedTokenAddress && selectedTokenDecimals) { + updateUserPreferences({ + lastUsedToken: { + chainId: selectedChainID, + address: selectedTokenAddress, + decimals: selectedTokenDecimals, + }, + }) + } onNext() refetchBalances(address ?? '') diff --git a/src/context/tokenSelector.context.tsx b/src/context/tokenSelector.context.tsx index e7d156d31..264efb1a5 100644 --- a/src/context/tokenSelector.context.tsx +++ b/src/context/tokenSelector.context.tsx @@ -36,17 +36,17 @@ export const tokenSelectorContext = createContext({ */ export const TokenContextProvider = ({ children }: { children: React.ReactNode }) => { const initialTokenData = { - tokenAddress: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', // USDC + address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', // USDC chainId: '10', // Optimism decimals: 6, } - const prefs = utils.getPeanutPreferences() - if (prefs && prefs.tokenAddress && prefs.chainId && prefs.decimals) { - initialTokenData.tokenAddress = prefs.tokenAddress - initialTokenData.chainId = prefs.chainId - initialTokenData.decimals = prefs.decimals + const { lastUsedToken } = utils.getUserPreferences() ?? {} + if (lastUsedToken) { + initialTokenData.address = lastUsedToken.address + initialTokenData.chainId = lastUsedToken.chainId + initialTokenData.decimals = lastUsedToken.decimals } - const [selectedTokenAddress, setSelectedTokenAddress] = useState(initialTokenData.tokenAddress) + const [selectedTokenAddress, setSelectedTokenAddress] = useState(initialTokenData.address) const [selectedChainID, setSelectedChainID] = useState(initialTokenData.chainId) const [selectedTokenPrice, setSelectedTokenPrice] = useState(undefined) const [inputDenomination, setInputDenomination] = useState('TOKEN') @@ -59,22 +59,18 @@ export const TokenContextProvider = ({ children }: { children: React.ReactNode } Record >({}) - const preferences = utils.getPeanutPreferences() - const updateSelectedChainID = (chainID: string) => { setSelectedTokenAddress('0x0000000000000000000000000000000000000000') setSelectedChainID(chainID) } const resetTokenContextProvider = () => { - if (preferences && preferences.tokenAddress == selectedTokenAddress && preferences.chainId == selectedChainID) - return - setSelectedChainID(preferences?.tokenAddress ? preferences.chainId : '10') - setSelectedTokenAddress( - preferences?.tokenAddress ? preferences.tokenAddress : '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85' - ) + const { lastUsedToken } = utils.getUserPreferences() ?? {} + const tokenData = lastUsedToken ?? initialTokenData + setSelectedChainID(tokenData.chainId) + setSelectedTokenAddress(tokenData.address) + setSelectedTokenDecimals(tokenData.decimals) setSelectedTokenPrice(undefined) - setSelectedTokenDecimals(undefined) } useEffect(() => { diff --git a/src/context/walletContext/walletContext.tsx b/src/context/walletContext/walletContext.tsx index 5ae29111c..75a464f49 100644 --- a/src/context/walletContext/walletContext.tsx +++ b/src/context/walletContext/walletContext.tsx @@ -12,8 +12,8 @@ import { backgroundColorFromAddress, areEvmAddressesEqual, fetchWalletBalances, - getFromLocalStorage, - saveToLocalStorage, + getUserPreferences, + updateUserPreferences, } from '@/utils' import { peanutPublicClient } from '@/constants/viem.consts' @@ -58,7 +58,7 @@ export const WalletProvider = ({ children }: { children: ReactNode }) => { const { addAccount, user } = useAuth() const [selectedAddress, setSelectedAddress] = useState( - getFromLocalStorage('selectedAddress') ?? undefined + getUserPreferences()?.lastSelectedWallet?.address ) const isWalletConnected = useCallback( @@ -162,7 +162,9 @@ export const WalletProvider = ({ children }: { children: ReactNode }) => { // Remember selected address useEffect(() => { if (selectedAddress) { - saveToLocalStorage('selectedAddress', selectedAddress) + updateUserPreferences({ + lastSelectedWallet: { address: selectedAddress }, + }) } }, [selectedAddress]) diff --git a/src/utils/general.utils.ts b/src/utils/general.utils.ts index 046837376..70a549a28 100644 --- a/src/utils/general.utils.ts +++ b/src/utils/general.utils.ts @@ -747,53 +747,44 @@ export const getRequestLinkFulfillmentsFromLocalStorage = () => { } } -export const updatePeanutPreferences = ({ - chainId, - tokenAddress, - decimals, -}: { - chainId?: string - tokenAddress?: string - decimals?: number -}) => { +export type UserPreferences = { + lastUsedToken?: { + chainId: string + address: string + decimals: number + } + lastSelectedWallet?: { + address: string + } +} + +export const updateUserPreferences = (partialPrefs: Partial): UserPreferences | undefined => { try { if (typeof localStorage === 'undefined') return - const key = `peanut-preferences` - - let data = { - chainId: chainId, - tokenAddress: tokenAddress, - decimals: decimals, + const currentPrefs = getUserPreferences() || {} + const newPrefs: UserPreferences = { + ...currentPrefs, + ...partialPrefs, } - localStorage.setItem(key, JSON.stringify(data)) + localStorage.setItem('user-preferences', JSON.stringify(newPrefs)) + return newPrefs } catch (error) { - console.error('Error adding data to localStorage:', error) + console.error('Error updating user preferences:', error) } } -export const getPeanutPreferences = () => { +export const getUserPreferences = (): UserPreferences | undefined => { try { if (typeof localStorage === 'undefined') return - const key = `peanut-preferences` + const storedData = localStorage.getItem('user-preferences') + if (!storedData) return undefined - const storedData = localStorage.getItem(key) - - let data = { - chainId: '', - tokenAddress: '', - decimals: undefined, - } - - if (storedData) { - data = JSON.parse(storedData) - } - - return data + return JSON.parse(storedData) as UserPreferences } catch (error) { - console.error('Error getting data from localStorage:', error) + console.error('Error getting user preferences:', error) } } From 0221660639a95d235568aa265d0f38225cecbf5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Wed, 4 Dec 2024 08:32:05 -0300 Subject: [PATCH 4/4] feat: fully reset token selector context --- src/context/tokenSelector.context.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/context/tokenSelector.context.tsx b/src/context/tokenSelector.context.tsx index 264efb1a5..ad2484ff1 100644 --- a/src/context/tokenSelector.context.tsx +++ b/src/context/tokenSelector.context.tsx @@ -71,6 +71,8 @@ export const TokenContextProvider = ({ children }: { children: React.ReactNode } setSelectedTokenAddress(tokenData.address) setSelectedTokenDecimals(tokenData.decimals) setSelectedTokenPrice(undefined) + setInputDenomination('TOKEN') + setSelectedTokenData(undefined) } useEffect(() => {