Skip to content

Commit 07906e8

Browse files
authored
fix wallet & account names problem, limit account number: OK-6944 OK-6733 OK-6952 (#429)
* fix(engine): improve default wallet name Fixes: OK-6944 * feat(engine): limit number of imported & derived accounts Fixes: OK-6952 * feat: supply default for account creating/recovering Fixes: OK-6733
1 parent ef1ce20 commit 07906e8

File tree

11 files changed

+144
-18
lines changed

11 files changed

+144
-18
lines changed

packages/engine/src/dbs/indexed/indexeddb.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ import {
99
AccountAlreadyExists,
1010
NotImplemented,
1111
OneKeyInternalError,
12+
TooManyDerivedAccounts,
13+
TooManyImportedAccounts,
1214
TooManyWatchingAccounts,
1315
WrongPassword,
1416
} from '../../errors';
15-
import { WATCHING_ACCOUNT_MAX_NUM } from '../../limits';
17+
import {
18+
DERIVED_ACCOUNT_MAX_NUM,
19+
IMPORTED_ACCOUNT_MAX_NUM,
20+
WATCHING_ACCOUNT_MAX_NUM,
21+
} from '../../limits';
1622
import { getPath } from '../../managers/derivation';
1723
import { walletIsImported } from '../../managers/wallet';
1824
import { AccountType, DBAccount, DBVariantAccount } from '../../types/account';
@@ -765,7 +771,7 @@ class IndexedDBApi implements DBAPI {
765771
const walletId = `hd-${context.nextHD}`;
766772
ret = {
767773
id: walletId,
768-
name: name || `HD Wallet ${context.nextHD}`,
774+
name: name || `Wallet ${context.nextHD}`,
769775
type: WALLET_TYPE_HD,
770776
backuped,
771777
accounts: [],
@@ -827,7 +833,7 @@ class IndexedDBApi implements DBAPI {
827833
}
828834
ret = {
829835
id: walletId,
830-
name: name || `HW Wallet of ${id}`,
836+
name,
831837
type: WALLET_TYPE_HW,
832838
backuped: true,
833839
accounts: [],
@@ -1139,6 +1145,23 @@ class IndexedDBApi implements DBAPI {
11391145
const category = `${pathComponents[1]}/${pathComponents[2]}`;
11401146
const purpose = pathComponents[1].slice(0, -1);
11411147
const coinType = pathComponents[2].slice(0, -1);
1148+
1149+
// Check account number limit
1150+
const accountIdPrefix = `${walletId}--m/${category}`;
1151+
if (
1152+
wallet.accounts.filter((id) => id.startsWith(accountIdPrefix))
1153+
.length > DERIVED_ACCOUNT_MAX_NUM
1154+
) {
1155+
reject(
1156+
new TooManyDerivedAccounts(
1157+
DERIVED_ACCOUNT_MAX_NUM,
1158+
parseInt(coinType),
1159+
parseInt(purpose),
1160+
),
1161+
);
1162+
return;
1163+
}
1164+
11421165
let nextId = wallet.nextAccountIds[category] || 0;
11431166
while (
11441167
wallet.accounts.includes(
@@ -1155,6 +1178,12 @@ class IndexedDBApi implements DBAPI {
11551178
.objectStore(CONTEXT_STORE_NAME)
11561179
.get(MAIN_CONTEXT);
11571180
getMainContextRequest.onsuccess = (_cevent) => {
1181+
if (wallet.accounts.length > IMPORTED_ACCOUNT_MAX_NUM) {
1182+
reject(
1183+
new TooManyImportedAccounts(IMPORTED_ACCOUNT_MAX_NUM),
1184+
);
1185+
return;
1186+
}
11581187
const context: OneKeyContext =
11591188
getMainContextRequest.result as OneKeyContext;
11601189
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion

packages/engine/src/dbs/realms/realm.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ import {
99
NotImplemented,
1010
OneKeyError,
1111
OneKeyInternalError,
12+
TooManyDerivedAccounts,
13+
TooManyImportedAccounts,
1214
TooManyWatchingAccounts,
1315
WrongPassword,
1416
} from '../../errors';
15-
import { WATCHING_ACCOUNT_MAX_NUM } from '../../limits';
17+
import {
18+
DERIVED_ACCOUNT_MAX_NUM,
19+
IMPORTED_ACCOUNT_MAX_NUM,
20+
WATCHING_ACCOUNT_MAX_NUM,
21+
} from '../../limits';
1622
import { getPath } from '../../managers/derivation';
1723
import { walletIsImported } from '../../managers/wallet';
1824
import { AccountType, DBAccount } from '../../types/account';
@@ -725,6 +731,20 @@ class RealmDB implements DBAPI {
725731
const category = `${pathComponents[1]}/${pathComponents[2]}`;
726732
const purpose = pathComponents[1].slice(0, -1);
727733
const coinType = pathComponents[2].slice(0, -1);
734+
735+
// Check account number limit
736+
const accountIdPrefix = `${walletId}--m/${category}`;
737+
if (
738+
wallet.accounts!.filtered('id beginsWith $0', accountIdPrefix)
739+
?.length > DERIVED_ACCOUNT_MAX_NUM
740+
) {
741+
throw new TooManyDerivedAccounts(
742+
DERIVED_ACCOUNT_MAX_NUM,
743+
parseInt(coinType),
744+
parseInt(purpose),
745+
);
746+
}
747+
728748
let nextId = wallet.nextAccountIds![category] || 0;
729749
while (
730750
wallet.accounts!.filtered(
@@ -738,6 +758,9 @@ class RealmDB implements DBAPI {
738758
break;
739759
}
740760
case WALLET_TYPE_IMPORTED: {
761+
if (wallet.accounts!.size > IMPORTED_ACCOUNT_MAX_NUM) {
762+
throw new TooManyImportedAccounts(IMPORTED_ACCOUNT_MAX_NUM);
763+
}
741764
this.realm!.create('Credential', {
742765
id: account.id,
743766
credential: JSON.stringify({
@@ -852,7 +875,7 @@ class RealmDB implements DBAPI {
852875
this.realm!.write(() => {
853876
wallet = this.realm!.create('Wallet', {
854877
id: walletId,
855-
name: name || `HD Wallet ${context!.nextHD}`,
878+
name: name || `Wallet ${context!.nextHD}`,
856879
type: WALLET_TYPE_HD,
857880
backuped,
858881
});

packages/engine/src/errors.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,27 @@ export class TooManyWatchingAccounts extends NumberLimit {
9393
key = 'msg__engine_too_many_watching_accounts';
9494
}
9595

96+
export class TooManyImportedAccounts extends NumberLimit {
97+
key = 'msg__engine__too_many_imported_accounts';
98+
}
99+
96100
export class TooManyHDWallets extends NumberLimit {
97101
key = 'msg__engine__too_many_hd_wallets';
98102
}
99103

100104
export class TooManyHWWallets extends NumberLimit {
101105
key = 'msg__engine__too_many_hw_wallets';
102106
}
107+
108+
export class TooManyDerivedAccounts extends NumberLimit {
109+
key = 'msg__engine__too_many_derived_accounts';
110+
111+
constructor(limit: number, coinType: number, purpose: number) {
112+
super(limit);
113+
this.info = {
114+
coinType: coinType.toString(),
115+
purpose: purpose.toString(),
116+
...this.info,
117+
};
118+
}
119+
}

packages/engine/src/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
import { getErc20TransferHistories, getTxHistories } from './managers/covalent';
4545
import { getDefaultPurpose, getXpubs } from './managers/derivation';
4646
import {
47+
getAccountNameInfoByImpl,
4748
getDefaultCurveByCoinType,
4849
implToAccountType,
4950
implToCoinTypes,
@@ -553,6 +554,9 @@ class Engine {
553554
}
554555

555556
const { impl } = dbNetwork;
557+
const accountPrefix =
558+
getAccountNameInfoByImpl(impl)[purpose || 'default'].prefix;
559+
556560
let credential: CredentialSelector;
557561
let outputFormat = 'pub'; // For UTXO, should be xpub, for now, only pub(software) or address(hardware) is possible.
558562

@@ -597,6 +601,7 @@ class Engine {
597601
return balances.map((balance, index) => ({
598602
index: start + index,
599603
path: accountInfos[index].path,
604+
defaultName: `${accountPrefix} Account #${start + index + 1}`,
600605
displayAddress: addresses[index],
601606
mainBalance:
602607
typeof balance === 'undefined'
@@ -642,6 +647,8 @@ class Engine {
642647
if (typeof accountType === 'undefined') {
643648
throw new OneKeyInternalError(`Unsupported implementation ${impl}.`);
644649
}
650+
const accountPrefix =
651+
getAccountNameInfoByImpl(impl)[purpose || 'default'].prefix;
645652

646653
const usedPurpose = purpose || getDefaultPurpose(impl);
647654
const usedIndexes = indexes || [
@@ -691,7 +698,9 @@ class Engine {
691698
}
692699

693700
const accountNum = usedIndexes[accountIndex] + 1;
694-
const name = (names || [])[accountIndex] || `Account #${accountNum}`;
701+
const name =
702+
(names || [])[accountIndex] ||
703+
`${accountPrefix} Account #${accountNum}`;
695704
const { id } = await this.dbApi.addAccountToWallet(wallet.id, {
696705
id: `${wallet.id}--${accountInfo.path}`,
697706
name,

packages/engine/src/limits.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export const WALLET_NAME_MAX_LENGTH = 24;
33
export const ACCOUNT_NAME_MIN_LENGTH = 1;
44
export const ACCOUNT_NAME_MAX_LENGTH = 24;
55
export const WATCHING_ACCOUNT_MAX_NUM = 100;
6-
export const HD_ACCOUNT_MAX_NUM = 100; // by implementation
6+
export const IMPORTED_ACCOUNT_MAX_NUM = 100;
7+
export const DERIVED_ACCOUNT_MAX_NUM = 100; // by implementation
78
export const HD_WALLET_MAX_NUM = 20;
89
export const HW_WALLET_MAX_NUM = 20;

packages/engine/src/managers/impl.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from '../constants';
1515
import { NotImplemented } from '../errors';
1616
import { AccountType } from '../types/account';
17+
import { AccountNameInfo } from '../types/network';
1718

1819
enum Curve {
1920
SECP256K1 = 'secp256k1',
@@ -67,10 +68,38 @@ function getDefaultCurveByCoinType(coinType: string): string {
6768
return getCurveByImpl(coinTypeToImpl[coinType]);
6869
}
6970

71+
const defaultAccountNameInfo: Record<
72+
string,
73+
Record<string, AccountNameInfo>
74+
> = {
75+
[IMPL_EVM]: { default: { prefix: 'ETH', category: `44'/${COINTYPE_ETH}'` } },
76+
[IMPL_SOL]: { default: { prefix: 'SOL', category: `44'/${COINTYPE_SOL}'` } },
77+
[IMPL_ALGO]: {
78+
default: { prefix: 'ALGO', category: `44'/${COINTYPE_ALGO}'` },
79+
},
80+
[IMPL_NEAR]: {
81+
default: { prefix: 'NEAR', category: `44'/${COINTYPE_NEAR}'` },
82+
},
83+
[IMPL_STC]: { default: { prefix: 'STC', category: `44'/${COINTYPE_STC}'` } },
84+
[IMPL_CFX]: { default: { prefix: 'CFX', category: `44'/${COINTYPE_CFX}'` } },
85+
// TODO: BTC
86+
};
87+
88+
function getAccountNameInfoByImpl(
89+
impl: string,
90+
): Record<string, AccountNameInfo> {
91+
const ret = defaultAccountNameInfo[impl];
92+
if (typeof ret === 'undefined') {
93+
throw new NotImplemented(`Implementation ${impl} is not supported.`);
94+
}
95+
return ret;
96+
}
97+
7098
export {
7199
implToCoinTypes,
72100
implToAccountType,
73101
isCoinTypeCompatibleWithImpl,
74102
getCurveByImpl,
75103
getDefaultCurveByCoinType,
104+
getAccountNameInfoByImpl,
76105
};

packages/engine/src/managers/network.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
Network,
99
} from '../types/network';
1010

11+
import { getAccountNameInfoByImpl } from './impl';
12+
1113
function getEVMNetworkToCreate(
1214
id: string,
1315
params: AddEVMNetworkParams,
@@ -113,6 +115,7 @@ function fromDBNetworkToNetwork(dbNetwork: DBNetwork): Network {
113115
tokenDisplayDecimals: 4,
114116
// extra info for dapp interactions
115117
extraInfo,
118+
accountNameInfo: getAccountNameInfoByImpl(dbNetwork.impl),
116119
blockExplorerURL: { name, ...blockExplorerURL } as BlockExplorer,
117120
};
118121
}

packages/engine/src/types/account.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type Account = DBBaseAccount & {
4141
type ImportableHDAccount = {
4242
index: number;
4343
path: string;
44+
defaultName: string;
4445
displayAddress: string;
4546
mainBalance: string;
4647
};

packages/engine/src/types/network.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ type EvmExtraInfo = {
3434
networkVersion: string;
3535
};
3636

37+
type AccountNameInfo = {
38+
prefix: string;
39+
category: string;
40+
};
41+
3742
type BlockExplorer = {
3843
name: string;
3944
address: string;
@@ -52,6 +57,8 @@ type Network = NetworkBase & {
5257
tokenDisplayDecimals: number;
5358
// extra info for dapp interactions
5459
extraInfo: EvmExtraInfo | Record<string, any>;
60+
// extra info for building up account name
61+
accountNameInfo: Record<string, AccountNameInfo>;
5562
// TODO: rpcURLs
5663
blockExplorerURL: BlockExplorer;
5764
};
@@ -85,6 +92,7 @@ export type {
8592
PresetNetwork,
8693
Network,
8794
EvmExtraInfo,
95+
AccountNameInfo,
8896
BlockExplorer,
8997
AddEVMNetworkParams,
9098
AddNetworkParams,

packages/kit/src/views/Account/AddNewAccount/RecoverConfirm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ const RecoverConfirm: FC = () => {
126126
>
127127
<Box flexDirection="column" flex={1} justifyContent="center" pl="24px">
128128
<Typography.Body2Strong>
129-
{`Account #${item.index + 1}`}
129+
{`${item.defaultName}`}
130130
</Typography.Body2Strong>
131131
<Address
132132
typography="Body2"

0 commit comments

Comments
 (0)