From ad49daf3817cb7cc766c7ebdc3c3b1a9af9d2c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gon=C3=A7alves?= Date: Thu, 14 Sep 2023 11:39:43 -0300 Subject: [PATCH] allow app receive dapp requests on startup --- src/core/Core.tsx | 46 +++++--- .../walletConnect/WalletConnect2Context.tsx | 111 ++++++++++-------- 2 files changed, 91 insertions(+), 66 deletions(-) diff --git a/src/core/Core.tsx b/src/core/Core.tsx index e816d49d1..ae1fe5ec7 100644 --- a/src/core/Core.tsx +++ b/src/core/Core.tsx @@ -1,10 +1,11 @@ -import { useCallback, useEffect } from 'react' +import { useCallback, useEffect, useState } from 'react' import { StatusBar, View } from 'react-native' import { SafeAreaProvider } from 'react-native-safe-area-context' import { createNavigationContainerRef, NavigationContainer, } from '@react-navigation/native' +import { RIFWallet } from '@rsksmart/rif-wallet-core' import { RootNavigationComponent, @@ -21,6 +22,7 @@ import { unlockApp, } from 'store/slices/settingsSlice' import { sharedStyles } from 'shared/constants' +import { WalletConnect2Provider } from 'src/screens/walletConnect/WalletConnect2Context' import { useStateSubscription } from './hooks/useStateSubscription' import { Cover } from './components/Cover' @@ -31,13 +33,12 @@ export const navigationContainerRef = export const Core = () => { const dispatch = useAppDispatch() - const settings = useAppSelector(selectWholeSettingsState) const requests = useAppSelector(selectRequests) const topColor = useAppSelector(selectTopColor) const isOffline = useIsOffline() - const { unlocked, active } = useStateSubscription() + const [wallet, setWallet] = useState(null) const unlockAppFn = useCallback(async () => { try { @@ -51,25 +52,38 @@ export const Core = () => { unlockAppFn() }, [unlockAppFn]) + /** + * Obs: calling selectWalletState will throw an error since the wallet is not yet ready. + * So we need to retrieve the wallet from the settings state. + */ + useEffect(() => { + const { wallets, walletsIsDeployed, selectedWallet } = settings + if (wallets && walletsIsDeployed) { + setWallet(wallets[selectedWallet]) + } + }, [settings, wallet]) + return ( {!active && } - {settings.loading && !unlocked ? ( - - ) : ( - <> - - {requests.length !== 0 && ( - dispatch(closeRequest())} - /> - )} - - )} + + {settings.loading && !unlocked ? ( + + ) : ( + <> + + {requests.length !== 0 && ( + dispatch(closeRequest())} + /> + )} + + )} + diff --git a/src/screens/walletConnect/WalletConnect2Context.tsx b/src/screens/walletConnect/WalletConnect2Context.tsx index 683244683..af20f71c5 100644 --- a/src/screens/walletConnect/WalletConnect2Context.tsx +++ b/src/screens/walletConnect/WalletConnect2Context.tsx @@ -1,4 +1,10 @@ -import { createContext, ReactElement, useEffect, useState } from 'react' +import { + createContext, + ReactElement, + useCallback, + useEffect, + useState, +} from 'react' import { getSdkError, parseUri } from '@walletconnect/utils' import Web3Wallet, { Web3WalletTypes } from '@walletconnect/web3wallet' import { IWeb3Wallet } from '@walletconnect/web3wallet' @@ -95,7 +101,7 @@ export const WalletConnect2Context = interface WalletConnect2ProviderProps { children: ReactElement - wallet: RIFWallet + wallet: RIFWallet | null } export const WalletConnect2Provider = ({ @@ -130,53 +136,56 @@ export const WalletConnect2Provider = ({ } } - const subscribeToEvents = (web3wallet: Web3Wallet) => { - web3wallet.on('session_proposal', async proposal => - onSessionProposal(proposal, web3wallet), - ) - web3wallet.on('session_request', async event => { - if (!wallet) { - return - } - const adapter = new WalletConnectAdapter(wallet) - const { - params: { - request: { method, params }, - }, - id, - topic, - } = event - - const rpcResponse = { - topic, - response: { + const subscribeToEvents = useCallback( + (web3wallet: Web3Wallet) => { + web3wallet.on('session_proposal', async proposal => + onSessionProposal(proposal, web3wallet), + ) + web3wallet.on('session_request', async event => { + if (!wallet) { + return + } + const adapter = new WalletConnectAdapter(wallet) + const { + params: { + request: { method, params }, + }, id, - jsonrpc: '2.0', - }, - } + topic, + } = event + + const rpcResponse = { + topic, + response: { + id, + jsonrpc: '2.0', + }, + } - adapter - .handleCall(method, params) - .then(signedMessage => { - web3wallet.respondSessionRequest({ - ...rpcResponse, - response: { - ...rpcResponse.response, - result: signedMessage, - }, + adapter + .handleCall(method, params) + .then(signedMessage => { + web3wallet.respondSessionRequest({ + ...rpcResponse, + response: { + ...rpcResponse.response, + result: signedMessage, + }, + }) }) - }) - .catch(_ => { - web3wallet.respondSessionRequest({ - ...rpcResponse, - response: { - ...rpcResponse.response, - error: getSdkError('USER_REJECTED'), - }, + .catch(_ => { + web3wallet.respondSessionRequest({ + ...rpcResponse, + response: { + ...rpcResponse.response, + error: getSdkError('USER_REJECTED'), + }, + }) }) - }) - }) - } + }) + }, + [wallet], + ) const onCreateNewSession = async (uri: string) => { try { @@ -261,18 +270,20 @@ export const WalletConnect2Provider = ({ } } - const onContextFirstLoad = async () => { + const onContextFirstLoad = useCallback(async () => { const web3wallet = await createWeb3Wallet() subscribeToEvents(web3wallet) setSessions(Object.values(web3wallet.getActiveSessions())) - } + }, [subscribeToEvents]) + /** * useEffect On first load, fetch previous saved sessions */ useEffect(() => { - onContextFirstLoad().catch(console.log) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + if (wallet) { + onContextFirstLoad().catch(console.log) + } + }, [onContextFirstLoad, wallet]) return (