Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: [ADN-412] Fix the duplication registration logic of the adding account #366

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions packages/adena-extension/src/common/errors/common/common-error.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import { BaseError } from '../base';

const ERROR_VALUE = {
FAILED_INITIALIZE_PROVIDER: {
status: 400,
type: 'FAILED_TO_INITIALIZE_PROVIDER',
},
NOT_FOUND_NETWORKS: {
status: 400,
type: 'NOT_FOUND_NETWORKS',
},
FAILED_INITIALIZE_PROVIDER: {
status: 400,
type: 'FAILED_TO_INITIALIZE_PROVIDER',
},
NOT_FOUND_NETWORKS: {
status: 400,
type: 'NOT_FOUND_NETWORKS',
},
FAILED_TO_RUN: {
status: 400,
type: 'FAILED_TO_RUN',
},
};

type ErrorType = keyof typeof ERROR_VALUE;

export class CommonError extends BaseError {
constructor(errorType: ErrorType) {
super(ERROR_VALUE[errorType]);
Object.setPrototypeOf(this, CommonError.prototype);
}
constructor(errorType: ErrorType) {
super(ERROR_VALUE[errorType]);
Object.setPrototypeOf(this, CommonError.prototype);
}
}
27 changes: 27 additions & 0 deletions packages/adena-extension/src/common/utils/timeout-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { CommonError } from '@common/errors/common';

export const DEFAULT_TIMEOUT = 1500 as const;

export async function waitForRun<T = undefined>(
promise: Promise<T>,
milliseconds?: number,
): Promise<T> {
milliseconds = milliseconds ?? DEFAULT_TIMEOUT;
let timer: number | NodeJS.Timeout;
const response = await Promise.all([
promise,
new Promise<'done'>((resolve) => {
timer = setTimeout(() => resolve('done'), milliseconds);
}),
] as const)
.catch((e) => {
console.error(e);
return [null, null];
})
.finally(() => clearTimeout(timer));

if (response[1] !== 'done') {
throw new CommonError('FAILED_TO_RUN');
}
return response[0] as T;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactElement } from 'react';
import React from 'react';
import styled, { useTheme } from 'styled-components';

import AnimationLoadingAccount from '@assets/web/loading-account-idle.gif';
Expand All @@ -15,11 +15,17 @@ const StyledMessageBox = styled(View)`
row-gap: 16px;
`;

const WebLoadingAccounts: React.FC = (): ReactElement => {
interface WebLoadingAccountsProps {
spacing?: number;
}

const WebLoadingAccounts: React.FC<WebLoadingAccountsProps> = ({
spacing = 0,
}) => {
const theme = useTheme();

return (
<StyledContainer>
<StyledContainer style={{ marginTop: `${spacing}px` }}>
<WebImg src={AnimationLoadingAccount} height={120} />
<StyledMessageBox>
<WebText type='headline2' textCenter>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { useCallback, useState } from 'react';
import { defaultAddressPrefix } from '@gnolang/tm2-js-client';
import { AirgapAccount, AddressKeyring, AdenaWallet, fromBech32 } from 'adena-module';
import {
AirgapAccount,
AddressKeyring,
AdenaWallet,
fromBech32,
isSingleAccount,
} from 'adena-module';

import useAppNavigate from '@hooks/use-app-navigate';
import { useAdenaContext, useWalletContext } from '@hooks/use-context';
import { useCurrentAccount } from '@hooks/use-current-account';
import { RoutePath } from '@types';
import { useLoadAccounts } from '@hooks/use-load-accounts';
import { waitForRun } from '@common/utils/timeout-utils';

export type UseSetupAirgapScreenReturn = {
address: string;
Expand All @@ -19,7 +26,7 @@ export type UseSetupAirgapScreenReturn = {
addAccount: (password?: string) => Promise<void>;
};

export type SetupAirgapStateType = 'INIT' | 'ENTER_ADDRESS' | 'COMPLETE';
export type SetupAirgapStateType = 'INIT' | 'ENTER_ADDRESS' | 'LOADING' | 'COMPLETE';

export const setupAirgapStep: Record<
SetupAirgapStateType,
Expand All @@ -40,6 +47,10 @@ export const setupAirgapStep: Record<
backTo: 'ENTER_ADDRESS',
stepNo: 2,
},
LOADING: {
backTo: 'ENTER_ADDRESS',
stepNo: 2,
},
};

const useSetupAirgapScreen = (): UseSetupAirgapScreenReturn => {
Expand Down Expand Up @@ -75,9 +86,10 @@ const useSetupAirgapScreen = (): UseSetupAirgapScreenReturn => {
}, [address]);

const _existsAddress = useCallback(async () => {
return Promise.all(accounts.map((account) => account.getAddress('g'))).then((addresses) =>
addresses.includes(address),
);
const checkAccounts = accounts.filter((account) => !isSingleAccount(account));
return Promise.all(
checkAccounts.map((account) => account.getAddress(defaultAddressPrefix)),
).then((addresses) => addresses.includes(address));
}, [accounts, address]);

const confirmAddress = useCallback(async () => {
Expand Down Expand Up @@ -113,7 +125,6 @@ const useSetupAirgapScreen = (): UseSetupAirgapScreenReturn => {
await changeCurrentAccount(storedAccount);
}
await updateWallet(clone);
navigate(RoutePath.WebAccountAddedComplete);
}, [address, walletService]);

const _createAddressAccount = useCallback(async () => {
Expand All @@ -135,7 +146,9 @@ const useSetupAirgapScreen = (): UseSetupAirgapScreenReturn => {
try {
const existWallet = await walletService.existsWallet();
if (existWallet) {
await _addAddressAccount();
setSetupAirgapState('LOADING');
await waitForRun<void>(_addAddressAccount());
navigate(RoutePath.WebAccountAddedComplete);
} else {
await _createAddressAccount();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { useCallback, useMemo, useState } from 'react';
import { Wallet, PrivateKeyKeyring, SingleAccount, Account, Keyring } from 'adena-module';
import {
Wallet,
PrivateKeyKeyring,
SingleAccount,
Account,
Keyring,
isAirgapAccount,
} from 'adena-module';

import { RoutePath } from '@types';
import useAppNavigate from '@hooks/use-app-navigate';
import { useWalletContext } from '@hooks/use-context';
import { useCurrentAccount } from '@hooks/use-current-account';
import useQuestionnaire from './use-questionnaire';
import { defaultAddressPrefix } from '@gnolang/tm2-js-client';

export type UseAccountImportReturn = {
isValidForm: boolean;
Expand Down Expand Up @@ -71,9 +79,10 @@ const useAccountImportScreen = ({ wallet }: { wallet: Wallet }): UseAccountImpor
}

const account = await SingleAccount.createBy(keyring, wallet.nextAccountName);
const address = await account.getAddress('g');
const address = await account.getAddress(defaultAddressPrefix);
const checkAccounts = wallet.accounts.filter((account) => !isAirgapAccount(account));
const storedAddresses = await Promise.all(
wallet.accounts.map((account) => account.getAddress('g')),
checkAccounts.map((account) => account.getAddress(defaultAddressPrefix)),
);
const existAddress = storedAddresses.includes(address);
if (existAddress) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { RoutePath } from '@types';
import SetupAirgapEnterAddress from './enter-address';
import SetupAirgapInit from './init';
import SetupAirgapCompleteScreen from './complete';
import WebLoadingAccounts from '@components/pages/web/loading-accounts';

const SetupAirgapScreen: React.FC = () => {
const {
Expand Down Expand Up @@ -41,7 +42,10 @@ const SetupAirgapScreen: React.FC = () => {

return (
<WebMain spacing={272}>
<WebMainHeader stepLength={4} onClickGoBack={onClickBack} currentStep={stopNo} />
{setupAirgapState !== 'LOADING' && (
<WebMainHeader stepLength={4} onClickGoBack={onClickBack} currentStep={stopNo} />
)}

{setupAirgapState === 'INIT' && <SetupAirgapInit initSetup={initSetup} />}
{setupAirgapState === 'ENTER_ADDRESS' && (
<SetupAirgapEnterAddress
Expand All @@ -54,6 +58,9 @@ const SetupAirgapScreen: React.FC = () => {
{setupAirgapState === 'COMPLETE' && (
<SetupAirgapCompleteScreen address={address} addAccount={addAccount} />
)}
{setupAirgapState === 'LOADING' && (
<WebLoadingAccounts spacing={344 - 272} />
)}
</WebMain>
);
};
Expand Down
Loading