Skip to content

Commit 94fdbc5

Browse files
committed
bip139: wallet metadata format
1 parent 5253e9a commit 94fdbc5

2 files changed

Lines changed: 296 additions & 0 deletions

File tree

README.mediawiki

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,13 @@ users (see also: [https://en.bitcoin.it/wiki/Economic_majority economic majority
820820
| Christopher Gilliard
821821
| Specification
822822
| Deployed
823+
|-
824+
| [[bip-0139.md|139]]
825+
| Applications
826+
| Wallet Metadata Backup Format
827+
| Pyth
828+
| Specification
829+
| Draft
823830
|- style="background-color: #ffcfcf"
824831
| [[bip-0140.mediawiki|140]]
825832
| Consensus (soft fork)

bip-0139.md

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

0 commit comments

Comments
 (0)