229 lines
7.2 KiB
TypeScript
229 lines
7.2 KiB
TypeScript
import React, { useCallback } from "react";
|
|
import { useForm, Controller, FieldErrors } from "react-hook-form";
|
|
import { TextInput, HelperText } from "react-native-paper";
|
|
import { z } from "zod";
|
|
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import {
|
|
NativeStackNavigationProp,
|
|
NativeStackScreenProps,
|
|
} from "@react-navigation/native-stack";
|
|
import { useNavigation } from "@react-navigation/native";
|
|
|
|
import { setInternetCredentials } from "../utils/key-store";
|
|
import { StackParamsList } from "../types";
|
|
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";
|
|
import { Container } from "../components/Container";
|
|
import { Button, Divider, Grid, Typography } from "@mui/material";
|
|
import { LoadingButton } from "@mui/lab";
|
|
import { ArrowBack } from "@mui/icons-material";
|
|
|
|
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
|
|
.string()
|
|
.url({ message: INVALID_URL_ERROR })
|
|
.or(z.literal("")),
|
|
gasPrice: z
|
|
.string()
|
|
.nonempty({ message: EMPTY_FIELD_ERROR })
|
|
.regex(/^\d+(\.\d+)?$/),
|
|
});
|
|
|
|
type EditNetworkProps = NativeStackScreenProps<StackParamsList, "EditNetwork">;
|
|
|
|
const EditNetwork = ({ route }: EditNetworkProps) => {
|
|
const { setNetworksData } = useNetworks();
|
|
const navigation =
|
|
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
|
|
|
const networkData = route.params.selectedNetwork;
|
|
|
|
const networksFormDataSchema =
|
|
networkData.namespace === COSMOS
|
|
? cosmosNetworksFormDataSchema
|
|
: ethNetworksFormSchema;
|
|
|
|
const {
|
|
control,
|
|
formState: { errors, isSubmitting },
|
|
handleSubmit,
|
|
} = useForm<z.infer<typeof networksFormDataSchema>>({
|
|
mode: "onChange",
|
|
resolver: zodResolver(networksFormDataSchema),
|
|
});
|
|
|
|
const submit = useCallback(
|
|
async (data: z.infer<typeof networksFormDataSchema>) => {
|
|
const retrievedNetworksData = await retrieveNetworksData();
|
|
const { type, ...dataWithoutType } = data;
|
|
const newNetworkData = { ...networkData, ...dataWithoutType };
|
|
const index = retrievedNetworksData.findIndex(
|
|
(network) => network.networkId === networkData.networkId,
|
|
);
|
|
|
|
retrievedNetworksData.splice(index, 1, newNetworkData);
|
|
|
|
await setInternetCredentials(
|
|
"networks",
|
|
"_",
|
|
JSON.stringify(retrievedNetworksData),
|
|
);
|
|
|
|
setNetworksData(retrievedNetworksData);
|
|
|
|
navigation.navigate("Home");
|
|
},
|
|
[networkData, navigation, setNetworksData],
|
|
);
|
|
const isCosmos = networkData.namespace === COSMOS;
|
|
|
|
return (
|
|
<Container boxProps={{ sx: { backgroundColor: "inherit" } }}>
|
|
<Button
|
|
startIcon={<ArrowBack />}
|
|
color="info"
|
|
sx={{ mb: 4 }}
|
|
onClick={() => navigation.navigate("Home")}
|
|
>
|
|
Home
|
|
</Button>
|
|
<Typography variant="h4" sx={{ mb: 4 }}>
|
|
Edit Network
|
|
</Typography>
|
|
<Container>
|
|
<Typography fontSize="1.5rem" fontWeight={500}>
|
|
Edit {networkData?.networkName} details
|
|
</Typography>
|
|
<Divider flexItem sx={{ my: 4 }} />
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={6}>
|
|
<Controller
|
|
control={control}
|
|
defaultValue={networkData.networkName}
|
|
name="networkName"
|
|
render={({ field: { onChange, onBlur, value } }) => (
|
|
<>
|
|
<TextInput
|
|
mode="outlined"
|
|
label="Network Name"
|
|
value={value}
|
|
onBlur={onBlur}
|
|
onChangeText={(textValue) => onChange(textValue)}
|
|
/>
|
|
<HelperText type="error">
|
|
{errors.networkName?.message}
|
|
</HelperText>
|
|
</>
|
|
)}
|
|
/>
|
|
</Grid>
|
|
<Grid item xs={6}>
|
|
<Controller
|
|
control={control}
|
|
name="rpcUrl"
|
|
defaultValue={networkData.rpcUrl}
|
|
render={({ field: { onChange, onBlur, value } }) => (
|
|
<>
|
|
<TextInput
|
|
mode="outlined"
|
|
label="New RPC URL"
|
|
onBlur={onBlur}
|
|
value={value}
|
|
onChangeText={(textValue) => onChange(textValue)}
|
|
/>
|
|
<HelperText type="error">{errors.rpcUrl?.message}</HelperText>
|
|
</>
|
|
)}
|
|
/>
|
|
</Grid>
|
|
|
|
<Grid item xs={isCosmos ? 6 : 12}>
|
|
<Controller
|
|
control={control}
|
|
defaultValue={networkData.blockExplorerUrl}
|
|
name="blockExplorerUrl"
|
|
render={({ field: { onChange, onBlur, value } }) => (
|
|
<>
|
|
<TextInput
|
|
mode="outlined"
|
|
value={value}
|
|
label="Block Explorer URL (Optional)"
|
|
onBlur={onBlur}
|
|
onChangeText={(textValue) => onChange(textValue)}
|
|
/>
|
|
<HelperText type="error">
|
|
{errors.blockExplorerUrl?.message}
|
|
</HelperText>
|
|
</>
|
|
)}
|
|
/>
|
|
</Grid>
|
|
{isCosmos && (
|
|
<Grid item xs={6}>
|
|
<Controller
|
|
control={control}
|
|
name="gasPrice"
|
|
defaultValue={networkData.gasPrice}
|
|
render={({ field: { onChange, onBlur, value } }) => (
|
|
<>
|
|
<TextInput
|
|
mode="outlined"
|
|
value={value}
|
|
label="Gas Price"
|
|
onBlur={onBlur}
|
|
onChangeText={onChange}
|
|
/>
|
|
<HelperText type="error">
|
|
{
|
|
(
|
|
errors as FieldErrors<
|
|
z.infer<typeof cosmosNetworksFormDataSchema>
|
|
>
|
|
).gasPrice?.message
|
|
}
|
|
</HelperText>
|
|
</>
|
|
)}
|
|
/>
|
|
</Grid>
|
|
)}
|
|
</Grid>
|
|
<LoadingButton
|
|
variant="contained"
|
|
loading={isSubmitting}
|
|
disabled={isSubmitting}
|
|
style={styles.networksButton}
|
|
onClick={handleSubmit(submit)}
|
|
sx={{ minWidth: "200px", px: 4, py: 1 }}
|
|
>
|
|
{isSubmitting ? "Adding" : "Submit"}
|
|
</LoadingButton>
|
|
</Container>
|
|
</Container>
|
|
);
|
|
};
|
|
|
|
export default EditNetwork;
|