diff --git a/packages/apps/dev-wallet/src/modules/wallet/wallet.hook.tsx b/packages/apps/dev-wallet/src/modules/wallet/wallet.hook.tsx index 2a3759500d..38abdd33ba 100644 --- a/packages/apps/dev-wallet/src/modules/wallet/wallet.hook.tsx +++ b/packages/apps/dev-wallet/src/modules/wallet/wallet.hook.tsx @@ -156,11 +156,18 @@ export const useWallet = () => { [context], ); - const createKey = useCallback(async (keySource: IKeySource) => { - const res = await WalletService.createKey(keySource, unlockKeySource); - keySourceManager.disconnect(); - return res; - }, []); + const createKey = useCallback( + async (keySource: IKeySource, index?: number) => { + const res = await WalletService.createKey( + keySource, + unlockKeySource, + index, + ); + keySourceManager.disconnect(); + return res; + }, + [], + ); const getPublicKeyData = useCallback( (publicKey: string) => { @@ -306,6 +313,43 @@ export const useWallet = () => { ); }; + + const createSpecificAccount = async ({ + contract, + index, + alias, + }: { + contract: string; + index: number; + alias?: string; + }) => { + const { accounts, fungibles } = context; + const symbol = fungibles.find((f) => f.contract === contract)?.symbol; + const filteredAccounts = accounts.filter( + (account) => account.contract === contract, + ); + + const accountAlias = + alias || + `${contract === 'coin' ? '' : `${symbol} `}Account ${filteredAccounts.length + 1}`; + + const keySource = context.keySources[0]; + const indexKey = await createKey(keySource, index); + const availableKey = keySource.keys.find( + (ksKey) => ksKey.publicKey === indexKey.publicKey, + ); + if (availableKey) { + // prompt for password anyway for account creation even if the key is available. + await askForPassword(); + return createAccountByKey({ + key: availableKey, + contract, + alias: accountAlias, + }); + } + return createAccountByKey({ key: indexKey, contract, alias: accountAlias }); + }; + return { getContact, createProfile, @@ -319,6 +363,7 @@ export const useWallet = () => { unlockKeySource, lockKeySource, createNextAccount, + createSpecificAccount, createAccountByKeyset, createAccountByKey, setActiveNetwork: (network: INetwork) => diff --git a/packages/apps/dev-wallet/src/modules/wallet/wallet.service.ts b/packages/apps/dev-wallet/src/modules/wallet/wallet.service.ts index b8eb11a252..328415ebfa 100644 --- a/packages/apps/dev-wallet/src/modules/wallet/wallet.service.ts +++ b/packages/apps/dev-wallet/src/modules/wallet/wallet.service.ts @@ -155,12 +155,13 @@ export const unlockProfile = async (profileId: string, password: string) => { export async function createKey( keySource: IKeySource, onConnect: (keySource: IKeySource) => Promise, + index?: number, ) { const service = await keySourceManager.get(keySource.source); if (!service.isConnected()) { await onConnect(keySource); } - const key = await service.createKey(keySource.uuid); + const key = await service.createKey(keySource.uuid, index); return key; } diff --git a/packages/apps/dev-wallet/src/pages/keys/Components/AddSpecificKey.tsx b/packages/apps/dev-wallet/src/pages/keys/Components/AddSpecificKey.tsx new file mode 100644 index 0000000000..64c0191fce --- /dev/null +++ b/packages/apps/dev-wallet/src/pages/keys/Components/AddSpecificKey.tsx @@ -0,0 +1,83 @@ +import { useWallet } from '@/modules/wallet/wallet.hook'; +import { IKeySource } from '@/modules/wallet/wallet.repository'; +import { getErrorMessage } from '@/utils/getErrorMessage'; +import { MonoDoNotDisturb } from '@kadena/kode-icons/system'; +import { + Button, + Heading, + Notification, + Stack, + Text, + TextField, +} from '@kadena/kode-ui'; +import { + RightAside, + RightAsideContent, + RightAsideHeader, + useLayout, +} from '@kadena/kode-ui/patterns'; +import { useState } from 'react'; + +export function AddSpecificKey({ + keySource, + isOpen, +}: { + keySource: IKeySource; + isOpen: boolean; +}) { + const [index, setIndex] = useState(''); + const { createKey } = useWallet(); + const isAvailable = !keySource.keys.find((k) => k.index === parseInt(index)); + const [error, setError] = useState(null); + const { setIsRightAsideExpanded } = useLayout(); + return ( + + + + +
{ + e.preventDefault(); + setError(null); + if (index && isAvailable) { + createKey(keySource, parseInt(index)) + .then(() => { + setIndex(''); + setIsRightAsideExpanded(false); + }) + .catch((e) => { + setError(getErrorMessage(e)); + }); + } + }} + > + Add {keySource.source} key + setIndex(e.target.value)} + type="number" + placeholder="e.g 123" + /> + {!isAvailable && ( + + + This index is already created + + + )} + {error && ( + + {error} + + )} + + +
+
+
+ ); +} diff --git a/packages/apps/dev-wallet/src/pages/keys/Components/Keys.tsx b/packages/apps/dev-wallet/src/pages/keys/Components/Keys.tsx index 7376bae20e..f9f6d663de 100644 --- a/packages/apps/dev-wallet/src/pages/keys/Components/Keys.tsx +++ b/packages/apps/dev-wallet/src/pages/keys/Components/Keys.tsx @@ -18,10 +18,22 @@ import { useLayout } from '@kadena/kode-ui/patterns'; import { useState } from 'react'; import { panelClass } from '../../home/style.css.ts'; import { AddKeySourceForm } from './AddKeySourceForm.tsx'; +import { AddSpecificKey } from './AddSpecificKey.tsx'; export function Keys() { const { keySources, profile, askForPassword, createKey } = useWallet(); const { setIsRightAsideExpanded, isRightAsideExpanded } = useLayout(); + const [asideTarget, setAsideTarget] = useState< + 'add-key-source' | 'add-specific-key' + >(); + const showKeySourceForm = () => { + setAsideTarget('add-key-source'); + setIsRightAsideExpanded(true); + }; + const showAddSpecificKeyForm = () => { + setAsideTarget('add-specific-key'); + setIsRightAsideExpanded(true); + }; // eslint-disable-next-line @typescript-eslint/no-unused-vars const [_, setError] = useState(null); const { createHDWallet } = useHDWallet(); @@ -54,7 +66,7 @@ export function Keys() { return ( <> setIsRightAsideExpanded(false)} onSave={async (sourcesToInstall) => { setIsRightAsideExpanded(false); @@ -93,7 +105,7 @@ export function Keys() { variant="outlined" isCompact onPress={() => { - setIsRightAsideExpanded(true); + showKeySourceForm(); }} > Add key Source @@ -107,6 +119,12 @@ export function Keys() { flexDirection={'column'} className={panelClass} > + {}} + onClick={() => { + showAddSpecificKeyForm(); + }} /> ) : ( diff --git a/packages/apps/dev-wallet/src/utils/getErrorMessage.ts b/packages/apps/dev-wallet/src/utils/getErrorMessage.ts new file mode 100644 index 0000000000..cefdf82330 --- /dev/null +++ b/packages/apps/dev-wallet/src/utils/getErrorMessage.ts @@ -0,0 +1,7 @@ +export const getErrorMessage = (e: any) => { + const message = 'message' in e ? e.message : JSON.stringify(e); + if (message) { + return typeof message === 'string' ? message : JSON.stringify(message); + } + return 'Unknown error'; +};