forked from cerc-io/laconic-wallet
Use page for handling sign requests (#42)
* Use sign request page instead of modal * Fix context * Remove multiple if statements * Change metadata * Remove sign modal * Make review changes * Remove state --------- Co-authored-by: Adw8 <adwait@deepstacksoft.com>
This commit is contained in:
parent
a4e0dc5406
commit
05be6008de
52
App.tsx
52
App.tsx
@ -15,7 +15,6 @@ import HomeScreen from './components/HomeScreen';
|
||||
import SignRequest from './components/SignRequest';
|
||||
import InvalidPath from './components/InvalidPath';
|
||||
import PairingModal from './components/PairingModal';
|
||||
import SignModal from './components/SignModal';
|
||||
import WalletConnect from './components/WalletConnect';
|
||||
import { StackParamsList } from './types';
|
||||
import useInitialization, {
|
||||
@ -23,6 +22,8 @@ import useInitialization, {
|
||||
} from './utils/wallet-connect/WalletConnectUtils';
|
||||
import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Lib';
|
||||
import { AccountsContext } from './context/AccountsContext';
|
||||
import { getSignParamsMessage } from './utils/wallet-connect/Helpers';
|
||||
import { navigationRef, navigateTo } from './utils/RootNavigation';
|
||||
|
||||
const Stack = createNativeStackNavigator<StackParamsList>();
|
||||
|
||||
@ -37,8 +38,13 @@ const App = (): React.JSX.Element => {
|
||||
SignClientTypes.EventArguments['session_proposal'] | undefined
|
||||
>();
|
||||
const [requestSession, setRequestSession] = useState<any>();
|
||||
const [requestEventData, setRequestEventData] = useState<any>();
|
||||
const [signModalVisible, setSignModalVisible] = useState(false);
|
||||
|
||||
const currentEthAddresses = useMemo(() => {
|
||||
if (accounts.ethAccounts.length > 0) {
|
||||
return accounts.ethAccounts.map(account => account.address);
|
||||
}
|
||||
return [];
|
||||
}, [accounts]);
|
||||
|
||||
const onSessionProposal = useCallback(
|
||||
(proposal: SignClientTypes.EventArguments['session_proposal']) => {
|
||||
@ -52,6 +58,8 @@ const App = (): React.JSX.Element => {
|
||||
async (requestEvent: SignClientTypes.EventArguments['session_request']) => {
|
||||
const { topic, params } = requestEvent;
|
||||
const { request } = params;
|
||||
const address = request.params[1];
|
||||
const message = getSignParamsMessage(request.params);
|
||||
const requestSessionData =
|
||||
web3wallet.engine.signClient.session.get(topic);
|
||||
|
||||
@ -59,27 +67,31 @@ const App = (): React.JSX.Element => {
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN:
|
||||
case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
|
||||
setRequestSession(requestSessionData);
|
||||
setRequestEventData(requestEvent);
|
||||
setSignModalVisible(true);
|
||||
if (address && message) {
|
||||
navigateTo('SignRequest', {
|
||||
network: 'eth',
|
||||
address,
|
||||
message,
|
||||
requestEvent,
|
||||
requestSession,
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
},
|
||||
[],
|
||||
[requestSession],
|
||||
);
|
||||
useEffect(() => {
|
||||
web3wallet?.on('session_proposal', onSessionProposal);
|
||||
web3wallet?.on('session_request', onSessionRequest);
|
||||
|
||||
return () => {
|
||||
web3wallet?.off('session_proposal', onSessionProposal);
|
||||
web3wallet?.off('session_request', onSessionRequest);
|
||||
};
|
||||
//TODO: Investigate dependancies
|
||||
});
|
||||
|
||||
const currentEthAddresses = useMemo(() => {
|
||||
if (accounts.ethAccounts.length > 0) {
|
||||
return accounts.ethAccounts.map(account => account.address);
|
||||
}
|
||||
|
||||
return [];
|
||||
}, [accounts]);
|
||||
|
||||
const linking = {
|
||||
prefixes: ['https://www.laconic-wallet.com'],
|
||||
config: {
|
||||
@ -92,7 +104,7 @@ const App = (): React.JSX.Element => {
|
||||
};
|
||||
|
||||
return (
|
||||
<NavigationContainer linking={linking}>
|
||||
<NavigationContainer linking={linking} ref={navigationRef}>
|
||||
<Stack.Navigator>
|
||||
<Stack.Screen
|
||||
name="Laconic"
|
||||
@ -114,7 +126,7 @@ const App = (): React.JSX.Element => {
|
||||
name="SignRequest"
|
||||
component={SignRequest}
|
||||
options={{
|
||||
title: 'Sign Message?',
|
||||
title: 'Sign this message?',
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
@ -140,14 +152,6 @@ const App = (): React.JSX.Element => {
|
||||
setCurrentProposal={setCurrentProposal}
|
||||
currentEthAddresses={currentEthAddresses}
|
||||
/>
|
||||
|
||||
<SignModal
|
||||
visible={signModalVisible}
|
||||
setModalVisible={setSignModalVisible}
|
||||
requestEvent={requestEventData}
|
||||
requestSession={requestSession}
|
||||
currentEthAddresses={currentEthAddresses}
|
||||
/>
|
||||
</NavigationContainer>
|
||||
);
|
||||
};
|
||||
|
@ -1,100 +0,0 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { Button, Text } from 'react-native-paper';
|
||||
import { Image, Modal, View } from 'react-native';
|
||||
|
||||
import { getSignParamsMessage } from '../utils/wallet-connect/Helpers';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import {
|
||||
approveEIP155Request,
|
||||
rejectEIP155Request,
|
||||
} from '../utils/wallet-connect/EIP155Requests';
|
||||
|
||||
import styles from '../styles/stylesheet';
|
||||
import { SignModalProps } from '../types';
|
||||
import { AccountsContext } from '../context/AccountsContext';
|
||||
|
||||
const SignModal = ({
|
||||
visible,
|
||||
setModalVisible,
|
||||
requestEvent,
|
||||
requestSession,
|
||||
currentEthAddresses,
|
||||
}: SignModalProps) => {
|
||||
const { accounts } = useContext(AccountsContext);
|
||||
|
||||
if (!requestEvent || !requestSession) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const chainID = requestEvent?.params?.chainId?.toUpperCase();
|
||||
const message = getSignParamsMessage(requestEvent?.params?.request?.params);
|
||||
|
||||
const requestName = requestSession?.peer?.metadata?.name;
|
||||
const requestIcon = requestSession?.peer?.metadata?.icons[0];
|
||||
const requestURL = requestSession?.peer?.metadata?.url;
|
||||
|
||||
const { topic } = requestEvent;
|
||||
|
||||
const onApprove = async () => {
|
||||
if (requestEvent) {
|
||||
const response = await approveEIP155Request(
|
||||
requestEvent,
|
||||
currentEthAddresses,
|
||||
accounts.ethAccounts,
|
||||
);
|
||||
await web3wallet.respondSessionRequest({
|
||||
topic,
|
||||
response,
|
||||
});
|
||||
setModalVisible(false);
|
||||
}
|
||||
};
|
||||
|
||||
const onReject = async () => {
|
||||
if (requestEvent) {
|
||||
const response = rejectEIP155Request(requestEvent);
|
||||
await web3wallet.respondSessionRequest({
|
||||
topic,
|
||||
response,
|
||||
});
|
||||
setModalVisible(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal visible={visible} animationType="slide" transparent>
|
||||
<View style={styles.container}>
|
||||
<View style={styles.modalContentContainer}>
|
||||
<Text variant="titleLarge">Sign this message?</Text>
|
||||
|
||||
<Image
|
||||
style={styles.dappLogo}
|
||||
source={{
|
||||
uri: requestIcon,
|
||||
}}
|
||||
/>
|
||||
|
||||
<Text>{requestName}</Text>
|
||||
<Text variant="bodyMedium">{requestURL}</Text>
|
||||
|
||||
<View style={styles.messageBody}>
|
||||
<Text variant="bodyLarge">{message}</Text>
|
||||
</View>
|
||||
<Text>Chains: {chainID}</Text>
|
||||
|
||||
<View style={styles.flexRow}>
|
||||
<Button mode="outlined" onPress={() => onReject()}>
|
||||
Cancel
|
||||
</Button>
|
||||
<View style={styles.space} />
|
||||
<Button mode="contained" onPress={() => onApprove()}>
|
||||
Accept
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignModal;
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { Alert, View } from 'react-native';
|
||||
import { ActivityIndicator, Button, Text } from 'react-native-paper';
|
||||
|
||||
@ -13,6 +13,11 @@ import AccountDetails from './AccountDetails';
|
||||
import styles from '../styles/stylesheet';
|
||||
import { signMessage } from '../utils/sign-message';
|
||||
import { retrieveSingleAccount } from '../utils/accounts';
|
||||
import {
|
||||
approveEIP155Request,
|
||||
rejectEIP155Request,
|
||||
} from '../utils/wallet-connect/EIP155Requests';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
|
||||
type SignRequestProps = NativeStackScreenProps<StackParamsList, 'SignRequest'>;
|
||||
|
||||
@ -20,7 +25,7 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
const [account, setAccount] = useState<Account>();
|
||||
const [message, setMessage] = useState<string>('');
|
||||
const [network, setNetwork] = useState<string>('');
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const navigation =
|
||||
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
||||
@ -36,7 +41,9 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
);
|
||||
if (!requestAccount) {
|
||||
navigation.navigate('InvalidPath');
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestAccount && requestAccount !== account) {
|
||||
setAccount(requestAccount);
|
||||
}
|
||||
@ -66,7 +73,6 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setLoaded(true);
|
||||
if (route.path) {
|
||||
const sanitizedRoute = sanitizePath(route.path);
|
||||
sanitizedRoute &&
|
||||
@ -76,11 +82,28 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
route.params?.address,
|
||||
route.params?.message,
|
||||
);
|
||||
return;
|
||||
}
|
||||
setLoaded(false);
|
||||
route.params &&
|
||||
retrieveData(
|
||||
route.params?.network,
|
||||
route.params?.address,
|
||||
route.params?.message,
|
||||
);
|
||||
setIsLoading(false);
|
||||
}, [route]);
|
||||
|
||||
const signMessageHandler = async () => {
|
||||
const handleEIP155Request = async () => {
|
||||
const { requestEvent } = route.params || {};
|
||||
const response = await approveEIP155Request(
|
||||
requestEvent,
|
||||
account?.counterId,
|
||||
);
|
||||
const { topic } = requestEvent;
|
||||
await web3wallet.respondSessionRequest({ topic, response });
|
||||
};
|
||||
|
||||
const handleIntent = async () => {
|
||||
if (!account) {
|
||||
throw new Error('Account is not valid');
|
||||
}
|
||||
@ -91,17 +114,36 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
accountId: account.counterId,
|
||||
});
|
||||
Alert.alert('Signature', signedMessage);
|
||||
navigation.navigate('Laconic');
|
||||
}
|
||||
};
|
||||
|
||||
const signMessageHandler = async () => {
|
||||
if (route.params?.requestEvent) {
|
||||
await handleEIP155Request();
|
||||
} else {
|
||||
await handleIntent();
|
||||
}
|
||||
|
||||
navigation.navigate('Laconic');
|
||||
};
|
||||
|
||||
const rejectRequestHandler = async () => {
|
||||
if (route.params?.requestEvent) {
|
||||
const response = rejectEIP155Request(route.params?.requestEvent);
|
||||
const { topic } = route.params?.requestEvent;
|
||||
await web3wallet.respondSessionRequest({
|
||||
topic,
|
||||
response,
|
||||
});
|
||||
}
|
||||
navigation.navigate('Laconic');
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{!loaded ? (
|
||||
{isLoading ? (
|
||||
<ActivityIndicator />
|
||||
) : (
|
||||
<View style={styles.appContainer}>
|
||||
<AccountDetails account={account} />
|
||||
<View style={styles.requestMessage}>
|
||||
@ -119,8 +161,6 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
) : (
|
||||
<ActivityIndicator />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
9
types.ts
9
types.ts
@ -4,7 +4,14 @@ export type StackParamsList = {
|
||||
Laconic: undefined;
|
||||
SignMessage: { selectedNetwork: string; accountInfo: Account } | undefined;
|
||||
SignRequest:
|
||||
| { network: string; address: string; message: string }
|
||||
| {
|
||||
network: string;
|
||||
address: string;
|
||||
message: string;
|
||||
// TODO: remove any
|
||||
requestEvent?: any;
|
||||
requestSession?: any;
|
||||
}
|
||||
| undefined;
|
||||
InvalidPath: undefined;
|
||||
WalletConnect: undefined;
|
||||
|
14
utils/RootNavigation.ts
Normal file
14
utils/RootNavigation.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import {
|
||||
CommonActions,
|
||||
createNavigationContainerRef,
|
||||
} from '@react-navigation/native';
|
||||
|
||||
import { StackParamsList } from '../types';
|
||||
|
||||
export const navigationRef = createNavigationContainerRef<StackParamsList>();
|
||||
|
||||
export function navigateTo(routeName: string, params?: object) {
|
||||
if (navigationRef.isReady()) {
|
||||
navigationRef.dispatch(CommonActions.navigate(routeName, params));
|
||||
}
|
||||
}
|
@ -5,27 +5,20 @@ import { SignClientTypes } from '@walletconnect/types';
|
||||
import { getSdkError } from '@walletconnect/utils';
|
||||
|
||||
import { EIP155_SIGNING_METHODS } from './EIP155Lib';
|
||||
import { getSignParamsMessage, getAccountNumberFromParams } from './Helpers';
|
||||
import { getSignParamsMessage } from './Helpers';
|
||||
import { signEthMessage } from '../sign-message';
|
||||
import { Account } from '../../types';
|
||||
|
||||
export async function approveEIP155Request(
|
||||
requestEvent: SignClientTypes.EventArguments['session_request'],
|
||||
currentEthAddresses: string[],
|
||||
ethAccounts: Account[],
|
||||
counterId: number | undefined,
|
||||
) {
|
||||
const { params, id } = requestEvent;
|
||||
const { request } = params;
|
||||
const counterId = await getAccountNumberFromParams(
|
||||
currentEthAddresses,
|
||||
ethAccounts,
|
||||
params,
|
||||
);
|
||||
|
||||
switch (request.method) {
|
||||
case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
|
||||
const message = getSignParamsMessage(request.params);
|
||||
const signedMessage = await signEthMessage(message, counterId);
|
||||
const signedMessage =
|
||||
counterId && (await signEthMessage(message, counterId));
|
||||
return formatJsonRpcResult(id, signedMessage);
|
||||
|
||||
default:
|
||||
|
@ -28,10 +28,10 @@ export async function createWeb3Wallet() {
|
||||
web3wallet = await Web3Wallet.init({
|
||||
core,
|
||||
metadata: {
|
||||
name: 'Web3Wallet React Native Tutorial',
|
||||
description: 'ReactNative Web3Wallet',
|
||||
url: 'https://walletconnect.com/',
|
||||
icons: ['https://avatars.githubusercontent.com/u/37784886'],
|
||||
name: 'Laconic Wallet',
|
||||
description: 'ReactNative Laconic Wallet',
|
||||
url: 'https://wallet.laconic.com/',
|
||||
icons: ['https://avatars.githubusercontent.com/u/92608123'],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user