laconic-wallet/utils.ts
shreerang6921 09a3b9fc75
Integrate functions with UI (#14)
* Add the creatHDWallet function

* Make review changes

* Add signMessage and signEthMessage functions

* Add signCosmosMessage function

* Add resetWallet function

* Add resetWallet function

* Integrate functions with UI

* Add Alerts to react component

* Make review changes

* Add comment in utils file

* Remove lowerCase conversion in signCosmosmessage function

---------

Co-authored-by: IshaVenikar <ishavenikar7@gmail.com>
2024-02-14 19:14:21 +05:30

165 lines
4.4 KiB
TypeScript

/* Importing this library provides react native with a secure random source.
For more information, "visit https://docs.ethers.org/v5/cookbook/react-native/#cookbook-reactnative-security" */
import 'react-native-get-random-values';
import '@ethersproject/shims';
import { Wallet, utils } from 'ethers';
import { HDNode } from 'ethers/lib/utils';
import {
setInternetCredentials,
getInternetCredentials,
resetInternetCredentials,
} from 'react-native-keychain';
import { AccountData, Secp256k1HdWallet } from '@cosmjs/amino';
import { stringToPath } from '@cosmjs/crypto';
const createWallet = async (): Promise<{
ethWalletInfo: { pubKey: string; address: string } | undefined;
cosmosWalletInfo: { pubKey: string; address: string } | undefined;
}> => {
try {
const mnemonic = utils.entropyToMnemonic(utils.randomBytes(32));
await setInternetCredentials('mnemonicServer', 'mnemonic', mnemonic);
const hdNode = HDNode.fromMnemonic(mnemonic);
const ethNode = hdNode.derivePath("m/44'/60'/0'/0/0");
const cosmosNode = hdNode.derivePath("m/44'/118'/0'/0/0");
const ethAddress = ethNode.address;
const cosmosAddress = (await getCosmosAccounts(mnemonic, 0)).data.address;
await setInternetCredentials(
'eth:keyServer:0',
'eth:key:0',
ethNode.privateKey,
);
await setInternetCredentials(
'cosmos:keyServer:0',
'cosmos:key:0',
cosmosNode.privateKey,
);
const ethWalletInfo = { pubKey: ethNode.publicKey, address: ethAddress };
const cosmosWalletInfo = {
pubKey: cosmosNode.publicKey,
address: cosmosAddress,
};
return { ethWalletInfo, cosmosWalletInfo };
} catch (error) {
console.error('Error creating HD wallet:', error);
return { ethWalletInfo: undefined, cosmosWalletInfo: undefined };
}
};
async function getCosmosAccounts(
mnemonic: string,
index: number,
): Promise<{ cosmosWallet: Secp256k1HdWallet; data: AccountData }> {
const cosmosWallet = await Secp256k1HdWallet.fromMnemonic(mnemonic, {
hdPaths: [stringToPath(`m/44'/118'/0'/0/${index}`)],
});
const accountsData = await cosmosWallet.getAccounts();
const data = accountsData[index];
return { cosmosWallet, data };
}
const signMessage = async (
message: string,
walletType: string,
index: number,
): Promise<string | undefined> => {
try {
console.log(walletType);
switch (walletType) {
case 'eth':
return await signEthMessage(message, index);
case 'cosmos':
return await signCosmosMessage(message, index);
default:
throw new Error('Invalid wallet type');
}
} catch (error) {
console.error('Error signing message:', error);
}
};
const signEthMessage = async (
message: string,
index: number,
): Promise<string | undefined> => {
try {
const keyCred = await getInternetCredentials(`eth:keyServer:${index}`);
if (!keyCred) {
throw new Error('Failed to retrieve internet credentials');
}
const wallet = new Wallet(keyCred.password);
const signature = await wallet.signMessage(message);
return signature;
} catch (error) {
console.error('Error signing Ethereum message:', error);
}
};
const signCosmosMessage = async (
message: string,
index: number,
): Promise<string | undefined> => {
try {
const mnemonicStore = await getInternetCredentials('mnemonicServer');
if (mnemonicStore) {
const mnemonic = mnemonicStore.password;
const cosmosAddress = (await getCosmosAccounts(mnemonic, index)).data
.address;
const cosmosSignature = await (
await getCosmosAccounts(mnemonic, index)
).cosmosWallet.signAmino(cosmosAddress, {
chain_id: '',
account_number: '0',
sequence: '0',
fee: {
gas: '0',
amount: [],
},
msgs: [
{
type: 'sign/MsgSignData',
value: {
signer: cosmosAddress,
data: btoa(message),
},
},
],
memo: '',
});
return cosmosSignature.signature.signature;
}
} catch (error) {
console.error('Error signing message:', error);
}
};
// const createAccount
const resetWallet = async () => {
// TODO: Add method to reset all the accounts
await resetInternetCredentials('mnemonicServer');
await resetInternetCredentials('eth:keyServer:0');
await resetInternetCredentials('cosmos:keyServer:0');
};
export { createWallet, signMessage, resetWallet };