forked from cerc-io/laconic-wallet
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:
parent
d44d8a3092
commit
9ab8c2ce4f
18
App.tsx
18
App.tsx
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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 };
|
||||
|
30
context/RequestContext.tsx
Normal file
30
context/RequestContext.tsx
Normal 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 };
|
5
index.js
5
index.js
@ -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>
|
||||
);
|
||||
|
@ -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",
|
||||
|
@ -202,6 +202,10 @@ const styles = StyleSheet.create({
|
||||
width: 400,
|
||||
height: 400,
|
||||
},
|
||||
dappDetails: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default styles;
|
||||
|
@ -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:
|
||||
|
15
yarn.lock
15
yarn.lock
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user