import React, { useCallback } from 'react'; import { View } from 'react-native'; import { useForm, Controller, FieldErrors } from 'react-hook-form'; import { TextInput, Button, HelperText, Text } 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'; 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; const EditNetwork = ({ route }: EditNetworkProps) => { const { setNetworksData } = useNetworks(); const navigation = useNavigation>(); const networkData = route.params.selectedNetwork; const networksFormDataSchema = networkData.namespace === COSMOS ? cosmosNetworksFormDataSchema : ethNetworksFormSchema; const { control, formState: { errors, isSubmitting }, handleSubmit, } = useForm>({ mode: 'onChange', resolver: zodResolver(networksFormDataSchema), }); const submit = useCallback( async (data: z.infer) => { 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], ); return ( Edit {networkData?.networkName} details ( <> onChange(textValue)} /> {errors.networkName?.message} )} /> ( <> onChange(textValue)} /> {errors.rpcUrl?.message} )} /> ( <> onChange(textValue)} /> {errors.blockExplorerUrl?.message} )} /> {networkData.namespace === COSMOS && ( ( <> { ( errors as FieldErrors< z.infer > ).gasPrice?.message } )} /> )} ); }; export default EditNetwork;