mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-03-03 05:55:03 +01:00
170 lines
6.7 KiB
Markdown
170 lines
6.7 KiB
Markdown
# 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](https://trezor.io/guides/trezor-suite/trezor-suite-desktop/labels-in-trezor-suite).
|
|
|
|
## 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](https://github.com/trezor/trezor-suite/tree/develop/packages/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
|
|
|
|
```javascript
|
|
{
|
|
"version": "1.0.0",
|
|
"walletLabel": "my hidden wallet label",
|
|
},
|
|
```
|
|
|
|
account metadata example
|
|
|
|
```javascript
|
|
{
|
|
"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](https://github.com/trezor/trezor-suite/blob/develop/packages/suite/src/actions/suite/constants/metadataConstants.ts)
|
|
Files encryption-decryption logic is located in
|
|
[suite/src/utils/suite/metadata.ts](https://github.com/trezor/trezor-suite/blob/develop/packages/suite/src/utils/suite/metadata.ts)
|
|
|
|
## Where data lives in the App
|
|
|
|
Settings related data is defined in [suite/src/reducers/suite/metadataReducer](https://github.com/trezor/trezor-suite/blob/develop/packages/suite/src/reducers/suite/metadataReducer.ts) 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.
|
|
1. User clicks "Add label" button.
|
|
1. Device metadata key is generated.
|
|
1. Using device metadata key, account metadata keys are created.
|
|
1. Open modal with metadata providers and connect.
|
|
1. Fetch data from metadata provider and set interval for fetching data.
|
|
1. 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`)
|
|
1. 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
|
|
1. if setting to false, it triggers removal of all metadata (including keys) from devices and accounts.
|
|
1. 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
|
|
1. disconnects metadata provider
|