Skip to content

Commit

Permalink
Merge pull request #307 from getsafle/feature-refactor-vault-recovery
Browse files Browse the repository at this point in the history
Feature refactor vault recovery
  • Loading branch information
sshubhamagg authored May 2, 2024
2 parents dd19edf + d47f274 commit 9880af1
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 147 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -635,4 +635,10 @@
##### [BREAKING Changes] Removed getAssets() method

* Removed function `getAssets()` to get the list of assets of all the accounts associated as it is moved to an api service.
* Updated avalanche, base and zkEVM controllers.
* Updated avalanche, base and zkEVM controllers.

### 2.5.1 (2024-02-20)

* Refactored recover vault logic and generalized it for evm and non evm chains
* updated labeling for evm and non evm wallet accounts
* Integrated restore account logs for vault recovery
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@getsafle/safle-vault",
"version": "2.5.0",
"version": "2.5.1",
"description": "Safle Vault is a non-custodial, flexible and highly available crypto wallet which can be used to access dapps, send/receive crypto and store identity. Vault SDK is used to manage the vault and provide methods to generate vault, add new accounts, update the state and also enable the user to perform several vault related operations.",
"main": "src/index.js",
"scripts": {
Expand Down
25 changes: 16 additions & 9 deletions src/lib/keyring.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ class Keyring {
const acc = await this.getAccounts();

if (Chains.evmChains.hasOwnProperty(this.chain) || this.chain === 'ethereum') {

let labelPrefix = 'EVM'
const accounts = await this.keyringInstance.getAccounts();

const keyring = await this.keyringInstance.getKeyringForAccount(accounts[0]);
Expand All @@ -229,7 +231,7 @@ class Keyring {

const newAccount = await this.keyringInstance.getAccounts();

this.decryptedVault.eth.public.push({ address: newAccount[newAccount.length - 1], isDeleted: false, isImported: false, label: `Wallet ${acc.response.length + 1}` })
this.decryptedVault.eth.public.push({ address: newAccount[newAccount.length - 1], isDeleted: false, isImported: false, label: `${labelPrefix} Wallet ${acc.response.length + 1}` })
this.decryptedVault.eth.numberOfAccounts++;

const encryptedVault = await helper.cryptography(JSON.stringify(this.decryptedVault), JSON.stringify(encryptionKey), 'encryption');
Expand All @@ -245,6 +247,8 @@ class Keyring {

let newAddress;

let labelPrefix = Chains.nonEvmChains[this.chain]

if (this[this.chain] === undefined) {
const keyringInstance = await helper.getCoinInstance(this.chain, mnemonic);

Expand All @@ -254,14 +258,14 @@ class Keyring {

newAddress = address;

const publicData = [ { address, isDeleted: false, isImported: false, label: `${this.chain[0].toUpperCase() + this.chain.slice(1)} Wallet ${acc.response ? acc.response.length + 1 : 1}` } ];
const publicData = [ { address, isDeleted: false, isImported: false, label: `${labelPrefix} Wallet ${acc.response ? acc.response.length + 1 : 1}` } ];
this.decryptedVault[this.chain] = { public: publicData, numberOfAccounts: 1 };
} else {
const { address } = await this[this.chain].addAccount();

newAddress = address;

(this.decryptedVault[this.chain] === undefined) ? this.decryptedVault[this.chain] = { public: [ { address: newAddress, isDeleted: false, isImported: false, label: `${this.chain[0].toUpperCase() + this.chain.slice(1)} Wallet ${acc.response.length + 1}` } ], numberOfAccounts: 1 } : this.decryptedVault[this.chain].public.push({ address: newAddress, isDeleted: false, isImported: false, label: `${this.chain[0].toUpperCase() + this.chain.slice(1)} Wallet ${acc.response.length + 1}` });
(this.decryptedVault[this.chain] === undefined) ? this.decryptedVault[this.chain] = { public: [ { address: newAddress, isDeleted: false, isImported: false, label: `${labelPrefix} Wallet ${acc.response.length + 1}` } ], numberOfAccounts: 1 } : this.decryptedVault[this.chain].public.push({ address: newAddress, isDeleted: false, isImported: false, label: `${labelPrefix} Wallet ${acc.response.length + 1}` });
this.decryptedVault[this.chain].numberOfAccounts++;
}

Expand Down Expand Up @@ -643,6 +647,8 @@ class Keyring {
}

if (Chains.evmChains.hasOwnProperty(this.chain) || this.chain === 'ethereum') {

let labelPrefix = 'EVM'

const keyringInstance = await helper.getCoinInstance(this.chain);

Expand All @@ -663,13 +669,14 @@ class Keyring {
}

if (this.decryptedVault.importedWallets === undefined) {
this.decryptedVault.importedWallets = { evmChains: { data: [{ address, privateKey: encryptedPrivKey, isDeleted: false, isImported: true, label: `Wallet ${numOfAcc + 1}` }] } };
this.decryptedVault.importedWallets = { evmChains: { data: [{ address, privateKey: encryptedPrivKey, isDeleted: false, isImported: true, label: `${labelPrefix} Wallet ${numOfAcc + 1}` }] } };
} else if (this.decryptedVault.importedWallets.evmChains === undefined) {
this.decryptedVault.importedWallets.evmChains = { data: [{ address, privateKey: encryptedPrivKey, isDeleted: false, isImported: true, label: `Wallet ${numOfAcc + 1}` }] };
this.decryptedVault.importedWallets.evmChains = { data: [{ address, privateKey: encryptedPrivKey, isDeleted: false, isImported: true, label: `${labelPrefix} Wallet ${numOfAcc + 1}` }] };
} else {
this.decryptedVault.importedWallets.evmChains.data.push({ address, privateKey: encryptedPrivKey, isDeleted: false, isImported: true, label: `Wallet ${numOfAcc + 1}` });
this.decryptedVault.importedWallets.evmChains.data.push({ address, privateKey: encryptedPrivKey, isDeleted: false, isImported: true, label: `${labelPrefix} Wallet ${numOfAcc + 1}` });
}
} else {
let labelPrefix = Chains.nonEvmChains[this.chain]
const { response: mnemonic } = await this.exportMnemonic(pin);

if (this[this.chain] === undefined) {
Expand Down Expand Up @@ -699,16 +706,16 @@ class Keyring {
if (this.decryptedVault.importedWallets === undefined) {
let object = {};

const data = [ { address, isDeleted: false, isImported: true, privateKey: encryptedPrivKey, label: `${this.chain[0].toUpperCase() + this.chain.slice(1)} Wallet ${numOfAcc + 1}` } ];
const data = [ { address, isDeleted: false, isImported: true, privateKey: encryptedPrivKey, label: `${labelPrefix} Wallet ${numOfAcc + 1}` } ];

object[this.chain] = { data };
this.decryptedVault.importedWallets = object;
} else if (this.decryptedVault.importedWallets[this.chain] === undefined) {
const data = [ { address, isDeleted: false, isImported: true, privateKey: encryptedPrivKey, label: `${this.chain[0].toUpperCase() + this.chain.slice(1)} Wallet ${numOfAcc + 1}` } ];
const data = [ { address, isDeleted: false, isImported: true, privateKey: encryptedPrivKey, label: `${labelPrefix} Wallet ${numOfAcc + 1}` } ];

this.decryptedVault.importedWallets[this.chain] = { data };
} else {
this.decryptedVault.importedWallets[this.chain].data.push({ address, isDeleted: false, isImported: true, privateKey: encryptedPrivKey, label: `${this.chain[0].toUpperCase() + this.chain.slice(1)} Wallet ${numOfAcc + 1}` });
this.decryptedVault.importedWallets[this.chain].data.push({ address, isDeleted: false, isImported: true, privateKey: encryptedPrivKey, label: `${labelPrefix} Wallet ${numOfAcc + 1}` });
}
}

Expand Down
24 changes: 15 additions & 9 deletions src/lib/vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ class Vault extends Keyring {

const privData = await helper.generatePrivData(mnemonic, pin);

const rawVault = { eth: { public: [ { address: accounts[0], isDeleted: false, isImported: false, label: 'Wallet 1' } ], private: privData, numberOfAccounts: 1 }}
const rawVault = { eth: { public: [ { address: accounts[0], isDeleted: false, isImported: false, label: 'EVM Wallet 1' } ], private: privData, numberOfAccounts: 1 }}

this.initializeSupportedChainKeyringController(mnemonic);

for (const chain of Object.keys(Chains.nonEvmChains)) {
const {address: addedAcc } = await this[chain].addAccount();
let label = `${chain.charAt(0).toUpperCase() + chain.substr(1).toLowerCase()} Wallet 1`
let label = `${Chains.nonEvmChains[chain]} Wallet 1`
rawVault[chain] = { public: [ { address: addedAcc, isDeleted: false, isImported: false, label: label } ], numberOfAccounts: 1 }
}

Expand Down Expand Up @@ -129,8 +129,14 @@ class Vault extends Keyring {

const vaultState = await this.keyringInstance.createNewVaultAndRestore(JSON.stringify(encryptionKey), mnemonic);

const accountsArray = await helper.removeEmptyAccounts(vaultState.keyrings[0].accounts[0], this.keyringInstance, vaultState, unmarshalApiKey, recoverMechanism, logs);

let accountsArray = [];
if(recoverMechanism === 'transactions') {
accountsArray = await helper.getAccountsFromTransactions(vaultState.keyrings[0].accounts[0], this.keyringInstance, vaultState, unmarshalApiKey)
}
else if (recoverMechanism === 'logs') {
accountsArray = await helper.getAccountsFromLogs('ethereum', this.keyringInstance, vaultState, logs, vaultState.keyrings[0].accounts[0])
}

const privData = await helper.generatePrivData(mnemonic, pin);

const numberOfAccounts = accountsArray.length;
Expand All @@ -141,14 +147,14 @@ class Vault extends Keyring {

//generate other chain's keyring instance and get accounts from logs
let obj = {}
for ( let chainData of nonEvmChainList) {

const keyringInstance = await helper.getCoinInstance(chainData.toLowerCase(), mnemonic);
for ( let chain of nonEvmChainList) {
const keyringInstance = await helper.getCoinInstance(chain.toLowerCase(), mnemonic);

const accArray = await helper.getAccountsFromLogs(keyringInstance, vaultState, recoverMechanism, logs);
let {address} = await keyringInstance.addAccount();
const accArray = await helper.getAccountsFromLogs(chain, keyringInstance, vaultState, logs, address);
const numberOfAcc = accArray.length;

rawVault[chainData.toLowerCase()] = { public: accArray, numberOfAccounts: numberOfAcc }
rawVault[chain.toLowerCase()] = { public: accArray, numberOfAccounts: numberOfAcc }

}

Expand Down
Loading

0 comments on commit 9880af1

Please sign in to comment.