diff --git a/README.mediawiki b/README.mediawiki index 5e68720d..caa51a60 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -834,6 +834,13 @@ users (see also: [https://en.bitcoin.it/wiki/Economic_majority economic majority | Pyth | Specification | Draft +|- +| [[bip-0139.md|139]] +| Applications +| Wallet Metadata Export Format +| Pyth +| Specification +| Draft |- style="background-color: #ffcfcf" | [[bip-0140.mediawiki|140]] | Consensus (soft fork) diff --git a/bip-0139.md b/bip-0139.md new file mode 100644 index 00000000..1a96f0e8 --- /dev/null +++ b/bip-0139.md @@ -0,0 +1,230 @@ +``` + BIP: 139 + Layer: Applications + Title: Wallet Metadata Export Format + Authors: Pyth + 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-`, where `` 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 `:`. + +### 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) diff --git a/bip-0139/field-registry.md b/bip-0139/field-registry.md new file mode 100644 index 00000000..a77d08f5 --- /dev/null +++ b/bip-0139/field-registry.md @@ -0,0 +1,380 @@ +# BIP-0139 Field Registry + +This file is the central repository of fields for the +[BIP-0139](../bip-0139.md) wallet metadata export format. +The `optional` column marks the optional fields, a blank means the field is mandatory. +Mandatory fields are fixed by BIP-0139, so a pull request against this file may add or +change optional fields only. + +## Wallet Fields + +Fields of the top-level wallet object. + +``` +| field | optional | type | description | +|--------------|----------|-----------|------------------------------------------------------------| +| version | | string | Export format and version. See Wallet Object Structure for | +| | | | the required value. | +|--------------|----------|-----------|------------------------------------------------------------| +| network | | string | Network of the wallet. See Wallet Object Structure for the | +| | | | permitted values. | +|--------------|----------|-----------|------------------------------------------------------------| +| accounts | | array | Account objects. Must not be empty. | +|--------------|----------|-----------|------------------------------------------------------------| +| name | optional | string | Wallet name or alias. | +|--------------|----------|-----------|------------------------------------------------------------| +| note | optional | string | Note about this export, written by the user when the | +| | | | export is made. | +|--------------|----------|-----------|------------------------------------------------------------| +| date | optional | timestamp | When the export was made. | +|--------------|----------|-----------|------------------------------------------------------------| +| exporter | optional | string | Name and version of the software that produced this | +| | | | export, e.g. `Sparrow 2.2.0`. | +|--------------|----------|-----------|------------------------------------------------------------| +| transactions | optional | object | Maps a transaction id to a transaction object. | +| | | | Transactions are recorded here rather than in the | +| | | | `account` object so a transaction related to several | +| | | | accounts is stored only once. Accounts reference them by | +| | | | transaction id. | +|--------------|----------|-----------|------------------------------------------------------------| +| psbts | optional | object | Maps a transaction id to a PSBT, as defined by BIP-0174 or | +| | | | BIP-0370. The key is the transaction id of the PSBT's | +| | | | *unsigned* transaction, which stays stable for the whole | +| | | | signing process, whereas the id of the finalized | +| | | | transaction changes as legacy inputs are signed. Kept at | +| | | | wallet level for the same reason as transactions. | +|--------------|----------|-----------|------------------------------------------------------------| +| signers | optional | array | Signer objects. | +|--------------|----------|-----------|------------------------------------------------------------| +| proprietary | optional | object | Application-specific metadata. | +``` + +## Account Fields + +Fields of the [account object][accountobj]. + +``` +| field | optional | type | description | +|--------------------|----------|-----------------|------------------------------------------------| +| type | | string | Type of account descriptor. See Account Object | +| | | | Structure for the permitted values. | +|--------------------|----------|-----------------|------------------------------------------------| +| descriptor | | string/array | Account descriptor. Its structure is defined | +| | | | by `type`. See Account Object Structure. | +|--------------------|----------|-----------------|------------------------------------------------| +| name | optional | string | Account name/alias. | +|--------------------|----------|-----------------|------------------------------------------------| +| description | optional | string | Account description. | +|--------------------|----------|-----------------|------------------------------------------------| +| status | optional | enum | Where the account is in its lifecycle. See | +| | | | Account Status. | +|--------------------|----------|-----------------|------------------------------------------------| +| hidden | optional | boolean | Whether the account is hidden in the wallet's | +| | | | interface. Independent of status: a hidden | +| | | | account may still be active. | +|--------------------|----------|-----------------|------------------------------------------------| +| change_descriptor | optional | string | Explicit change-side descriptor, paired with | +| | | | descriptor. For wallets that keep receive and | +| | | | change descriptors separate, such as Bitcoin | +| | | | Core. | +|--------------------|----------|-----------------|------------------------------------------------| +| receive_index | optional | integer | Maximum generated receive index for receive | +| | | | addresses. | +|--------------------|----------|-----------------|------------------------------------------------| +| change_index | optional | integer | Maximum generated change index for change | +| | | | addresses. | +|--------------------|----------|-----------------|------------------------------------------------| +| range_start | optional | integer | Cached keypool range start of the receive | +| | | | descriptor. Ranged descriptors only. | +|--------------------|----------|-----------------|------------------------------------------------| +| range_end | optional | integer | Cached keypool range end of the receive | +| | | | descriptor. Ranged descriptors only. | +|--------------------|----------|-----------------|------------------------------------------------| +| change_range_start | optional | integer | Cached keypool range start of the | +| | | | change_descriptor. Ranged descriptors only. | +|--------------------|----------|-----------------|------------------------------------------------| +| change_range_end | optional | integer | Cached keypool range end of the | +| | | | change_descriptor. Ranged descriptors only. | +|--------------------|----------|-----------------|------------------------------------------------| +| gap_limit | optional | integer | Consecutive unused addresses a wallet must | +| | | | scan past the last used one before concluding | +| | | | there are no more. A single value covers both | +| | | | the receive and change sides. | +|--------------------|----------|-----------------|------------------------------------------------| +| birth_block | optional | integer | Account creation time as a block height. An | +| | | | importer may start scanning here instead of at | +| | | | genesis. Many wallets record a creation date | +| | | | rather than a block height. An exporter | +| | | | holding only a date SHOULD convert it against | +| | | | a chain source. If it cannot, it MAY estimate | +| | | | the height as (date - genesis_block_time) / | +| | | | 600, anchored at the network's genesis block | +| | | | and never at the chain tip: the chain has | +| | | | historically run slightly ahead of the | +| | | | ten-minute target, so extrapolating forward | +| | | | from genesis should land below the true height | +| | | | while counting back from the tip lands above | +| | | | it. The estimate MUST be at or before the true | +| | | | height, never after, because too early only | +| | | | costs scanning time while too late silently | +| | | | misses transactions. An exporter that can do | +| | | | neither SHOULD omit this field. | +|--------------------|----------|-----------------|------------------------------------------------| +| last_height | optional | integer | Height this account has been synced to. A | +| | | | wallet that tracks one sync point for the | +| | | | whole export writes that same height into | +| | | | every account. | +|--------------------|----------|-----------------|------------------------------------------------| +| bip352_labels | optional | array or object | The silent payment label indices in use. | +| | | | Either an array of integers ([0, 1, 2]) or an | +| | | | object with start and end members ({"start": | +| | | | 0, "end": 10}), where end is exclusive. | +|--------------------|----------|-----------------|------------------------------------------------| +| keys | optional | object | Maps a key fingerprint to a key object. | +|--------------------|----------|-----------------|------------------------------------------------| +| labels | optional | array | Label structures for transactions, addresses, | +| | | | outputs and keys, following BIP-0329. | +|--------------------|----------|-----------------|------------------------------------------------| +| transactions | optional | array | Transaction ids referencing the wallet's | +| | | | transactions map, for transactions related to | +| | | | this account. | +|--------------------|----------|-----------------|------------------------------------------------| +| coins | optional | array | Coin objects owned by the account, silent | +| | | | payment outputs included. | +|--------------------|----------|-----------------|------------------------------------------------| +| psbts | optional | array | Transaction ids referencing the wallet's psbts | +| | | | map, for PSBTs related to this account. | +|--------------------|----------|-----------------|------------------------------------------------| +| bip39_mnemonic | optional | string | Mnemonic words following BIP-0039. Since | +| | | | exports may be stored online, this field is | +| | | | intended for test networks only (testnet3, | +| | | | testnet4, signet, regtest); it MUST NOT be | +| | | | used to store mainnet mnemonics. The field | +| | | | carries the words alone. A seed protected by a | +| | | | BIP-39 passphrase MUST NOT use it. | +|--------------------|----------|-----------------|------------------------------------------------| +| proprietary | optional | object | Application-specific metadata. | +``` + +### Account Status + +The `status` field may contain one of the following values. + +- `active`: The account can derive new addresses. +- `superseded`: The account no longer derives new addresses, but must still be + watched because it may hold or receive coins. +- `archived`: The user retired the account, it is no longer watched. + +## Signer Fields + +Fields of the [signer object][signerobj]. + +``` +| field | optional | type | description | +|-----------------------|----------|---------|-----------------------------------------------------| +| fingerprints | | array | BIP32 fingerprints of keys held by this signer. | +|-----------------------|----------|---------|-----------------------------------------------------| +| key_status | optional | enum | Status of the signer's keys. See Key Status. | +|-----------------------|----------|---------|-----------------------------------------------------| +| bip85_derivation_path | optional | string | BIP-0085 derivation path used to derive this | +| | | | signer's key from a master key, if one was used. | +|-----------------------|----------|---------|-----------------------------------------------------| +| key_storage | optional | enum | Whether the signer's key is `hot` or `cold`. | +|-----------------------|----------|---------|-----------------------------------------------------| +| devices | optional | array | Device objects for the last-seen devices holding | +| | | | this key. Entries are not keyed and do not identify | +| | | | a physical device across exports. See Device | +| | | | object. | +``` + +### Key Status + +The `key_status` field may contain one of the following values. + +- `inactive`: The key is not yet actively used. +- `active`: The key is actively used. +- `revoked`: The key has been revoked and MUST NOT be used anymore. + +### Device object + +The device object may contain any of these fields. + +``` +| field | optional | type | description | +|---------------------|----------|-----------|----------------------------------------------------| +| vendor | optional | string | Device vendor name. | +|---------------------|----------|-----------|----------------------------------------------------| +| model | optional | string | Device model name. | +|---------------------|----------|-----------|----------------------------------------------------| +| firmware_version | optional | string | Device firmware version. See Device Firmware | +| | | | Version. | +|---------------------|----------|-----------|----------------------------------------------------| +| transports | optional | array | Media over which the device can be reached, in | +| | | | order of preference. See Device Transports. | +|---------------------|----------|-----------|----------------------------------------------------| +| registered | optional | bool | Whether the descriptor has been registered on the | +| | | | device. | +|---------------------|----------|-----------|----------------------------------------------------| +| descriptor_checksum | optional | string | Checksum of the descriptor that registered applies | +| | | | to. Devices are listed at wallet level, a | +| | | | registration covers a single descriptor. An | +| | | | importer MUST treat registered as absent when this | +| | | | does not match the descriptor being imported. | +|---------------------|----------|-----------|----------------------------------------------------| +| descriptor_stored | optional | bool | Whether the device kept the descriptor, so later | +| | | | requests may name it by its alias alone. | +| | | | Independent of proof of registration: a device | +| | | | may store the descriptor and return a proof. | +|---------------------|----------|-----------|----------------------------------------------------| +| last_health_check | optional | timestamp | Timestamp of the last health check processed on | +| | | | this device. | +``` + +### Device Transports + +The `transports` array may contain any of the following values. + +- `usb`: Wired connection, whether the device presents as an HID device or as a serial + port. +- `bluetooth`: Wireless connection to the host. +- `nfc`: Tap, including devices presenting as a smartcard. +- `qr`: QR codes, animated or not. The encoding is not recorded here. +- `sdcard`: A file carried to the device on removable storage. + +Entries are ordered by preference, most preferred first. An importer MUST ignore a +value it does not know rather than reject the whole array. + +### Device Firmware Version + +The `firmware_version` field takes the form `..`, each part a +decimal integer, optionally followed by `-`. + +`` may be one of the following values. + +- `alpha` +- `beta` +- `rc` +- `prerelease` + +## Key Fields + +Fields of the [key object][keyobj]. + +``` +| field | optional | type | description | +|-----------------------|----------|--------|--------------------------------------------------------------| +| key | | string | BIP-0032 public key fingerprint. | +|-----------------------|----------|--------|--------------------------------------------------------------| +| alias | optional | string | User-defined alias for the key. | +|-----------------------|----------|--------|--------------------------------------------------------------| +| role | optional | enum | Role of the key in wallet operations. See Key Roles. | +|-----------------------|----------|--------|--------------------------------------------------------------| +| key_type | optional | enum | Ownership of the key. See Key Types. | +|-----------------------|----------|--------|--------------------------------------------------------------| +| proof_of_registration | optional | array | Pairs of [descriptor, proof] for this key. Both are strings; | +| | | | the proof is lowercase hexadecimal. | +``` + +### Key Roles + +The `role` field may contain one of the following values. + +- `main`: Key used for normal spending conditions. +- `recovery`: Key designated for recovery scenarios. +- `inheritance`: Key to inherit funds if the primary user disappears. +- `cosigning`: Key designated for policy-enforcing cosigning. + +### Key Types + +The `key_type` field may contain one of the following values. + +- `internal`: User-owned key. +- `external`: Key held by heirs or trusted individuals. +- `third_party`: Key held by a service provider. + +## Transaction Fields + +Fields of the [transaction object][txobj]. The transaction id is the key of the +wallet's `transactions` map, not a field. + +``` +| field | optional | type | description | +|---------------|----------|-----------|-----------------------------------------------------------| +| wtxid | optional | string | Witness transaction id (hex). Segwit only. | +|---------------|----------|-----------|-----------------------------------------------------------| +| hex | optional | string | Raw transaction (hex). | +|---------------|----------|-----------|-----------------------------------------------------------| +| fee | optional | integer | Transaction fee in sats. | +|---------------|----------|-----------|-----------------------------------------------------------| +| block_time | optional | timestamp | Time of the block confirming the transaction. Absent | +| | | | while unconfirmed. This and time_received are separate | +| | | | measurements and neither substitutes for the other, an | +| | | | exporter emits whichever it holds. | +|---------------|----------|-----------|-----------------------------------------------------------| +| time_received | optional | timestamp | When the exporting wallet first observed the transaction. | +| | | | MAY be earlier than block_time. | +|---------------|----------|-----------|-----------------------------------------------------------| +| blockhash | optional | string | Confirming block hash (hex). | +|---------------|----------|-----------|-----------------------------------------------------------| +| blockheight | optional | integer | Confirming block height. | +|---------------|----------|-----------|-----------------------------------------------------------| +| blockindex | optional | integer | Position of the transaction in the confirming block. | +|---------------|----------|-----------|-----------------------------------------------------------| +| abandoned | optional | boolean | Whether the user decided to abandon this transaction. | +``` + +## Coin Fields + +Fields of the [coin object][coinobj]. Silent payment outputs are coins and use this object +too, with `tweak` set. + +``` +| field | optional | type | description | +|------------------|----------|---------|----------------------------------------------------------| +| outpoint | | string | The outpoint, in the form `:`. | +|------------------|----------|---------|----------------------------------------------------------| +| amount | optional | integer | Output amount in sats. | +|------------------|----------|---------|----------------------------------------------------------| +| script | optional | string | Output script (hex). | +|------------------|----------|---------|----------------------------------------------------------| +| block_height | optional | integer | Height of the block containing the funding transaction. | +| | | | If null, that transaction was unconfirmed at export. | +|------------------|----------|---------|----------------------------------------------------------| +| is_change | optional | boolean | Whether the output was paid to a change address. | +|------------------|----------|---------|----------------------------------------------------------| +| derivation_index | optional | integer | Index the output's address was derived at. | +|------------------|----------|---------|----------------------------------------------------------| +| is_immature | optional | boolean | The output is an immature coinbase output. | +|------------------|----------|---------|----------------------------------------------------------| +| is_from_self | optional | boolean | The funding transaction was made by this wallet. | +|------------------|----------|---------|----------------------------------------------------------| +| frozen | optional | boolean | The user marked this output as do-not-spend. | +|------------------|----------|---------|----------------------------------------------------------| +| spend_status | optional | enum | Spend status of the output. See Spend Status. | +|------------------|----------|---------|----------------------------------------------------------| +| tweak | optional | string | Silent payment outputs only: the 32-byte tweak needed | +| | | | to derive the output, as defined by BIP-0352, encoded | +| | | | as 64 lowercase hexadecimal characters in big-endian | +| | | | order. Absent for ordinary outputs. | +|------------------|----------|---------|----------------------------------------------------------| +| sp_label | optional | string | Silent payment outputs only: the BIP-0352 label scalar | +| | | | of the labelled address the output was paid to, encoded | +| | | | as 64 lowercase hexadecimal characters in big-endian | +| | | | order. Absent for the unlabelled address. This is | +| | | | protocol data, not an annotation. | +``` + +### Spend Status + +The `spend_status` field may contain one of the following values. + +- `unconfirmed`: The transaction is broadcast but not yet confirmed in a block. +- `replaced`: The transaction has been replaced by a transaction confirmed in a block. +- `unspent`: The transaction has been confirmed in a block and the output is unspent. +- `spent`: The transaction has been confirmed in a block and the output is spent. + +[txobj]: ../bip-0139.md#transaction-object-structure +[signerobj]: ../bip-0139.md#signer-object-structure +[keyobj]: ../bip-0139.md#key-object-structure +[coinobj]: ../bip-0139.md#coin-object-structure +[accountobj]: ../bip-0139.md#account-object-structure