forked from cerc-io/laconic-wallet
Handle incorrect RPC URL error and reject request (#112)
* Fix gas limit type for evm chains * Handle incorrect rpc url error * Fix edit network form not working for evm chains
This commit is contained in:
parent
db0b21ddd1
commit
b05b5894b0
@ -1,4 +1,12 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: '@react-native',
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
ignoreRestSiblings: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ const TxErrorDialog = ({
|
||||
return (
|
||||
<Portal>
|
||||
<Dialog visible={visible} onDismiss={hideDialog}>
|
||||
<Dialog.Title>Error sending transaction</Dialog.Title>
|
||||
<Dialog.Title>Transaction Error</Dialog.Title>
|
||||
<Dialog.Content>
|
||||
<Text variant="bodyMedium">{error}</Text>
|
||||
</Dialog.Content>
|
||||
|
@ -133,12 +133,17 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
requestedNetwork?.addressPrefix,
|
||||
);
|
||||
|
||||
try {
|
||||
const client = await SigningStargateClient.connectWithSigner(
|
||||
requestedNetwork?.rpcUrl!,
|
||||
sender,
|
||||
);
|
||||
|
||||
setCosmosStargateClient(client);
|
||||
} catch (error: any) {
|
||||
setTxError(error.message);
|
||||
setIsTxErrorDialogOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
setClient();
|
||||
@ -149,8 +154,16 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
if (!requestedNetwork) {
|
||||
throw new Error('Requested chain not supported');
|
||||
}
|
||||
try {
|
||||
const ethProvider = new providers.JsonRpcProvider(
|
||||
requestedNetwork.rpcUrl,
|
||||
);
|
||||
|
||||
return new providers.JsonRpcProvider(requestedNetwork.rpcUrl);
|
||||
return ethProvider;
|
||||
} catch (error: any) {
|
||||
setTxError(error.message);
|
||||
setIsTxErrorDialogOpen(true);
|
||||
}
|
||||
}
|
||||
}, [requestedNetwork, namespace]);
|
||||
|
||||
@ -202,7 +215,6 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
cosmosGasLimit,
|
||||
requestedNetwork,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
retrieveData(transaction.from!);
|
||||
}, [retrieveData, transaction]);
|
||||
@ -231,9 +243,10 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
],
|
||||
gas: cosmosGasLimit!,
|
||||
},
|
||||
ethGasLimit: transaction.gasLimit
|
||||
? String(transaction.gasLimit)
|
||||
: ethGasLimit,
|
||||
ethGasLimit:
|
||||
namespace === EIP155
|
||||
? BigNumber.from(transaction.gasLimit ?? ethGasLimit)
|
||||
: undefined,
|
||||
ethGasPrice: transaction.gasPrice
|
||||
? String(transaction.gasPrice)
|
||||
: ethGasPrice,
|
||||
@ -245,7 +258,7 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
await web3wallet!.respondSessionRequest({ topic, response });
|
||||
navigation.navigate('Laconic');
|
||||
} catch (error: any) {
|
||||
setTxError(String(error));
|
||||
setTxError(error.message);
|
||||
setIsTxErrorDialogOpen(true);
|
||||
}
|
||||
setIsTxLoading(false);
|
||||
@ -264,13 +277,15 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
|
||||
useEffect(() => {
|
||||
const getAccountBalance = async () => {
|
||||
try {
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
if (namespace === EIP155) {
|
||||
const fetchedBalance =
|
||||
provider && (await provider.getBalance(account.address));
|
||||
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
const fetchedBalance = await provider.getBalance(account.address);
|
||||
setBalance(fetchedBalance ? fetchedBalance.toString() : '0');
|
||||
} else {
|
||||
const cosmosBalance = await cosmosStargateClient?.getBalance(
|
||||
@ -280,6 +295,10 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
|
||||
setBalance(cosmosBalance?.amount!);
|
||||
}
|
||||
} catch (error: any) {
|
||||
setTxError(error.message);
|
||||
setIsTxErrorDialogOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
getAccountBalance();
|
||||
@ -311,6 +330,7 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
|
||||
useEffect(() => {
|
||||
const getEthGas = async () => {
|
||||
try {
|
||||
if (transaction.gasLimit && transaction.gasPrice) {
|
||||
return;
|
||||
}
|
||||
@ -339,13 +359,17 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
const gasLimit = await provider.estimateGas(transactionObject);
|
||||
|
||||
setEthGasLimit(String(gasLimit));
|
||||
} catch (error: any) {
|
||||
setTxError(error.message);
|
||||
setIsTxErrorDialogOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
getEthGas();
|
||||
}, [provider, transaction, isSufficientFunds]);
|
||||
|
||||
useEffect(() => {
|
||||
const getCosmosGas = async () => {
|
||||
try {
|
||||
if (!cosmosStargateClient) {
|
||||
return;
|
||||
}
|
||||
@ -364,8 +388,11 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
Math.round(gasEstimation * Number(Config.DEFAULT_GAS_ADJUSTMENT)),
|
||||
),
|
||||
);
|
||||
} catch (error: any) {
|
||||
setTxError(error.message);
|
||||
setIsTxErrorDialogOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
getCosmosGas();
|
||||
}, [cosmosStargateClient, isSufficientFunds, sendMsg, transaction]);
|
||||
|
||||
@ -479,7 +506,7 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
|
||||
visible={isTxErrorDialogOpen}
|
||||
hideDialog={() => {
|
||||
setIsTxErrorDialogOpen(false);
|
||||
if (!isSufficientFunds) {
|
||||
if (!isSufficientFunds || !balance || !fees) {
|
||||
rejectRequestHandler();
|
||||
navigation.navigate('Laconic');
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { ScrollView, View } from 'react-native';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { useForm, Controller, FieldErrors } from 'react-hook-form';
|
||||
import { TextInput, Button, HelperText, Text } from 'react-native-paper';
|
||||
import { setInternetCredentials } from 'react-native-keychain';
|
||||
import { z } from 'zod';
|
||||
@ -17,12 +17,25 @@ import styles from '../styles/stylesheet';
|
||||
import { retrieveNetworksData } from '../utils/accounts';
|
||||
import { useNetworks } from '../context/NetworksContext';
|
||||
import {
|
||||
COSMOS,
|
||||
EIP155,
|
||||
EMPTY_FIELD_ERROR,
|
||||
INVALID_URL_ERROR,
|
||||
} from '../utils/constants';
|
||||
|
||||
const networksFormDataSchema = z.object({
|
||||
const ethNetworksFormSchema = z.object({
|
||||
// Adding type field for resolving typescript error
|
||||
type: z.literal(EIP155).optional(),
|
||||
networkName: z.string().nonempty({ message: EMPTY_FIELD_ERROR }),
|
||||
rpcUrl: z.string().url({ message: INVALID_URL_ERROR }),
|
||||
blockExplorerUrl: z
|
||||
.string()
|
||||
.url({ message: INVALID_URL_ERROR })
|
||||
.or(z.literal('')),
|
||||
});
|
||||
|
||||
const cosmosNetworksFormDataSchema = z.object({
|
||||
type: z.literal(COSMOS).optional(),
|
||||
networkName: z.string().nonempty({ message: EMPTY_FIELD_ERROR }),
|
||||
rpcUrl: z.string().url({ message: INVALID_URL_ERROR }),
|
||||
blockExplorerUrl: z
|
||||
@ -42,6 +55,13 @@ const EditNetwork = ({ route }: EditNetworkProps) => {
|
||||
const navigation =
|
||||
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
||||
|
||||
const networkData = route.params.selectedNetwork;
|
||||
|
||||
const networksFormDataSchema =
|
||||
networkData.namespace === COSMOS
|
||||
? cosmosNetworksFormDataSchema
|
||||
: ethNetworksFormSchema;
|
||||
|
||||
const {
|
||||
control,
|
||||
formState: { errors, isSubmitting },
|
||||
@ -50,13 +70,12 @@ const EditNetwork = ({ route }: EditNetworkProps) => {
|
||||
mode: 'onChange',
|
||||
resolver: zodResolver(networksFormDataSchema),
|
||||
});
|
||||
const networkData = route.params.selectedNetwork;
|
||||
|
||||
const submit = useCallback(
|
||||
async (data: z.infer<typeof networksFormDataSchema>) => {
|
||||
const retrievedNetworksData = await retrieveNetworksData();
|
||||
|
||||
const newNetworkData = { ...networkData, ...data };
|
||||
const { type, ...dataWithoutType } = data;
|
||||
const newNetworkData = { ...networkData, ...dataWithoutType };
|
||||
const index = retrievedNetworksData.findIndex(
|
||||
network => network.networkId === networkData.networkId,
|
||||
);
|
||||
@ -137,7 +156,7 @@ const EditNetwork = ({ route }: EditNetworkProps) => {
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
{networkData.namespace !== EIP155 ? (
|
||||
{networkData.namespace === COSMOS && (
|
||||
<Controller
|
||||
control={control}
|
||||
name="gasPrice"
|
||||
@ -151,11 +170,19 @@ const EditNetwork = ({ route }: EditNetworkProps) => {
|
||||
onBlur={onBlur}
|
||||
onChangeText={onChange}
|
||||
/>
|
||||
<HelperText type="error">{errors.gasPrice?.message}</HelperText>
|
||||
<HelperText type="error">
|
||||
{
|
||||
(
|
||||
errors as FieldErrors<
|
||||
z.infer<typeof cosmosNetworksFormDataSchema>
|
||||
>
|
||||
).gasPrice?.message
|
||||
}
|
||||
</HelperText>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
) : null}
|
||||
)}
|
||||
<Button
|
||||
mode="contained"
|
||||
loading={isSubmitting}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Taken from https://medium.com/walletconnect/how-to-build-a-wallet-in-react-native-with-the-web3wallet-sdk-b6f57bf02f9a
|
||||
import { Wallet, providers } from 'ethers';
|
||||
import { BigNumber, Wallet, providers } from 'ethers';
|
||||
|
||||
import { formatJsonRpcError, formatJsonRpcResult } from '@json-rpc-tools/utils';
|
||||
import { SignClientTypes } from '@walletconnect/types';
|
||||
@ -36,7 +36,7 @@ export async function approveWalletConnectRequest({
|
||||
message?: string;
|
||||
provider?: providers.JsonRpcProvider | SigningStargateClient;
|
||||
cosmosFee?: StdFee;
|
||||
ethGasLimit?: string;
|
||||
ethGasLimit?: BigNumber;
|
||||
ethGasPrice?: string;
|
||||
sendMsg?: MsgSendEncodeObject;
|
||||
memo?: string;
|
||||
|
Loading…
Reference in New Issue
Block a user