Skip to content

Commit

Permalink
Add fake account support
Browse files Browse the repository at this point in the history
  • Loading branch information
d-manevich committed Oct 26, 2023
1 parent baf8ffa commit 0808422
Show file tree
Hide file tree
Showing 36 changed files with 272 additions and 56 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ dev/
prod/
tmp/
build/
.DS_Store
.DS_Store
.yarn/*
3 changes: 3 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-1.22.19.cjs
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,6 @@
"node": ">=16.0.0",
"yarn": ">=1.22.0",
"npm": "please-use-yarn"
}
},
"packageManager": "[email protected]"
}
2 changes: 2 additions & 0 deletions src/Popup/Routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Route, Routes as BaseRoutes } from 'react-router-dom';
import { PATH } from '~/constants/route';
import { useExtensionStorage } from '~/Popup/hooks/useExtensionStorage';
import AccountCreate from '~/Popup/pages/Account/Create';
import AccountCreateFake from '~/Popup/pages/Account/Create/Fake';
import AccountCreateImportMnemonic from '~/Popup/pages/Account/Create/Import/Mnemonic';
import AccountCreateImportPrivateKey from '~/Popup/pages/Account/Create/Import/PrivateKey';
import AccountCreateNewLedger from '~/Popup/pages/Account/Create/New/Ledger';
Expand Down Expand Up @@ -131,6 +132,7 @@ export default function Routes() {
<Route path={PATH.ACCOUNT__CREATE__NEW__LEDGER} element={<AccountCreateNewLedger />} />
<Route path={PATH.ACCOUNT__CREATE__IMPORT__MNEMONIC} element={<AccountCreateImportMnemonic />} />
<Route path={PATH.ACCOUNT__CREATE__IMPORT__PRIVATE_KEY} element={<AccountCreateImportPrivateKey />} />
<Route path={PATH.ACCOUNT__CREATE__FAKE} element={<AccountCreateFake />} />

<Route path={PATH.CHAIN__MANAGEMENT} element={<ChainManagement />} />
<Route path={PATH.CHAIN__MANAGEMENT__USE} element={<ChainManagementUse />} />
Expand Down
22 changes: 11 additions & 11 deletions src/Popup/background/messageProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque
(currentAccount.type !== 'LEDGER' || (currentAccount.type === 'LEDGER' && currentAccount.cosmosPublicKey))
) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

const publicKey = keyPair?.publicKey.toString('hex') || '';

Expand Down Expand Up @@ -620,7 +620,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque

if (chain?.id && currentAccountAllowedOrigins.includes(origin) && currentPassword) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

const publicKey = keyPair?.publicKey.toString('hex') || '';

Expand Down Expand Up @@ -991,7 +991,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque

if (currentAccountAllowedOrigins.includes(origin) && currentPassword) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

if ((currentAccount.type === 'LEDGER' && currentAccount.ethereumPublicKey) || currentAccount.type !== 'LEDGER') {
if (address.toLowerCase() !== validatedParams[0].toLowerCase()) {
Expand Down Expand Up @@ -1024,7 +1024,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque

if (currentAccountAllowedOrigins.includes(origin) && currentPassword) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);
if ((currentAccount.type === 'LEDGER' && currentAccount.ethereumPublicKey) || currentAccount.type !== 'LEDGER') {
if (address.toLowerCase() !== validatedParams[0].toLowerCase()) {
throw new EthereumRPCError(RPC_ERROR.INVALID_PARAMS, 'Invalid address', message.id);
Expand Down Expand Up @@ -1078,7 +1078,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque

if (currentAccountAllowedOrigins.includes(origin) && currentPassword) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

if ((currentAccount.type === 'LEDGER' && currentAccount.ethereumPublicKey) || currentAccount.type !== 'LEDGER') {
if (address.toLowerCase() !== validatedParams[1].toLowerCase()) {
Expand Down Expand Up @@ -1112,7 +1112,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque
if (currentAccountAllowedOrigins.includes(origin) && currentPassword) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);

const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

if ((currentAccount.type === 'LEDGER' && currentAccount.ethereumPublicKey) || currentAccount.type !== 'LEDGER') {
if (address.toLowerCase() !== toHex(validatedParams[0].from, { addPrefix: true }).toLowerCase()) {
Expand Down Expand Up @@ -1164,7 +1164,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque
(currentAccount.type !== 'LEDGER' || (currentAccount.type === 'LEDGER' && currentAccount.ethereumPublicKey))
) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

const result: EthRequestAccountsResponse = [address];

Expand Down Expand Up @@ -1426,7 +1426,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque
(currentAccount.type !== 'LEDGER' || (currentAccount.type === 'LEDGER' && currentAccount.ethereumPublicKey))
) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

const result: EthRequestAccountsResponse = address ? [address] : [];

Expand Down Expand Up @@ -1456,7 +1456,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque
(currentAccount.type !== 'LEDGER' || (currentAccount.type === 'LEDGER' && currentAccount.ethereumPublicKey))
) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

const result: EthCoinbaseResponse = address || null;

Expand Down Expand Up @@ -1560,7 +1560,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque
if (method === 'aptos_connect' || method === 'aptos_account') {
if (currentAccountAllowedOrigins.includes(origin) && currentPassword) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

const result: AptosConnectResponse = { address, publicKey: `0x${keyPair?.publicKey.toString('hex') || ''}` };

Expand Down Expand Up @@ -1758,7 +1758,7 @@ export async function cstob(request: ContentScriptToBackgroundEventMessage<Reque
if (currentAccountAllowedOrigins.includes(origin) && currentAccountSuiPermissions.includes('viewAccount')) {
if (currentPassword) {
const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

const publicKey = `0x${keyPair?.publicKey.toString('hex') || ''}`;
const result: SuiGetAccountResponse = {
Expand Down
2 changes: 1 addition & 1 deletion src/Popup/hooks/SWR/cache/useAccounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function useAccounts(suspense?: boolean) {
addresses[chain.id] = storageAddress;
} else {
const keypair = getKeyPair(account, chain, currentPassword);
const address = getAddress(chain, keypair?.publicKey);
const address = getAddress(account, chain, keypair?.publicKey);
addresses[chain.id] = address;
localStorage.setItem(key, address);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Popup/hooks/useCurrent/useCurrentAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function useCurrentAccount() {
emitToWeb({ line: 'COSMOS', type: 'accountChanged' }, origins);

const ethereumKeyPair = getKeyPair(accounts.find((item) => item.id === newAccountId)!, ETHEREUM, currentPassword);
const ethereumAddress = getAddress(ETHEREUM, ethereumKeyPair?.publicKey);
const ethereumAddress = getAddress(accounts.find((item) => item.id === newAccountId)!, ETHEREUM, ethereumKeyPair?.publicKey);

const currentAccountOrigins = Array.from(new Set(allowedOrigins.filter((item) => item.accountId === newAccountId).map((item) => item.origin)));
const currentAccountNotOrigins = Array.from(new Set(allowedOrigins.filter((item) => item.accountId !== newAccountId).map((item) => item.origin)));
Expand All @@ -65,7 +65,7 @@ export function useCurrentAccount() {
);

const aptosKeyPair = getKeyPair(accounts.find((item) => item.id === newAccountId)!, APTOS, currentPassword);
const aptosAddress = getAddress(APTOS, aptosKeyPair?.publicKey);
const aptosAddress = getAddress(accounts.find((item) => item.id === newAccountId)!, APTOS, aptosKeyPair?.publicKey);

emitToWeb({ line: 'APTOS', type: 'accountChange', message: { result: aptosAddress } }, currentAccountOrigins);
emitToWeb(
Expand All @@ -74,7 +74,7 @@ export function useCurrentAccount() {
);

const suiKeyPair = getKeyPair(accounts.find((item) => item.id === newAccountId)!, SUI, currentPassword);
const suiAddress = getAddress(SUI, suiKeyPair?.publicKey);
const suiAddress = getAddress(accounts.find((item) => item.id === newAccountId)!, SUI, suiKeyPair?.publicKey);

emitToWeb({ line: 'SUI', type: 'accountChange', message: { result: suiAddress } }, currentAccountOrigins);
emitToWeb(
Expand Down
94 changes: 94 additions & 0 deletions src/Popup/pages/Account/Create/Fake/entry.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { useForm } from 'react-hook-form';
import { useSnackbar } from 'notistack';
import { useSetRecoilState } from 'recoil';
import { v4 as uuidv4 } from 'uuid';
import { joiResolver } from '@hookform/resolvers/joi';

import Button from '~/Popup/components/common/Button';
import { useCurrentAccount } from '~/Popup/hooks/useCurrent/useCurrentAccount';
import { useLoading } from '~/Popup/hooks/useLoading';
import { useNavigate } from '~/Popup/hooks/useNavigate';
import { useTranslation } from '~/Popup/hooks/useTranslation';
import { disposableLoadingState } from '~/Popup/recoils/loading';

import { BottomContainer, Container, InputContainer, StyledInput48 } from './styled';
import type { FakeForm } from './useSchema';
import { useSchema } from './useSchema';

export type CheckWord = {
index: number;
word: string;
};

export default function Entry() {
const { navigateBack } = useNavigate();

const { currentAccount, addAccount } = useCurrentAccount();

const { setLoadingOverlay } = useLoading();

const { enqueueSnackbar } = useSnackbar();

const setDisposableLoading = useSetRecoilState(disposableLoadingState);

const { fakeForm } = useSchema();

const { t } = useTranslation();

const {
register,
handleSubmit,
formState: { errors, isDirty },
reset,
} = useForm<FakeForm>({
resolver: joiResolver(fakeForm),
mode: 'onSubmit',
reValidateMode: 'onSubmit',
shouldFocusError: true,
});

const submit = async (data: FakeForm) => {
setDisposableLoading(false);
setLoadingOverlay(true);

const accountId = uuidv4();

await addAccount({
...currentAccount,
id: accountId,
name: data.name,
address: data.address,
});

setLoadingOverlay(false);

reset();
enqueueSnackbar('success creating new account');
navigateBack();
};

return (
<form onSubmit={handleSubmit(submit)}>
<Container>
<InputContainer>
<div>
<StyledInput48
placeholder={t('pages.Account.Create.Import.Mnemonic.entry.accountNamePlaceholder')}
inputProps={register('name')}
error={!!errors.name}
helperText={errors.name?.message}
/>
</div>
<div>
<StyledInput48 placeholder="Address" inputProps={register('address')} error={!!errors.address} helperText={errors.address?.message} />
</div>
</InputContainer>
<BottomContainer>
<Button type="submit" disabled={!isDirty}>
{t('pages.Account.Create.Import.Mnemonic.entry.done')}
</Button>
</BottomContainer>
</Container>
</form>
);
}
14 changes: 14 additions & 0 deletions src/Popup/pages/Account/Create/Fake/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Lock from '~/Popup/components/Lock';

import Entry from './entry';
import Layout from './layout';

export default function Fake() {
return (
<Lock>
<Layout>
<Entry />
</Layout>
</Lock>
);
}
16 changes: 16 additions & 0 deletions src/Popup/pages/Account/Create/Fake/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import BaseLayout from '~/Popup/components/BaseLayout';
import { useNavigate } from '~/Popup/hooks/useNavigate';

type LayoutProps = {
children: JSX.Element;
};

export default function Layout({ children }: LayoutProps) {
const { navigateBack } = useNavigate();

return (
<BaseLayout useHeader={{}} useSubHeader={{ title: 'Add Fake Account', onClick: () => navigateBack() }}>
{children}
</BaseLayout>
);
}
42 changes: 42 additions & 0 deletions src/Popup/pages/Account/Create/Fake/styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { styled } from '@mui/material/styles';

import Input from '~/Popup/components/common/Input';

export const Container = styled('div')({
width: '100%',
height: '100%',

padding: '0.8rem 1.6rem 0',

position: 'relative',
});

export const InputContainer = styled('div')({
display: 'grid',
gridTemplateColumns: '1fr',
rowGap: '0.8rem',
});

export const BottomContainer = styled('div')({
position: 'absolute',

width: 'calc(100% - 3.2rem)',

bottom: '1.6rem',
});

export const BottomSettingButtonContainer = styled('div')({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',

marginBottom: '2.4rem',
});

export const StyledInput48 = styled(Input)({
height: '4.8rem',
});

export const StyledInput140 = styled(Input)({
minHeight: '14rem',
});
31 changes: 31 additions & 0 deletions src/Popup/pages/Account/Create/Fake/useSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useTranslation } from '~/Popup/hooks/useTranslation';
import Joi from '~/Popup/utils/joi';

export type FakeForm = {
name: string;
address: string;
};

export function useSchema() {
const { t } = useTranslation();
const fakeForm = Joi.object<FakeForm>({
name: Joi.string()
.required()
.min(1)
.max(20)
.messages({
'string.base': t('schema.common.string.base'),
'string.empty': t('schema.common.string.empty'),
'string.min': t('schema.common.string.min'),
'string.max': t('schema.common.string.max'),
}),
address: Joi.string()
.required()
.messages({
'string.base': t('schema.common.string.base'),
'string.empty': t('schema.common.string.empty'),
}),
});

return { fakeForm };
}
1 change: 1 addition & 0 deletions src/Popup/pages/Account/Create/entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default function Entry() {
<MenuButton onClick={() => navigate('/account/create/new/ledger')}>{t('pages.Account.Create.entry.createLedgerAccount')}</MenuButton>
<MenuButton onClick={() => navigate('/account/create/import/mnemonic')}>{t('pages.Account.Create.entry.importMnemonic')}</MenuButton>
<MenuButton onClick={() => navigate('/account/create/import/private-key')}>{t('pages.Account.Create.entry.importPrivateKey')}</MenuButton>
<MenuButton onClick={() => navigate('/account/create/fake')}>Add Fake Account</MenuButton>
</ListContainer>
</Container>
);
Expand Down
2 changes: 1 addition & 1 deletion src/Popup/pages/Popup/Aptos/SignMessage/entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function Entry({ queue }: EntryProps) {
const { t } = useTranslation();

const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

const { chainId } = currentAptosNetwork;

Expand Down
2 changes: 1 addition & 1 deletion src/Popup/pages/Popup/Aptos/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function Header({ network, origin, className }: HeaderProps) {
const { currentPassword } = useCurrentPassword();

const keyPair = getKeyPair(currentAccount, chain, currentPassword);
const address = getAddress(chain, keyPair?.publicKey);
const address = getAddress(currentAccount, chain, keyPair?.publicKey);

const chainName = (() => {
if (network) {
Expand Down
Loading

0 comments on commit 0808422

Please sign in to comment.