Display details coming from dapp in sign request page (#44)

* Add qr-code scanner button in homescreen header

* Display dapp details on sign request page

* Center details coming from dapp

* Remove request event state from request context
This commit is contained in:
shreerang6921 2024-03-07 16:02:35 +05:30 committed by GitHub
parent d44d8a3092
commit 9ab8c2ce4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 125 additions and 37 deletions

18
App.tsx
View File

@ -1,10 +1,4 @@
import React, {
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { SignClientTypes } from '@walletconnect/types';
import { NavigationContainer } from '@react-navigation/native';
@ -21,23 +15,25 @@ import useInitialization, {
web3wallet,
} from './utils/wallet-connect/WalletConnectUtils';
import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Lib';
import { AccountsContext } from './context/AccountsContext';
import { useAccounts } from './context/AccountsContext';
import { getSignParamsMessage } from './utils/wallet-connect/Helpers';
import { navigationRef, navigateTo } from './utils/RootNavigation';
import { useRequests } from './context/RequestContext';
const Stack = createNativeStackNavigator<StackParamsList>();
const App = (): React.JSX.Element => {
useInitialization();
const { accounts } = useContext(AccountsContext);
const { accounts } = useAccounts();
const { requestSession, setRequestSession } = useRequests();
const [modalVisible, setModalVisible] = useState(false);
//TODO: Remove any
const [currentProposal, setCurrentProposal] = useState<
SignClientTypes.EventArguments['session_proposal'] | undefined
>();
const [requestSession, setRequestSession] = useState<any>();
const currentEthAddresses = useMemo(() => {
if (accounts.ethAccounts.length > 0) {
@ -79,7 +75,7 @@ const App = (): React.JSX.Element => {
return;
}
},
[requestSession],
[requestSession, setRequestSession],
);
useEffect(() => {
web3wallet?.on('session_proposal', onSessionProposal);

View File

@ -1,4 +1,4 @@
import React, { useContext, useState } from 'react';
import React, { useState } from 'react';
import { ScrollView, TouchableOpacity, View } from 'react-native';
import { Button, List, Text, useTheme } from 'react-native-paper';
@ -10,7 +10,7 @@ import { addAccount } from '../utils/accounts';
import styles from '../styles/stylesheet';
import HDPathDialog from './HDPathDialog';
import AccountDetails from './AccountDetails';
import { AccountsContext } from '../context/AccountsContext';
import { useAccounts } from '../context/AccountsContext';
const Accounts = ({
network,
@ -20,7 +20,7 @@ const Accounts = ({
const navigation =
useNavigation<NativeStackNavigationProp<StackParamsList>>();
const { accounts, setAccounts } = useContext(AccountsContext);
const { accounts, setAccounts } = useAccounts();
const [expanded, setExpanded] = useState(false);
const [isAccountCreating, setIsAccountCreating] = useState(false);
@ -135,17 +135,6 @@ const Accounts = ({
Sign Message
</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
navigation.navigate('WalletConnect');
}}>
<Text
variant="titleSmall"
style={[styles.hyperlink, { color: theme.colors.primary }]}>
Connect Wallet
</Text>
</TouchableOpacity>
</View>
</View>
</ScrollView>

View File

@ -1,6 +1,10 @@
import React, { useContext, useEffect, useState } from 'react';
import React, { useEffect, useState } from 'react';
import { View, ActivityIndicator } from 'react-native';
import { Button, Text } from 'react-native-paper';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useNavigation } from '@react-navigation/native';
import { createWallet, resetWallet, retrieveAccounts } from '../utils/accounts';
import { DialogComponent } from './Dialog';
@ -9,10 +13,30 @@ import Accounts from './Accounts';
import CreateWallet from './CreateWallet';
import ResetWalletDialog from './ResetWalletDialog';
import styles from '../styles/stylesheet';
import { AccountsContext } from '../context/AccountsContext';
import { useAccounts } from '../context/AccountsContext';
import { StackParamsList } from '../types';
const HomeScreen = () => {
const { accounts, setAccounts } = useContext(AccountsContext);
const { accounts, setAccounts } = useAccounts();
const navigation =
useNavigation<NativeStackNavigationProp<StackParamsList>>();
useEffect(() => {
if (accounts.ethAccounts.length > 0) {
navigation.setOptions({
headerRight: () => (
<Button onPress={() => navigation.navigate('WalletConnect')}>
{<Icon name={'qrcode-scan'} size={20} />}
</Button>
),
});
} else {
navigation.setOptions({
headerRight: undefined,
});
}
}, [navigation, accounts]);
const [isWalletCreated, setIsWalletCreated] = useState<boolean>(false);
const [isWalletCreating, setIsWalletCreating] = useState<boolean>(false);

View File

@ -1,5 +1,5 @@
import React, { useContext, useEffect, useState } from 'react';
import { Alert, View } from 'react-native';
import React, { useEffect, useState } from 'react';
import { Alert, Image, View } from 'react-native';
import { ActivityIndicator, Button, Text } from 'react-native-paper';
import { useNavigation } from '@react-navigation/native';
@ -18,10 +18,17 @@ import {
rejectEIP155Request,
} from '../utils/wallet-connect/EIP155Requests';
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
import { useRequests } from '../context/RequestContext';
type SignRequestProps = NativeStackScreenProps<StackParamsList, 'SignRequest'>;
const SignRequest = ({ route }: SignRequestProps) => {
const { requestSession } = useRequests();
const requestName = requestSession?.peer?.metadata?.name;
const requestIcon = requestSession?.peer?.metadata?.icons[0];
const requestURL = requestSession?.peer?.metadata?.url;
const [account, setAccount] = useState<Account>();
const [message, setMessage] = useState<string>('');
const [network, setNetwork] = useState<string>('');
@ -95,9 +102,14 @@ const SignRequest = ({ route }: SignRequestProps) => {
const handleEIP155Request = async () => {
const { requestEvent } = route.params || {};
if (!account) {
throw new Error('account not found');
}
const response = await approveEIP155Request(
requestEvent,
account?.counterId,
account.counterId,
);
const { topic } = requestEvent;
await web3wallet.respondSessionRequest({ topic, response });
@ -147,6 +159,16 @@ const SignRequest = ({ route }: SignRequestProps) => {
</View>
) : (
<View style={styles.appContainer}>
<View style={styles.dappDetails}>
<Image
style={styles.dappLogo}
source={{
uri: requestIcon,
}}
/>
<Text>{requestName}</Text>
<Text variant="bodyMedium">{requestURL}</Text>
</View>
<AccountDetails account={account} />
<View style={styles.requestMessage}>
<Text variant="bodyLarge">{message}</Text>

View File

@ -1,4 +1,4 @@
import React, { createContext, useState } from 'react';
import React, { createContext, useContext, useState } from 'react';
import { AccountsState } from '../types';
@ -10,6 +10,11 @@ const AccountsContext = createContext<{
setAccounts: () => {},
});
const useAccounts = () => {
const accountsContext = useContext(AccountsContext);
return accountsContext;
};
const AccountsProvider = ({ children }: { children: any }) => {
const [accounts, setAccounts] = useState<AccountsState>({
ethAccounts: [],
@ -22,4 +27,4 @@ const AccountsProvider = ({ children }: { children: any }) => {
);
};
export { AccountsContext, AccountsProvider };
export { useAccounts, AccountsProvider };

View File

@ -0,0 +1,30 @@
import React, { createContext, useContext, useState } from 'react';
const RequestContext = createContext<{
// TODO: Remove any type
requestSession: any;
setRequestSession: (requestSession: any) => void;
}>({
requestSession: {},
setRequestSession: () => {},
});
const useRequests = () => {
const requestContext = useContext(RequestContext);
return requestContext;
};
const RequestProvider = ({ children }: { children: any }) => {
const [requestSession, setRequestSession] = useState<any>({});
return (
<RequestContext.Provider
value={{
requestSession,
setRequestSession,
}}>
{children}
</RequestContext.Provider>
);
};
export { useRequests, RequestProvider };

View File

@ -5,13 +5,16 @@ import { PaperProvider } from 'react-native-paper';
import App from './App';
import { AccountsProvider } from './context/AccountsContext';
import { RequestProvider } from './context/RequestContext';
import { name as appName } from './app.json';
export default function Main() {
return (
<PaperProvider>
<AccountsProvider>
<App />
<RequestProvider>
<App />
</RequestProvider>
</AccountsProvider>
</PaperProvider>
);

View File

@ -48,6 +48,7 @@
"@react-native/metro-config": "0.73.4",
"@react-native/typescript-config": "0.73.1",
"@types/react": "^18.2.6",
"@types/react-native-vector-icons": "^6.4.18",
"@types/react-test-renderer": "^18.0.0",
"@walletconnect/jsonrpc-types": "^1.0.3",
"babel-jest": "^29.6.3",

View File

@ -202,6 +202,10 @@ const styles = StyleSheet.create({
width: 400,
height: 400,
},
dappDetails: {
display: 'flex',
alignItems: 'center',
},
});
export default styles;

View File

@ -10,15 +10,14 @@ import { signEthMessage } from '../sign-message';
export async function approveEIP155Request(
requestEvent: SignClientTypes.EventArguments['session_request'],
counterId: number | undefined,
counterId: number,
) {
const { params, id } = requestEvent;
const { request } = params;
switch (request.method) {
case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
const message = getSignParamsMessage(request.params);
const signedMessage =
counterId !== undefined && (await signEthMessage(message, counterId));
const signedMessage = await signEthMessage(message, counterId);
return formatJsonRpcResult(id, signedMessage);
default:

View File

@ -2691,6 +2691,21 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563"
integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==
"@types/react-native-vector-icons@^6.4.18":
version "6.4.18"
resolved "https://registry.yarnpkg.com/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.18.tgz#18671c617b9d0958747bc959903470dde91a8c79"
integrity sha512-YGlNWb+k5laTBHd7+uZowB9DpIK3SXUneZqAiKQaj1jnJCZM0x71GDim5JCTMi4IFkhc9m8H/Gm28T5BjyivUw==
dependencies:
"@types/react" "*"
"@types/react-native" "^0.70"
"@types/react-native@^0.70":
version "0.70.19"
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.70.19.tgz#b4e651dcf7f49c69ff3a4c3072584cad93155582"
integrity sha512-c6WbyCgWTBgKKMESj/8b4w+zWcZSsCforson7UdXtXMecG3MxCinYi6ihhrHVPyUrVzORsvEzK8zg32z4pK6Sg==
dependencies:
"@types/react" "*"
"@types/react-test-renderer@^18.0.0":
version "18.0.7"
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-18.0.7.tgz#2cfe657adb3688cdf543995eceb2e062b5a68728"