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

refactor: use withKeyring to batch account restore operation #11409

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
41 changes: 17 additions & 24 deletions app/util/importAdditionalAccounts.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { BNToHex } from '../util/number';
import Logger from '../util/Logger';
import ExtendedKeyringTypes from '../../app/constants/keyringTypes';

const HD_KEY_TREE_ERROR = 'MetamaskController - No HD Key Tree found';
const ZERO_BALANCE = '0x0';
const MAX = 20;

Expand All @@ -30,31 +29,25 @@ const getBalance = async (address, ethQuery) =>
*/
export default async () => {
const { KeyringController } = Engine.context;

const ethQuery = Engine.getGlobalEthQuery();
let accounts = await KeyringController.getAccounts();
let lastBalance = await getBalance(accounts[accounts.length - 1], ethQuery);

const { keyrings } = KeyringController.state;
const filteredKeyrings = keyrings.filter(
(keyring) => keyring.type === ExtendedKeyringTypes.hd,
);
const primaryKeyring = filteredKeyrings[0];
if (!primaryKeyring) throw new Error(HD_KEY_TREE_ERROR);
await KeyringController.withKeyring(
{ type: ExtendedKeyringTypes.hd },
async (primaryKeyring) => {
let i = 0;
// seek out the first zero balance
while (i < MAX) {
const [newAccount] = await primaryKeyring.addAccounts(1);
const newAccountBalance = await getBalance(newAccount, ethQuery);
mikesposito marked this conversation as resolved.
Show resolved Hide resolved

let i = 0;
// seek out the first zero balance
while (lastBalance !== ZERO_BALANCE) {
if (i === MAX) break;
await KeyringController.addNewAccountWithoutUpdate(primaryKeyring);
accounts = await KeyringController.getAccounts();
lastBalance = await getBalance(accounts[accounts.length - 1], ethQuery);
i++;
}
if (newAccountBalance === ZERO_BALANCE) {
// remove extra zero balance account we just added and break the loop
primaryKeyring.removeAccount(newAccount);
break;
}

// remove extra zero balance account potentially created from seeking ahead
if (accounts.length > 1 && lastBalance === ZERO_BALANCE) {
await KeyringController.removeAccount(accounts[accounts.length - 1]);
accounts = await KeyringController.getAccounts();
}
i++;
}
},
);
Copy link
Member Author

@mikesposito mikesposito Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KeyringController wil do all the heavy lifting here: race condition protection, primary keyring existence check, batch state update with the resulting keyring, rollback in case of error and automatic vault update

};
Loading