FuelLabs/forc-wallet

Use a single wallet file for storing both the keystore and derived account tracking

mitchmindtree opened this issue · 2 comments

It would be nice if a user could store their wallet within a single file in a portable way without having to zip up a directory.

It would also help with some of the ambiguity around "wallet paths" in the UI, as it's not always clear if a wallet path refers to a .wallet file (the keystore), or the directory containing both .wallet and .accounts files.

Currently, it looks like the main reason we store the .wallet keystore and .accounts data in separate files is because the eth_keystore crate only exposes functions that operate on the keystore as an independent file. We could easily work around this by serializing just the keystore to a temporary file, interacting with eth_keystore crate, then updating our original wallet file as necessary.

File Layout

A simple JSON file that basically joins our current files, e.g.

{
    "keystore": /* serialization of keystore (currently `.wallet`) */,
    "accounts": /* serialization of `Accounts` (currently `.accounts`) */
}

Full example:

{
  "keystore": {
    "crypto": {
      "cipher": "aes-128-ctr",
      "cipherparams": {
        "iv": "749e7fab374762912860986c2e08d48e"
      },
      "ciphertext": "032cd4033bf089c54f3c36947cc072b75bf936d3a1b74e351d7fba8531d41c3a60dbf68314f5d495426ffc15c214e57d06eca1be09a58527ad2efca1939cb4137dfe8b346b3c76a6287f8e4c58e6a7b5a7c8f3d4f32db984bafea521d7808f0aecff40d043106e72651ce2f33646653de62b9bc137dd6688af0d38572344e99b91d1599d4bb6d633b60de00aaf12c5b8",
      "kdf": "scrypt",
      "kdfparams": {
        "dklen": 32,
        "n": 8192,
        "p": 1,
        "r": 8,
        "salt": "398e5f2d3fb11f3aa009d209da9dd02c43568b343f7162499669c74957c9bb98"
      },
      "mac": "9885432bf3b6e914bdb312a37babcca19becfc4f7d86d913ebcc172bcd1a9f22"
    },
    "id": "dc8c6438-f953-4a1d-8abc-52cf403d9915",
    "version": 3
  },
  "accounts": {
    "addresses": [
      "fuel1htrldg7wpelrnhvad8lwcep57duhpxmj2h6a55nhr4md4839cy2q04p3tu"
    ]
  }
}

Note the accounts layout may be subject to change as of #77.


Edit: Please correct me if I'm missing some other motivation to using solely .wallet keystore files! E.g. Perhaps this is some standard file format that can be used with different ETH tooling?

I can see that the eth_keystore crate aims to adhere to the "Web3 Secret Storage Definition" here:

https://ethereum.org/en/developers/docs/data-structures-and-encoding/web3-secret-storage/#top

In the case that someone does want the pure keystore representation, we could provide a forc wallet export keystore command which outputs the JSON adhering to Web3 Secret Storage Definition, and similarly provide a forc wallet import keystore ./path/to/keystore command.

That said, I'm not sure how much we care about adhering to this standard, as we're already ignoring the recommended file location etc mentioned here.

Perhaps a better option could be to:

  1. When accepting wallet paths on the command line, only accept paths to files adhering to the keystore spec described in Web3 Secret Storage Definition.
  2. For tracking known, derived account addresses, do so using a cache-like approach within .fuel/wallets/accounts/<wallet-ciphertext>.json, so that no matter where the wallet is stored, we can track known derived account addresses in a single location.

This change would also allow us the option of relocating the file to the recommended location in the Web3 Secret Storage Definition, i.e. ~/web3/keystore/ if we wish to follow this convention.