---
eip: 2386
title: Ethereum 2 Hierarchical Deterministic Walletstore
author: Jim McDonald <Jim@mcdee.net>
discussions-to: https://ethereum-magicians.org/t/eip-2386-walletstore/3792
status: Stagnant
type: Standards Track
category: ERC
created: 2019-11-21
requires: 2334, 2335
---

## Simple Summary

A JSON format for the storage and retrieval of Ethereum 2 hierarchical deterministic (HD) wallet definitions.

## Abstract

Ethereum has the concept of keystores: pieces of data that define a key (see [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335) for details).  This adds the concept of walletstores: stores that define wallets and how keys in said wallets are created.

## Motivation

Hierarchical deterministic wallets create keys from a _seed_ and a _path_.  The seed needs to be accessible to create new keys, however it should also be protected to the same extent as private keys to stop it from becoming an easy attack vector.  The path, or at least the variable part of it, needs to be stored to ensure that keys are not duplicated.  Providing a standard method to do this can promote interoperability between wallets and similar software.

Given that a wallet has an amount of data and metadata that is useful when accessing existing keys and creating new keys, standardizing this information and how it is stored allows it to be portable between different wallet providers with minimal effort.

## Specification

The elements of a hierarchical deterministic walletstore are as follows:

### UUID

The `uuid` provided in the walletstore is a randomly-generated type 4 UUID as specified by [RFC 4122](https://tools.ietf.org/html/rfc4122). It is intended to be used as a 128-bit proxy for referring to a particular wallet, used to uniquely identify wallets.

This element MUST be present.  It MUST be a string following the syntactic structure as laid out in [section 3 of RFC 4122](https://tools.ietf.org/html/rfc4122#section-3).

### Name

The `name` provided in the walletstore is a UTF-8 string.  It is intended to serve as the user-friendly accessor.  The only restriction on the name is that it MUST NOT start with the underscore (`_`) character.

This element MUST be present.  It MUST be a string.

### Version

The `version` provided is the version of the walletstore.

This element MUST be present.  It MUST be the integer `1`.

### Type

The `type` provided is the type of wallet.  This informs mechanisms such as key generation.

This element MUST be present.  It MUST be the string `hierarchical deterministic`.

### Crypto

The `crypto` provided is the secure storage of a secret for wallets that require this information.  For hierarchical deterministic wallets this is the seed from which they calculate individual private keys.

This element MUST be present.  It MUST be an object that follows the definition described in [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335).

### Next Account

The `nextaccount` provided is the index to be supplied to the path `m/12381/60/<index>/0` when creating a new private key from the seed.  The path follows [EIP-2334](https://eips.ethereum.org/EIPS/eip-2334).

This element MUST be present if the wallet type requires it.  It MUST be a non-negative integer.

### JSON schema

The walletstore follows a similar format to that of the keystore described in [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335).

```json
{
    "$ref": "#/definitions/Walletstore",
    "definitions": {
        "Walletstore": {
            "type": "object",
            "properties": {
                "crypto": {
                    "type": "object",
                    "properties": {
                        "kdf": {
                            "$ref": "#/definitions/Module"
                        },
                        "checksum": {
                            "$ref": "#/definitions/Module"
                        },
                        "cipher": {
                            "$ref": "#/definitions/Module"
                        }
                    }
                },
                "name": {
                    "type": "string"
                },
                "nextaccount": {
                    "type": "integer"
                },
                "type": {
                    "type": "string"
                },
                "uuid": {
                    "type": "string",
                    "format": "uuid"
                },
                "version": {
                    "type": "integer"
                }
            },
            "required": [
                "name",
                "type",
                "uuid",
                "version"
                "crypto"
                "nextaccount"
            ],
            "title": "Walletstore"
        },
        "Module": {
            "type": "object",
            "properties": {
                "function": {
                    "type": "string"
                },
                "params": {
                    "type": "object"
                },
                "message": {
                    "type": "string"
                }
            },
            "required": [
                "function",
                "message",
                "params"
            ]
        }
    }
}
```

## Rationale

A standard for walletstores, similar to that for keystores, provides a higher level of compatibility between wallets and allows for simpler wallet and key interchange between them.

## Test Cases

### Test Vector

Password `'testpassword'`
Seed `0x147addc7ec981eb2715a22603813271cce540e0b7f577126011eb06249d9227c`

```json
{
  "crypto": {
    "checksum": {
      "function": "sha256",
      "message": "8bdadea203eeaf8f23c96137af176ded4b098773410634727bd81c4e8f7f1021",
      "params": {}
    },
    "cipher": {
      "function": "aes-128-ctr",
      "message": "7f8211b88dfb8694bac7de3fa32f5f84d0a30f15563358133cda3b287e0f3f4a",
      "params": {
        "iv": "9476702ab99beff3e8012eff49ffb60d"
      }
    },
    "kdf": {
      "function": "pbkdf2",
      "message": "",
      "params": {
        "c": 16,
        "dklen": 32,
        "prf": "hmac-sha256",
        "salt": "dd35b0c08ebb672fe18832120a55cb8098f428306bf5820f5486b514f61eb712"
      }
    }
  },
  "name": "Test wallet 2",
  "nextaccount": 0,
  "type": "hierarchical deterministic",
  "uuid": "b74559b8-ed56-4841-b25c-dba1b7c9d9d5",
  "version": 1
}
```

## Implementation

A Go implementation of the hierarchical deterministic wallet can be found at [https://github.com/wealdtech/go-eth2-wallet-hd](https://github.com/wealdtech/go-eth2-wallet-hd).

## Security Considerations

The seed stored in the `crypto` section of the wallet can be used to generate any key along the derived path.  As such, the security of all keys generated by HD wallets is reduced to the security of the passphrase and strength of the encryption used to protect the seed, regardless of the security of the passphrase and strength of the encryption used to protect individual keystores.

It is possible to work with only the walletstore plus an index for each key, in which case stronger passphrases can be used as decryption only needs to take place once.  It is also possible to use generated keystores without the walletstore, in which case a breach of security will expose only the keystore.

An example high-security configuration may involve the walletstore existing on an offline computer, from which keystores are generated.  The keystores can then be moved individually to an online computer to be used for signing.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
