Skip to content

Commit

Permalink
feat(dev-wallet): allow key generation on specific index (#2699)
Browse files Browse the repository at this point in the history
* feat(dev-wallet): allow key generation on specific index

* feat(dw): add specific key form

---------

Co-authored-by: Javad Khalilian <khalilian.javad@gmail.com>
  • Loading branch information
alber70g and javadkh2 authored Nov 28, 2024
1 parent b350c27 commit 0a397fd
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 9 deletions.
55 changes: 50 additions & 5 deletions packages/apps/dev-wallet/src/modules/wallet/wallet.hook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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,
Expand All @@ -319,6 +363,7 @@ export const useWallet = () => {
unlockKeySource,
lockKeySource,
createNextAccount,
createSpecificAccount,
createAccountByKeyset,
createAccountByKey,
setActiveNetwork: (network: INetwork) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,13 @@ export const unlockProfile = async (profileId: string, password: string) => {
export async function createKey(
keySource: IKeySource,
onConnect: (keySource: IKeySource) => Promise<void>,
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;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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<string | null>(null);
const { setIsRightAsideExpanded } = useLayout();
return (
<RightAside isOpen={isOpen}>
<RightAsideHeader label="Add Specific Key" />
<RightAsideContent>
<Stack gap={'md'} flexDirection={'column'}>
<form
style={{ display: 'contents' }}
onSubmit={async (e) => {
e.preventDefault();
setError(null);
if (index && isAvailable) {
createKey(keySource, parseInt(index))
.then(() => {
setIndex('');
setIsRightAsideExpanded(false);
})
.catch((e) => {
setError(getErrorMessage(e));
});
}
}}
>
<Heading variant="h5">Add {keySource.source} key</Heading>
<TextField
label="Key Index"
value={index}
onChange={(e) => setIndex(e.target.value)}
type="number"
placeholder="e.g 123"
/>
{!isAvailable && (
<Text>
<Stack gap={'xs'} alignItems={'center'}>
<MonoDoNotDisturb /> This index is already created
</Stack>
</Text>
)}
{error && (
<Notification intent="negative" role="alert">
{error}
</Notification>
)}
<Button type="submit" isDisabled={!isAvailable}>
Add Key
</Button>
</form>
</Stack>
</RightAsideContent>
</RightAside>
);
}
26 changes: 23 additions & 3 deletions packages/apps/dev-wallet/src/pages/keys/Components/Keys.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<string | null>(null);
const { createHDWallet } = useHDWallet();
Expand Down Expand Up @@ -54,7 +66,7 @@ export function Keys() {
return (
<>
<AddKeySourceForm
isOpen={isRightAsideExpanded}
isOpen={isRightAsideExpanded && asideTarget === 'add-key-source'}
close={() => setIsRightAsideExpanded(false)}
onSave={async (sourcesToInstall) => {
setIsRightAsideExpanded(false);
Expand Down Expand Up @@ -93,7 +105,7 @@ export function Keys() {
variant="outlined"
isCompact
onPress={() => {
setIsRightAsideExpanded(true);
showKeySourceForm();
}}
>
Add key Source
Expand All @@ -107,6 +119,12 @@ export function Keys() {
flexDirection={'column'}
className={panelClass}
>
<AddSpecificKey
keySource={keySource}
isOpen={
isRightAsideExpanded && asideTarget === 'add-specific-key'
}
/>
<Stack
gap={'lg'}
justifyContent={'space-between'}
Expand Down Expand Up @@ -137,7 +155,9 @@ export function Keys() {
) ? (
<ContextMenuItem
label="Create specific key"
onClick={() => {}}
onClick={() => {
showAddSpecificKeyForm();
}}
/>
) : (
<ContextMenuDivider />
Expand Down
7 changes: 7 additions & 0 deletions packages/apps/dev-wallet/src/utils/getErrorMessage.ts
Original file line number Diff line number Diff line change
@@ -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';
};

0 comments on commit 0a397fd

Please sign in to comment.