Create hook to add network
This commit is contained in:
parent
fe3d2411a2
commit
8d60fd9e4b
@ -45,6 +45,7 @@ import SignRequestEmbed from "./screens/SignRequestEmbed";
|
||||
import useAddAccountEmbed from "./hooks/useAddAccountEmbed";
|
||||
import useExportPKEmbed from "./hooks/useExportPrivateKeyEmbed";
|
||||
import { SignTxEmbed } from "./screens/SignTxEmbed";
|
||||
import useAddNetworkEmbed from "./hooks/useAddNetworkEmbed";
|
||||
|
||||
const Stack = createStackNavigator<StackParamsList>();
|
||||
|
||||
@ -287,6 +288,7 @@ const App = (): React.JSX.Element => {
|
||||
useWebViewHandler();
|
||||
useAddAccountEmbed();
|
||||
useExportPKEmbed();
|
||||
useAddNetworkEmbed();
|
||||
|
||||
return (
|
||||
<Surface style={styles.appSurface}>
|
||||
|
39
src/hooks/useAddNetworkEmbed.ts
Normal file
39
src/hooks/useAddNetworkEmbed.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { addNewNetwork } from '../utils/accounts';
|
||||
import { ADD_NETWORK } from '../utils/constants';
|
||||
|
||||
const REACT_APP_ALLOWED_URLS = import.meta.env.REACT_APP_ALLOWED_URLS;
|
||||
|
||||
const useAddNetworkEmbed = () => {
|
||||
useEffect(() => {
|
||||
const handleAddNetwork = async (event: MessageEvent) => {
|
||||
if (event.data.type !== ADD_NETWORK) return;
|
||||
|
||||
if (!REACT_APP_ALLOWED_URLS) {
|
||||
console.log('Allowed URLs are not set');
|
||||
return;
|
||||
}
|
||||
|
||||
const allowedUrls = REACT_APP_ALLOWED_URLS.split(',').map(url => url.trim());
|
||||
|
||||
if (!allowedUrls.includes(event.origin)) {
|
||||
console.log('Unauthorized app.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { networkData } = event.data;
|
||||
await addNewNetwork(networkData);
|
||||
} catch (err) {
|
||||
console.error('Error preparing sign request:', err);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', handleAddNetwork);
|
||||
return () => window.removeEventListener('message', handleAddNetwork);
|
||||
}, []);
|
||||
|
||||
}
|
||||
|
||||
export default useAddNetworkEmbed;
|
@ -1,8 +1,6 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { useForm, Controller, useWatch, FieldErrors } from "react-hook-form";
|
||||
import { TextInput, HelperText } from "react-native-paper";
|
||||
|
||||
import { HDNode } from "ethers/lib/utils";
|
||||
import { chains } from "chain-registry";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import { z } from "zod";
|
||||
@ -10,27 +8,21 @@ import { z } from "zod";
|
||||
import { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Divider, Grid } from "@mui/material";
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
|
||||
import { StackParamsList } from "../types";
|
||||
import { SelectNetworkType } from "../components/SelectNetworkType";
|
||||
import { addAccountsForNetwork, getNextAccountId, storeNetworkData } from "../utils/accounts";
|
||||
import { addAccountsForNetwork, addNewNetwork, getNextAccountId, storeNetworkData } from "../utils/accounts";
|
||||
import { useNetworks } from "../context/NetworksContext";
|
||||
import {
|
||||
COSMOS,
|
||||
EIP155,
|
||||
CHAINID_DEBOUNCE_DELAY,
|
||||
EMPTY_FIELD_ERROR,
|
||||
INVALID_URL_ERROR,
|
||||
IS_NUMBER_REGEX,
|
||||
} from "../utils/constants";
|
||||
import { getCosmosAccountByHDPath } from "../utils/accounts";
|
||||
import ETH_CHAINS from "../assets/ethereum-chains.json";
|
||||
import {
|
||||
getInternetCredentials,
|
||||
setInternetCredentials,
|
||||
} from "../utils/key-store";
|
||||
import { Divider, Grid } from "@mui/material";
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
import { Layout } from "../components/Layout";
|
||||
|
||||
const ethNetworkDataSchema = z.object({
|
||||
@ -143,42 +135,8 @@ const AddNetwork = () => {
|
||||
isDefault: false,
|
||||
};
|
||||
|
||||
const mnemonicServer = await getInternetCredentials("mnemonicServer");
|
||||
const mnemonic = mnemonicServer;
|
||||
const retrievedNetworksData = await addNewNetwork(newNetworkData);
|
||||
|
||||
if (!mnemonic) {
|
||||
throw new Error("Mnemonic not found");
|
||||
}
|
||||
|
||||
const hdNode = HDNode.fromMnemonic(mnemonic);
|
||||
|
||||
const hdPath = `m/44'/${newNetworkData.coinType}'/0'/0/0`;
|
||||
const node = hdNode.derivePath(hdPath);
|
||||
let address;
|
||||
|
||||
switch (newNetworkData.namespace) {
|
||||
case EIP155:
|
||||
address = node.address;
|
||||
break;
|
||||
|
||||
case COSMOS:
|
||||
address = (
|
||||
await getCosmosAccountByHDPath(
|
||||
mnemonic,
|
||||
hdPath,
|
||||
(newNetworkData as z.infer<typeof cosmosNetworkDataSchema>)
|
||||
.addressPrefix,
|
||||
)
|
||||
).data.address;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Unsupported namespace");
|
||||
}
|
||||
|
||||
const accountInfo = `${hdPath},${node.privateKey},${node.publicKey},${address}`;
|
||||
|
||||
const retrievedNetworksData = await storeNetworkData(newNetworkData);
|
||||
setNetworksData(retrievedNetworksData);
|
||||
|
||||
// Get number of accounts in first network
|
||||
@ -190,24 +148,6 @@ const AddNetwork = () => {
|
||||
(network) => network.chainId === newNetworkData.chainId,
|
||||
);
|
||||
|
||||
await Promise.all([
|
||||
setInternetCredentials(
|
||||
`accounts/${newNetworkData.namespace}:${newNetworkData.chainId}/0`,
|
||||
"_",
|
||||
accountInfo,
|
||||
),
|
||||
setInternetCredentials(
|
||||
`addAccountCounter/${newNetworkData.namespace}:${newNetworkData.chainId}`,
|
||||
"_",
|
||||
"1",
|
||||
),
|
||||
setInternetCredentials(
|
||||
`accountIndices/${newNetworkData.namespace}:${newNetworkData.chainId}`,
|
||||
"_",
|
||||
"0",
|
||||
),
|
||||
]);
|
||||
|
||||
await addAccountsForNetwork(selectedNetwork!, nextAccountId - 1);
|
||||
|
||||
navigation.navigate("Home");
|
||||
|
@ -160,6 +160,66 @@ const addAccountFromHDPath = async (
|
||||
}
|
||||
};
|
||||
|
||||
const addNewNetwork = async (
|
||||
newNetworkData: NetworksFormData
|
||||
): Promise<NetworksDataState[]> => {
|
||||
const mnemonicServer = await getInternetCredentials("mnemonicServer");
|
||||
const mnemonic = mnemonicServer;
|
||||
|
||||
if (!mnemonic) {
|
||||
throw new Error("Mnemonic not found");
|
||||
}
|
||||
|
||||
const hdNode = HDNode.fromMnemonic(mnemonic);
|
||||
|
||||
const hdPath = `m/44'/${newNetworkData.coinType}'/0'/0/0`;
|
||||
const node = hdNode.derivePath(hdPath);
|
||||
let address;
|
||||
|
||||
switch (newNetworkData.namespace) {
|
||||
case EIP155:
|
||||
address = node.address;
|
||||
break;
|
||||
|
||||
case COSMOS:
|
||||
address = (
|
||||
await getCosmosAccountByHDPath(
|
||||
mnemonic,
|
||||
hdPath,
|
||||
newNetworkData.addressPrefix,
|
||||
)
|
||||
).data.address;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Unsupported namespace");
|
||||
}
|
||||
|
||||
const accountInfo = `${hdPath},${node.privateKey},${node.publicKey},${address}`;
|
||||
|
||||
await Promise.all([
|
||||
setInternetCredentials(
|
||||
`accounts/${newNetworkData.namespace}:${newNetworkData.chainId}/0`,
|
||||
"_",
|
||||
accountInfo,
|
||||
),
|
||||
setInternetCredentials(
|
||||
`addAccountCounter/${newNetworkData.namespace}:${newNetworkData.chainId}`,
|
||||
"_",
|
||||
"1",
|
||||
),
|
||||
setInternetCredentials(
|
||||
`accountIndices/${newNetworkData.namespace}:${newNetworkData.chainId}`,
|
||||
"_",
|
||||
"0",
|
||||
),
|
||||
]);
|
||||
|
||||
const retrievedNetworksData = await storeNetworkData(newNetworkData);
|
||||
|
||||
return retrievedNetworksData;
|
||||
}
|
||||
|
||||
const storeNetworkData = async (
|
||||
networkData: NetworksFormData,
|
||||
): Promise<NetworksDataState[]> => {
|
||||
@ -180,11 +240,13 @@ const storeNetworkData = async (
|
||||
networkId: String(networkId),
|
||||
},
|
||||
];
|
||||
|
||||
await setInternetCredentials(
|
||||
'networks',
|
||||
'_',
|
||||
JSON.stringify(updatedNetworks),
|
||||
);
|
||||
|
||||
return updatedNetworks;
|
||||
};
|
||||
|
||||
@ -194,7 +256,9 @@ const retrieveNetworksData = async (): Promise<NetworksDataState[]> => {
|
||||
if(!networks){
|
||||
return [];
|
||||
}
|
||||
|
||||
const parsedNetworks: NetworksDataState[] = JSON.parse(networks);
|
||||
|
||||
return parsedNetworks;
|
||||
};
|
||||
|
||||
@ -217,6 +281,7 @@ export const retrieveAccountsForNetwork = async (
|
||||
address,
|
||||
hdPath: path,
|
||||
};
|
||||
|
||||
return account;
|
||||
}),
|
||||
);
|
||||
@ -234,6 +299,7 @@ const retrieveAccounts = async (
|
||||
if (!accountIndices) {
|
||||
return;
|
||||
}
|
||||
|
||||
const loadedAccounts = await retrieveAccountsForNetwork(
|
||||
`${currentNetworkData.namespace}:${currentNetworkData.chainId}`,
|
||||
accountIndices,
|
||||
@ -382,4 +448,5 @@ export {
|
||||
getNextAccountId,
|
||||
updateAccountCounter,
|
||||
getCosmosAccountByHDPath,
|
||||
addNewNetwork
|
||||
};
|
||||
|
@ -98,6 +98,7 @@ export const REQUEST_ACCOUNT_PK = 'REQUEST_ACCOUNT_PK';
|
||||
export const REQUEST_ADD_ACCOUNT = 'REQUEST_ADD_ACCOUNT';
|
||||
export const AUTO_SIGN_IN = 'AUTO_SIGN_IN';
|
||||
export const CHECK_BALANCE = 'CHECK_BALANCE';
|
||||
export const ADD_NETWORK = 'ADD_NETWORK';
|
||||
|
||||
// iframe response types
|
||||
export const COSMOS_ACCOUNTS_RESPONSE = 'COSMOS_ACCOUNTS_RESPONSE';
|
||||
|
Loading…
Reference in New Issue
Block a user