Skip to content

Commit 1fc70c4

Browse files
committed
wallet metadata format
1 parent 9a30c28 commit 1fc70c4

1 file changed

Lines changed: 284 additions & 0 deletions

File tree

bip-wallet-backup.md

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
```
2+
BIP: ?
3+
Layer: Applications
4+
Title: Wallet Metadata Backup Format
5+
Authors: Pyth <pythcoiner@wizardsardine.com>
6+
Status: Draft
7+
Type: Specification
8+
Assigned: ?
9+
License: BSD-2-Clause
10+
Discussion: https://groups.google.com/g/bitcoindev/c/ylPeOnEIhO8
11+
```
12+
13+
## Abstract
14+
15+
This document specifies a format for exporting wallet backup data, including accounts,
16+
descriptors, associated keys, labels, transactions, and partially signed Bitcoin
17+
transactions (PSBTs).
18+
The format aims to standardize wallet backup and restore operations across different
19+
Bitcoin wallet implementations by providing a common structure and field naming
20+
conventions.
21+
All fields are optional except for the base structure, which must include at least one
22+
account entry.
23+
24+
## Copyright
25+
26+
This BIP is licensed under the BSD 2-clause license.
27+
28+
## Motivation
29+
30+
Bitcoin software wallets store various forms of metadata beyond just private keys,
31+
including account structures, descriptors, labels, and transaction history.
32+
While [BIP-0039](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
33+
and [BIP-0032](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) provide
34+
standardized mechanisms for key recovery, they do not preserve additional wallet-specific
35+
metadata necessary for seamless migration between wallets.
36+
37+
A standardized wallet backup format ensures that users can migrate wallets without losing
38+
critical metadata, reducing vendor lock-in and enabling more robust recovery options.
39+
This BIP serves as a central repository where wallet developers can document their usage
40+
of the global format, improving interoperability without forcing a specific
41+
implementation.
42+
43+
## Rationale
44+
45+
Several wallet implementations store backup data in proprietary formats, making migration
46+
difficult.
47+
This proposal introduces a structured, human-readable format, leveraging JSON to store
48+
wallet metadata in a portable way.
49+
The format is flexible and extensible, allowing wallet developers to include as much or
50+
as little information as they think necessary.
51+
52+
By making all fields optional except for the base structure with at least one account,
53+
this standard accommodates diverse use cases and preferences.
54+
Wallet developers can include only the fields relevant to their application while
55+
maintaining structural integrity.
56+
57+
## Specification
58+
59+
A wallet backup is a UTF-8 encoded text file containing a single valid JSON object
60+
representing the backup structure.
61+
This object includes wallet-level metadata, multiple accounts, and associated key data.
62+
63+
### version
64+
65+
This BIP defines version 1 of this specification.
66+
67+
### Wallet Backup Structure
68+
69+
The top-level JSON object must contain at least one account in the `accounts` array.
70+
All other fields are optional.
71+
72+
- `version`: Optional integer version of the backup format.
73+
- `bip`: Optional integer value representing the number of this BIP.
74+
- `name`: Optional string wallet name.
75+
NOTE: `alias` is an alias of `name`.
76+
- `description`: Optional string wallet description.
77+
- `accounts`: Mandatory array of account objects.
78+
Must contain at least one account.
79+
See [Account Object Structure](#account-object-structure).
80+
- `network`: Optional string network identifier.
81+
Valid values are `bitcoin` (mainnet), `testnet3`, `testnet4`, `signet`, and `regtest`.
82+
- `last_height`: Optional integer representing the last block height the exporter had
83+
processed.
84+
- `proprietary`: Optional JSON object storing application-specific metadata.
85+
86+
### Account Object Structure
87+
88+
Each account object in the `accounts` array represents a single account within the wallet.
89+
All fields are optional, allowing wallets to include only the metadata they support.
90+
91+
- `name`: Optional string account name.
92+
NOTE: `alias` is an alias of `name`.
93+
- `description`: Optional string account description.
94+
- `active`: Optional boolean field indicating if the account is active.
95+
- `type`: Optional string describing the account type.
96+
Possible values include `bip_380` (output descriptor), `bip_388` (wallet policies),
97+
`bip_392` (silent payments), or any arbitrary string representing metadata needed to
98+
find and spend coins for an account.
99+
- `output_type`: Optional string describing the output category of the account.
100+
Values used by bitcoin core are `legacy`, `p2sh-segwit`, `bech32`, and `bech32m`.
101+
- `descriptor`: Optional string or object representing the account structure as
102+
defined by the value in `type`.
103+
- `change_descriptor`: Optional string or object representing an explicit change-side
104+
descriptor, paired with `descriptor`. Intended for wallets that do not use BIP-389
105+
multipath descriptors (e.g. Bitcoin Core).
106+
- `descriptor_id`: Optional string containing a stable hexadecimal identifier for the
107+
receive `descriptor`. Its construction is implementation-defined, but it MUST be stable
108+
across exports of the same descriptor.
109+
- `change_descriptor_id`: Optional string. Same semantics as `descriptor_id`, for
110+
`change_descriptor`.
111+
- `receive_index`: Optional integer representing the maximum receive index for generated
112+
receive addresses.
113+
- `change_index`: Optional integer representing the maximum change index for generated
114+
change addresses.
115+
- `range_start`: Optional integer representing the cached keypool range start of the
116+
receive `descriptor`. Present only for ranged descriptors.
117+
- `range_end`: Optional integer representing the cached keypool range end of the receive
118+
`descriptor`. Present only for ranged descriptors.
119+
- `change_range_start`: Optional integer representing the cached keypool range start of
120+
the `change_descriptor`. Present only for ranged descriptors.
121+
- `change_range_end`: Optional integer representing the cached keypool range end of the
122+
`change_descriptor`. Present only for ranged descriptors.
123+
- `timestamp`: Optional integer Unix timestamp representing account creation time in
124+
seconds.
125+
- `iso_8601_datetime`: optional string representing account creation time in ISO 8601
126+
format.
127+
- `block_height`: Optional integer representing account creation time in bitcoin block
128+
height unit.
129+
- `last_height`: Optional integer representing the last seen block height.
130+
- `bip352_labels`: Optional array of silent payments labels (`[0,1,2]`), or range (`{0-10}`).
131+
- `keys`: Optional object mapping descriptor key fingerprints to key metadata objects.
132+
See [Key Object Structure](#key-object-structure).
133+
- `bip329_labels`: Optional array containing label structures for transactions, addresses, and
134+
keys following [BIP-0329](https://github.com/bitcoin/bips/blob/master/bip-0329.mediawiki).
135+
NOTE: `labels` is an alias of `bip329_labels`.
136+
- `transactions`: Optional array containing transactions.
137+
Wallets may include only transactions spending coins controlled by the account, only
138+
transactions funding controlled coins, or only their corresponding outpoints.
139+
See [Transaction Object Structure](#transaction-object-structure).
140+
- `bip352_outputs`: Optional array of
141+
[Silent Payment Owned Output Object Structure](#silent-payment-owned-output-object-structure).
142+
- `bip174_psbts`: Optional array containing unspent but partially signed transactions as defined
143+
by [BIP-0174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki).
144+
- `bip370_psbts`: Optional array containing unspent but partially signed transactions as defined
145+
by [BIP-0370](https://github.com/bitcoin/bips/blob/master/bip-370.mediawiki).
146+
- `psbts`: Optinnal array than can contains both BIP-0174 & BIP-0370 PSBTs.
147+
- `bip39_mnemonic`: Optional string containing mnemonic words following BIP39.
148+
Since backups may be stored online, storing mainnet mnemonics is strongly discouraged.
149+
- `proprietary`: Optional JSON object storing account-specific metadata.
150+
151+
### Key Object Structure
152+
153+
Keys in the `keys` dictionary are indexed by their
154+
[BIP32 fingerprint](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#key-identifiers).
155+
Each key object contains metadata about the key.
156+
157+
- `key`: Optional string representing the public key fingerprint in hexadecimal form.
158+
- `alias`: Optional string user-defined alias for the key.
159+
- `role`: Optional string role of the key in wallet operations.
160+
See [Key Roles](#key-roles).
161+
- `key_type`: Optional string describing ownership of the key.
162+
See [Key Types](#key-types).
163+
- `key_status`: Optional string describing the status of the key.
164+
See [Key Status](#key-status).
165+
- `bip85_derivation_path`: Optional string describing the
166+
[BIP-0085](https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki) derivation
167+
path used to derive this key from the master key.
168+
169+
### Key Roles
170+
171+
The `role` field may contain one of the following values.
172+
173+
- `main`: Key used for normal spending conditions.
174+
- `recovery`: Key designated for recovery scenarios.
175+
- `inheritance`: Key to inherit funds if the primary user disappears.
176+
- `cosigning`: Key designated for policy-enforcing cosigning.
177+
178+
### Key Types
179+
180+
The `key_type` field may contain one of the following values.
181+
182+
- `internal`: Main user-owned key.
183+
- `external`: Key held by heirs or trusted individuals.
184+
- `third_party`: Key held by a service provider.
185+
186+
### Key Status
187+
188+
The `key_status` field may contain one of the following values.
189+
190+
- `active`: The key is actively used.
191+
- `inactive`: The key is not yet actively used.
192+
- `revoked`: The key has been revoked and MUST NOT be used anymore.
193+
194+
### Transaction Object Structure
195+
196+
Each entry in the `transactions` array is a JSON object describing a single transaction
197+
relevant to the account. All fields are optional except `txid`.
198+
199+
- `txid`: Optional string containing the transaction id (hex).
200+
- `wtxid`: Optional string containing the witness transaction id (hex). Segwit only.
201+
- `hex`: Optional string containing the raw transaction (hex).
202+
- `time`: Optional integer representing the best-known transaction time in unix
203+
seconds. Block time when confirmed, otherwise first-seen time.
204+
- `time_received`: Optional integer representing when the exporting wallet first
205+
observed the transaction, in unix seconds. MAY be earlier than `time`.
206+
- `blockhash`: Optional string containing the confirming block hash (hex).
207+
- `blockheight`: Optional integer containing the confirming block height.
208+
- `blockindex`: Optional integer containing the position of the transaction in the
209+
confirming block.
210+
- `abandoned`: Optional boolean representing user-driven abandoned state, separate
211+
from mempool eviction.
212+
213+
### Silent Payment Owned Output Object Structure
214+
215+
- `outpoint`: Optional string representing the outpoint in the form `<txid>:<vout>`.
216+
- `block_height`: Optional integer representing the height of the block containing
217+
the transaction.
218+
NOTE: if `block_height` value is `null`, it means the outpoints belongs to an
219+
unconfirmed transaction at the time of backup.
220+
- `tweak`: Optional hexadecimal string representing the tweak.
221+
- `amount`: Optional integer representing the output amount value in sats.
222+
- `script`: Optional hexadecimal string representing the spending script for this
223+
outpoint.
224+
- `label`: Optional string representing a label attached to this output, similar to
225+
BIP-0329 label.
226+
- `spend_status`: Optional string describing the spend status of the output.
227+
See [Spend status](#spend-status).
228+
229+
### Spend Status
230+
231+
The `spend_status` field may contain one of the following values.
232+
233+
- `unconfirmed`: The transaction is broadcast but not yet confirmed in a block.
234+
- `replaced`: The transaction has been replaced by a transaction confirmed in a block.
235+
- `unspent`: The transaction has been confirmed in a block and the output is unspent.
236+
- `spent`: The transaction has been confirmed in a block and the output is spent.
237+
238+
## Importing
239+
240+
When importing a wallet backup follow these guidelines.
241+
242+
* Importing wallets should preserve all metadata they support and discard unsupported
243+
fields.
244+
* Wallets should warn users if essential data cannot be restored.
245+
* Wallets should ensure that key roles and types are properly mapped to their internal
246+
structures if used.
247+
* Wallets may truncate labels or other string fields if necessary, but should warn users
248+
when truncation occurs.
249+
* Wallets should validate the structure and ensure at least one account is present before
250+
attempting import.
251+
252+
## Encryption
253+
254+
This format can be encrypted following [BIP-XXXX](https://github.com/bitcoin/bips/pull/1951).
255+
256+
## Security Considerations
257+
258+
* The backup format should not include private keys to avoid unintended key exposure.
259+
* Backups should be encrypted to prevent unauthorized access.
260+
* Care should be taken to ensure that proprietary metadata does not contain sensitive
261+
information.
262+
* Since backups may be stored online or in cloud storage, storing mainnet mnemonics or
263+
private keys is strongly discouraged.
264+
265+
## Backwards Compatibility
266+
267+
This format is extensible and allows future additions without breaking compatibility.
268+
Wallets may ignore fields they do not recognize while maintaining the structural
269+
integrity of the backup.
270+
Future revisions may add fields, and wallets should gracefully handle unknown entries by
271+
ignoring them.
272+
273+
## Reference Implementation
274+
275+
TBD
276+
277+
## References
278+
279+
* [BIP-0032: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
280+
* [BIP-0039: Mnemonic code for generating deterministic keys](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
281+
* [BIP-0174: Partially Signed Bitcoin Transaction Format](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)
282+
* [BIP-0329: Wallet Labels Export Format](https://github.com/bitcoin/bips/blob/master/bip-0329.mediawiki)
283+
* [BIP-0380: Output Script Descriptors](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki)
284+
* [BIP-0085: Deterministic Entropy From BIP32 Keychains](https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki)

0 commit comments

Comments
 (0)