Skip to content

Commit

Permalink
feat: enhance account migration process and ensure complete before lo…
Browse files Browse the repository at this point in the history
…ading keys
  • Loading branch information
F-OBrien committed Jan 8, 2025
1 parent 2450b91 commit d5b8e1a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 22 deletions.
37 changes: 34 additions & 3 deletions packages/core/src/store/accountMigrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,46 @@ export default class AccountMigrations extends BaseStore<KeyringJson> implements
// EXTENSION_PREFIX configured in webpack.shared.cjs
public async migrateUnPrefixedAccounts (): Promise<void> {
const accountsStore = new AccountsStore();
const migrationPromises: Promise<void>[] = [];

const migrateAccount = async (key: string, value: KeyringJson): Promise<void> => {
if (key.startsWith('account:')) {
await accountsStore.set(key, value);
let existingValue: KeyringJson | null = null;

await accountsStore.get(key, (value) => {
existingValue = value;
});

// If the account already exists, remove the old storage key
if (existingValue) {
console.log(`Account with key ${key} already migrated, removing the old storage key`);
await super.remove(key);

return;
}

// migrate the account to the new storage key
await accountsStore.set(key, value);

// Verify the migration was successful
await accountsStore.get(key, (value) => {
existingValue = value;
});

if (existingValue) {
// Migration successful, remove the old storage key
await super.remove(key);
console.log(`Migration successful for key ${key}`);
} else {
console.error(`Failed to verify migration for key ${key}`);
}
};

await super.all((key, value): void => {
migrateAccount(key, value).catch(console.error);
if (key.startsWith('account:')) {
migrationPromises.push(migrateAccount(key, value).catch(console.error));
}
});

await Promise.all(migrationPromises);
}
}
21 changes: 20 additions & 1 deletion packages/extension/src/background-init.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
/* global chrome */

import { AccountsStore } from '@polkadot/extension-base/stores';
import { keyring } from '@polkadot/ui-keyring';
import { cryptoWaitReady } from '@polkadot/util-crypto';

import { fatalErrorHandler } from '@polymeshassociation/extension-core/utils';

import { checkForUpdateAndMigrate } from './migrations';

// Ensure crypto is ready and load all keyring data
async function initializeCryptoAndKeyring () {
await cryptoWaitReady();
console.log('crypto initialized');

keyring.loadAll({ store: new AccountsStore(), type: 'sr25519' });
console.log('initialization completed');
}

/*
This is placed in a separate file to ensure that the listener is registered immediately,
avoiding any delays caused by other imports or initializations. When placed in background.ts
it was not being registered before the event was emitted.
*/

chrome.runtime.onInstalled.addListener((details) => {
checkForUpdateAndMigrate(details).catch(console.error);
checkForUpdateAndMigrate(details)
.then(() => {
return initializeCryptoAndKeyring();
})
.catch(fatalErrorHandler);
});
16 changes: 0 additions & 16 deletions packages/extension/src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@ import type { PolyRequestSignatures, PolyTransportRequestMessage } from '@polyme

import { withErrorLog } from '@polkadot/extension-base/background';
import { PORT_CONTENT, PORT_EXTENSION } from '@polkadot/extension-base/defaults';
import { AccountsStore } from '@polkadot/extension-base/stores';
import { keyring } from '@polkadot/ui-keyring';
import { assert } from '@polkadot/util';
import { cryptoWaitReady } from '@polkadot/util-crypto';

import subscribePolymesh, { accountsSynchronizer } from '@polymeshassociation/extension-core';
import handlers from '@polymeshassociation/extension-core/background/handlers';
import { fatalErrorHandler } from '@polymeshassociation/extension-core/utils';

// setup the notification (same a FF default background, white text)
withErrorLog(() => chrome.action.setBadgeBackgroundColor({ color: '#d90000' }));
Expand Down Expand Up @@ -114,15 +110,3 @@ chrome.tabs.onActivated.addListener(() => {
chrome.tabs.onRemoved.addListener(() => {
getActiveTabs();
});

// initial setup
cryptoWaitReady()
.then((): void => {
console.log('crypto initialized');

// load all the keyring data
keyring.loadAll({ store: new AccountsStore(), type: 'sr25519' });

console.log('initialization completed');
})
.catch(fatalErrorHandler);
4 changes: 2 additions & 2 deletions packages/extension/src/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ async function runMigrations () {
}

// Check for version update and perform migration if needed
export async function checkForUpdateAndMigrate (details: chrome.runtime.InstalledDetails) {
export async function checkForUpdateAndMigrate (details: chrome.runtime.InstalledDetails): Promise<void> {
if (details.reason === chrome.runtime.OnInstalledReason.UPDATE) {
const previousVersion = details.previousVersion;

// Migrate Account Prefixes. Runs when no lastVersion or a previous version of 2.0.2 or earlier
if (previousVersion && isVersionEarlierOrEqual(previousVersion, '2.0.2')) {
if (!previousVersion || isVersionEarlierOrEqual(previousVersion, '2.2.0')) {
await runMigrations();
}
}
Expand Down

0 comments on commit d5b8e1a

Please sign in to comment.