diff --git a/App.tsx b/App.tsx index 3927687..b304288 100644 --- a/App.tsx +++ b/App.tsx @@ -1,4 +1,10 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from 'react'; import { SignClientTypes } from '@walletconnect/types'; import { NavigationContainer } from '@react-navigation/native'; @@ -16,13 +22,15 @@ import useInitialization, { web3wallet, } from './utils/wallet-connect/WalletConnectUtils'; import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Lib'; -import { retrieveAccounts } from './utils/accounts'; +import { AccountsContext } from './context/AccountsContext'; const Stack = createNativeStackNavigator(); const App = (): React.JSX.Element => { useInitialization(); + const { accounts } = useContext(AccountsContext); + const [modalVisible, setModalVisible] = useState(false); //TODO: Remove any const [currentProposal, setCurrentProposal] = useState< @@ -31,7 +39,6 @@ const App = (): React.JSX.Element => { const [requestSession, setRequestSession] = useState(); const [requestEventData, setRequestEventData] = useState(); const [signModalVisible, setSignModalVisible] = useState(false); - const [currentEthAddresses, setCurrentEthAddresses] = useState([]); const onSessionProposal = useCallback( (proposal: SignClientTypes.EventArguments['session_proposal']) => { @@ -65,19 +72,13 @@ const App = (): React.JSX.Element => { //TODO: Investigate dependancies }); - useEffect(() => { - const fetchEthAccounts = async () => { - const { ethLoadedAccounts } = await retrieveAccounts(); + const currentEthAddresses = useMemo(() => { + if (accounts.ethAccounts.length > 0) { + return accounts.ethAccounts.map(account => account.address); + } - if (ethLoadedAccounts) { - const ethAddreses = ethLoadedAccounts.map(account => account.address); - setCurrentEthAddresses(ethAddreses); - } - }; - - fetchEthAccounts(); - // TODO: Use context to maintain accounts state - }, [modalVisible]); + return []; + }, [accounts]); const linking = { prefixes: ['https://www.laconic-wallet.com'], diff --git a/components/Accounts.tsx b/components/Accounts.tsx index bea18df..30d6086 100644 --- a/components/Accounts.tsx +++ b/components/Accounts.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useContext, useState } from 'react'; import { ScrollView, TouchableOpacity, View } from 'react-native'; import { Button, List, Text, useTheme } from 'react-native-paper'; @@ -10,16 +10,18 @@ import { addAccount } from '../utils/accounts'; import styles from '../styles/stylesheet'; import HDPathDialog from './HDPathDialog'; import AccountDetails from './AccountDetails'; +import { AccountsContext } from '../context/AccountsContext'; const Accounts = ({ network, - accounts, - updateAccounts, currentIndex, updateIndex: updateId, }: AccountsProps) => { const navigation = useNavigation>(); + + const { accounts, setAccounts } = useContext(AccountsContext); + const [expanded, setExpanded] = useState(false); const [isAccountCreating, setIsAccountCreating] = useState(false); const [hdDialog, setHdDialog] = useState(false); @@ -28,6 +30,25 @@ const Accounts = ({ const handlePress = () => setExpanded(!expanded); + const updateAccounts = (account: Account) => { + switch (network) { + case 'eth': + setAccounts({ + ...accounts, + ethAccounts: [...accounts.ethAccounts, account], + }); + break; + case 'cosmos': + setAccounts({ + ...accounts, + cosmosAccounts: [...accounts.cosmosAccounts, account], + }); + break; + default: + console.error('Select a valid network!'); + } + }; + const addAccountHandler = async () => { setIsAccountCreating(true); const newAccount = await addAccount(network); diff --git a/components/HomeScreen.tsx b/components/HomeScreen.tsx index 39e7362..c1deb4a 100644 --- a/components/HomeScreen.tsx +++ b/components/HomeScreen.tsx @@ -1,17 +1,19 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { View, ActivityIndicator } from 'react-native'; import { Button, Text } from 'react-native-paper'; import { createWallet, resetWallet, retrieveAccounts } from '../utils/accounts'; import { DialogComponent } from './Dialog'; import { NetworkDropdown } from './NetworkDropdown'; -import { Account, AccountsState } from '../types'; import Accounts from './Accounts'; import CreateWallet from './CreateWallet'; import ResetWalletDialog from './ResetWalletDialog'; import styles from '../styles/stylesheet'; +import { AccountsContext } from '../context/AccountsContext'; const HomeScreen = () => { + const { accounts, setAccounts } = useContext(AccountsContext); + const [isWalletCreated, setIsWalletCreated] = useState(false); const [isWalletCreating, setIsWalletCreating] = useState(false); const [walletDialog, setWalletDialog] = useState(false); @@ -20,10 +22,6 @@ const HomeScreen = () => { const [currentIndex, setCurrentIndex] = useState(0); const [isAccountsFetched, setIsAccountsFetched] = useState(false); const [phrase, setPhrase] = useState(''); - const [accounts, setAccounts] = useState({ - ethAccounts: [], - cosmosAccounts: [], - }); const hideWalletDialog = () => setWalletDialog(false); const hideResetDialog = () => setResetWalletDialog(false); @@ -64,25 +62,6 @@ const HomeScreen = () => { setCurrentIndex(index); }; - const updateAccounts = (account: Account) => { - switch (network) { - case 'eth': - setAccounts({ - ...accounts, - ethAccounts: [...accounts.ethAccounts, account], - }); - break; - case 'cosmos': - setAccounts({ - ...accounts, - cosmosAccounts: [...accounts.cosmosAccounts, account], - }); - break; - default: - console.error('Select a valid network!'); - } - }; - useEffect(() => { const fetchAccounts = async () => { if (isAccountsFetched) { @@ -104,7 +83,7 @@ const HomeScreen = () => { }; fetchAccounts(); - }, [isAccountsFetched]); + }, [isAccountsFetched, setAccounts]); return ( @@ -122,10 +101,8 @@ const HomeScreen = () => { diff --git a/components/SignModal.tsx b/components/SignModal.tsx index 1c6eab9..4c4d70f 100644 --- a/components/SignModal.tsx +++ b/components/SignModal.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useContext } from 'react'; import { Button, Text } from 'react-native-paper'; import { Image, Modal, View } from 'react-native'; @@ -11,6 +11,7 @@ import { import styles from '../styles/stylesheet'; import { SignModalProps } from '../types'; +import { AccountsContext } from '../context/AccountsContext'; const SignModal = ({ visible, @@ -19,6 +20,8 @@ const SignModal = ({ requestSession, currentEthAddresses, }: SignModalProps) => { + const { accounts } = useContext(AccountsContext); + if (!requestEvent || !requestSession) { return null; } @@ -37,6 +40,7 @@ const SignModal = ({ const response = await approveEIP155Request( requestEvent, currentEthAddresses, + accounts.ethAccounts, ); await web3wallet.respondSessionRequest({ topic, diff --git a/context/AccountsContext.tsx b/context/AccountsContext.tsx new file mode 100644 index 0000000..642769f --- /dev/null +++ b/context/AccountsContext.tsx @@ -0,0 +1,25 @@ +import React, { createContext, useState } from 'react'; + +import { AccountsState } from '../types'; + +const AccountsContext = createContext<{ + accounts: AccountsState; + setAccounts: (account: AccountsState) => void; +}>({ + accounts: { ethAccounts: [], cosmosAccounts: [] }, + setAccounts: () => {}, +}); + +const AccountsProvider = ({ children }: { children: any }) => { + const [accounts, setAccounts] = useState({ + ethAccounts: [], + cosmosAccounts: [], + }); + return ( + + {children} + + ); +}; + +export { AccountsContext, AccountsProvider }; diff --git a/index.js b/index.js index 8a143d6..25ceda7 100644 --- a/index.js +++ b/index.js @@ -4,12 +4,15 @@ import { AppRegistry } from 'react-native'; import { PaperProvider } from 'react-native-paper'; import App from './App'; +import { AccountsProvider } from './context/AccountsContext'; import { name as appName } from './app.json'; export default function Main() { return ( - + + + ); } diff --git a/types.ts b/types.ts index 36aed1b..f294a82 100644 --- a/types.ts +++ b/types.ts @@ -25,13 +25,8 @@ export type WalletDetails = { export type AccountsProps = { network: string; - accounts: { - ethAccounts: Account[]; - cosmosAccounts: Account[]; - }; currentIndex: number; updateIndex: (index: number) => void; - updateAccounts: (account: Account) => void; }; export type NetworkDropdownProps = { diff --git a/utils/wallet-connect/EIP155Requests.ts b/utils/wallet-connect/EIP155Requests.ts index e46df18..414c127 100644 --- a/utils/wallet-connect/EIP155Requests.ts +++ b/utils/wallet-connect/EIP155Requests.ts @@ -7,15 +7,18 @@ import { getSdkError } from '@walletconnect/utils'; import { EIP155_SIGNING_METHODS } from './EIP155Lib'; import { getSignParamsMessage, getAccountNumberFromParams } from './Helpers'; import { signEthMessage } from '../sign-message'; +import { Account } from '../../types'; export async function approveEIP155Request( requestEvent: SignClientTypes.EventArguments['session_request'], currentEthAddresses: string[], + ethAccounts: Account[], ) { const { params, id } = requestEvent; const { request } = params; const counterId = await getAccountNumberFromParams( currentEthAddresses, + ethAccounts, params, ); diff --git a/utils/wallet-connect/Helpers.ts b/utils/wallet-connect/Helpers.ts index fb082b7..5f777a9 100644 --- a/utils/wallet-connect/Helpers.ts +++ b/utils/wallet-connect/Helpers.ts @@ -1,9 +1,10 @@ // Taken from https://medium.com/walletconnect/how-to-build-a-wallet-in-react-native-with-the-web3wallet-sdk-b6f57bf02f9a -import { retrieveAccounts } from '../accounts'; -import { EIP155_CHAINS, TEIP155Chain } from './EIP155Lib'; import { utils } from 'ethers'; +import { Account } from '../../types'; +import { EIP155_CHAINS, TEIP155Chain } from './EIP155Lib'; + /** * Truncates string (in the middle) via given lenght value */ @@ -67,6 +68,7 @@ export function getSignTypedDataParamsData(params: string[]) { */ export async function getAccountNumberFromParams( addresses: string[], + ethAccounts: Account[], params: any, ) { const paramsString = JSON.stringify(params); @@ -78,9 +80,7 @@ export async function getAccountNumberFromParams( } }); - const { ethLoadedAccounts } = await retrieveAccounts(); - - const currentAccount = ethLoadedAccounts!.find( + const currentAccount = ethAccounts!.find( account => account.address === address, );