forked from cerc-io/laconic-wallet
Compare commits
9 Commits
release-v0
...
main
Author | SHA1 | Date | |
---|---|---|---|
bb5223afda | |||
e975f4c9f7 | |||
4827fa8c7c | |||
36c3adb1b1 | |||
2ca91cad06 | |||
eab4fd425a | |||
361b79b696 | |||
0bd9dec8a9 | |||
c027f5b934 |
@ -2,3 +2,4 @@ WALLET_CONNECT_PROJECT_ID=
|
||||
DEFAULT_GAS_PRICE=0.025
|
||||
# Reference: https://github.com/cosmos/cosmos-sdk/issues/16020
|
||||
DEFAULT_GAS_ADJUSTMENT=2
|
||||
LACONICD_RPC_URL=https://laconicd.laconic.com
|
||||
|
@ -9,7 +9,6 @@
|
||||
- Function for creating web3 wallet
|
||||
|
||||
```js
|
||||
export let web3wallet: IWeb3Wallet;
|
||||
export let core: ICore;
|
||||
|
||||
export async function createWeb3Wallet() {
|
||||
@ -26,23 +25,27 @@
|
||||
icons: ['https://avatars.githubusercontent.com/u/92608123'],
|
||||
},
|
||||
});
|
||||
|
||||
return web3wallet;
|
||||
}
|
||||
```
|
||||
|
||||
- Hook used for intializing web3 wallet
|
||||
|
||||
```js
|
||||
export default function useInitialization() {
|
||||
export default function useInitialization(setWeb3wallet) {
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
|
||||
const onInitialize = useCallback(async () => {
|
||||
try {
|
||||
await createWeb3Wallet();
|
||||
const web3walletInstance = await createWeb3Wallet();
|
||||
setWeb3wallet(web3walletInstance);
|
||||
|
||||
setInitialized(true);
|
||||
} catch (err: unknown) {
|
||||
console.log('Error for initializing', err);
|
||||
console.error('Error for initializing', err);
|
||||
}
|
||||
}, []);
|
||||
}, [setWeb3wallet]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!initialized) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
"prepare": "husky"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cerc-io/registry-sdk": "^0.2.2",
|
||||
"@cerc-io/registry-sdk": "^0.2.5",
|
||||
"@cosmjs/amino": "^0.32.3",
|
||||
"@cosmjs/crypto": "^0.32.3",
|
||||
"@cosmjs/proto-signing": "^0.32.3",
|
||||
@ -21,6 +21,7 @@
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"@json-rpc-tools/utils": "^1.7.6",
|
||||
"@react-native-async-storage/async-storage": "^1.22.3",
|
||||
"@react-native-clipboard/clipboard": "^1.14.1",
|
||||
"@react-native-community/netinfo": "^11.3.1",
|
||||
"@react-navigation/elements": "^1.3.30",
|
||||
"@react-navigation/native": "^6.1.10",
|
||||
|
1
react-native-config.d.ts
vendored
1
react-native-config.d.ts
vendored
@ -4,6 +4,7 @@ declare module 'react-native-config' {
|
||||
WALLET_CONNECT_PROJECT_ID: string;
|
||||
DEFAULT_GAS_PRICE: string;
|
||||
DEFAULT_GAS_ADJUSTMENT: string;
|
||||
LACONICD_RPC_URL: string;
|
||||
}
|
||||
|
||||
export const Config: NativeConfig;
|
||||
|
31
scripts/build-apk.sh
Executable file
31
scripts/build-apk.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Default value for IS_RELEASE
|
||||
IS_RELEASE=${IS_RELEASE:-false}
|
||||
|
||||
# Install dependencies
|
||||
echo "Installing dependencies..."
|
||||
yarn
|
||||
|
||||
# Create the necessary directory for assets
|
||||
mkdir -p android/app/src/main/assets/
|
||||
|
||||
# Bundle the React Native application
|
||||
yarn react-native bundle \
|
||||
--platform android \
|
||||
--dev false \
|
||||
--entry-file index.js \
|
||||
--bundle-output android/app/src/main/assets/index.android.bundle \
|
||||
--assets-dest android/app/src/main/res
|
||||
|
||||
# Navigate to the android directory
|
||||
cd android
|
||||
|
||||
# Run the Gradle build based on the IS_RELEASE flag
|
||||
if [ "$IS_RELEASE" = "true" ]; then
|
||||
echo "Building release version..."
|
||||
./gradlew assembleRelease
|
||||
else
|
||||
echo "Building debug version..."
|
||||
./gradlew assembleDebug
|
||||
fi
|
@ -24,7 +24,6 @@ import AddSession from './screens/AddSession';
|
||||
import WalletConnect from './screens/WalletConnect';
|
||||
import ApproveTransaction from './screens/ApproveTransaction';
|
||||
import { StackParamsList } from './types';
|
||||
import { web3wallet } from './utils/wallet-connect/WalletConnectUtils';
|
||||
import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Data';
|
||||
import { getSignParamsMessage } from './utils/wallet-connect/helpers';
|
||||
import ApproveTransfer from './screens/ApproveTransfer';
|
||||
@ -41,7 +40,7 @@ const App = (): React.JSX.Element => {
|
||||
const navigation =
|
||||
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
||||
|
||||
const { setActiveSessions } = useWalletConnect();
|
||||
const { web3wallet, setActiveSessions } = useWalletConnect();
|
||||
const { accounts, setCurrentIndex } = useAccounts();
|
||||
const { networksData, selectedNetwork, setSelectedNetwork } = useNetworks();
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
@ -63,7 +62,7 @@ const App = (): React.JSX.Element => {
|
||||
setModalVisible(true);
|
||||
setCurrentProposal(proposal);
|
||||
},
|
||||
[accounts],
|
||||
[accounts, web3wallet],
|
||||
);
|
||||
|
||||
const onSessionRequest = useCallback(
|
||||
@ -197,13 +196,14 @@ const App = (): React.JSX.Element => {
|
||||
setSelectedNetwork,
|
||||
setCurrentIndex,
|
||||
selectedNetwork,
|
||||
web3wallet,
|
||||
],
|
||||
);
|
||||
|
||||
const onSessionDelete = useCallback(() => {
|
||||
const sessions = web3wallet!.getActiveSessions();
|
||||
setActiveSessions(sessions);
|
||||
}, [setActiveSessions]);
|
||||
}, [setActiveSessions, web3wallet]);
|
||||
|
||||
useEffect(() => {
|
||||
web3wallet?.on('session_proposal', onSessionProposal);
|
||||
|
@ -12,11 +12,11 @@ import styles from '../styles/stylesheet';
|
||||
import HDPathDialog from './HDPathDialog';
|
||||
import AccountDetails from './AccountDetails';
|
||||
import { useAccounts } from '../context/AccountsContext';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import { useNetworks } from '../context/NetworksContext';
|
||||
import ConfirmDialog from './ConfirmDialog';
|
||||
import { getNamespaces } from '../utils/wallet-connect/helpers';
|
||||
import ShowPKDialog from './ShowPKDialog';
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
|
||||
const Accounts = () => {
|
||||
const navigation =
|
||||
@ -26,6 +26,8 @@ const Accounts = () => {
|
||||
useAccounts();
|
||||
const { networksData, selectedNetwork, setNetworksData, setSelectedNetwork } =
|
||||
useNetworks();
|
||||
|
||||
const { web3wallet } = useWalletConnect();
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const [isAccountCreating, setIsAccountCreating] = useState(false);
|
||||
const [hdDialog, setHdDialog] = useState(false);
|
||||
@ -58,7 +60,6 @@ const Accounts = () => {
|
||||
networksData,
|
||||
selectedNetwork!,
|
||||
accounts,
|
||||
currentIndex,
|
||||
);
|
||||
|
||||
if (!updatedNamespaces) {
|
||||
@ -74,7 +75,7 @@ const Accounts = () => {
|
||||
// Call the updateSessions function when the 'accounts' dependency changes
|
||||
updateSessions();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [accounts]);
|
||||
}, [accounts, web3wallet]);
|
||||
|
||||
const addAccountHandler = async () => {
|
||||
setIsAccountCreating(true);
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { Button, Dialog, Portal, Text } from 'react-native-paper';
|
||||
import { Button, Dialog, Portal, Snackbar, Text } from 'react-native-paper';
|
||||
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
|
||||
import styles from '../styles/stylesheet';
|
||||
import GridView from './Grid';
|
||||
@ -11,29 +13,45 @@ const DialogComponent = ({
|
||||
hideDialog,
|
||||
contentText,
|
||||
}: CustomDialogProps) => {
|
||||
const [toastVisible, setToastVisible] = useState(false);
|
||||
|
||||
const words = contentText.split(' ');
|
||||
|
||||
const handleCopy = () => {
|
||||
Clipboard.setString(contentText);
|
||||
setToastVisible(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
<Dialog visible={visible} onDismiss={hideDialog}>
|
||||
<Dialog.Content>
|
||||
<Text variant="titleLarge">Mnemonic</Text>
|
||||
<View style={styles.dialogTitle}>
|
||||
<Text variant="titleMedium">
|
||||
Your mnemonic provides full access to your wallet and funds. Make
|
||||
sure to note it down.{' '}
|
||||
</Text>
|
||||
<Text variant="titleMedium" style={styles.dialogWarning}>
|
||||
Do not share your mnemonic with anyone
|
||||
</Text>
|
||||
<GridView words={words} />
|
||||
</View>
|
||||
</Dialog.Content>
|
||||
<Dialog.Actions>
|
||||
<Button onPress={hideDialog}>Done</Button>
|
||||
</Dialog.Actions>
|
||||
</Dialog>
|
||||
</Portal>
|
||||
<>
|
||||
<Portal>
|
||||
<Dialog visible={visible} onDismiss={hideDialog}>
|
||||
<Dialog.Content>
|
||||
<Text variant="titleLarge">Mnemonic</Text>
|
||||
<View style={styles.dialogTitle}>
|
||||
<Text variant="titleMedium">
|
||||
Your mnemonic provides full access to your wallet and funds.
|
||||
Make sure to note it down.{' '}
|
||||
</Text>
|
||||
<Text variant="titleMedium" style={styles.dialogWarning}>
|
||||
Do not share your mnemonic with anyone
|
||||
</Text>
|
||||
<GridView words={words} />
|
||||
</View>
|
||||
</Dialog.Content>
|
||||
<Dialog.Actions>
|
||||
<Button onPress={handleCopy}>Copy</Button>
|
||||
<Button onPress={hideDialog}>Done</Button>
|
||||
</Dialog.Actions>
|
||||
</Dialog>
|
||||
</Portal>
|
||||
<Snackbar
|
||||
visible={toastVisible}
|
||||
onDismiss={() => setToastVisible(false)}
|
||||
duration={1000}>
|
||||
Mnemonic copied to clipboard
|
||||
</Snackbar>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,6 @@ import { buildApprovedNamespaces, getSdkError } from '@walletconnect/utils';
|
||||
|
||||
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';
|
||||
import { useNetworks } from '../context/NetworksContext';
|
||||
@ -21,7 +20,7 @@ const PairingModal = ({
|
||||
setModalVisible,
|
||||
setToastVisible,
|
||||
}: PairingModalProps) => {
|
||||
const { accounts, currentIndex } = useAccounts();
|
||||
const { accounts } = useAccounts();
|
||||
const { selectedNetwork, networksData } = useNetworks();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [chainError, setChainError] = useState('');
|
||||
@ -87,7 +86,7 @@ const PairingModal = ({
|
||||
});
|
||||
}, [currentProposal]);
|
||||
|
||||
const { setActiveSessions } = useWalletConnect();
|
||||
const { setActiveSessions, web3wallet } = useWalletConnect();
|
||||
|
||||
useEffect(() => {
|
||||
const getSupportedNamespaces = async () => {
|
||||
@ -104,7 +103,6 @@ const PairingModal = ({
|
||||
networksData,
|
||||
selectedNetwork!,
|
||||
accounts,
|
||||
currentIndex,
|
||||
);
|
||||
setSupportedNamespaces(nameSpaces);
|
||||
} catch (err) {
|
||||
@ -130,7 +128,7 @@ const PairingModal = ({
|
||||
networksData,
|
||||
selectedNetwork,
|
||||
accounts,
|
||||
currentIndex,
|
||||
web3wallet,
|
||||
setCurrentProposal,
|
||||
setModalVisible,
|
||||
]);
|
||||
|
@ -1,14 +1,16 @@
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
|
||||
import { SessionTypes } from '@walletconnect/types';
|
||||
import { IWeb3Wallet } from '@walletconnect/web3wallet';
|
||||
|
||||
import { WalletConnectContextProps } from '../types';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import useInitialization from '../hooks/useInitialization';
|
||||
|
||||
const WalletConnectContext = createContext<WalletConnectContextProps>({
|
||||
activeSessions: {},
|
||||
setActiveSessions: () => {},
|
||||
web3wallet: {} as IWeb3Wallet,
|
||||
setWeb3wallet: () => {},
|
||||
});
|
||||
|
||||
const useWalletConnect = () => {
|
||||
@ -17,12 +19,14 @@ const useWalletConnect = () => {
|
||||
};
|
||||
|
||||
const WalletConnectProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
useInitialization();
|
||||
const [web3wallet, setWeb3wallet] = useState<IWeb3Wallet | undefined>();
|
||||
|
||||
useInitialization(setWeb3wallet);
|
||||
|
||||
useEffect(() => {
|
||||
const sessions = (web3wallet && web3wallet.getActiveSessions()) || {};
|
||||
setActiveSessions(sessions);
|
||||
}, []);
|
||||
}, [web3wallet]);
|
||||
|
||||
const [activeSessions, setActiveSessions] = useState<
|
||||
Record<string, SessionTypes.Struct>
|
||||
@ -33,6 +37,8 @@ const WalletConnectProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
value={{
|
||||
activeSessions,
|
||||
setActiveSessions,
|
||||
web3wallet,
|
||||
setWeb3wallet,
|
||||
}}>
|
||||
{children}
|
||||
</WalletConnectContext.Provider>
|
||||
|
@ -1,17 +1,24 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { IWeb3Wallet } from '@walletconnect/web3wallet';
|
||||
|
||||
import { createWeb3Wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
|
||||
export default function useInitialization() {
|
||||
export default function useInitialization(
|
||||
setWeb3wallet: React.Dispatch<React.SetStateAction<IWeb3Wallet | undefined>>,
|
||||
) {
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
|
||||
const onInitialize = useCallback(async () => {
|
||||
try {
|
||||
await createWeb3Wallet();
|
||||
const web3walletInstance = await createWeb3Wallet();
|
||||
setWeb3wallet(web3walletInstance);
|
||||
|
||||
setInitialized(true);
|
||||
} catch (err: unknown) {
|
||||
console.error('Error for initializing', err);
|
||||
}
|
||||
}, []);
|
||||
}, [setWeb3wallet]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!initialized) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { AppState, TouchableOpacity, View } from 'react-native';
|
||||
import { Button, Text, TextInput } from 'react-native-paper';
|
||||
import {
|
||||
@ -15,6 +15,7 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { web3WalletPair } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import styles from '../styles/stylesheet';
|
||||
import { StackParamsList } from '../types';
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
|
||||
const AddSession = () => {
|
||||
const navigation =
|
||||
@ -23,6 +24,8 @@ const AddSession = () => {
|
||||
const { hasPermission, requestPermission } = useCameraPermission();
|
||||
const device = useCameraDevice('back');
|
||||
|
||||
const { web3wallet } = useWalletConnect();
|
||||
|
||||
const [currentWCURI, setCurrentWCURI] = useState<string>('');
|
||||
const [isActive, setIsActive] = useState(AppState.currentState === 'active');
|
||||
const [isScanning, setScanning] = useState(true);
|
||||
@ -45,11 +48,15 @@ const AddSession = () => {
|
||||
await Linking.openSettings();
|
||||
};
|
||||
|
||||
const pair = async () => {
|
||||
const pairing = await web3WalletPair({ uri: currentWCURI });
|
||||
const pair = useCallback(async () => {
|
||||
if (!web3wallet) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pairing = await web3WalletPair(web3wallet, { uri: currentWCURI });
|
||||
navigation.navigate('WalletConnect');
|
||||
return pairing;
|
||||
};
|
||||
}, [web3wallet, currentWCURI, navigation]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleAppStateChange = (newState: string) => {
|
||||
|
@ -1,15 +1,16 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Image, ScrollView, View } from 'react-native';
|
||||
import { Button, Text, TextInput } from 'react-native-paper';
|
||||
import { SvgUri } from 'react-native-svg';
|
||||
import Config from 'react-native-config';
|
||||
import { MsgCreateValidator } from 'cosmjs-types/cosmos/staking/v1beta1/tx';
|
||||
|
||||
import {
|
||||
NativeStackNavigationProp,
|
||||
NativeStackScreenProps,
|
||||
} from '@react-navigation/native-stack';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { DirectSecp256k1Wallet } from '@cosmjs/proto-signing';
|
||||
import { DirectSecp256k1Wallet, EncodeObject } from '@cosmjs/proto-signing';
|
||||
import { LaconicClient } from '@cerc-io/registry-sdk';
|
||||
import { GasPrice, calculateFee } from '@cosmjs/stargate';
|
||||
import { formatJsonRpcError } from '@json-rpc-tools/utils';
|
||||
@ -25,10 +26,10 @@ import {
|
||||
approveWalletConnectRequest,
|
||||
rejectWalletConnectRequest,
|
||||
} from '../utils/wallet-connect/wallet-connect-requests';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import { MEMO } from './ApproveTransfer';
|
||||
import TxErrorDialog from '../components/TxErrorDialog';
|
||||
import AccountDetails from '../components/AccountDetails';
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
|
||||
type ApproveTransactionProps = NativeStackScreenProps<
|
||||
StackParamsList,
|
||||
@ -42,13 +43,14 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
const requestName = requestSession.peer.metadata.name;
|
||||
const requestIcon = requestSession.peer.metadata.icons[0];
|
||||
const requestURL = requestSession.peer.metadata.url;
|
||||
const transactionMessage = route.params.transactionMessage;
|
||||
const signer = route.params.signer;
|
||||
const requestEvent = route.params.requestEvent;
|
||||
const chainId = requestEvent.params.chainId;
|
||||
const requestEventId = requestEvent.id;
|
||||
const topic = requestEvent.topic;
|
||||
|
||||
const { web3wallet } = useWalletConnect();
|
||||
|
||||
const [account, setAccount] = useState<Account>();
|
||||
const [cosmosStargateClient, setCosmosStargateClient] =
|
||||
useState<LaconicClient>();
|
||||
@ -67,6 +69,20 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
);
|
||||
const namespace = requestedNetwork!.namespace;
|
||||
|
||||
const transactionMessage = useMemo((): EncodeObject => {
|
||||
const inputTxMsg = route.params.transactionMessage;
|
||||
|
||||
// If it's a MsgCreateValidator, decode the tx msg value using MsgCreateValidator type
|
||||
if (inputTxMsg.typeUrl.includes('MsgCreateValidator')) {
|
||||
return {
|
||||
typeUrl: inputTxMsg.typeUrl,
|
||||
value: MsgCreateValidator.fromJSON(inputTxMsg.value),
|
||||
};
|
||||
}
|
||||
|
||||
return inputTxMsg;
|
||||
}, [route.params.transactionMessage]);
|
||||
|
||||
useEffect(() => {
|
||||
if (namespace !== COSMOS) {
|
||||
return;
|
||||
@ -104,7 +120,15 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
};
|
||||
|
||||
setClient();
|
||||
}, [account, requestedNetwork, chainId, namespace, requestEventId, topic]);
|
||||
}, [
|
||||
account,
|
||||
requestedNetwork,
|
||||
chainId,
|
||||
namespace,
|
||||
requestEventId,
|
||||
topic,
|
||||
web3wallet,
|
||||
]);
|
||||
|
||||
const retrieveData = useCallback(
|
||||
async (requestAddress: string) => {
|
||||
@ -134,7 +158,7 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
return;
|
||||
}
|
||||
const gasEstimation = await cosmosStargateClient!.simulate(
|
||||
transactionMessage.value.participant!,
|
||||
signer,
|
||||
[transactionMessage],
|
||||
MEMO,
|
||||
);
|
||||
@ -152,7 +176,14 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
}
|
||||
};
|
||||
getCosmosGas();
|
||||
}, [cosmosStargateClient, transactionMessage, requestEventId, topic]);
|
||||
}, [
|
||||
cosmosStargateClient,
|
||||
transactionMessage,
|
||||
requestEventId,
|
||||
topic,
|
||||
web3wallet,
|
||||
signer,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const gasPrice = GasPrice.fromString(
|
||||
@ -227,6 +258,13 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
navigation.navigate('Laconic');
|
||||
};
|
||||
|
||||
const replacer = (key: string, value: any): any => {
|
||||
if (value instanceof Uint8Array) {
|
||||
return Buffer.from(value).toString('hex');
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ScrollView contentContainerStyle={styles.approveTransaction}>
|
||||
@ -251,7 +289,7 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
</Text>
|
||||
<View style={styles.messageBody}>
|
||||
<Text variant="bodyLarge">
|
||||
{JSON.stringify(transactionMessage, null, 2)}
|
||||
{JSON.stringify(transactionMessage, replacer, 2)}
|
||||
</Text>
|
||||
</View>
|
||||
<>
|
||||
|
@ -34,7 +34,6 @@ import {
|
||||
rejectWalletConnectRequest,
|
||||
WalletConnectRequests,
|
||||
} from '../utils/wallet-connect/wallet-connect-requests';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import DataBox from '../components/DataBox';
|
||||
import { getPathKey } from '../utils/misc';
|
||||
import { useNetworks } from '../context/NetworksContext';
|
||||
@ -42,6 +41,7 @@ import { COSMOS, EIP155, IS_NUMBER_REGEX } from '../utils/constants';
|
||||
import TxErrorDialog from '../components/TxErrorDialog';
|
||||
import { EIP155_SIGNING_METHODS } from '../utils/wallet-connect/EIP155Data';
|
||||
import { COSMOS_METHODS } from '../utils/wallet-connect/COSMOSData';
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
|
||||
export const MEMO = 'Sending signed tx from Laconic Wallet';
|
||||
// Reference: https://ethereum.org/en/developers/docs/gas/#what-is-gas-limit
|
||||
@ -64,6 +64,8 @@ const ApproveTransfer = ({ route }: SignRequestProps) => {
|
||||
const chainId = requestEvent.params.chainId;
|
||||
const requestMethod = requestEvent.params.request.method;
|
||||
|
||||
const { web3wallet } = useWalletConnect();
|
||||
|
||||
const [account, setAccount] = useState<Account>();
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [balance, setBalance] = useState<string>('');
|
||||
|
@ -16,7 +16,6 @@ import styles from '../styles/stylesheet';
|
||||
import { useAccounts } from '../context/AccountsContext';
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
import { NetworksDataState, StackParamsList } from '../types';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import { useNetworks } from '../context/NetworksContext';
|
||||
|
||||
const WCLogo = () => {
|
||||
@ -33,7 +32,7 @@ const HomeScreen = () => {
|
||||
|
||||
const { networksData, selectedNetwork, setSelectedNetwork, setNetworksData } =
|
||||
useNetworks();
|
||||
const { setActiveSessions } = useWalletConnect();
|
||||
const { web3wallet, setActiveSessions } = useWalletConnect();
|
||||
|
||||
const navigation =
|
||||
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
||||
@ -110,6 +109,7 @@ const HomeScreen = () => {
|
||||
|
||||
hideResetDialog();
|
||||
}, [
|
||||
web3wallet,
|
||||
setAccounts,
|
||||
setActiveSessions,
|
||||
setCurrentIndex,
|
||||
|
@ -20,10 +20,10 @@ import {
|
||||
rejectWalletConnectRequest,
|
||||
WalletConnectRequests,
|
||||
} from '../utils/wallet-connect/wallet-connect-requests';
|
||||
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
||||
import { EIP155_SIGNING_METHODS } from '../utils/wallet-connect/EIP155Data';
|
||||
import { useNetworks } from '../context/NetworksContext';
|
||||
import { COSMOS_METHODS } from '../utils/wallet-connect/COSMOSData';
|
||||
import { useWalletConnect } from '../context/WalletConnectContext';
|
||||
|
||||
type SignRequestProps = NativeStackScreenProps<StackParamsList, 'SignRequest'>;
|
||||
|
||||
@ -35,6 +35,8 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
const requestIcon = requestSession?.peer?.metadata?.icons[0];
|
||||
const requestURL = requestSession?.peer?.metadata?.url;
|
||||
|
||||
const { web3wallet } = useWalletConnect();
|
||||
|
||||
const [account, setAccount] = useState<Account>();
|
||||
const [message, setMessage] = useState<string>('');
|
||||
const [namespace, setNamespace] = useState<string>('');
|
||||
@ -86,21 +88,13 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestAccount !== account) {
|
||||
setAccount(requestAccount);
|
||||
}
|
||||
if (requestMessage !== message) {
|
||||
setMessage(decodeURIComponent(requestMessage));
|
||||
}
|
||||
if (requestNamespace !== namespace) {
|
||||
setNamespace(requestNamespace);
|
||||
}
|
||||
if (requestChainId !== chainId) {
|
||||
setChainId(requestChainId);
|
||||
}
|
||||
setAccount(requestAccount);
|
||||
setMessage(decodeURIComponent(requestMessage));
|
||||
setNamespace(requestNamespace);
|
||||
setChainId(requestChainId);
|
||||
setIsLoading(false);
|
||||
},
|
||||
[account, message, navigation, namespace, chainId],
|
||||
[navigation],
|
||||
);
|
||||
|
||||
const sanitizePath = useCallback(
|
||||
|
@ -6,11 +6,10 @@ import { SvgUri } from 'react-native-svg';
|
||||
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() {
|
||||
const { activeSessions, setActiveSessions } = useWalletConnect();
|
||||
const { web3wallet, activeSessions, setActiveSessions } = useWalletConnect();
|
||||
|
||||
const disconnect = async (sessionId: string) => {
|
||||
await web3wallet!.disconnectSession({
|
||||
@ -23,9 +22,9 @@ export default function WalletConnect() {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const sessions = web3wallet!.getActiveSessions();
|
||||
const sessions = web3wallet?.getActiveSessions() || {};
|
||||
setActiveSessions(sessions);
|
||||
}, [setActiveSessions]);
|
||||
}, [web3wallet, setActiveSessions]);
|
||||
|
||||
return (
|
||||
<View>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { PopulatedTransaction } from 'ethers';
|
||||
|
||||
import { SignClientTypes, SessionTypes } from '@walletconnect/types';
|
||||
import { Web3WalletTypes } from '@walletconnect/web3wallet';
|
||||
import { IWeb3Wallet, Web3WalletTypes } from '@walletconnect/web3wallet';
|
||||
import { EncodeObject } from '@cosmjs/proto-signing';
|
||||
|
||||
export type StackParamsList = {
|
||||
@ -127,4 +127,6 @@ export interface WalletConnectContextProps {
|
||||
setActiveSessions: (
|
||||
activeSessions: Record<string, SessionTypes.Struct>,
|
||||
) => void;
|
||||
web3wallet: IWeb3Wallet | undefined;
|
||||
setWeb3wallet: React.Dispatch<React.SetStateAction<IWeb3Wallet | undefined>>;
|
||||
}
|
||||
|
@ -1,9 +1,22 @@
|
||||
import Config from 'react-native-config';
|
||||
import { COSMOS_TESTNET_CHAINS } from './wallet-connect/COSMOSData';
|
||||
import { EIP155_CHAINS } from './wallet-connect/EIP155Data';
|
||||
|
||||
export const EIP155 = 'eip155';
|
||||
export const COSMOS = 'cosmos';
|
||||
export const DEFAULT_NETWORKS = [
|
||||
{
|
||||
chainId: 'laconic_9000-1',
|
||||
networkName: 'laconicd',
|
||||
namespace: COSMOS,
|
||||
rpcUrl: Config.LACONICD_RPC_URL,
|
||||
blockExplorerUrl: '',
|
||||
nativeDenom: 'alnt',
|
||||
addressPrefix: 'laconic',
|
||||
coinType: '118',
|
||||
gasPrice: '1',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
chainId: '1',
|
||||
networkName: EIP155_CHAINS['eip155:1'].name,
|
||||
|
@ -6,7 +6,6 @@ import { Core } from '@walletconnect/core';
|
||||
import { ICore } from '@walletconnect/types';
|
||||
import { Web3Wallet, IWeb3Wallet } from '@walletconnect/web3wallet';
|
||||
|
||||
export let web3wallet: IWeb3Wallet | undefined;
|
||||
export let core: ICore;
|
||||
|
||||
export async function createWeb3Wallet() {
|
||||
@ -14,7 +13,7 @@ export async function createWeb3Wallet() {
|
||||
projectId: Config.WALLET_CONNECT_PROJECT_ID,
|
||||
});
|
||||
|
||||
web3wallet = await Web3Wallet.init({
|
||||
const web3wallet = await Web3Wallet.init({
|
||||
core,
|
||||
metadata: {
|
||||
name: 'Laconic Wallet',
|
||||
@ -23,9 +22,14 @@ export async function createWeb3Wallet() {
|
||||
icons: ['https://avatars.githubusercontent.com/u/92608123'],
|
||||
},
|
||||
});
|
||||
|
||||
return web3wallet;
|
||||
}
|
||||
|
||||
export async function web3WalletPair(params: { uri: string }) {
|
||||
export async function web3WalletPair(
|
||||
web3wallet: IWeb3Wallet,
|
||||
params: { uri: string },
|
||||
) {
|
||||
if (web3wallet) {
|
||||
return await web3wallet.core.pairing.pair({ uri: params.uri });
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ export const getNamespaces = async (
|
||||
networksData: NetworksDataState[],
|
||||
selectedNetwork: NetworksDataState,
|
||||
accounts: Account[],
|
||||
currentIndex: number,
|
||||
) => {
|
||||
const namespaceChainId = `${selectedNetwork.namespace}:${selectedNetwork.chainId}`;
|
||||
|
||||
@ -101,23 +100,6 @@ export const getNamespaces = async (
|
||||
const requiredAddressesArray = await Promise.all(requiredAddressesPromise);
|
||||
const requiredAddresses = requiredAddressesArray.flat();
|
||||
|
||||
let sortedAccounts = requiredAddresses;
|
||||
|
||||
// If selected network is included in chains requested from dApp,
|
||||
// Put selected account as first account
|
||||
if (walletConnectChains.includes(namespaceChainId)) {
|
||||
const currentAddresses = requiredAddresses.filter(address =>
|
||||
address.includes(namespaceChainId),
|
||||
);
|
||||
sortedAccounts = [
|
||||
currentAddresses[currentIndex],
|
||||
...currentAddresses.filter((address, index) => index !== currentIndex),
|
||||
...requiredAddresses.filter(
|
||||
address => !currentAddresses.includes(address),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
// construct namespace object
|
||||
const newNamespaces = {
|
||||
eip155: {
|
||||
@ -133,7 +115,7 @@ export const getNamespaces = async (
|
||||
...(optionalNamespaces.eip155?.events ?? []),
|
||||
...(requiredNamespaces.eip155?.events ?? []),
|
||||
],
|
||||
accounts: sortedAccounts.filter(account => account.includes(EIP155)),
|
||||
accounts: requiredAddresses.filter(account => account.includes(EIP155)),
|
||||
},
|
||||
cosmos: {
|
||||
chains: walletConnectChains.filter(chain => chain.includes(COSMOS)),
|
||||
@ -147,18 +129,12 @@ export const getNamespaces = async (
|
||||
...(optionalNamespaces.cosmos?.events ?? []),
|
||||
...(requiredNamespaces.cosmos?.events ?? []),
|
||||
],
|
||||
accounts: sortedAccounts.filter(account => account.includes(COSMOS)),
|
||||
accounts: requiredAddresses.filter(account => account.includes(COSMOS)),
|
||||
},
|
||||
};
|
||||
|
||||
return newNamespaces;
|
||||
} else {
|
||||
// Set selected account as the first account in supported namespaces
|
||||
const sortedAccounts = [
|
||||
accounts[currentIndex],
|
||||
...accounts.filter((account, index) => index !== currentIndex),
|
||||
];
|
||||
|
||||
switch (selectedNetwork.namespace) {
|
||||
case EIP155:
|
||||
return {
|
||||
@ -175,7 +151,7 @@ export const getNamespaces = async (
|
||||
...(optionalNamespaces.eip155?.events ?? []),
|
||||
...(requiredNamespaces.eip155?.events ?? []),
|
||||
],
|
||||
accounts: sortedAccounts.map(ethAccount => {
|
||||
accounts: accounts.map(ethAccount => {
|
||||
return `${namespaceChainId}:${ethAccount.address}`;
|
||||
}),
|
||||
},
|
||||
@ -200,7 +176,7 @@ export const getNamespaces = async (
|
||||
...(optionalNamespaces.cosmos?.events ?? []),
|
||||
...(requiredNamespaces.cosmos?.events ?? []),
|
||||
],
|
||||
accounts: sortedAccounts.map(cosmosAccount => {
|
||||
accounts: accounts.map(cosmosAccount => {
|
||||
return `${namespaceChainId}:${cosmosAccount.address}`;
|
||||
}),
|
||||
},
|
||||
|
13
yarn.lock
13
yarn.lock
@ -752,10 +752,10 @@
|
||||
deepmerge "^3.2.0"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
|
||||
"@cerc-io/registry-sdk@^0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fregistry-sdk/-/0.2.2/registry-sdk-0.2.2.tgz#2e8a533f069b4bb9f4cd4798e783f52e29167d0d"
|
||||
integrity sha512-ocRMbWtdewOg02ORfK1U+qbTqB46anHP4ApXokGkY4d+mFSApR3sdUEi2geHcs8oh+SG8YAp7LUJ9AAJneNY8g==
|
||||
"@cerc-io/registry-sdk@^0.2.5":
|
||||
version "0.2.5"
|
||||
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fregistry-sdk/-/0.2.5/registry-sdk-0.2.5.tgz#9ca19fecb2923520dd6a19946c309ecb2ec780a2"
|
||||
integrity sha512-/KXAYf9gStaX/rRBMCEeDCexEIpTOFHeHzMK9B3xfCT+SyYZE9WC9GpX299LzBYJKKPsb0/JvnDfip9S1igJtA==
|
||||
dependencies:
|
||||
"@cosmjs/amino" "^0.28.1"
|
||||
"@cosmjs/crypto" "^0.28.1"
|
||||
@ -2071,6 +2071,11 @@
|
||||
dependencies:
|
||||
merge-options "^3.0.4"
|
||||
|
||||
"@react-native-clipboard/clipboard@^1.14.1":
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-clipboard/clipboard/-/clipboard-1.14.1.tgz#835f82fc86881a0808a8405f2576617bb5383554"
|
||||
integrity sha512-SM3el0A28SwoeJljVNhF217o0nI4E7RfalLmuRQcT1/7tGcxUjgFa3jyrEndYUct8/uxxK5EUNGUu1YEDqzxqw==
|
||||
|
||||
"@react-native-community/cli-clean@12.3.2":
|
||||
version "12.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-12.3.2.tgz#d4f1730c3d22d816b4d513d330d5f3896a3f5921"
|
||||
|
Loading…
Reference in New Issue
Block a user