mirror of
https://github.com/bitcoin/bips.git
synced 2026-11-02 19:41:29 +00:00
230 lines
10 KiB
Markdown
230 lines
10 KiB
Markdown
```
|
|||
|
|
BIP: 139
|
||
|
|
Layer: Applications
|
||
|
|
Title: Wallet Metadata Export Format
|
||
|
|
Authors: Pyth <pythcoiner@wizardsardine.com>
|
||
|
|
Status: Draft
|
||
|
|
Type: Specification
|
||
|
|
Assigned: 2026-05-11
|
||
|
|
License: BSD-2-Clause
|
||
|
|
Discussion: https://groups.google.com/g/bitcoindev/c/ylPeOnEIhO8
|
||
|
|
```
|
||
|
|
|
||
|
|
## Abstract
|
||
|
|
|
||
|
|
This document specifies a format for exporting the metadata of a wallet: its accounts,
|
||
|
|
descriptors, key information, signers, labels, transactions, coins, and partially signed
|
||
|
|
Bitcoin transactions (PSBTs).
|
||
|
|
The format gives these records a common structure and common field names, so that
|
||
|
|
what one wallet application writes another can read.
|
||
|
|
Each object structure defines a few mandatory fields; all other fields are optional.
|
||
|
|
The base structure must include at least one account entry.
|
||
|
|
|
||
|
|
The fields of the format are collected in a companion
|
||
|
|
[field registry](bip-0139/field-registry.md), which acts as a central repository where
|
||
|
|
a wallet implementer can register their usage of a field and share that usage through a
|
||
|
|
test vector.
|
||
|
|
|
||
|
|
## Copyright
|
||
|
|
|
||
|
|
This BIP is licensed under the BSD 2-clause license.
|
||
|
|
|
||
|
|
## Motivation
|
||
|
|
|
||
|
|
[BIP-0032](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) and
|
||
|
|
[BIP-0039](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) let a
|
||
|
|
user carry keys from one application to another, and
|
||
|
|
[BIP-0329](https://github.com/bitcoin/bips/blob/master/bip-0329.mediawiki) does the
|
||
|
|
same for the labels attached to a wallet's records.
|
||
|
|
There is no specification targeting the entire set of metadata a wallet can carry:
|
||
|
|
|
||
|
|
- list of accounts attached to this wallet and their descriptors.
|
||
|
|
- list of signers holding a key in the descriptor & how to interact with these signers.
|
||
|
|
- when an account has been created & what the last seen chain tip is.
|
||
|
|
- which outputs are owned by the account & which of them have been frozen by the user.
|
||
|
|
- etc.
|
||
|
|
|
||
|
|
A big part of this metadata cannot be recovered from the chain, so a user willing to
|
||
|
|
migrate from one wallet to another has to re-enter it by hand or do without it.
|
||
|
|
A format that two applications can both write and read removes that cost, and the
|
||
|
|
lock-in that follows from it.
|
||
|
|
|
||
|
|
## Rationale
|
||
|
|
|
||
|
|
Several wallet applications already export their whole state, each in a form only they
|
||
|
|
can read.
|
||
|
|
Because each format is specific to one application, moving between any two of them
|
||
|
|
means writing a converter for that pair.
|
||
|
|
This proposal introduces a structured format, leveraging JSON to store wallet
|
||
|
|
metadata in a portable way.
|
||
|
|
The format is flexible and extensible, allowing wallet developers to include as much
|
||
|
|
or as little information as they think necessary.
|
||
|
|
|
||
|
|
By keeping the mandatory set of metadata small and keeping every other field
|
||
|
|
optional, this spec accommodates diverse use cases and preferences.
|
||
|
|
Wallet developers can include only the fields relevant to their software while
|
||
|
|
maintaining structural integrity.
|
||
|
|
|
||
|
|
## Specification
|
||
|
|
|
||
|
|
A wallet export is a UTF-8 encoded text file containing a single valid JSON object
|
||
|
|
representing the wallet.
|
||
|
|
This object includes wallet-level metadata, multiple accounts, and associated key
|
||
|
|
data.
|
||
|
|
|
||
|
|
Every timestamp in this format and its registry is an integer representing a Unix
|
||
|
|
timestamp in seconds.
|
||
|
|
Block heights are integers and are never interchangeable with timestamps.
|
||
|
|
|
||
|
|
### Field Registry
|
||
|
|
|
||
|
|
The fields of every object structure are defined in the
|
||
|
|
[field registry](bip-0139/field-registry.md) rather than in this document, so new
|
||
|
|
fields could be added without amending this BIP.
|
||
|
|
The registry records field and object definitions and marks mandatory fields, so each
|
||
|
|
object's structure can be read from its table.
|
||
|
|
A registry pull request may add or change optional fields only. The mandatory fields
|
||
|
|
are fixed by this BIP, and making a field mandatory is a change to this BIP.
|
||
|
|
Registration of a new field must state the field name, the object it belongs to,
|
||
|
|
its type, and a short description, and should link a test vector or an implementation
|
||
|
|
using it when available.
|
||
|
|
A field name must not conflict with an already registered field of the same object.
|
||
|
|
|
||
|
|
### Wallet Object Structure
|
||
|
|
|
||
|
|
The top-level JSON object must contain the `version` and `network` fields and at
|
||
|
|
least one account in the `accounts` array.
|
||
|
|
Its fields are listed in the [field registry](bip-0139/field-registry.md).
|
||
|
|
|
||
|
|
- `version`: Mandatory string identifying the version of the export format.
|
||
|
|
Must be `BIP139-<version>`, where `<version>` is an integer.
|
||
|
|
The export format version is incremented only for changes that are not backward
|
||
|
|
compatible, such as adding a mandatory field.
|
||
|
|
- `network`: Mandatory string naming the network the export covers.
|
||
|
|
Must be one of `bitcoin` (mainnet), `testnet3`, `testnet4`, `signet`, `mutinynet`
|
||
|
|
or `regtest`.
|
||
|
|
An export covers a single network. A wallet holding accounts on more than one
|
||
|
|
writes one export per network.
|
||
|
|
- `accounts`: Mandatory array of account objects.
|
||
|
|
Must contain at least one account.
|
||
|
|
See [Account Object Structure](#account-object-structure).
|
||
|
|
|
||
|
|
The optional `signers` array holds information about devices that hold key material
|
||
|
|
present in at least one account's descriptor. See [Signer Object Structure](#signer-object-structure).
|
||
|
|
|
||
|
|
### Account Object Structure
|
||
|
|
|
||
|
|
Each account object in the `accounts` array represents a single account within the
|
||
|
|
wallet and must contain the `type` and `descriptor` fields.
|
||
|
|
Its fields are listed in the [field registry](bip-0139/field-registry.md).
|
||
|
|
|
||
|
|
- `type`: Mandatory string naming the account descriptor type.
|
||
|
|
Must be one of `bip380` (output descriptor), `multi_bip380` (a set of BIP-0380
|
||
|
|
output descriptors), `bip388` (wallet policies), or `bip392` (silent payments).
|
||
|
|
- `descriptor`: Mandatory value representing the account descriptor, with structure
|
||
|
|
defined by `type`.
|
||
|
|
The value is a string for every type except `multi_bip380`, which uses an array of
|
||
|
|
strings.
|
||
|
|
|
||
|
|
A `multi_bip380` account groups several BIP380 descriptors without further restriction.
|
||
|
|
This can be needed for wallets such as Electrum.
|
||
|
|
|
||
|
|
### Signer Object Structure
|
||
|
|
|
||
|
|
Each entry in the `signers` array describes one holder of key material: a hardware
|
||
|
|
device, a piece of software, or a remote service. A signer must contain the
|
||
|
|
`fingerprints` field, and the field must not be empty.
|
||
|
|
The signer object's fields are listed in the [field registry](bip-0139/field-registry.md).
|
||
|
|
|
||
|
|
- `fingerprints`: Mandatory array of BIP32 fingerprints held by this signer, in
|
||
|
|
hexadecimal form.
|
||
|
|
|
||
|
|
The field is a list because one signer can hold several master keys, as with a device
|
||
|
|
that has more than one mnemonic loaded, or several keys generated using the BIP-0039
|
||
|
|
passphrase mechanism.
|
||
|
|
The relation is many-to-many: a key restored onto two devices appears in the
|
||
|
|
`fingerprints` of two signers.
|
||
|
|
|
||
|
|
Signers are listed in the wallet object rather than inside each `accounts` object because
|
||
|
|
a signer can be related to several accounts and none of its metadata should change
|
||
|
|
between accounts. A signer used by three accounts is written once, so the copies
|
||
|
|
cannot drift.
|
||
|
|
|
||
|
|
### Key Object Structure
|
||
|
|
|
||
|
|
Keys in the `keys` dictionary are indexed by their
|
||
|
|
[BIP32 fingerprint](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#key-identifiers).
|
||
|
|
Each key object records how *this account* uses the key and must contain the `key`
|
||
|
|
field. Its fields are listed in the [field registry](bip-0139/field-registry.md).
|
||
|
|
|
||
|
|
What the key *is*, independent of any account, belongs in the wallet-level `signers`
|
||
|
|
array instead. The fingerprint is the shared key that reconciles the two.
|
||
|
|
|
||
|
|
- `key`: Mandatory string representing the public key fingerprint in hexadecimal
|
||
|
|
form.
|
||
|
|
|
||
|
|
### Transaction Object Structure
|
||
|
|
|
||
|
|
Values of the wallet's `transactions` map are JSON objects, each describing a single
|
||
|
|
transaction. Each is keyed by its transaction id, so the object itself carries no
|
||
|
|
identifier. Its fields are listed in the [field registry](bip-0139/field-registry.md).
|
||
|
|
|
||
|
|
### Coin Object Structure
|
||
|
|
|
||
|
|
Each entry in the `coins` array is a JSON object describing a single output owned by
|
||
|
|
the account and must contain the `outpoint` field.
|
||
|
|
The coin object's fields are listed in the [field registry](bip-0139/field-registry.md).
|
||
|
|
|
||
|
|
A coin object records wallet state: what the account owns and what the user has
|
||
|
|
decided about it. Silent payment outputs are coins too, and carry a `tweak` alongside
|
||
|
|
the rest.
|
||
|
|
|
||
|
|
- `outpoint`: Mandatory string representing the outpoint in the form `<txid>:<vout>`.
|
||
|
|
|
||
|
|
### Importing
|
||
|
|
|
||
|
|
When importing a file defined by this specification, software should follow these
|
||
|
|
guidelines:
|
||
|
|
|
||
|
|
* Software should validate the structure, ensure at least one account is present, and
|
||
|
|
check that every object carries its mandatory fields before attempting import.
|
||
|
|
* Software, during import, should preserve all metadata it supports and discard
|
||
|
|
unsupported fields.
|
||
|
|
* Software should warn users if essential data cannot be restored.
|
||
|
|
* Wallets may truncate labels or other string fields if necessary, but should warn
|
||
|
|
users when truncation occurs.
|
||
|
|
|
||
|
|
## Encryption
|
||
|
|
|
||
|
|
This format can be encrypted following [BIP-138](https://github.com/bitcoin/bips/pull/1951).
|
||
|
|
|
||
|
|
## Security Considerations
|
||
|
|
|
||
|
|
* The format MUST NOT include mainnet secret signing keys or mnemonics, since an
|
||
|
|
export kept as a backup may be stored online or in cloud storage.
|
||
|
|
A BIP-0392 descriptor may include a private silent payment scan key, which is
|
||
|
|
allowed on mainnet.
|
||
|
|
* Care should be taken to ensure that proprietary metadata does not contain sensitive
|
||
|
|
information.
|
||
|
|
|
||
|
|
## Backwards Compatibility
|
||
|
|
|
||
|
|
This format is extensible and allows future additions without breaking compatibility.
|
||
|
|
New fields are added through the [field registry](bip-0139/field-registry.md), and
|
||
|
|
wallets should gracefully handle unknown entries by ignoring them.
|
||
|
|
|
||
|
|
For all enum types, if the field is optional and the enum type is unknown, the field
|
||
|
|
must not be imported, but import of the file SHOULD NOT fail.
|
||
|
|
|
||
|
|
## Reference Implementation
|
||
|
|
|
||
|
|
TBD
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
* [BIP-0032: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
|
||
|
|
* [BIP-0039: Mnemonic code for generating deterministic keys](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
|
||
|
|
* [BIP-0174: Partially Signed Bitcoin Transaction Format](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)
|
||
|
|
* [BIP-0329: Wallet Labels Export Format](https://github.com/bitcoin/bips/blob/master/bip-0329.mediawiki)
|
||
|
|
* [BIP-0380: Output Script Descriptors](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki)
|
||
|
|
* [BIP-0085: Deterministic Entropy From BIP32 Keychains](https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki)
|