Metadata (labeling)

Metadata is a feature that allows the user to associate persistent data with their wallets, accounts, receive addresses, and outputs. Trezor Suite refers to metadata as to "labeling" in the user interface.

For non-technical introduction, see Trezor Learn.

Data stores

Because Trezor Suite is not a typical application with a backend server, data must be stored elsewhere. Currently supported providers are:

  • Dropbox
  • Google Drive
  • Local file system (desktop only)

Google Drive specifics

Google Drive authentication has differing implementations for desktop and web version of Suite. For security reasons, Google does not allow the authorization code flow for web apps, thus only allowing the user of web Suite to log in via the implicit flow with an access token lasting for lasts one hour. Authorization code flow used in the desktop app leverages a refresh token to enable the user to stay logged in permanently while using desktop Suite. To implement this flow, we had to establish an authorization backend holding a client_secret, see @trezor/auth-server. If the authorization via our backend fails for some reason, there is a fallback to the implicit flow in the desktop app. TODO: switch from the fallback flow to the authorization code flow as soon as possible so that the user does not have to re-authenticate every hour.

Data structure in store

version 1.0.0 (current)

device metadata example

{
  "version": "1.0.0",
  "walletLabel": "my hidden wallet label",
},

account metadata example

{
  "version": "1.0.0",
  "accountLabel": "my cool account label",
  "outputLabels": {
    "9f472739fa7034dfb9736fa4d98915f2e8ddf70a86ee5e0a9ac0634f8c1d0007": {
      "0": "transaction 1"
    },
  },
  "addressLabels": {
    "bc1qannfxke2tfd4l7vhepehpvt05y83v3qsf6nfkk": "my cool address label",
  }
}

version 2.0.0 (future)

Each record will have timestamp which will allow user to resolve potential conflicts. (Implementation not currently planned.)

Data encryption

Data is stored in encrypted form using aes-256-gcm cipher. Master key for encryption is generated by users Trezor with constants defined in suite/src/actions/suite/constants/metadataConstants.ts Files encryption-decryption logic is located in suite/src/utils/suite/metadata.ts

Where data lives in the App

Settings related data is defined in suite/src/reducers/suite/metadataReducer which contains

{
 enabled: bool,
 initiating: bool,
 provider: {
  isCloud: bool,
   type: "dropbox" | "google" | "fileSystem",
   tokens: {
    accessToken?: string,
    refreshToken?: string
   },
   user: string
 }
}

Metadata itself is divided into 2 groups (device metadata and account metadata). They are stored together with concrete records.

Device has metadata property:

{
  /*
   - disabled is initial state. user has not interacted with metadata before, metadata keys are not available
   - enabled means that metadata is enabled for this device and application has metadata keys. App will try to download and decipher metadata
   - cancelled means that user rejected cipherKeyValue call on device.
  */
  status: "disabled" |"enabled" | "cancelled",
  key: string,
  fileName: string,
  aesKey: string,
  walletLabel: string
}

Account has metadata property which is an object of following shape:

{
  key: string(xpub),
  fileName: string,
  aesKey: string,
  outputLabels: {
    [string(txid)]: {
      [number(outputIndex)]: string
    },
  },
  addressLabels: {
    [string(address)]: string,
  },
  accountLabel: string
}

Where metadata is set and displayed

  • Wallet label is set in the modal where wallet is selected.
  • Account label is set in account header.
  • Receiving address label is set in the receive address list.
  • Output label is set in send form address field, coin control or transaction history

Note that transaction history displays output label and address next to each other. If the output does not have a label, only the address is shown. If it does, the address is shown when the label is hovered. The address is displayed as follows:

  • If a receive address has a label, its label is displayed.
  • If a receive address has a label and it belongs to the same account, it is replaced by "Sent to myself".
  • If an outgoing address belongs to another discovered wallet or account, it is replaced by the account label (and wallet label, if it is a different wallet).
  • If none of the above is true, plain address is displayed.

Wallet and account labels can also be displayed in other places in Suite as read-only, e.g. in send form when sending to an address belonging to another discovered wallet or account.

Device name set in device settings is not part of metadata.

User stories

First time user:

  1. User opens App for the first time. Metadata is disabled. "Add label" buttons are present on mouse hover over labelable data.
  2. User clicks "Add label" button.
  3. Device metadata key is generated.
  4. Using device metadata key, account metadata keys are created.
  5. Open modal with metadata providers and connect.
  6. Fetch data from metadata provider and set interval for fetching data.
  7. Activate editable input.

Metadata enabled during discovery process:

Controlled by discoveryActions and metadataMiddleware

  1. If passphrase is not used, device metadata key is generated before discovery process starts. (discoveryActions)
  2. If passphrase is used, metadata key is generated either:
    • in the middle of the discovery process after successfully receiving the first bundle of accounts and at least one account is not empty. (discoveryActions)
    • after passphrase confirmation process. (metadataMiddleware)

How to turn metadata off

  • controls for common metadata related actions are located in general settings under the labeling section
  • there is a switch which:
    1. sets metadata.enabled bool value
    2. if setting to false, it triggers removal of all metadata (including keys) from devices and accounts.
    3. if setting to false, disconnects metadata provider (Dropbox, Google Drive)
  • there is a button "disconnect provider" which:
    1. triggers removal of all metadata values (excluding metadata keys) from devices and accounts. This way provider might be reconnected without reconnecting device
    2. disconnects metadata provider