Skip to content

Commit aeee423

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

1 file changed

Lines changed: 285 additions & 0 deletions

File tree

bip-wallet-backup.md

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

0 commit comments

Comments
 (0)