Compare commits
17 Commits
ec3617ad42
...
7f44fc1cf0
Author | SHA1 | Date | |
---|---|---|---|
7f44fc1cf0 | |||
e4b9e32a09 | |||
43305a8d2f | |||
|
17e96d0e52 | ||
1686eca519 | |||
|
0b32e4b4c4 | ||
1907d2326a | |||
|
2f19af25a7 | ||
|
af9b10341c | ||
|
72d9bd453f | ||
|
190e0e6b14 | ||
b6cd5deddd | |||
1e0a0e66cc | |||
cc2e608bc4 | |||
f035129537 | |||
|
18f66c53b2 | ||
0a6fc415ea |
@ -1,18 +0,0 @@
|
||||
const config = {
|
||||
arrowParens: "always",
|
||||
printWidth: 80,
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
tabWidth: 2,
|
||||
trailingComma: "es5",
|
||||
importOrderSeparation: true,
|
||||
importOrderSortSpecifiers: true,
|
||||
plugins: ["@trivago/prettier-plugin-sort-imports"],
|
||||
importOrder: [
|
||||
"<THIRD_PARTY_MODULES>",
|
||||
"^(pages|components|utils|icons|test|graphql)/(.*)$",
|
||||
"^[./]",
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import React from "react";
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
|
||||
import { CreateWalletProps } from "../types";
|
||||
|
@ -1,66 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { Dialog, DialogActions, DialogContent, DialogTitle, TextField, Grid, Button, Typography } from "@mui/material";
|
||||
|
||||
const ImportWalletDialog = ({
|
||||
visible,
|
||||
hideDialog,
|
||||
importWalletHandler
|
||||
}: {
|
||||
visible: boolean;
|
||||
hideDialog: () => void;
|
||||
importWalletHandler: (recoveryPhrase: string) => Promise<void>;
|
||||
}) => {
|
||||
const [words, setWords] = useState(Array(12).fill(''));
|
||||
|
||||
const handleWordChange = (index: number, value: string) => {
|
||||
const newWords = [...words];
|
||||
newWords[index] = value;
|
||||
setWords(newWords);
|
||||
};
|
||||
|
||||
const handlePaste = (event: React.ClipboardEvent<HTMLDivElement>) => {
|
||||
const pastedText = event.clipboardData.getData('Text');
|
||||
const splitWords = pastedText.trim().split(/\s+/);
|
||||
|
||||
if (splitWords.length === 12) {
|
||||
setWords(splitWords);
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setWords(Array(12).fill(''));
|
||||
},[visible]);
|
||||
|
||||
return (
|
||||
<Dialog open={visible} onClose={hideDialog}>
|
||||
<DialogTitle>Import your wallet from your mnemonic</DialogTitle>
|
||||
<DialogContent>
|
||||
<Typography>
|
||||
(You can paste your entire mnemonic into the first textbox)
|
||||
</Typography>
|
||||
<Grid container spacing={2}>
|
||||
{words.map((word, index) => (
|
||||
<Grid item xs={6} sm={4} key={index}>
|
||||
<TextField
|
||||
value={word}
|
||||
onChange={(e) => handleWordChange(index, e.target.value)}
|
||||
onPaste={index === 0 ? handlePaste : undefined}
|
||||
placeholder={`Word ${index + 1}`}
|
||||
fullWidth
|
||||
margin="normal"
|
||||
/>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => importWalletHandler(words.join(' '))}>Import Wallet</Button>
|
||||
<Button onClick={hideDialog}>Cancel</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImportWalletDialog;
|
@ -1,51 +0,0 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
Button,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
|
||||
import styles from "../styles/stylesheet";
|
||||
import GridView from "./Grid";
|
||||
import { CustomDialogProps } from "../types";
|
||||
|
||||
const MnemonicDialog = ({
|
||||
visible,
|
||||
hideDialog,
|
||||
contentText,
|
||||
}: CustomDialogProps) => {
|
||||
const words = contentText.split(" ");
|
||||
|
||||
const copyMnemonic = () => {
|
||||
navigator.clipboard.writeText(contentText);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={visible} onClose={hideDialog}>
|
||||
<DialogTitle style={{ ...styles.mnemonicTitle }}>Mnemonic</DialogTitle>
|
||||
<DialogContent style={{ ...styles.mnemonicContainer }}>
|
||||
<Typography component="div">
|
||||
Your mnemonic provides full access to your wallet and funds. <br />
|
||||
Make sure to note it down.
|
||||
</Typography>
|
||||
<Typography component="div" style={{ ...styles.mnomonicDialogWarning }}>
|
||||
Do not share your mnemonic with anyone
|
||||
</Typography>
|
||||
<GridView words={words} />
|
||||
</DialogContent>
|
||||
<DialogActions style={{ ...styles.mnemonicButtonRow }}>
|
||||
<Button style={{ ...styles.mnemonicButton }} onClick={copyMnemonic}>
|
||||
Copy
|
||||
</Button>
|
||||
<Button style={{ ...styles.mnemonicButton }} onClick={hideDialog}>
|
||||
Done
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export { MnemonicDialog };
|
@ -1,14 +1,13 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Image, ScrollView, View } from 'react-native';
|
||||
import { Button, Text, TextInput } from 'react-native-paper';
|
||||
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, EncodeObject } from '@cosmjs/proto-signing';
|
||||
import { DirectSecp256k1Wallet } from '@cosmjs/proto-signing';
|
||||
import { LaconicClient } from '@cerc-io/registry-sdk';
|
||||
import { GasPrice, calculateFee } from '@cosmjs/stargate';
|
||||
import { formatJsonRpcError } from '@json-rpc-tools/utils';
|
||||
@ -41,6 +40,7 @@ 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;
|
||||
@ -67,20 +67,6 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
|
||||
const { web3wallet } = useWalletConnect();
|
||||
|
||||
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;
|
||||
@ -152,7 +138,7 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
return;
|
||||
}
|
||||
const gasEstimation = await cosmosStargateClient!.simulate(
|
||||
signer,
|
||||
transactionMessage.value.participant!,
|
||||
[transactionMessage],
|
||||
MEMO,
|
||||
);
|
||||
@ -174,7 +160,7 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
}
|
||||
};
|
||||
getCosmosGas();
|
||||
}, [cosmosStargateClient, transactionMessage, requestEventId, topic, web3wallet, signer]);
|
||||
}, [cosmosStargateClient, transactionMessage, requestEventId, topic, web3wallet]);
|
||||
|
||||
useEffect(() => {
|
||||
const gasPrice = GasPrice.fromString(
|
||||
@ -253,13 +239,6 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
navigation.navigate('Home');
|
||||
};
|
||||
|
||||
const replacer = (key: string, value: any): any => {
|
||||
if (value instanceof Uint8Array) {
|
||||
return Buffer.from(value).toString('hex');
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ScrollView contentContainerStyle={styles.approveTransaction}>
|
||||
@ -285,7 +264,7 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => {
|
||||
</Text>
|
||||
<View style={styles.messageBody}>
|
||||
<Text variant="bodyLarge">
|
||||
{JSON.stringify(transactionMessage, replacer, 2)}
|
||||
{JSON.stringify(transactionMessage, null, 2)}
|
||||
</Text>
|
||||
</View>
|
||||
<>
|
||||
|
@ -1,13 +1,14 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { View, ActivityIndicator, Image } from "react-native";
|
||||
import { Text } from "react-native-paper";
|
||||
import { Button, Divider, Portal, Snackbar } from "@mui/material";
|
||||
import { Button, Divider } from "@mui/material";
|
||||
|
||||
import { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { getSdkError } from "@walletconnect/utils";
|
||||
|
||||
import { createWallet, resetWallet, retrieveAccounts } from "../utils/accounts";
|
||||
import { DialogComponent } from "../components/Dialog";
|
||||
import { NetworkDropdown } from "../components/NetworkDropdown";
|
||||
import Accounts from "../components/Accounts";
|
||||
import CreateWallet from "../components/CreateWallet";
|
||||
@ -17,8 +18,6 @@ import { useAccounts } from "../context/AccountsContext";
|
||||
import { useWalletConnect } from "../context/WalletConnectContext";
|
||||
import { NetworksDataState, StackParamsList } from "../types";
|
||||
import { useNetworks } from "../context/NetworksContext";
|
||||
import ImportWalletDialog from "../components/ImportWalletDialog";
|
||||
import { MnemonicDialog } from "../components/MnemonicDialog";
|
||||
import { Container } from "../components/Container";
|
||||
|
||||
const WCLogo = () => {
|
||||
@ -58,15 +57,12 @@ const HomeScreen = () => {
|
||||
|
||||
const [isWalletCreated, setIsWalletCreated] = useState<boolean>(false);
|
||||
const [isWalletCreating, setIsWalletCreating] = useState<boolean>(false);
|
||||
const [importWalletDialog, setImportWalletDialog] = useState<boolean>(false);
|
||||
const [mnemonicDialog, setMnemonicDialog] = useState<boolean>(false);
|
||||
const [walletDialog, setWalletDialog] = useState<boolean>(false);
|
||||
const [resetWalletDialog, setResetWalletDialog] = useState<boolean>(false);
|
||||
const [toastVisible, setToastVisible] = useState(false);
|
||||
const [invalidMnemonicError, setInvalidMnemonicError] = useState("");
|
||||
const [isAccountsFetched, setIsAccountsFetched] = useState<boolean>(true);
|
||||
const [phrase, setPhrase] = useState("");
|
||||
|
||||
const hideMnemonicDialog = () => setMnemonicDialog(false);
|
||||
const hideWalletDialog = () => setWalletDialog(false);
|
||||
const hideResetDialog = () => setResetWalletDialog(false);
|
||||
|
||||
const fetchAccounts = useCallback(async () => {
|
||||
@ -89,27 +85,12 @@ const HomeScreen = () => {
|
||||
const mnemonic = await createWallet(networksData);
|
||||
if (mnemonic) {
|
||||
fetchAccounts();
|
||||
setMnemonicDialog(true);
|
||||
setWalletDialog(true);
|
||||
setPhrase(mnemonic);
|
||||
setSelectedNetwork(networksData[0]);
|
||||
}
|
||||
};
|
||||
|
||||
const importWalletHandler = async (recoveryPhrase: string) => {
|
||||
try {
|
||||
const mnemonic = await createWallet(networksData, recoveryPhrase);
|
||||
if (mnemonic) {
|
||||
fetchAccounts();
|
||||
setPhrase(mnemonic);
|
||||
setSelectedNetwork(networksData[0]);
|
||||
setImportWalletDialog(false);
|
||||
}
|
||||
} catch (error: any) {
|
||||
setInvalidMnemonicError((error.message as string).toUpperCase());
|
||||
setToastVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
const confirmResetWallet = useCallback(async () => {
|
||||
setIsWalletCreated(false);
|
||||
setIsWalletCreating(false);
|
||||
@ -173,29 +154,14 @@ const HomeScreen = () => {
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<CreateWallet
|
||||
isWalletCreating={isWalletCreating}
|
||||
createWalletHandler={createWalletHandler}
|
||||
/>
|
||||
<View style={styles.createWalletContainer}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => setImportWalletDialog(true)}
|
||||
>
|
||||
Import Wallet
|
||||
</Button>
|
||||
</View>
|
||||
</>
|
||||
<CreateWallet
|
||||
isWalletCreating={isWalletCreating}
|
||||
createWalletHandler={createWalletHandler}
|
||||
/>
|
||||
)}
|
||||
<ImportWalletDialog
|
||||
visible={importWalletDialog}
|
||||
hideDialog={() => setImportWalletDialog(false)}
|
||||
importWalletHandler={importWalletHandler}
|
||||
/>
|
||||
<MnemonicDialog
|
||||
visible={mnemonicDialog}
|
||||
hideDialog={hideMnemonicDialog}
|
||||
<DialogComponent
|
||||
visible={walletDialog}
|
||||
hideDialog={hideWalletDialog}
|
||||
contentText={phrase}
|
||||
/>
|
||||
<ConfirmDialog
|
||||
@ -205,16 +171,6 @@ const HomeScreen = () => {
|
||||
onConfirm={confirmResetWallet}
|
||||
/>
|
||||
</Container>
|
||||
<Portal>
|
||||
<Snackbar
|
||||
open={toastVisible}
|
||||
autoHideDuration={3000}
|
||||
message={invalidMnemonicError}
|
||||
onClose={() => setToastVisible(false)}
|
||||
anchorOrigin={{ horizontal: "center", vertical: "bottom" }}
|
||||
ContentProps={{ style: { backgroundColor: "red", color: "white" } }}
|
||||
/>
|
||||
</Portal>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
@ -4,7 +4,7 @@ const styles = StyleSheet.create({
|
||||
createWalletContainer: {
|
||||
marginTop: 20,
|
||||
alignSelf: 'center',
|
||||
marginBottom: 30,
|
||||
marginBottom: 40
|
||||
},
|
||||
signLink: {
|
||||
alignItems: 'flex-end',
|
||||
|
@ -27,23 +27,12 @@ import { COSMOS, EIP155 } from './constants';
|
||||
|
||||
const createWallet = async (
|
||||
networksData: NetworksDataState[],
|
||||
recoveryPhrase?: string,
|
||||
): Promise<string> => {
|
||||
const mnemonic = recoveryPhrase ? recoveryPhrase : utils.entropyToMnemonic(utils.randomBytes(16));
|
||||
|
||||
const hdNode = HDNode.fromMnemonic(mnemonic);
|
||||
const mnemonic = utils.entropyToMnemonic(utils.randomBytes(16));
|
||||
await setInternetCredentials('mnemonicServer', 'mnemonic', mnemonic);
|
||||
|
||||
await createWalletFromMnemonic(networksData, hdNode, mnemonic);
|
||||
const hdNode = HDNode.fromMnemonic(mnemonic);
|
||||
|
||||
return mnemonic;
|
||||
};
|
||||
|
||||
const createWalletFromMnemonic = async (
|
||||
networksData: NetworksDataState[],
|
||||
hdNode: HDNode,
|
||||
mnemonic: string
|
||||
): Promise<void> => {
|
||||
for (const network of networksData) {
|
||||
const hdPath = `m/44'/${network.coinType}'/0'/0/0`;
|
||||
const node = hdNode.derivePath(hdPath);
|
||||
@ -84,6 +73,8 @@ const createWalletFromMnemonic = async (
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
return mnemonic;
|
||||
};
|
||||
|
||||
const addAccount = async (
|
||||
|
@ -46,5 +46,3 @@ export const EMPTY_FIELD_ERROR = 'Field cannot be empty';
|
||||
export const INVALID_URL_ERROR = 'Invalid URL';
|
||||
|
||||
export const IS_NUMBER_REGEX = /^\d+$/;
|
||||
|
||||
export const IS_IMPORT_WALLET_ENABLED = false;
|
||||
|
@ -7,7 +7,7 @@ import { getSdkError } from '@walletconnect/utils';
|
||||
import {
|
||||
SigningStargateClient,
|
||||
StdFee,
|
||||
MsgSendEncodeObject
|
||||
MsgSendEncodeObject,
|
||||
} from '@cosmjs/stargate';
|
||||
import { EncodeObject } from '@cosmjs/proto-signing';
|
||||
import { LaconicClient } from '@cerc-io/registry-sdk';
|
||||
|
Loading…
Reference in New Issue
Block a user