Skip to content

App upgrade and Migration

Pascal Lapointe edited this page Aug 25, 2021 · 3 revisions

The Upgrade & Migration system as been developed to support the growth of Nami Wallet. As the application evolve, changes need to be made to the data structure. If not done properly, theses changes often lead to unexpected behavior or even end up breaking the app, forcing the end user to reset and start fresh. This is where the migration system comes into play.

Upgrade & Migration flow

  1. Application start -> Check if the migration object is present in the storage. If not, the system assume it is a new install and the migration object is initialized to the current App version.

    {  
      ...,
      migration : {
        version: 'CURRENT_VERSION (1.X.X)',
        completed: [],
      },
      ...,
    {
    
  2. The app version is compared with the version stored under the migration.version key. If a mismatch is detected, the migrate() function is trigged.

  3. The migrate() function first determine if the app need to be upgraded, or downgraded. Then it filter through the set of available migration scripts that fit the proper version range.

    • In case of an upgrade, the range will fit the following criteria: ]storageVersion,appVersion]. Scripts will be ran in an ascending order.

    • In case of a downgrade, the range will fit the following criteria: [storageVersion,appVersion[. Scripts will be ran in a descending order.

  4. Upgrade informations can be attached to each migration scripts. Theses informations are returned as the output of the migrate() function. After each Upgrade, the wallet show theses information to the user. Nothing is actually shown if a Downgrade takes place. Downgrade are usually used as a mean to easily revert the storage to an older state when writing and testing new migration scripts. In case of a faulty app release, downgrade could be used to revert the wallet to a bug free state.

Migration Scripts

Migrations scripts can be found under /src/migrations/ folder. They are simple js module with the following structure:

```
const migration = {
  version: '1.0.0',
  up: (pwd) => {
    // Upgrade logic here
  },
  down: (pwd) => {
    // Downgrade logic here
  },
  info: [
    {
      title: 'Feature #1',
      detail: 'This new feature allow the user to see the Feature #1',
    },
    { title: 'Bug fix: Feature #2', detail: null },
    ...
  ],
  pwdRequired: true,
};

export default migration;
```

You can notice that an optional pwdRequired property allow a migration to ask or the user password if key decryption is needed. This option shall be used only in exceptional case.

The info property describes what changes are brought by the new App version. They are displayed only on Upgrade.

Creating a new migration script

The following steps describe how to create a new migration scripts:

  1. Duplicate & rename a migration files under /src/migrations/.

  2. Insert the storage migration logic under up() and down(). Fill the info object with applied changes and insure the pwdRequired property is set false unless needed.

  3. Import the migration file in /src/lib/migration.js and add the imported migration to the MIG_SCRIPTS array.

  4. Change the app version in package.json.

  5. Open the app to test your new migration. Revert the version to an older one in package.json to downgrade.

  6. Make sure to thoroughly test the Upgrade & Downgrade process before releasing any migrations affecting the storage.

Clone this wiki locally