Skip to content

Commit e9a7b5e

Browse files
authored
feat: support for multiple HD Wallet keyrings (#578)
1 parent 6f6d5ce commit e9a7b5e

File tree

17 files changed

+853
-714
lines changed

17 files changed

+853
-714
lines changed

packages/adena-extension/src/hooks/use-add-account.tsx

Lines changed: 0 additions & 43 deletions
This file was deleted.

packages/adena-extension/src/hooks/web/use-account-add-screen.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
import { isHDWalletKeyring, SeedAccount } from 'adena-module';
12
import { useCallback, useState } from 'react';
2-
import { SeedAccount } from 'adena-module';
33

4-
import { RoutePath } from '@types';
4+
import { waitForRun } from '@common/utils/timeout-utils';
55
import useAppNavigate from '@hooks/use-app-navigate';
66
import { useWalletContext } from '@hooks/use-context';
77
import { useCurrentAccount } from '@hooks/use-current-account';
8+
import { RoutePath } from '@types';
89
import useQuestionnaire from './use-questionnaire';
9-
import { waitForRun } from '@common/utils/timeout-utils';
1010

1111
export type UseAccountAddScreenReturn = {
1212
step: AccountAddStateType;
@@ -64,11 +64,20 @@ const useAccountAddScreen = (): UseAccountAddScreenReturn => {
6464
if (!wallet) {
6565
return false;
6666
}
67-
const account = await SeedAccount.createByWallet(wallet);
68-
account.index = wallet.lastAccountIndex + 1;
69-
account.name = `Account ${wallet.lastAccountIndex + 1}`;
67+
68+
const hdWalletKeyring = wallet.keyrings.find(isHDWalletKeyring);
69+
if (!hdWalletKeyring) {
70+
return false;
71+
}
72+
73+
const name = `Account ${wallet.lastAccountIndex + 1}`;
74+
const hdPath = wallet.getNextHDPathBy(hdWalletKeyring);
75+
const index = wallet.lastAccountIndex + 1;
76+
const account = await SeedAccount.createBy(hdWalletKeyring, name, hdPath, index);
77+
7078
const clone = wallet.clone();
7179
clone.addAccount(account);
80+
7281
const storedAccount = clone.accounts.find((storedAccount) => storedAccount.id === account.id);
7382
if (storedAccount) {
7483
await changeCurrentAccount(storedAccount);

packages/adena-extension/src/hooks/web/use-wallet-create-screen.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { useCallback, useMemo, useState } from 'react';
21
import { AdenaWallet, HDWalletKeyring, SeedAccount } from 'adena-module';
2+
import { useCallback, useMemo, useState } from 'react';
33

4-
import { RoutePath } from '@types';
54
import useAppNavigate from '@hooks/use-app-navigate';
65
import { useWalletContext } from '@hooks/use-context';
76
import { useCurrentAccount } from '@hooks/use-current-account';
8-
import useQuestionnaire from './use-questionnaire';
97
import useIndicatorStep, {
108
UseIndicatorStepReturn,
119
} from '@hooks/wallet/broadcast-transaction/use-indicator-step';
10+
import { RoutePath } from '@types';
11+
import useQuestionnaire from './use-questionnaire';
1212

1313
export type UseWalletCreateReturn = {
1414
seeds: string;

packages/adena-extension/src/hooks/web/wallet-export/use-wallet-export-screen.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { useCallback, useEffect, useState } from 'react';
21
import { Account } from 'adena-module';
2+
import { useCallback, useEffect, useState } from 'react';
33

4-
import useAppNavigate from '@hooks/use-app-navigate';
5-
import { useAdenaContext, useWalletContext } from '@hooks/use-context';
6-
import { useCurrentAccount } from '@hooks/use-current-account';
7-
import { RoutePath } from '@types';
8-
import { AdenaStorage } from '@common/storage';
94
import {
105
WALLET_EXPORT_ACCOUNT_ID,
116
WALLET_EXPORT_TYPE_STORAGE_KEY,
127
} from '@common/constants/storage.constant';
13-
import useQuestionnaire from '../use-questionnaire';
8+
import { AdenaStorage } from '@common/storage';
9+
import useAppNavigate from '@hooks/use-app-navigate';
10+
import { useAdenaContext, useWalletContext } from '@hooks/use-context';
11+
import { useCurrentAccount } from '@hooks/use-current-account';
1412
import useIndicatorStep, {
1513
UseIndicatorStepReturn,
1614
} from '@hooks/wallet/broadcast-transaction/use-indicator-step';
1715
import { useQuery } from '@tanstack/react-query';
16+
import { RoutePath } from '@types';
17+
import useQuestionnaire from '../use-questionnaire';
1818

1919
export type UseWalletExportReturn = {
2020
currentAccount: Account | null;
@@ -152,7 +152,7 @@ const useWalletExportScreen = (): UseWalletExportReturn => {
152152
const privateKey = await instance.getPrivateKeyStr();
153153
setExportData(privateKey);
154154
} else {
155-
const seedPhrase = instance.mnemonic;
155+
const seedPhrase = instance.getMnemonic();
156156
setExportData(seedPhrase);
157157
}
158158
setWalletExportState('RESULT');

packages/adena-module/src/utils/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
export * from './address';
12
export { arrayContentEquals, arrayContentStartsWith } from './arrays';
23
export { assert, assertDefined, assertDefinedAndNotNull } from './assert';
4+
export * from './data';
5+
export * from './messages';
36
export { sleep } from './sleep';
47
export { isDefined, isNonNullObject, isUint8Array } from './typechecks';
5-
export * from './messages';
6-
export * from './address';

packages/adena-module/src/wallet/account/seed-account.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { v4 as uuidv4 } from 'uuid';
2-
import { Account, AccountInfo } from './account';
3-
import { Wallet } from '../wallet';
4-
import { isHDWalletKeyring, Keyring, KeyringType } from '../../wallet/keyring';
2+
53
import { publicKeyToAddress } from '../../utils/address';
4+
import { isHDWalletKeyring, Keyring, KeyringType } from '../../wallet/keyring';
5+
import { Wallet } from '../wallet';
6+
import { Account, AccountInfo } from './account';
67

78
export class SeedAccount implements Account {
89
public readonly id;
@@ -60,7 +61,7 @@ export class SeedAccount implements Account {
6061
};
6162
}
6263

63-
public static async createBy(keyring: Keyring, name: string, hdPath: number) {
64+
public static async createBy(keyring: Keyring, name: string, hdPath: number, index = 1) {
6465
if (!isHDWalletKeyring(keyring)) {
6566
throw new Error('Invalid account type');
6667
}
@@ -69,7 +70,7 @@ export class SeedAccount implements Account {
6970
const { id: keyringId, type: type } = keyring;
7071
return new SeedAccount({
7172
keyringId,
72-
index: 1,
73+
index,
7374
type,
7475
publicKey: Array.from(publicKey),
7576
name,
@@ -78,10 +79,11 @@ export class SeedAccount implements Account {
7879
}
7980

8081
public static async createByWallet(wallet: Wallet) {
81-
if (!wallet.hdWalletKeyring) {
82-
throw new Error('HD Wallet does not exist');
82+
if (!wallet.currentKeyring || !isHDWalletKeyring(wallet.currentKeyring)) {
83+
throw new Error('The current keyring is not an HD Wallet Keyring');
8384
}
84-
return this.createBy(wallet.hdWalletKeyring, wallet.nextAccountName, wallet.nextHDPath);
85+
const hdPath = wallet.getNextHDPathBy(wallet.currentKeyring);
86+
return this.createBy(wallet.currentKeyring, wallet.nextAccountName, hdPath);
8587
}
8688

8789
public static fromData(accountInfo: AccountInfo) {

packages/adena-module/src/wallet/keyring/address-keyring.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import {
66
uint8ArrayToBase64,
77
} from '@gnolang/tm2-js-client';
88
import { v4 as uuidv4 } from 'uuid';
9-
import { Keyring, KeyringData, KeyringType } from './keyring';
9+
1010
import { Document, fromBech32 } from '../..';
11+
import { Keyring, KeyringData, KeyringType } from './keyring';
1112

1213
export class AddressKeyring implements Keyring {
1314
public readonly id: string;

packages/adena-module/src/wallet/keyring/hd-wallet-keyring.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import {
22
generateKeyPair,
3-
Wallet as Tm2Wallet,
4-
Tx,
5-
TxSignature,
63
Provider,
74
TransactionEndpoint,
5+
Tx,
6+
TxSignature,
7+
Wallet as Tm2Wallet,
88
} from '@gnolang/tm2-js-client';
99
import { v4 as uuidv4 } from 'uuid';
10+
1011
import { Bip39, EnglishMnemonic } from '../../crypto';
11-
import { useTm2Wallet, decodeTxMessages, Document, documentToTx, makeSignedTx } from './../..';
12+
import { Document, makeSignedTx, useTm2Wallet } from './../..';
1213
import { Keyring, KeyringData, KeyringType } from './keyring';
1314

1415
export class HDWalletKeyring implements Keyring {

packages/adena-module/src/wallet/keyring/keyring-util.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import { Tx, Wallet as Tm2Wallet } from '@gnolang/tm2-js-client';
2+
3+
import { decodeTxMessages, Document, documentToTx } from './../../utils/messages';
14
import { AddressKeyring } from './address-keyring';
25
import { HDWalletKeyring } from './hd-wallet-keyring';
36
import { Keyring } from './keyring';
47
import { LedgerKeyring } from './ledger-keyring';
58
import { PrivateKeyKeyring } from './private-key-keyring';
69
import { Web3AuthKeyring } from './web3-auth-keyring';
7-
import { Tx, Wallet as Tm2Wallet } from '@gnolang/tm2-js-client';
8-
import { Document, documentToTx, decodeTxMessages } from './../../utils/messages';
910

1011
export function isHDWalletKeyring(keyring: Keyring): keyring is HDWalletKeyring {
1112
return keyring.type === 'HD_WALLET';

packages/adena-module/src/wallet/keyring/keyring.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Tx,
66
TxSignature,
77
} from '@gnolang/tm2-js-client';
8+
89
import { Document } from './../..';
910
import { AddressKeyring } from './address-keyring';
1011
import { HDWalletKeyring } from './hd-wallet-keyring';

0 commit comments

Comments
 (0)