forked from cerc-io/laconic-wallet
Display active sessions on walletconnect page (#50)
* Replace QR icon with WC logo * Change screen title * Display active sessions * Change title * Display sessions on WalletConnect page * Display session topic in list item * Fix types * Add line * Change message * Move useEffect to WalletConnectContext * Disconnect sessions on resetting wallet * Review changes --------- Co-authored-by: Adw8 <adwait@deepstacksoft.com>
This commit is contained in:
parent
7219162185
commit
cf197f386f
35
App.tsx
35
App.tsx
@ -1,8 +1,9 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Button, Snackbar } from 'react-native-paper';
|
||||
import { Button, Snackbar, Text } from 'react-native-paper';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
|
||||
import { SignClientTypes } from '@walletconnect/types';
|
||||
import { getSdkError } from '@walletconnect/utils';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import {
|
||||
NativeStackNavigationProp,
|
||||
@ -17,22 +18,19 @@ import PairingModal from './components/PairingModal';
|
||||
import AddSession from './components/AddSession';
|
||||
import WalletConnect from './components/WalletConnect';
|
||||
import { StackParamsList } from './types';
|
||||
import useInitialization, {
|
||||
web3wallet,
|
||||
} from './utils/wallet-connect/WalletConnectUtils';
|
||||
import { web3wallet } from './utils/wallet-connect/WalletConnectUtils';
|
||||
import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Lib';
|
||||
import { getSignParamsMessage } from './utils/wallet-connect/Helpers';
|
||||
import { useRequests } from './context/RequestContext';
|
||||
import { useWalletConnect } from './context/WalletConnectContext';
|
||||
|
||||
const Stack = createNativeStackNavigator<StackParamsList>();
|
||||
|
||||
const App = (): React.JSX.Element => {
|
||||
useInitialization();
|
||||
|
||||
const navigation =
|
||||
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
||||
|
||||
const { requestSession, setRequestSession } = useRequests();
|
||||
const { requestSession, setRequestSession, setActiveSessions } =
|
||||
useWalletConnect();
|
||||
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const [toastVisible, setToastVisible] = useState(false);
|
||||
@ -95,13 +93,20 @@ const App = (): React.JSX.Element => {
|
||||
},
|
||||
[requestSession, setRequestSession, navigation],
|
||||
);
|
||||
|
||||
const onSessionDelete = useCallback(() => {
|
||||
let sessions = web3wallet?.getActiveSessions();
|
||||
setActiveSessions(sessions);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
web3wallet?.on('session_proposal', onSessionProposal);
|
||||
web3wallet?.on('session_request', onSessionRequest);
|
||||
|
||||
web3wallet?.on('session_delete', onSessionDelete);
|
||||
return () => {
|
||||
web3wallet?.off('session_proposal', onSessionProposal);
|
||||
web3wallet?.off('session_request', onSessionRequest);
|
||||
web3wallet?.off('session_delete', onSessionDelete);
|
||||
};
|
||||
//TODO: Investigate dependencies
|
||||
});
|
||||
@ -113,7 +118,7 @@ const App = (): React.JSX.Element => {
|
||||
name="Laconic"
|
||||
component={HomeScreen}
|
||||
options={{
|
||||
title: 'Laconic Wallet',
|
||||
headerTitle: () => <Text variant="titleLarge">Laconic Wallet</Text>,
|
||||
headerBackVisible: false,
|
||||
}}
|
||||
/>
|
||||
@ -121,7 +126,7 @@ const App = (): React.JSX.Element => {
|
||||
name="SignMessage"
|
||||
component={SignMessage}
|
||||
options={{
|
||||
title: 'Sign Message',
|
||||
headerTitle: () => <Text variant="titleLarge">Sign Message</Text>,
|
||||
}}
|
||||
initialParams={{ selectedNetwork: 'Ethereum' }}
|
||||
/>
|
||||
@ -129,14 +134,16 @@ const App = (): React.JSX.Element => {
|
||||
name="SignRequest"
|
||||
component={SignRequest}
|
||||
options={{
|
||||
title: 'Sign this message?',
|
||||
headerTitle: () => (
|
||||
<Text variant="titleLarge">Sign this message?</Text>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="InvalidPath"
|
||||
component={InvalidPath}
|
||||
options={{
|
||||
title: 'Bad Request',
|
||||
headerTitle: () => <Text variant="titleLarge">Bad Request</Text>,
|
||||
headerBackVisible: false,
|
||||
}}
|
||||
/>
|
||||
@ -144,7 +151,7 @@ const App = (): React.JSX.Element => {
|
||||
name="WalletConnect"
|
||||
component={WalletConnect}
|
||||
options={{
|
||||
title: 'WalletConnect Sessions',
|
||||
headerTitle: () => <Text variant="titleLarge">WalletConnect</Text>,
|
||||
headerRight: () => (
|
||||
<Button
|
||||
onPress={() => {
|
||||
|
@ -45,18 +45,7 @@ const AddSession = () => {
|
||||
navigation.navigate('WalletConnect');
|
||||
return pairing;
|
||||
};
|
||||
// const disconnect = async () => {
|
||||
// const activeSessions = await web3wallet.getActiveSessions();
|
||||
// const topic = Object.values(activeSessions)[0].topic;
|
||||
// if (activeSessions) {
|
||||
// await web3wallet.disconnectSession({
|
||||
// topic,
|
||||
// reason: getSdkError('USER_DISCONNECTED'),
|
||||
// });
|
||||
// navigation.navigate('Laconic');
|
||||
// return;
|
||||
// }
|
||||
// };
|
||||
|
||||
useEffect(() => {
|
||||
const handleAppStateChange = (newState: string) => {
|
||||
setIsActive(newState === 'active');
|
||||
|
@ -1,14 +1,10 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
View,
|
||||
ActivityIndicator,
|
||||
TouchableHighlight,
|
||||
Image,
|
||||
} from 'react-native';
|
||||
import { View, ActivityIndicator, Image } from 'react-native';
|
||||
import { Button, Text } from 'react-native-paper';
|
||||
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { getSdkError } from '@walletconnect/utils';
|
||||
|
||||
import { createWallet, resetWallet, retrieveAccounts } from '../utils/accounts';
|
||||
import { DialogComponent } from './Dialog';
|
||||
@ -18,12 +14,14 @@ import CreateWallet from './CreateWallet';
|
||||
import ResetWalletDialog from './ResetWalletDialog';
|
||||
import styles from '../styles/stylesheet';
|
||||
import { useAccounts } from '../context/AccountsContext';
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
import { StackParamsList } from '../types';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
|
||||
const WCLogo = () => {
|
||||
return (
|
||||
<Image
|
||||
style={{ width: 32, height: 20, margin: 0 }}
|
||||
style={{ width: 24, height: 15, margin: 0 }}
|
||||
source={require('../assets/WalletConnect-Icon-Blueberry.png')}
|
||||
/>
|
||||
);
|
||||
@ -31,6 +29,7 @@ const WCLogo = () => {
|
||||
|
||||
const HomeScreen = () => {
|
||||
const { accounts, setAccounts } = useAccounts();
|
||||
const { setActiveSessions } = useWalletConnect();
|
||||
|
||||
const navigation =
|
||||
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
||||
@ -38,10 +37,9 @@ const HomeScreen = () => {
|
||||
if (accounts.ethAccounts.length > 0) {
|
||||
navigation.setOptions({
|
||||
headerRight: () => (
|
||||
<TouchableHighlight
|
||||
onPress={() => navigation.navigate('WalletConnect')}>
|
||||
<Button onPress={() => navigation.navigate('WalletConnect')}>
|
||||
{<WCLogo />}
|
||||
</TouchableHighlight>
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
} else {
|
||||
@ -86,6 +84,16 @@ const HomeScreen = () => {
|
||||
cosmosAccounts: [],
|
||||
});
|
||||
setCurrentIndex(0);
|
||||
const sessions = await web3wallet.getActiveSessions();
|
||||
|
||||
Object.keys(sessions).forEach(async sessionId => {
|
||||
await web3wallet.disconnectSession({
|
||||
topic: sessionId,
|
||||
reason: getSdkError('USER_DISCONNECTED'),
|
||||
});
|
||||
});
|
||||
setActiveSessions({});
|
||||
|
||||
hideResetDialog();
|
||||
setNetwork('eth');
|
||||
};
|
||||
|
@ -9,6 +9,7 @@ import { PairingModalProps } from '../types';
|
||||
import styles from '../styles/stylesheet';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import { useAccounts } from '../context/AccountsContext';
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
|
||||
const PairingModal = ({
|
||||
visible,
|
||||
@ -92,6 +93,8 @@ const PairingModal = ({
|
||||
});
|
||||
}, [currentProposal]);
|
||||
|
||||
const { setActiveSessions } = useWalletConnect();
|
||||
|
||||
const handleAccept = async () => {
|
||||
if (currentProposal) {
|
||||
const { id, params } = currentProposal;
|
||||
@ -140,6 +143,8 @@ const PairingModal = ({
|
||||
namespaces,
|
||||
});
|
||||
|
||||
const sessions = web3wallet.getActiveSessions();
|
||||
setActiveSessions(sessions);
|
||||
setModalVisible(false);
|
||||
setToastVisible(true);
|
||||
setCurrentProposal(undefined);
|
||||
|
@ -35,7 +35,7 @@ const SignMessage = ({ route }: SignProps) => {
|
||||
<ScrollView style={styles.signPage}>
|
||||
<View style={styles.accountInfo}>
|
||||
<View>
|
||||
<Text variant="headlineSmall">
|
||||
<Text variant="titleMedium">
|
||||
{account && `Account ${account.counterId + 1}`}
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -18,12 +18,12 @@ import {
|
||||
rejectEIP155Request,
|
||||
} from '../utils/wallet-connect/WalletConnectRequests';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import { useRequests } from '../context/RequestContext';
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
|
||||
type SignRequestProps = NativeStackScreenProps<StackParamsList, 'SignRequest'>;
|
||||
|
||||
const SignRequest = ({ route }: SignRequestProps) => {
|
||||
const { requestSession } = useRequests();
|
||||
const { requestSession } = useWalletConnect();
|
||||
|
||||
const requestName = requestSession?.peer?.metadata?.name;
|
||||
const requestIcon = requestSession?.peer?.metadata?.icons[0];
|
||||
|
@ -1,6 +1,71 @@
|
||||
import React from 'react';
|
||||
import { View, Text } from 'react-native';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Image, TouchableOpacity, View } from 'react-native';
|
||||
import { List, Text } from 'react-native-paper';
|
||||
|
||||
import { getSdkError } from '@walletconnect/utils';
|
||||
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import styles from '../styles/stylesheet';
|
||||
|
||||
export default function WalletConnect() {
|
||||
return <View />;
|
||||
const { activeSessions, setActiveSessions } = useWalletConnect();
|
||||
|
||||
const disconnect = async (sessionId: string) => {
|
||||
await web3wallet.disconnectSession({
|
||||
topic: sessionId,
|
||||
reason: getSdkError('USER_DISCONNECTED'),
|
||||
});
|
||||
const sessions = await web3wallet?.getActiveSessions();
|
||||
setActiveSessions(sessions);
|
||||
return;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const sessions = web3wallet.getActiveSessions();
|
||||
setActiveSessions(sessions);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<View>
|
||||
{Object.keys(activeSessions).length > 0 ? (
|
||||
<>
|
||||
<View style={{ marginLeft: 12, marginTop: 12 }}>
|
||||
<Text variant="titleMedium">Active Sessions</Text>
|
||||
</View>
|
||||
<List.Section>
|
||||
{Object.entries(activeSessions).map(
|
||||
([sessionId, session], index) => (
|
||||
<List.Item
|
||||
style={{ paddingLeft: 12, borderBottomWidth: 0.5 }}
|
||||
key={sessionId}
|
||||
title={`${session.peer.metadata.name}`}
|
||||
descriptionNumberOfLines={7}
|
||||
//TODO: Refactor
|
||||
description={`${sessionId} \n\n${session.peer.metadata.url}\n\n${session.peer.metadata.description}`}
|
||||
left={() => (
|
||||
<Image
|
||||
style={styles.dappLogo}
|
||||
source={{ uri: session.peer.metadata.icons[0] }}
|
||||
/>
|
||||
)}
|
||||
right={() => (
|
||||
<TouchableOpacity
|
||||
onPress={() => disconnect(sessionId)}
|
||||
style={{ display: 'flex', justifyContent: 'center' }}>
|
||||
<List.Icon icon="close" />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</List.Section>
|
||||
</>
|
||||
) : (
|
||||
<View style={{ display: 'flex', alignItems: 'center', marginTop: 12 }}>
|
||||
<Text>You have no active sessions</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
|
||||
interface RequestContextProps {
|
||||
requestSession: any;
|
||||
setRequestSession: (requestSession: any) => void;
|
||||
}
|
||||
|
||||
const RequestContext = createContext<RequestContextProps>({
|
||||
requestSession: {},
|
||||
setRequestSession: () => {},
|
||||
});
|
||||
|
||||
const useRequests = () => {
|
||||
const requestContext = useContext(RequestContext);
|
||||
return requestContext;
|
||||
};
|
||||
|
||||
const RequestProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const [requestSession, setRequestSession] = useState<any>({});
|
||||
return (
|
||||
<RequestContext.Provider
|
||||
value={{
|
||||
requestSession,
|
||||
setRequestSession,
|
||||
}}>
|
||||
{children}
|
||||
</RequestContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export { useRequests, RequestProvider };
|
48
context/WalletConnectContext.tsx
Normal file
48
context/WalletConnectContext.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
|
||||
import { SessionTypes } from '@walletconnect/types';
|
||||
|
||||
import { WalletConnectContextProps } from '../types';
|
||||
import useInitialization, {
|
||||
web3wallet,
|
||||
} from '../utils/wallet-connect/WalletConnectUtils';
|
||||
|
||||
const WalletConnectContext = createContext<WalletConnectContextProps>({
|
||||
requestSession: {},
|
||||
setRequestSession: () => {},
|
||||
activeSessions: {},
|
||||
setActiveSessions: () => {},
|
||||
});
|
||||
|
||||
const useWalletConnect = () => {
|
||||
const walletConnectContext = useContext(WalletConnectContext);
|
||||
return walletConnectContext;
|
||||
};
|
||||
|
||||
const WalletConnectProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
useInitialization();
|
||||
|
||||
useEffect(() => {
|
||||
const sessions = web3wallet?.getActiveSessions() ?? {};
|
||||
setActiveSessions(sessions);
|
||||
}, []);
|
||||
|
||||
const [requestSession, setRequestSession] = useState<any>({});
|
||||
const [activeSessions, setActiveSessions] = useState<
|
||||
Record<string, SessionTypes.Struct>
|
||||
>({});
|
||||
|
||||
return (
|
||||
<WalletConnectContext.Provider
|
||||
value={{
|
||||
requestSession,
|
||||
setRequestSession,
|
||||
activeSessions,
|
||||
setActiveSessions,
|
||||
}}>
|
||||
{children}
|
||||
</WalletConnectContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export { useWalletConnect, WalletConnectProvider };
|
6
index.js
6
index.js
@ -7,7 +7,7 @@ import { NavigationContainer } from '@react-navigation/native';
|
||||
|
||||
import App from './App';
|
||||
import { AccountsProvider } from './context/AccountsContext';
|
||||
import { RequestProvider } from './context/RequestContext';
|
||||
import { WalletConnectProvider } from './context/WalletConnectContext';
|
||||
import { name as appName } from './app.json';
|
||||
|
||||
export default function Main() {
|
||||
@ -24,11 +24,11 @@ export default function Main() {
|
||||
return (
|
||||
<PaperProvider>
|
||||
<AccountsProvider>
|
||||
<RequestProvider>
|
||||
<WalletConnectProvider>
|
||||
<NavigationContainer linking={linking}>
|
||||
<App />
|
||||
</NavigationContainer>
|
||||
</RequestProvider>
|
||||
</WalletConnectProvider>
|
||||
</AccountsProvider>
|
||||
</PaperProvider>
|
||||
);
|
||||
|
@ -18,7 +18,7 @@ const styles = StyleSheet.create({
|
||||
fontWeight: '700',
|
||||
},
|
||||
accountContainer: {
|
||||
marginTop: 24,
|
||||
marginTop: 12,
|
||||
},
|
||||
addAccountButton: {
|
||||
marginTop: 24,
|
||||
@ -48,7 +48,7 @@ const styles = StyleSheet.create({
|
||||
paddingHorizontal: 24,
|
||||
},
|
||||
accountInfo: {
|
||||
marginTop: 24,
|
||||
marginTop: 12,
|
||||
marginBottom: 30,
|
||||
},
|
||||
networkDropdown: {
|
||||
|
12
types.ts
12
types.ts
@ -1,5 +1,4 @@
|
||||
import { StdSignDoc } from '@cosmjs/amino';
|
||||
import { SignClientTypes } from '@walletconnect/types';
|
||||
import { SignClientTypes, SessionTypes } from '@walletconnect/types';
|
||||
|
||||
export type StackParamsList = {
|
||||
Laconic: undefined;
|
||||
@ -109,3 +108,12 @@ export interface SignModalProps {
|
||||
requestEvent: SignClientTypes.EventArguments['session_request'] | undefined;
|
||||
currentEthAddresses: string[];
|
||||
}
|
||||
|
||||
export interface WalletConnectContextProps {
|
||||
requestSession: any;
|
||||
setRequestSession: (requestSession: any) => void;
|
||||
activeSessions: Record<string, SessionTypes.Struct>;
|
||||
setActiveSessions: (
|
||||
activeSessions: Record<string, SessionTypes.Struct>,
|
||||
) => void;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user