diff --git a/types/src/lib.rs b/types/src/lib.rs index d07770e6..4e477634 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -183,6 +183,9 @@ pub fn compact_size_decode(slice: &mut &[u8]) -> u64 { pub struct ScriptPubkey { /// Script assembly. pub asm: String, + /// Inferred descriptor for the output. v23 and later only. + #[serde(rename = "desc")] + pub descriptor: Option, /// Script hex. pub hex: String, /// Number of required signatures - deprecated in Core v22. diff --git a/types/src/model/blockchain.rs b/types/src/model/blockchain.rs index 091fcd60..273987d3 100644 --- a/types/src/model/blockchain.rs +++ b/types/src/model/blockchain.rs @@ -306,6 +306,12 @@ pub struct GetBlockStats { pub utxo_increase: i32, /// The increase/decrease in size for the utxo index (not discounting op_return and similar). pub utxo_size_increase: i32, + /// The increase/decrease in the number of unspent outputs, not counting unspendables. + /// v25 and later only. + pub utxo_increase_actual: Option, + /// The increase/decrease in size for the utxo index, not counting unspendables. + /// v25 and later only. + pub utxo_size_increase_actual: Option, } /// Models the result of JSON-RPC method `getchaintips`. @@ -516,6 +522,9 @@ pub struct GetTxOutSetInfo { /// /// This was removed in Bitcoin Core v26, and hence will be `None` for v26 and later. pub hash_serialized_2: Option, // FIXME: What sort of hash is this? + /// The serialized hash (only present if 'hash_serialized_3' hash_type is chosen). + /// v26 and later only. + pub hash_serialized_3: Option, /// The estimated size of the chainstate on disk. pub disk_size: u32, /// The total amount. diff --git a/types/src/model/mod.rs b/types/src/model/mod.rs index 007d3d69..70c9fe68 100644 --- a/types/src/model/mod.rs +++ b/types/src/model/mod.rs @@ -55,11 +55,11 @@ pub use self::{ GetAddressesByLabel, GetBalance, GetBalances, GetBalancesMine, GetBalancesWatchOnly, GetNewAddress, GetRawChangeAddress, GetReceivedByAddress, GetReceivedByLabel, GetTransaction, GetTransactionDetail, GetUnconfirmedBalance, GetWalletInfo, - ListAddressGroupings, ListAddressGroupingsItem, ListLabels, ListLockUnspent, - ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListReceivedByLabel, - ListReceivedByLabelItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, - ListTransactionsItem, ListUnspent, ListUnspentItem, ListWallets, LoadWallet, - RescanBlockchain, ScriptType, SendMany, SendToAddress, SignMessage, TransactionCategory, - UnloadWallet, WalletCreateFundedPsbt, WalletProcessPsbt, + LastProcessedBlock, ListAddressGroupings, ListAddressGroupingsItem, ListLabels, + ListLockUnspent, ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, + ListReceivedByLabel, ListReceivedByLabelItem, ListSinceBlock, ListSinceBlockTransaction, + ListTransactions, ListTransactionsItem, ListUnspent, ListUnspentItem, ListWallets, + LoadWallet, RescanBlockchain, ScriptType, SendMany, SendToAddress, SignMessage, + TransactionCategory, UnloadWallet, WalletCreateFundedPsbt, WalletProcessPsbt, }, }; diff --git a/types/src/model/raw_transactions.rs b/types/src/model/raw_transactions.rs index 80efcd21..552d1fa5 100644 --- a/types/src/model/raw_transactions.rs +++ b/types/src/model/raw_transactions.rs @@ -93,8 +93,12 @@ pub struct DecodeRawTransaction(pub Transaction); pub struct DecodeScript { /// The `scriptPubkey`. pub script_pubkey: Option, + /// Inferred descriptor for the script. v23 and later only. + pub descriptor: Option, /// The output type. - pub type_: Option, + pub type_: String, + /// Bitcoin address (only if a well-defined address exists). v22 and later only. + pub address: Option>, /// The required signatures. pub required_signatures: Option, /// List of bitcoin addresses. diff --git a/types/src/model/wallet.rs b/types/src/model/wallet.rs index a7755692..d93406f1 100644 --- a/types/src/model/wallet.rs +++ b/types/src/model/wallet.rs @@ -232,7 +232,11 @@ pub struct GetBalance(pub Amount); pub struct GetBalances { /// Balances from outputs that the wallet can sign. pub mine: GetBalancesMine, + /// Watchonly balances (not present if wallet does not watch anything). pub watch_only: Option, + /// Hash and height of the block this information was generated on. v26 and later only. + #[serde(rename = "lastprocessedblock")] + pub last_processed_block: Option, } /// Balances from outputs that the wallet can sign. @@ -290,27 +294,49 @@ pub struct GetTransaction { pub fee: Option, /// The number of confirmations. pub confirmations: i64, // Docs do not indicate what negative value means? + /// Only present if the transaction's only input is a coinbase one. v20 and later only. + pub generated: Option, /// Whether we consider the outputs of this unconfirmed transaction safe to spend. pub trusted: Option, /// The block hash. pub block_hash: Option, + /// The block height containing the transaction. v20 and later only. + pub block_height: Option, /// The index of the transaction in the block that includes it. pub block_index: Option, /// The time in seconds since epoch (1 Jan 1970 GMT). pub block_time: Option, /// The transaction id. pub txid: Txid, + /// The hash of serialized transaction, including witness data. v24 and later only. + pub wtxid: Option, /// Confirmed transactions that have been detected by the wallet to conflict with this transaction. pub wallet_conflicts: Vec, + /// Only if 'category' is 'send'. The txid if this tx was replaced. v23 and later only. + pub replaced_by_txid: Option, + /// Only if 'category' is 'send'. The txid if this tx replaces another. v23 and later only. + pub replaces_txid: Option, + /// Transactions in the mempool that directly conflict with either this transaction or an ancestor transaction. v28 and later only. + pub mempool_conflicts: Option>, + /// If a comment to is associated with the transaction. v23 and later only. + pub to: Option, /// The transaction time in seconds since epoch (1 Jan 1970 GMT). pub time: u32, /// The time received in seconds since epoch (1 Jan 1970 GMT). pub time_received: u32, + /// If a comment is associated with the transaction, only present if not empty. v20 to v24 only. + pub comment: Option, /// Whether this transaction could be replaced due to BIP125 (replace-by-fee); /// may be unknown for unconfirmed transactions not in the mempool pub bip125_replaceable: Bip125Replaceable, + /// Only if 'category' is 'received'. List of parent descriptors for the output script of this coin. v24 and later only. + pub parent_descriptors: Option>, /// Transaction details. pub details: Vec, + /// The decoded transaction (only present when `verbose` is passed). v19 and later only. + pub decoded: Option, + /// Hash and height of the block this information was generated on. v26 and later only. + pub last_processed_block: Option, /// The transaction, parsed from hex string. pub tx: Transaction, } @@ -318,6 +344,10 @@ pub struct GetTransaction { /// Part of the `GetTransaction`. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct GetTransactionDetail { + /// Only returns true if imported addresses were involved in transaction. v20 and later only. + pub involves_watchonly: Option, + /// DEPRECATED. The account name involved in the transaction, can be "" for the default account. + pub account: Option, // Docs are wrong, this is not documented as optional. /// The bitcoin address involved in the transaction. pub address: Address, /// The category, either 'send' or 'receive'. @@ -338,6 +368,18 @@ pub struct GetTransactionDetail { /// /// Only available for the 'send' category of transactions. pub abandoned: Option, + /// Only if 'category' is 'received'. List of parent descriptors for the output script of this + /// coin. v24 and later only. + pub parent_descriptors: Option>, +} + +/// Part of the `GetTransaction`. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct LastProcessedBlock { + /// Hash of the block this information was generated on. + pub hash: BlockHash, + /// Height of the block this information was generated on. + pub height: u32, } /// Models the result of JSON-RPC method `getunconfirmedbalance`. @@ -616,6 +658,9 @@ pub struct ListUnspentItem { /// and unconfirmed replacement transactions are considered unsafe and are not eligible for /// spending by fundrawtransaction and sendtoaddress. pub safe: bool, + /// List of parent descriptors for the scriptPubKey of this coin. v24 and later only. + #[serde(rename = "parent_descs")] + pub parent_descriptors: Option>, } /// Models the result of JSON-RPC method `listwallets`. diff --git a/types/src/v17/blockchain/into.rs b/types/src/v17/blockchain/into.rs index 874d14a8..d3fcdd1d 100644 --- a/types/src/v17/blockchain/into.rs +++ b/types/src/v17/blockchain/into.rs @@ -261,6 +261,8 @@ impl GetBlockStats { txs: crate::to_u32(self.txs, "txs")?, utxo_increase: self.utxo_increase, utxo_size_increase: self.utxo_size_increase, + utxo_increase_actual: None, // v25 and later only. + utxo_size_increase_actual: None, // v25 and later only. }) } } @@ -541,6 +543,7 @@ impl GetTxOutSetInfo { tx_outs, bogo_size, hash_serialized_2, + hash_serialized_3: None, // v26 and later only. disk_size, total_amount, }) diff --git a/types/src/v17/control.rs b/types/src/v17/control.rs index f0610f80..e7e0f71b 100644 --- a/types/src/v17/control.rs +++ b/types/src/v17/control.rs @@ -52,25 +52,25 @@ pub struct Locked { /// > Gets and sets the logging configuration. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct Logging { - pub net: bool, - pub tor: bool, - pub mempool: bool, - pub http: bool, + pub addrman: bool, pub bench: bool, - pub zmq: bool, + pub cmpctblock: bool, + pub coindb: bool, pub db: bool, - pub rpc: bool, pub estimatefee: bool, - pub addrman: bool, - pub selectcoins: bool, - pub reindex: bool, - pub cmpctblock: bool, - pub rand: bool, + pub http: bool, + pub leveldb: bool, + pub libevent: bool, + pub mempool: bool, + pub mempoolrej: bool, + pub net: bool, pub prune: bool, pub proxy: bool, - pub mempoolrej: bool, - pub libevent: bool, - pub coindb: bool, pub qt: bool, - pub leveldb: bool, + pub rand: bool, + pub reindex: bool, + pub rpc: bool, + pub selectcoins: bool, + pub tor: bool, + pub zmq: bool, } diff --git a/types/src/v17/mod.rs b/types/src/v17/mod.rs index ff9b89ae..d67b3d8e 100644 --- a/types/src/v17/mod.rs +++ b/types/src/v17/mod.rs @@ -271,20 +271,20 @@ pub use self::{ ValidateAddress, ValidateAddressError, VerifyMessage, }, wallet::{ - AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddressInformation, BumpFee, - BumpFeeError, CreateWallet, DumpPrivKey, DumpWallet, EncryptWallet, GetAddressInfo, - GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, - GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetNewAddress, GetRawChangeAddress, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTransactionDetailError, - GetTransactionError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, - ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, - ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, - ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, - ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, - ListTransactionsItem, ListTransactionsItemError, ListUnspent, ListUnspentItem, - ListUnspentItemError, ListWallets, LoadWallet, RescanBlockchain, SendMany, SendToAddress, - SignMessage, TransactionCategory, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, - WalletProcessPsbt, + AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddressInformation, + Bip125Replaceable, BumpFee, BumpFeeError, CreateWallet, DumpPrivKey, DumpWallet, + EncryptWallet, GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, + GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetNewAddress, + GetRawChangeAddress, GetReceivedByAddress, GetTransaction, GetTransactionDetail, + GetTransactionDetailError, GetTransactionError, GetUnconfirmedBalance, GetWalletInfo, + GetWalletInfoError, ListAddressGroupings, ListAddressGroupingsError, + ListAddressGroupingsItem, ListLabels, ListLockUnspent, ListLockUnspentItem, + ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, + ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, + ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, + ListTransactionsItemError, ListUnspent, ListUnspentItem, ListUnspentItemError, ListWallets, + LoadWallet, RescanBlockchain, SendMany, SendToAddress, SignMessage, TransactionCategory, + WalletCreateFundedPsbt, WalletCreateFundedPsbtError, WalletProcessPsbt, }, zmq::GetZmqNotifications, }; diff --git a/types/src/v17/raw_transactions/into.rs b/types/src/v17/raw_transactions/into.rs index 6687ed68..6e432798 100644 --- a/types/src/v17/raw_transactions/into.rs +++ b/types/src/v17/raw_transactions/into.rs @@ -304,6 +304,8 @@ impl DecodeScript { Ok(model::DecodeScript { script_pubkey, type_: self.type_, + descriptor: None, + address: None, required_signatures: self.required_signatures, addresses, p2sh, diff --git a/types/src/v17/raw_transactions/mod.rs b/types/src/v17/raw_transactions/mod.rs index ff3fc5a4..99d2f4b1 100644 --- a/types/src/v17/raw_transactions/mod.rs +++ b/types/src/v17/raw_transactions/mod.rs @@ -209,7 +209,7 @@ pub struct DecodeScript { pub hex: Option, /// The output type. #[serde(rename = "type")] - pub type_: Option, + pub type_: String, /// The required signatures. #[serde(rename = "reqSigs")] pub required_signatures: Option, diff --git a/types/src/v17/wallet/into.rs b/types/src/v17/wallet/into.rs index e07f240d..07c2a10d 100644 --- a/types/src/v17/wallet/into.rs +++ b/types/src/v17/wallet/into.rs @@ -354,16 +354,27 @@ impl GetTransaction { amount, fee, confirmations: self.confirmations, + generated: None, // v20 and later only. trusted: self.trusted, block_hash, + block_height: None, // v20 and later only. block_index, block_time: self.block_time, txid, + wtxid: None, // v24 and later only. wallet_conflicts, + replaced_by_txid: None, // v23 and later only. + replaces_txid: None, // v23 and later only. + mempool_conflicts: None, // v28 and later only. + to: None, // v23 and later only. time: self.time, time_received: self.time_received, + comment: None, // v20 to v24 only. bip125_replaceable: self.bip125_replaceable.into_model(), + parent_descriptors: None, // v24 and later only. details, + decoded: None, // v19 and later only. + last_processed_block: None, // v26 and later only. tx, }) } @@ -379,6 +390,8 @@ impl GetTransactionDetail { let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; Ok(model::GetTransactionDetail { + involves_watchonly: None, // v20 and later only. + account: self.account, address, category: self.category.into_model(), amount, @@ -386,6 +399,7 @@ impl GetTransactionDetail { vout: self.vout, fee, abandoned: self.abandoned, + parent_descriptors: None, // v24 and later only. }) } } @@ -670,6 +684,7 @@ impl ListUnspentItem { solvable: self.solvable, descriptor: None, safe: self.safe, + parent_descriptors: None, // v24 and later only. }) } } diff --git a/types/src/v18/wallet/into.rs b/types/src/v18/wallet/into.rs index 5da27a65..b21e6497 100644 --- a/types/src/v18/wallet/into.rs +++ b/types/src/v18/wallet/into.rs @@ -85,6 +85,7 @@ impl ListUnspentItem { solvable: self.solvable, descriptor: self.descriptor, safe: self.safe, + parent_descriptors: None, // v24 and later only. }) } } diff --git a/types/src/v19/mod.rs b/types/src/v19/mod.rs index fad92229..d4844e04 100644 --- a/types/src/v19/mod.rs +++ b/types/src/v19/mod.rs @@ -244,36 +244,39 @@ pub use self::{ control::GetRpcInfo, network::{GetNetworkInfo, GetPeerInfo, PeerInfo}, util::GetDescriptorInfo, - wallet::{GetBalances, GetBalancesMine, GetBalancesWatchOnly}, + wallet::{ + GetBalances, GetBalancesError, GetBalancesMine, GetBalancesWatchOnly, GetTransaction, + }, }; #[doc(inline)] pub use crate::v17::{ AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddedNode, AddedNodeAddress, - AddressInformation, Banned, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, - CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisig, CreateMultisigError, - CreatePsbt, CreateRawTransaction, CreateWallet, DecodePsbt, DecodePsbtError, - DecodeRawTransaction, DecodeScript, DecodeScriptError, DumpPrivKey, DumpWallet, EncryptWallet, - EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, FundRawTransactionError, - Generate, GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, GetAddressInfoEmbedded, - GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, - GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderError, - GetBlockHeaderVerbose, GetBlockHeaderVerboseError, GetBlockStats, GetBlockStatsError, - GetBlockTemplate, GetBlockTemplateError, GetBlockVerboseOne, GetBlockVerboseOneError, - GetBlockVerboseZero, GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, - GetMemoryInfoStats, GetMempoolInfoError, GetMiningInfo, GetNetTotals, GetNetworkInfoAddress, - GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, - GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, - GetRawTransactionVerboseError, GetReceivedByAddress, GetTransaction, GetTransactionDetail, - GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, GetTxOutSetInfo, - GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, - GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, - ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, - ListReceivedByAddress, ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, - ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, - ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, - ListWallets, LoadWallet, Locked, Logging, PruneBlockchain, RawTransactionError, - RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, - SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, + AddressInformation, Banned, Bip125Replaceable, BumpFee, BumpFeeError, ChainTips, + ChainTipsError, ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, + CreateMultisig, CreateMultisigError, CreatePsbt, CreateRawTransaction, CreateWallet, + DecodePsbt, DecodePsbtError, DecodeRawTransaction, DecodeScript, DecodeScriptError, + DumpPrivKey, DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, + FundRawTransaction, FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, + GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, + GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, + GetBlockHash, GetBlockHeader, GetBlockHeaderError, GetBlockHeaderVerbose, + GetBlockHeaderVerboseError, GetBlockStats, GetBlockStatsError, GetBlockTemplate, + GetBlockTemplateError, GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, + GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, + GetMempoolInfoError, GetMiningInfo, GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, + GetRawTransaction, GetRawTransactionVerbose, GetRawTransactionVerboseError, + GetReceivedByAddress, GetTransactionDetail, GetTransactionDetailError, GetTransactionError, + GetTxOut, GetTxOutError, GetTxOutSetInfo, GetTxOutSetInfoError, GetUnconfirmedBalance, + GetWalletInfo, GetWalletInfoError, GetZmqNotifications, ListAddressGroupings, + ListAddressGroupingsError, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, + ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, + ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, + ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, + ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, LoadWallet, + Locked, Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, + RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, + SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo, diff --git a/types/src/v19/wallet.rs b/types/src/v19/wallet.rs deleted file mode 100644 index b8e72ee8..00000000 --- a/types/src/v19/wallet.rs +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -//! The JSON-RPC API for Bitcoin Core `v0.19` - wallet. -//! -//! Types for methods found under the `== Wallet ==` section of the API docs. - -use bitcoin::amount::ParseAmountError; -use bitcoin::Amount; -use serde::{Deserialize, Serialize}; - -use crate::model; - -/// Result of the JSON-RPC method `getbalances`. -/// -/// > getbalances -/// > -/// > Returns an object with all balances in BTC. -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct GetBalances { - /// Balances from outputs that the wallet can sign. - pub mine: GetBalancesMine, - #[serde(rename = "watchonly")] - pub watch_only: Option, -} - -/// Balances from outputs that the wallet can sign. -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct GetBalancesMine { - /// Trusted balance (outputs created by the wallet or confirmed outputs). - pub trusted: f64, - /// Untrusted pending balance (outputs created by others that are in the mempool). - pub untrusted_pending: f64, - /// Balance from immature coinbase outputs. - pub immature: f64, - /// Balance from coins sent to addresses that were previously spent from (potentially privacy violating). - /// - /// Only present if `avoid_reuse` is set. - pub used: Option, -} - -/// Hash and height of the block this information was generated on. -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct GetBalancesWatchOnly { - /// Trusted balance (outputs created by the wallet or confirmed outputs). - pub trusted: f64, - /// Untrusted pending balance (outputs created by others that are in the mempool). - pub untrusted_pending: f64, - /// Balance from immature coinbase outputs. - pub immature: f64, -} - -impl GetBalances { - /// Converts version specific type to a version nonspecific, more strongly typed type. - pub fn into_model(self) -> Result { - let mine = self.mine.into_model()?; - let watch_only = self.watch_only.map(|watch_only| watch_only.into_model()).transpose()?; - - Ok(model::GetBalances { mine, watch_only }) - } -} - -impl GetBalancesMine { - /// Converts version specific type to a version nonspecific, more strongly typed type. - pub fn into_model(self) -> Result { - let trusted = Amount::from_btc(self.trusted)?; - let untrusted_pending = Amount::from_btc(self.untrusted_pending)?; - let immature = Amount::from_btc(self.immature)?; - let used = self.used.map(Amount::from_btc).transpose()?; - - Ok(model::GetBalancesMine { trusted, untrusted_pending, immature, used }) - } -} - -impl GetBalancesWatchOnly { - /// Converts version specific type to a version nonspecific, more strongly typed type. - pub fn into_model(self) -> Result { - let trusted = Amount::from_btc(self.trusted)?; - let untrusted_pending = Amount::from_btc(self.untrusted_pending)?; - let immature = Amount::from_btc(self.immature)?; - - Ok(model::GetBalancesWatchOnly { trusted, untrusted_pending, immature }) - } -} diff --git a/types/src/v19/wallet/error.rs b/types/src/v19/wallet/error.rs new file mode 100644 index 00000000..ba21e98b --- /dev/null +++ b/types/src/v19/wallet/error.rs @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: CC0-1.0 + +use core::fmt; + +use bitcoin::amount::ParseAmountError; + +use crate::error::write_err; + +/// Error when converting a `GetBalances` type into the model type. +#[derive(Debug)] +pub enum GetBalancesError { + /// Conversion of the `mine` field failed. + Mine(ParseAmountError), + /// Conversion of the `watchonly` field failed. + WatchOnly(ParseAmountError), +} + +impl fmt::Display for GetBalancesError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use GetBalancesError as E; + + match *self { + E::Mine(ref e) => write_err!(f, "conversion of the `mine` field failed"; e), + E::WatchOnly(ref e) => write_err!(f, "conversion of the `watchonly` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for GetBalancesError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use GetBalancesError as E; + + match *self { + E::Mine(ref e) => Some(e), + E::WatchOnly(ref e) => Some(e), + } + } +} diff --git a/types/src/v19/wallet/into.rs b/types/src/v19/wallet/into.rs new file mode 100644 index 00000000..905e218a --- /dev/null +++ b/types/src/v19/wallet/into.rs @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::amount::ParseAmountError; +use bitcoin::consensus::encode; +use bitcoin::{Amount, BlockHash, SignedAmount, Transaction, Txid}; + +use super::{ + GetBalances, GetBalancesError, GetBalancesMine, GetBalancesWatchOnly, GetTransaction, + GetTransactionError, +}; +use crate::model; + +impl GetBalances { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetBalancesError as E; + + let mine = self.mine.into_model().map_err(E::Mine)?; + let watch_only = self + .watch_only + .map(|watch_only| watch_only.into_model()) + .transpose() + .map_err(E::WatchOnly)?; + let last_processed_block = None; // v26 and later only. + + Ok(model::GetBalances { mine, watch_only, last_processed_block }) + } +} + +impl GetBalancesMine { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + let trusted = Amount::from_btc(self.trusted)?; + let untrusted_pending = Amount::from_btc(self.untrusted_pending)?; + let immature = Amount::from_btc(self.immature)?; + let used = self.used.map(Amount::from_btc).transpose()?; + + Ok(model::GetBalancesMine { trusted, untrusted_pending, immature, used }) + } +} + +impl GetBalancesWatchOnly { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + let trusted = Amount::from_btc(self.trusted)?; + let untrusted_pending = Amount::from_btc(self.untrusted_pending)?; + let immature = Amount::from_btc(self.immature)?; + + Ok(model::GetBalancesWatchOnly { trusted, untrusted_pending, immature }) + } +} + +impl GetTransaction { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTransactionError as E; + + let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; + let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; + let block_hash = + self.block_hash.map(|s| s.parse::().map_err(E::BlockHash)).transpose()?; + let block_index = + self.block_index.map(|idx| crate::to_u32(idx, "block_index")).transpose()?; + let txid = self.txid.parse::().map_err(E::Txid)?; + let wallet_conflicts = self + .wallet_conflicts + .into_iter() + .map(|s| s.parse::().map_err(E::WalletConflicts)) + .collect::, _>>()?; + let tx = encode::deserialize_hex::(&self.hex).map_err(E::Tx)?; + let details = self + .details + .into_iter() + .map(|d| d.into_model().map_err(E::Details)) + .collect::, _>>()?; + + Ok(model::GetTransaction { + amount, + fee, + confirmations: self.confirmations, + generated: None, // v20 and later only. + trusted: self.trusted, + block_hash, + block_height: None, // v20 and later only. + block_index, + block_time: self.block_time, + txid, + wtxid: None, // v24 and later only. + wallet_conflicts, + replaced_by_txid: None, // v23 and later only. + replaces_txid: None, // v23 and later only. + mempool_conflicts: None, // v28 and later only. + to: None, // v23 and later only. + time: self.time, + time_received: self.time_received, + comment: None, // v20 to v24 only. + bip125_replaceable: self.bip125_replaceable.into_model(), + parent_descriptors: None, // v24 and later only. + details, + decoded: self.decoded, + last_processed_block: None, // v26 and later only. + tx, + }) + } +} diff --git a/types/src/v19/wallet/mod.rs b/types/src/v19/wallet/mod.rs new file mode 100644 index 00000000..3abe9761 --- /dev/null +++ b/types/src/v19/wallet/mod.rs @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v0.19` - wallet. +//! +//! Types for methods found under the `== Wallet ==` section of the API docs. + +mod error; +mod into; + +use bitcoin::Transaction; +use serde::{Deserialize, Serialize}; + +pub use self::error::GetBalancesError; +use super::{Bip125Replaceable, GetTransactionDetail, GetTransactionError}; + +/// Result of the JSON-RPC method `getbalances`. +/// +/// > getbalances +/// > +/// > Returns an object with all balances in BTC. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetBalances { + /// Balances from outputs that the wallet can sign. + pub mine: GetBalancesMine, + #[serde(rename = "watchonly")] + pub watch_only: Option, +} + +/// Balances from outputs that the wallet can sign. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetBalancesMine { + /// Trusted balance (outputs created by the wallet or confirmed outputs). + pub trusted: f64, + /// Untrusted pending balance (outputs created by others that are in the mempool). + pub untrusted_pending: f64, + /// Balance from immature coinbase outputs. + pub immature: f64, + /// Balance from coins sent to addresses that were previously spent from (potentially privacy violating). + /// + /// Only present if `avoid_reuse` is set. + pub used: Option, +} + +/// Hash and height of the block this information was generated on. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetBalancesWatchOnly { + /// Trusted balance (outputs created by the wallet or confirmed outputs). + pub trusted: f64, + /// Untrusted pending balance (outputs created by others that are in the mempool). + pub untrusted_pending: f64, + /// Balance from immature coinbase outputs. + pub immature: f64, +} + +/// Result of the JSON-RPC method `gettransaction`. +/// +/// > gettransaction "txid" ( include_watchonly ) +/// > +/// > Get detailed information about in-wallet transaction `` +/// > +/// > Arguments: +/// > 1. txid (string, required) The transaction id +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTransaction { + /// The transaction amount in BTC. + pub amount: f64, + /// The amount of the fee in BTC. + /// + /// This is negative and only available for the 'send' category of transactions. + pub fee: Option, + /// The number of confirmations. + pub confirmations: i64, + /// Whether we consider the outputs of this unconfirmed transaction safe to spend. + pub trusted: Option, + /// The block hash. + #[serde(rename = "blockhash")] + pub block_hash: Option, + /// The index of the transaction in the block that includes it. + #[serde(rename = "blockindex")] + pub block_index: Option, + /// The time in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "blocktime")] + pub block_time: Option, + /// The transaction id. + pub txid: String, + /// Confirmed transactions that have been detected by the wallet to conflict with this transaction. + #[serde(rename = "walletconflicts")] + pub wallet_conflicts: Vec, + /// The transaction time in seconds since epoch (1 Jan 1970 GMT). + pub time: u32, + /// The time received in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "timereceived")] + pub time_received: u32, + /// Whether this transaction could be replaced due to BIP125 (replace-by-fee); + /// may be unknown for unconfirmed transactions not in the mempool + #[serde(rename = "bip125-replaceable")] + pub bip125_replaceable: Bip125Replaceable, + /// Transaction details. + pub details: Vec, + /// Raw data for transaction. + pub hex: String, + /// The decoded transaction (only present when `verbose` is passed). v19 and later only. + pub decoded: Option, +} diff --git a/types/src/v20/control.rs b/types/src/v20/control.rs index c27e227b..6141f4d9 100644 --- a/types/src/v20/control.rs +++ b/types/src/v20/control.rs @@ -13,26 +13,26 @@ use serde::{Deserialize, Serialize}; /// > Gets and sets the logging configuration. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct Logging { - pub net: bool, - pub tor: bool, - pub mempool: bool, - pub http: bool, - pub bench: bool, - pub zmq: bool, - pub walletdb: bool, - pub rpc: bool, - pub estimatefee: bool, pub addrman: bool, - pub selectcoins: bool, - pub reindex: bool, + pub bench: bool, pub cmpctblock: bool, - pub rand: bool, + pub coindb: bool, + pub estimatefee: bool, + pub http: bool, + pub leveldb: bool, + pub libevent: bool, + pub mempool: bool, + pub mempoolrej: bool, + pub net: bool, pub prune: bool, pub proxy: bool, - pub mempoolrej: bool, - pub libevent: bool, - pub coindb: bool, pub qt: bool, - pub leveldb: bool, + pub rand: bool, + pub reindex: bool, + pub rpc: bool, + pub selectcoins: bool, + pub tor: bool, pub validation: bool, + pub walletdb: bool, + pub zmq: bool, } diff --git a/types/src/v20/mod.rs b/types/src/v20/mod.rs index 3a0bfdbf..b105b31a 100644 --- a/types/src/v20/mod.rs +++ b/types/src/v20/mod.rs @@ -229,37 +229,39 @@ mod control; mod network; mod util; +mod wallet; #[doc(inline)] pub use self::{ control::Logging, network::{Banned, ListBanned}, util::CreateMultisig, + wallet::{GetTransaction, GetTransactionDetail}, }; #[doc(inline)] pub use crate::{ v17::{ AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddedNode, AddedNodeAddress, - AddressInformation, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, - CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, CreatePsbt, - CreateRawTransaction, CreateWallet, DecodePsbt, DecodePsbtError, DecodeRawTransaction, - DecodeScript, DecodeScriptError, DumpPrivKey, DumpWallet, EncryptWallet, EstimateSmartFee, - FinalizePsbt, FinalizePsbtError, FundRawTransaction, FundRawTransactionError, Generate, - GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, GetAddressInfoEmbedded, - GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, - GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, - GetBlockHeaderError, GetBlockHeaderVerbose, GetBlockHeaderVerboseError, GetBlockStats, - GetBlockStatsError, GetBlockTemplate, GetBlockTemplateError, GetBlockVerboseOne, - GetBlockVerboseOneError, GetBlockVerboseZero, GetChainTips, GetChainTxStatsError, - GetConnectionCount, GetDifficulty, GetMemoryInfoStats, GetMempoolInfoError, GetMiningInfo, - GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, - GetRawTransactionVerbose, GetRawTransactionVerboseError, GetReceivedByAddress, - GetTransaction, GetTransactionDetail, GetTransactionDetailError, GetTransactionError, - GetTxOut, GetTxOutError, GetTxOutSetInfo, GetTxOutSetInfoError, GetUnconfirmedBalance, - GetWalletInfo, GetWalletInfoError, GetZmqNotifications, ListAddressGroupings, - ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, ListLockUnspent, - ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, + AddressInformation, Bip125Replaceable, BumpFee, BumpFeeError, ChainTips, ChainTipsError, + ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, + CreatePsbt, CreateRawTransaction, CreateWallet, DecodePsbt, DecodePsbtError, + DecodeRawTransaction, DecodeScript, DecodeScriptError, DumpPrivKey, DumpWallet, + EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, + FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, + GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, + GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, + GetBlockHash, GetBlockHeader, GetBlockHeaderError, GetBlockHeaderVerbose, + GetBlockHeaderVerboseError, GetBlockStats, GetBlockStatsError, GetBlockTemplate, + GetBlockTemplateError, GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, + GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, + GetMempoolInfoError, GetMiningInfo, GetNetTotals, GetNetworkInfoAddress, + GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, + GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, + GetRawTransactionVerboseError, GetReceivedByAddress, GetTransactionDetailError, + GetTransactionError, GetTxOut, GetTxOutError, GetTxOutSetInfo, GetTxOutSetInfoError, + GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, GetZmqNotifications, + ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, + ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, @@ -278,12 +280,12 @@ pub use crate::{ ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetBlockchainInfo, - GetBlockchainInfoError, GetChainTxStats, GetDescriptorInfo, GetMempoolAncestors, - GetMempoolAncestorsVerbose, GetMempoolDescendants, GetMempoolDescendantsVerbose, - GetMempoolEntry, GetMempoolInfo, GetNetworkInfo, GetPeerInfo, GetRpcInfo, - MapMempoolEntryError, MempoolEntry, MempoolEntryError, MempoolEntryFees, + Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, + GetBalancesError, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, + GetBlockFilterError, GetBlockchainInfo, GetBlockchainInfoError, GetChainTxStats, + GetDescriptorInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, + GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetworkInfo, GetPeerInfo, + GetRpcInfo, MapMempoolEntryError, MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, Softfork, SoftforkType, }, }; diff --git a/types/src/v20/wallet/into.rs b/types/src/v20/wallet/into.rs new file mode 100644 index 00000000..dea4fbaf --- /dev/null +++ b/types/src/v20/wallet/into.rs @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::consensus::encode; +use bitcoin::{Address, BlockHash, SignedAmount, Transaction, Txid}; + +use super::{GetTransaction, GetTransactionDetail, GetTransactionDetailError, GetTransactionError}; +use crate::model; + +impl GetTransaction { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTransactionError as E; + + let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; + let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; + let block_hash = + self.block_hash.map(|s| s.parse::().map_err(E::BlockHash)).transpose()?; + let block_index = + self.block_index.map(|idx| crate::to_u32(idx, "block_index")).transpose()?; + let block_height = + self.block_height.map(|h| crate::to_u32(h, "block_height")).transpose()?; + let txid = self.txid.parse::().map_err(E::Txid)?; + let wallet_conflicts = self + .wallet_conflicts + .into_iter() + .map(|s| s.parse::().map_err(E::WalletConflicts)) + .collect::, _>>()?; + let tx = encode::deserialize_hex::(&self.hex).map_err(E::Tx)?; + let details = self + .details + .into_iter() + .map(|d| d.into_model().map_err(E::Details)) + .collect::, _>>()?; + + Ok(model::GetTransaction { + amount, + fee, + confirmations: self.confirmations, + generated: self.generated, + trusted: self.trusted, + block_hash, + block_height, + block_index, + block_time: self.block_time, + txid, + wtxid: None, // v24 and later only. + wallet_conflicts, + replaced_by_txid: None, // v23 and later only. + replaces_txid: None, // v23 and later only. + mempool_conflicts: None, // v28 and later only. + to: None, // v23 and later only. + time: self.time, + time_received: self.time_received, + comment: self.comment, + bip125_replaceable: self.bip125_replaceable.into_model(), + parent_descriptors: None, // v24 and later only. + details, + decoded: self.decoded, + last_processed_block: None, // v26 and later only. + tx, + }) + } +} + +impl GetTransactionDetail { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTransactionDetailError as E; + + let address = self.address.parse::>().map_err(E::Address)?; + let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; + let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; + + Ok(model::GetTransactionDetail { + involves_watchonly: self.involves_watchonly, + account: self.account, + address, + category: self.category.into_model(), + amount, + label: self.label, + vout: self.vout, + fee, + abandoned: self.abandoned, + parent_descriptors: None, // v24 and later only. + }) + } +} diff --git a/types/src/v20/wallet/mod.rs b/types/src/v20/wallet/mod.rs new file mode 100644 index 00000000..fe9e601f --- /dev/null +++ b/types/src/v20/wallet/mod.rs @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v20` - wallet. +//! +//! Types for methods found under the `== Wallet ==` section of the API docs. + +mod into; + +use bitcoin::Transaction; +use serde::{Deserialize, Serialize}; + +pub use super::{ + Bip125Replaceable, GetTransactionDetailError, GetTransactionError, TransactionCategory, +}; + +/// Result of the JSON-RPC method `gettransaction`. +/// +/// > gettransaction "txid" ( include_watchonly ) +/// > +/// > Get detailed information about in-wallet transaction `` +/// > +/// > Arguments: +/// > 1. txid (string, required) The transaction id +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTransaction { + /// The transaction amount in BTC. + pub amount: f64, + /// The amount of the fee in BTC. + /// + /// This is negative and only available for the 'send' category of transactions. + pub fee: Option, + /// The number of confirmations. + pub confirmations: i64, + /// Only present if the transaction's only input is a coinbase one. v20 and later only. + pub generated: Option, + /// Whether we consider the outputs of this unconfirmed transaction safe to spend. + pub trusted: Option, + /// The block hash. + #[serde(rename = "blockhash")] + pub block_hash: Option, + /// The block height containing the transaction. v20 and later only. + #[serde(rename = "blockheight")] + pub block_height: Option, + /// The index of the transaction in the block that includes it. + #[serde(rename = "blockindex")] + pub block_index: Option, + /// The time in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "blocktime")] + pub block_time: Option, + /// The transaction id. + pub txid: String, + /// Confirmed transactions that have been detected by the wallet to conflict with this transaction. + #[serde(rename = "walletconflicts")] + pub wallet_conflicts: Vec, + /// The transaction time in seconds since epoch (1 Jan 1970 GMT). + pub time: u32, + /// The time received in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "timereceived")] + pub time_received: u32, + /// If a comment is associated with the transaction, only present if not empty. v20 to v24 only. + pub comment: Option, + /// Whether this transaction could be replaced due to BIP125 (replace-by-fee); + /// may be unknown for unconfirmed transactions not in the mempool + #[serde(rename = "bip125-replaceable")] + pub bip125_replaceable: Bip125Replaceable, + /// Transaction details. + pub details: Vec, + /// Raw data for transaction. + pub hex: String, + /// The decoded transaction (only present when `verbose` is passed). v19 and later only. + pub decoded: Option, +} + +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTransactionDetail { + /// Only returns true if imported addresses were involved in transaction. v20 and later only. + #[serde(rename = "involvesWatchonly")] + pub involves_watchonly: Option, + /// DEPRECATED. The account name involved in the transaction, can be "" for the default account. + pub account: Option, // Docs are wrong, this is not documented as optional. + /// The bitcoin address involved in the transaction. + pub address: String, + /// The category, either 'send' or 'receive'. + pub category: TransactionCategory, + /// The amount in BTC. + pub amount: f64, + /// A comment for the address/transaction, if any. + pub label: Option, + /// the vout value. + pub vout: u32, + /// The amount of the fee. + /// + /// This is negative and only available for the 'send' category of transactions. + pub fee: Option, + /// If the transaction has been abandoned (inputs are respendable). + /// + /// Only available for the 'send' category of transactions. + pub abandoned: Option, +} diff --git a/types/src/v21/mod.rs b/types/src/v21/mod.rs index 96748025..34820009 100644 --- a/types/src/v21/mod.rs +++ b/types/src/v21/mod.rs @@ -264,21 +264,20 @@ pub use crate::{ GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, GetRawTransactionVerboseError, GetReceivedByAddress, - GetTransaction, GetTransactionDetail, GetTransactionDetailError, GetTransactionError, - GetTxOut, GetTxOutError, GetTxOutSetInfo, GetTxOutSetInfoError, GetUnconfirmedBalance, - GetWalletInfo, GetWalletInfoError, GetZmqNotifications, ListAddressGroupings, - ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, ListLockUnspent, - ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, - ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, - ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, - ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, - LoadWallet, Locked, PruneBlockchain, RawTransactionError, RawTransactionInput, - RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, - SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, - SignRawTransactionError, SoftforkReject, TestMempoolAccept, TransactionCategory, - UploadTarget, ValidateAddress, ValidateAddressError, VerifyChain, VerifyMessage, - VerifyTxOutProof, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, WalletProcessPsbt, - WitnessUtxo, + GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, GetTxOutSetInfo, + GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, + GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, + ListAddressGroupingsItem, ListLabels, ListLockUnspent, ListLockUnspentItem, + ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, + ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, + ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, + ListTransactionsItemError, ListUnspentItemError, ListWallets, LoadWallet, Locked, + PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, + RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, + SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, + SoftforkReject, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, + ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, + WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo, }, v18::{ ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing, @@ -287,11 +286,11 @@ pub use crate::{ ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, + Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesError, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetBlockchainInfoError, GetChainTxStats, GetDescriptorInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, }, - v20::{Banned, CreateMultisig, ListBanned, Logging}, + v20::{Banned, CreateMultisig, GetTransaction, GetTransactionDetail, ListBanned, Logging}, }; diff --git a/types/src/v22/control.rs b/types/src/v22/control.rs index 9e6fbf0e..82ea74bc 100644 --- a/types/src/v22/control.rs +++ b/types/src/v22/control.rs @@ -13,28 +13,28 @@ use serde::{Deserialize, Serialize}; /// > Gets and sets the logging configuration. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct Logging { - pub net: bool, - pub tor: bool, - pub mempool: bool, - pub http: bool, - pub bench: bool, - pub zmq: bool, - pub walletdb: bool, - pub rpc: bool, - pub estimatefee: bool, pub addrman: bool, - pub selectcoins: bool, - pub reindex: bool, + pub bench: bool, pub cmpctblock: bool, - pub rand: bool, + pub coindb: bool, + pub estimatefee: bool, + pub http: bool, + pub i2p: bool, + pub ipc: bool, + pub leveldb: bool, + pub libevent: bool, + pub mempool: bool, + pub mempoolrej: bool, + pub net: bool, pub prune: bool, pub proxy: bool, - pub mempoolrej: bool, - pub libevent: bool, - pub coindb: bool, pub qt: bool, - pub leveldb: bool, + pub rand: bool, + pub reindex: bool, + pub rpc: bool, + pub selectcoins: bool, + pub tor: bool, pub validation: bool, - pub i2p: bool, - pub ipc: bool, + pub walletdb: bool, + pub zmq: bool, } diff --git a/types/src/v22/mod.rs b/types/src/v22/mod.rs index e26bd526..c1ec64ad 100644 --- a/types/src/v22/mod.rs +++ b/types/src/v22/mod.rs @@ -246,12 +246,14 @@ mod blockchain; mod control; mod network; +mod raw_transactions; #[doc(inline)] pub use self::{ blockchain::GetMempoolInfo, control::Logging, network::{Banned, GetPeerInfo, ListBanned}, + raw_transactions::{DecodeScript, DecodeScriptError}, }; #[doc(inline)] pub use crate::{ @@ -260,23 +262,22 @@ pub use crate::{ AddressInformation, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, CreatePsbt, CreateRawTransaction, CreateWallet, DecodePsbt, DecodePsbtError, DecodeRawTransaction, - DecodeScript, DecodeScriptError, DumpPrivKey, DumpWallet, EncryptWallet, EstimateSmartFee, - FinalizePsbt, FinalizePsbtError, FundRawTransaction, FundRawTransactionError, Generate, - GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, GetAddressInfoEmbedded, - GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, - GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, - GetBlockHeaderError, GetBlockHeaderVerbose, GetBlockHeaderVerboseError, GetBlockStats, - GetBlockStatsError, GetBlockTemplate, GetBlockTemplateError, GetBlockVerboseOne, - GetBlockVerboseOneError, GetBlockVerboseZero, GetChainTips, GetChainTxStatsError, - GetConnectionCount, GetDifficulty, GetMemoryInfoStats, GetMempoolInfoError, GetMiningInfo, - GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, - GetRawTransactionVerbose, GetRawTransactionVerboseError, GetReceivedByAddress, - GetTransaction, GetTransactionDetail, GetTransactionDetailError, GetTransactionError, - GetTxOut, GetTxOutError, GetTxOutSetInfo, GetTxOutSetInfoError, GetUnconfirmedBalance, - GetWalletInfo, GetWalletInfoError, GetZmqNotifications, ListAddressGroupings, - ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, ListLockUnspent, - ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, + DumpPrivKey, DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, + FundRawTransaction, FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, + GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, + GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, + GetBlockHash, GetBlockHeader, GetBlockHeaderError, GetBlockHeaderVerbose, + GetBlockHeaderVerboseError, GetBlockStats, GetBlockStatsError, GetBlockTemplate, + GetBlockTemplateError, GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, + GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, + GetMempoolInfoError, GetMiningInfo, GetNetTotals, GetNetworkInfoAddress, + GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, + GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, + GetRawTransactionVerboseError, GetReceivedByAddress, GetTransactionDetailError, + GetTransactionError, GetTxOut, GetTxOutError, GetTxOutSetInfo, GetTxOutSetInfoError, + GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, GetZmqNotifications, + ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, + ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, @@ -295,13 +296,13 @@ pub use crate::{ ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, + Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesError, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetBlockchainInfoError, GetChainTxStats, GetDescriptorInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, }, - v20::CreateMultisig, + v20::{CreateMultisig, GetTransaction, GetTransactionDetail}, v21::{ Bip9SoftforkInfo, GetBlockchainInfo, GetMempoolEntry, GetNetworkInfo, Softfork, SoftforkType, UnloadWallet, diff --git a/types/src/v22/raw_transactions/error.rs b/types/src/v22/raw_transactions/error.rs new file mode 100644 index 00000000..de5dee59 --- /dev/null +++ b/types/src/v22/raw_transactions/error.rs @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: CC0-1.0 + +use core::fmt; + +use bitcoin::{address, hex}; + +use crate::error::write_err; + +/// Error when converting a `DecodeScript` type into the model type. +#[derive(Debug)] +pub enum DecodeScriptError { + /// Conversion of the transaction `hex` field failed. + Hex(hex::HexToBytesError), + /// Conversion of the transaction `address` field failed. + Address(address::ParseError), + /// Conversion of the transaction `addresses` field failed. + Addresses(address::ParseError), + /// Conversion of the transaction `p2sh` field failed. + P2sh(address::ParseError), +} + +impl fmt::Display for DecodeScriptError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use DecodeScriptError as E; + + match *self { + E::Hex(ref e) => write_err!(f, "conversion of the `hex` field failed"; e), + E::Address(ref e) => write_err!(f, "conversion of the `address` field failed"; e), + E::Addresses(ref e) => write_err!(f, "conversion of the `addresses` field failed"; e), + E::P2sh(ref e) => write_err!(f, "conversion of the `p2sh` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for DecodeScriptError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use DecodeScriptError as E; + + match *self { + E::Hex(ref e) => Some(e), + E::Address(ref e) => Some(e), + E::Addresses(ref e) => Some(e), + E::P2sh(ref e) => Some(e), + } + } +} diff --git a/types/src/v22/raw_transactions/into.rs b/types/src/v22/raw_transactions/into.rs new file mode 100644 index 00000000..317d8efe --- /dev/null +++ b/types/src/v22/raw_transactions/into.rs @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::Address; + +use super::{DecodeScript, DecodeScriptError}; +use crate::model; + +impl DecodeScript { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use DecodeScriptError as E; + + let address = match self.address { + Some(addr) => Some(addr.parse::>().map_err(E::Address)?), + None => None, + }; + let addresses = match self.addresses { + Some(addresses) => addresses + .iter() + .map(|s| s.parse::>()) + .collect::>() + .map_err(E::Addresses)?, + None => vec![], + }; + let p2sh = self.p2sh.map(|s| s.parse::>()).transpose().map_err(E::P2sh)?; + + Ok(model::DecodeScript { + script_pubkey: None, + type_: self.type_, + descriptor: None, + address, + required_signatures: self.required_signatures, + addresses, + p2sh, + p2sh_segwit: self.p2sh_segwit, + }) + } +} diff --git a/types/src/v22/raw_transactions/mod.rs b/types/src/v22/raw_transactions/mod.rs new file mode 100644 index 00000000..1b356b63 --- /dev/null +++ b/types/src/v22/raw_transactions/mod.rs @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v22` - raw transactions. +//! +//! Types for methods found under the `== Rawtransactions ==` section of the API docs. + +mod error; +mod into; + +use serde::{Deserialize, Serialize}; + +pub use self::error::DecodeScriptError; + +/// Result of JSON-RPC method `decodescript`. +/// +/// > decodescript "hexstring" +/// > +/// > Decode a hex-encoded script. +/// > +/// > Arguments: +/// > 1. "hexstring" (string) the hex encoded script +// The docs on Core v0.17 appear to be way off what is actually returned. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct DecodeScript { + /// Script public key. + pub asm: String, + /// The output type. + #[serde(rename = "type")] + pub type_: String, + /// Bitcoin address (only if a well-defined address exists). v22 and later only. + pub address: Option, + /// The required signatures. + #[serde(rename = "reqSigs")] + pub required_signatures: Option, + /// List of bitcoin addresses. + pub addresses: Option>, + /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). + pub p2sh: Option, + /// Segwit data (see `DecodeScriptSegwit` for explanation). + pub segwit: Option, + /// Address of the P2SH script wrapping this witness redeem script + #[serde(rename = "p2sh-segwit")] + pub p2sh_segwit: Option, +} + +/// `segwit` item returned as part of `decodescript`. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct DecodeScriptSegwit { + /// Script public key. + pub asm: String, + /// Hex encoded public key. + pub hex: String, + /// The output type. + #[serde(rename = "type")] + pub type_: String, + /// Bitcoin address (only if a well-defined address exists). v22 and later only. + pub address: Option, + /// The required signatures. + #[serde(rename = "reqSigs")] + pub required_signatures: Option, + /// List of bitcoin addresses. + pub addresses: Option>, + /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). + #[serde(rename = "p2sh-segwit")] + pub p2sh_segtwit: Option, +} diff --git a/types/src/v23/control.rs b/types/src/v23/control.rs new file mode 100644 index 00000000..b76e8b61 --- /dev/null +++ b/types/src/v23/control.rs @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v23` - control. +//! +//! Types for methods found under the `== Control ==` section of the API docs. + +use serde::{Deserialize, Serialize}; + +/// Result of JSON-RPC method `logging`. +/// +/// > logging ( `` `` ) +/// +/// > Gets and sets the logging configuration. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct Logging { + pub addrman: bool, + pub bench: bool, + pub blockstorage: bool, // v23 and later only + pub cmpctblock: bool, + pub coindb: bool, + pub estimatefee: bool, + pub http: bool, + pub i2p: bool, // v23 and later only + pub ipc: bool, // v23 and later only + pub leveldb: bool, + pub libevent: bool, + pub mempool: bool, + pub mempoolrej: bool, + pub net: bool, + pub prune: bool, + pub proxy: bool, + pub qt: bool, + pub rand: bool, + pub reindex: bool, + pub rpc: bool, + pub selectcoins: bool, + pub tor: bool, + pub util: bool, // v23 to v27 only + pub validation: bool, // v23 and later only + pub walletdb: bool, // v23 and later only + pub zmq: bool, +} diff --git a/types/src/v23/mod.rs b/types/src/v23/mod.rs index 27777f71..f59bee8c 100644 --- a/types/src/v23/mod.rs +++ b/types/src/v23/mod.rs @@ -237,27 +237,32 @@ // JSON-RPC types by API section. mod blockchain; +mod control; mod network; mod raw_transactions; mod util; +mod wallet; #[doc(inline)] pub use self::{ blockchain::{GetBlockchainInfo, GetMempoolEntry, SaveMempool}, + control::Logging, network::GetPeerInfo, raw_transactions::{ - DecodePsbt, DecodePsbtError, GlobalXpub, Proprietary, PsbtInput, PsbtOutput, + DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, GlobalXpub, Proprietary, + PsbtInput, PsbtOutput, }, util::CreateMultisig, + wallet::{GetTransaction, GetTransactionError}, }; #[doc(inline)] pub use crate::{ v17::{ AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddedNode, AddedNodeAddress, - AddressInformation, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, - CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, CreatePsbt, - CreateRawTransaction, CreateWallet, DecodeRawTransaction, DecodeScript, DecodeScriptError, - DumpPrivKey, DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, + AddressInformation, Bip125Replaceable, BumpFee, BumpFeeError, ChainTips, ChainTipsError, + ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, + CreatePsbt, CreateRawTransaction, CreateWallet, DecodeRawTransaction, DumpPrivKey, + DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, @@ -268,10 +273,9 @@ pub use crate::{ GetMempoolInfoError, GetMiningInfo, GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, - GetRawTransactionVerboseError, GetReceivedByAddress, GetTransaction, GetTransactionDetail, - GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, GetTxOutSetInfo, - GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, - GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, + GetRawTransactionVerboseError, GetReceivedByAddress, GetTransactionDetailError, GetTxOut, + GetTxOutError, GetTxOutSetInfo, GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfo, + GetWalletInfoError, GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, @@ -291,13 +295,15 @@ pub use crate::{ ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetBlockchainInfoError, - GetChainTxStats, GetDescriptorInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, - GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, - MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, - Softfork, SoftforkType, + Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, + GetBalancesError, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, + GetBlockFilterError, GetBlockchainInfoError, GetChainTxStats, GetDescriptorInfo, + GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, + GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, MempoolEntry, + MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, Softfork, + SoftforkType, }, + v20::GetTransactionDetail, v21::{GetNetworkInfo, UnloadWallet}, - v22::{Banned, GetMempoolInfo, ListBanned, Logging, ScriptPubkey}, + v22::{Banned, GetMempoolInfo, ListBanned, ScriptPubkey}, }; diff --git a/types/src/v23/raw_transactions/error.rs b/types/src/v23/raw_transactions/error.rs index 1d353948..ab9ad9ef 100644 --- a/types/src/v23/raw_transactions/error.rs +++ b/types/src/v23/raw_transactions/error.rs @@ -2,7 +2,7 @@ use core::fmt; -use bitcoin::{bip32, hex, sighash}; +use bitcoin::{address, bip32, hex, sighash}; use crate::error::write_err; use crate::v17::{Bip32DerivError, PartialSignatureError, RawTransactionError, WitnessUtxoError}; @@ -255,3 +255,43 @@ impl std::error::Error for PsbtOutputError { } } } + +/// Error when converting a `DecodeScript` type into the model type. +#[derive(Debug)] +pub enum DecodeScriptError { + /// Conversion of the transaction `hex` field failed. + Hex(hex::HexToBytesError), + /// Conversion of the transaction `address` field failed. + Address(address::ParseError), + /// Conversion of the transaction `addresses` field failed. + Addresses(address::ParseError), + /// Conversion of the transaction `p2sh` field failed. + P2sh(address::ParseError), +} + +impl fmt::Display for DecodeScriptError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use DecodeScriptError as E; + + match *self { + E::Hex(ref e) => write_err!(f, "conversion of the `hex` field failed"; e), + E::Address(ref e) => write_err!(f, "conversion of the `address` field failed"; e), + E::Addresses(ref e) => write_err!(f, "conversion of the `addresses` field failed"; e), + E::P2sh(ref e) => write_err!(f, "conversion of the `p2sh` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for DecodeScriptError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use DecodeScriptError as E; + + match *self { + E::Hex(ref e) => Some(e), + E::Address(ref e) => Some(e), + E::Addresses(ref e) => Some(e), + E::P2sh(ref e) => Some(e), + } + } +} diff --git a/types/src/v23/raw_transactions/into.rs b/types/src/v23/raw_transactions/into.rs index 043a496f..7697a3b3 100644 --- a/types/src/v23/raw_transactions/into.rs +++ b/types/src/v23/raw_transactions/into.rs @@ -6,11 +6,11 @@ use bitcoin::bip32::{DerivationPath, Fingerprint, KeySource, Xpub}; use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d}; use bitcoin::hex::{self, FromHex as _}; use bitcoin::psbt::{self, raw, PsbtSighashType}; -use bitcoin::Amount; +use bitcoin::{Address, Amount}; use super::{ - DecodePsbt, DecodePsbtError, GlobalXpub, GlobalXpubError, Proprietary, PsbtInput, - PsbtInputError, PsbtOutput, PsbtOutputError, + DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, GlobalXpub, GlobalXpubError, + Proprietary, PsbtInput, PsbtInputError, PsbtOutput, PsbtOutputError, }; use crate::model; @@ -306,3 +306,35 @@ impl PsbtOutput { }) } } + +impl DecodeScript { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use DecodeScriptError as E; + + let address = match self.address { + Some(addr) => Some(addr.parse::>().map_err(E::Address)?), + None => None, + }; + let addresses = match self.addresses { + Some(addresses) => addresses + .iter() + .map(|s| s.parse::>()) + .collect::>() + .map_err(E::Addresses)?, + None => vec![], + }; + let p2sh = self.p2sh.map(|s| s.parse::>()).transpose().map_err(E::P2sh)?; + + Ok(model::DecodeScript { + script_pubkey: None, + type_: self.type_, + descriptor: self.descriptor, + address, + required_signatures: self.required_signatures, + addresses, + p2sh, + p2sh_segwit: self.p2sh_segwit, + }) + } +} diff --git a/types/src/v23/raw_transactions/mod.rs b/types/src/v23/raw_transactions/mod.rs index 28c3cece..c975f82c 100644 --- a/types/src/v23/raw_transactions/mod.rs +++ b/types/src/v23/raw_transactions/mod.rs @@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize}; use crate::ScriptSig; #[rustfmt::skip] // Keep public re-exports separate. -pub use self::error::{DecodePsbtError, GlobalXpubError, PsbtInputError, PsbtOutputError}; +pub use self::error::{DecodePsbtError, DecodeScriptError, GlobalXpubError, PsbtInputError, PsbtOutputError}; // Re-export types that appear in the public API of this module. pub use crate::psbt::{Bip32Deriv, PsbtScript, RawTransaction, WitnessUtxo}; @@ -121,3 +121,63 @@ pub struct PsbtOutput { /// The unknown global fields. pub unknown: Option>, } + +/// Result of JSON-RPC method `decodescript`. +/// +/// > decodescript "hexstring" +/// > +/// > Decode a hex-encoded script. +/// > +/// > Arguments: +/// > 1. "hexstring" (string) the hex encoded script +// The docs on Core v0.17 appear to be way off what is actually returned. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct DecodeScript { + /// Script public key. + pub asm: String, + /// Inferred descriptor for the script. v23 and later only. + #[serde(rename = "desc")] + pub descriptor: Option, + /// The output type. + #[serde(rename = "type")] + pub type_: String, + /// Bitcoin address (only if a well-defined address exists). v22 and later only. + pub address: Option, + /// The required signatures. + #[serde(rename = "reqSigs")] + pub required_signatures: Option, + /// List of bitcoin addresses. + pub addresses: Option>, + /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). + pub p2sh: Option, + /// Segwit data (see `DecodeScriptSegwit` for explanation). + pub segwit: Option, + /// Address of the P2SH script wrapping this witness redeem script + #[serde(rename = "p2sh-segwit")] + pub p2sh_segwit: Option, +} + +/// `segwit` item returned as part of `decodescript`. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct DecodeScriptSegwit { + /// Script public key. + pub asm: String, + /// Hex encoded public key. + pub hex: String, + /// The output type. + #[serde(rename = "type")] + pub type_: String, + /// Bitcoin address (only if a well-defined address exists). v22 and later only. + pub address: Option, + /// The required signatures. + #[serde(rename = "reqSigs")] + pub required_signatures: Option, + /// List of bitcoin addresses. + pub addresses: Option>, + /// Inferred descriptor for the script. v23 and later only. + #[serde(rename = "desc")] + pub descriptor: Option, + /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). + #[serde(rename = "p2sh-segwit")] + pub p2sh_segtwit: Option, +} diff --git a/types/src/v23/wallet/error.rs b/types/src/v23/wallet/error.rs new file mode 100644 index 00000000..3feae06c --- /dev/null +++ b/types/src/v23/wallet/error.rs @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: CC0-1.0 + +use core::fmt; + +use bitcoin::amount::ParseAmountError; +use bitcoin::consensus::encode; +use bitcoin::hex; + +use super::GetTransactionDetailError; +use crate::error::write_err; +use crate::NumericError; + +/// Error when converting a `GetTransaction` type into the model type. +#[derive(Debug)] +pub enum GetTransactionError { + /// Conversion of numeric type to expected type failed. + Numeric(NumericError), + /// Conversion of the `amount` field failed. + Amount(ParseAmountError), + /// Conversion of the `fee` field failed. + Fee(ParseAmountError), + /// Conversion of the `block_hash` field failed. + BlockHash(hex::HexToArrayError), + /// Conversion of the `txid` field failed. + Txid(hex::HexToArrayError), + /// Conversion of the `wallet_conflicts` field failed. + WalletConflicts(hex::HexToArrayError), + /// Conversion of the `replaced_by_txid` field failed. + ReplacedByTxid(hex::HexToArrayError), + /// Conversion of the `replaces_txid` field failed. + ReplacesTxid(hex::HexToArrayError), + /// Conversion of the transaction `hex` field failed. + Tx(encode::FromHexError), + /// Conversion of the `details` field failed. + Details(GetTransactionDetailError), +} + +impl fmt::Display for GetTransactionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use GetTransactionError as E; + + match *self { + E::Numeric(ref e) => write_err!(f, "numeric"; e), + E::Amount(ref e) => write_err!(f, "conversion of the `amount` field failed"; e), + E::Fee(ref e) => write_err!(f, "conversion of the `fee` field failed"; e), + E::BlockHash(ref e) => write_err!(f, "conversion of the `block_hash` field failed"; e), + E::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e), + E::WalletConflicts(ref e) => + write_err!(f, "conversion of the `wallet_conflicts` field failed"; e), + E::ReplacedByTxid(ref e) => + write_err!(f, "conversion of the `replaced_by_txid` field failed"; e), + E::ReplacesTxid(ref e) => + write_err!(f, "conversion of the `replaces_txid` field failed"; e), + E::Tx(ref e) => write_err!(f, "conversion of the `hex` field failed"; e), + E::Details(ref e) => write_err!(f, "conversion of the `details` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for GetTransactionError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use GetTransactionError as E; + + match *self { + E::Numeric(ref e) => Some(e), + E::Amount(ref e) => Some(e), + E::Fee(ref e) => Some(e), + E::BlockHash(ref e) => Some(e), + E::Txid(ref e) => Some(e), + E::WalletConflicts(ref e) => Some(e), + E::ReplacedByTxid(ref e) => Some(e), + E::ReplacesTxid(ref e) => Some(e), + E::Tx(ref e) => Some(e), + E::Details(ref e) => Some(e), + } + } +} + +impl From for GetTransactionError { + fn from(e: NumericError) -> Self { Self::Numeric(e) } +} diff --git a/types/src/v23/wallet/into.rs b/types/src/v23/wallet/into.rs new file mode 100644 index 00000000..5b925cff --- /dev/null +++ b/types/src/v23/wallet/into.rs @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::consensus::encode; +use bitcoin::{BlockHash, SignedAmount, Transaction, Txid}; + +use super::{GetTransaction, GetTransactionError}; +use crate::model; + +impl GetTransaction { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTransactionError as E; + + let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; + let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; + let block_hash = + self.block_hash.map(|s| s.parse::().map_err(E::BlockHash)).transpose()?; + let block_index = + self.block_index.map(|idx| crate::to_u32(idx, "block_index")).transpose()?; + let block_height = + self.block_height.map(|h| crate::to_u32(h, "block_height")).transpose()?; + let txid = self.txid.parse::().map_err(E::Txid)?; + let wallet_conflicts = self + .wallet_conflicts + .into_iter() + .map(|s| s.parse::().map_err(E::WalletConflicts)) + .collect::, _>>()?; + let replaced_by_txid = self + .replaced_by_txid + .map(|s| s.parse::().map_err(E::ReplacedByTxid)) + .transpose()?; + let replaces_txid = + self.replaces_txid.map(|s| s.parse::().map_err(E::ReplacesTxid)).transpose()?; + let tx = encode::deserialize_hex::(&self.hex).map_err(E::Tx)?; + let details = self + .details + .into_iter() + .map(|d| d.into_model().map_err(E::Details)) + .collect::, _>>()?; + + Ok(model::GetTransaction { + amount, + fee, + confirmations: self.confirmations, + generated: self.generated, + trusted: self.trusted, + block_hash, + block_height, + block_index, + block_time: self.block_time, + txid, + wtxid: None, + wallet_conflicts, + replaced_by_txid, + replaces_txid, + mempool_conflicts: None, // v28 and later only. + to: self.to, + time: self.time, + time_received: self.time_received, + comment: self.comment, + bip125_replaceable: self.bip125_replaceable.into_model(), + parent_descriptors: None, // v24 and later only. + details, + decoded: self.decoded, + last_processed_block: None, // v26 and later only. + tx, + }) + } +} diff --git a/types/src/v23/wallet/mod.rs b/types/src/v23/wallet/mod.rs new file mode 100644 index 00000000..ea1fb1f0 --- /dev/null +++ b/types/src/v23/wallet/mod.rs @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v23` - wallet. +//! +//! Types for methods found under the `== Wallet ==` section of the API docs. + +mod error; +mod into; + +use bitcoin::Transaction; +use serde::{Deserialize, Serialize}; + +pub use self::error::GetTransactionError; +pub use super::{Bip125Replaceable, GetTransactionDetail, GetTransactionDetailError}; + +/// Result of the JSON-RPC method `gettransaction`. +/// +/// > gettransaction "txid" ( include_watchonly ) +/// > +/// > Get detailed information about in-wallet transaction `` +/// > +/// > Arguments: +/// > 1. txid (string, required) The transaction id +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTransaction { + /// The transaction amount in BTC. + pub amount: f64, + /// The amount of the fee in BTC. + /// + /// This is negative and only available for the 'send' category of transactions. + pub fee: Option, + /// The number of confirmations. + pub confirmations: i64, + /// Only present if the transaction's only input is a coinbase one. v20 and later only. + pub generated: Option, + /// Whether we consider the outputs of this unconfirmed transaction safe to spend. + pub trusted: Option, + /// The block hash. + #[serde(rename = "blockhash")] + pub block_hash: Option, + /// The block height containing the transaction. v20 and later only. + #[serde(rename = "blockheight")] + pub block_height: Option, + /// The index of the transaction in the block that includes it. + #[serde(rename = "blockindex")] + pub block_index: Option, + /// The time in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "blocktime")] + pub block_time: Option, + /// The transaction id. + pub txid: String, + /// Confirmed transactions that have been detected by the wallet to conflict with this transaction. + #[serde(rename = "walletconflicts")] + pub wallet_conflicts: Vec, + /// Only if 'category' is 'send'. The txid if this tx was replaced. v23 and later only. + pub replaced_by_txid: Option, + /// Only if 'category' is 'send'. The txid if this tx replaces another. v23 and later only. + pub replaces_txid: Option, + /// If a comment to is associated with the transaction. v23 and later only. + pub to: Option, + /// The transaction time in seconds since epoch (1 Jan 1970 GMT). + pub time: u32, + /// The time received in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "timereceived")] + pub time_received: u32, + /// If a comment is associated with the transaction, only present if not empty. v20 to v24 only. + pub comment: Option, + /// Whether this transaction could be replaced due to BIP125 (replace-by-fee); + /// may be unknown for unconfirmed transactions not in the mempool + #[serde(rename = "bip125-replaceable")] + pub bip125_replaceable: Bip125Replaceable, + /// Transaction details. + pub details: Vec, + /// Raw data for transaction. + pub hex: String, + /// The decoded transaction (only present when `verbose` is passed). v19 and later only. + pub decoded: Option, +} diff --git a/types/src/v24/mod.rs b/types/src/v24/mod.rs index fe4c9524..c9f3d0e6 100644 --- a/types/src/v24/mod.rs +++ b/types/src/v24/mod.rs @@ -243,6 +243,7 @@ mod blockchain; mod network; mod raw_transactions; +mod wallet; #[doc(inline)] pub use self::{ @@ -252,15 +253,18 @@ pub use self::{ DecodePsbt, DecodePsbtError, GlobalXpub, Proprietary, PsbtInput, PsbtOutput, TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, }, + wallet::{ + GetTransaction, GetTransactionDetail, GetTransactionError, ListUnspent, ListUnspentItem, + }, }; #[doc(inline)] pub use crate::{ v17::{ AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddedNode, AddedNodeAddress, - AddressInformation, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, - CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, CreatePsbt, - CreateRawTransaction, CreateWallet, DecodeRawTransaction, DecodeScript, DecodeScriptError, - DumpPrivKey, DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, + AddressInformation, Bip125Replaceable, BumpFee, BumpFeeError, ChainTips, ChainTipsError, + ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, + CreatePsbt, CreateRawTransaction, CreateWallet, DecodeRawTransaction, DumpPrivKey, + DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, @@ -271,10 +275,9 @@ pub use crate::{ GetMempoolInfoError, GetMiningInfo, GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, - GetRawTransactionVerboseError, GetReceivedByAddress, GetTransaction, GetTransactionDetail, - GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, GetTxOutSetInfo, - GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, - GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, + GetRawTransactionVerboseError, GetReceivedByAddress, GetTransactionDetailError, GetTxOut, + GetTxOutError, GetTxOutSetInfo, GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfo, + GetWalletInfoError, GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, @@ -290,18 +293,21 @@ pub use crate::{ v18::{ ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing, AnalyzePsbtInputMissingError, DeriveAddresses, GetNodeAddresses, GetReceivedByLabel, - JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListUnspent, ListUnspentItem, - ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, + JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListWalletDir, + ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetBlockchainInfoError, - GetChainTxStats, GetDescriptorInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, - GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, - MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, - Softfork, SoftforkType, + Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, + GetBalancesError, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, + GetBlockFilterError, GetBlockchainInfoError, GetChainTxStats, GetDescriptorInfo, + GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, + GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, MempoolEntry, + MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, Softfork, + SoftforkType, }, v21::{GetNetworkInfo, UnloadWallet}, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, - v23::{CreateMultisig, GetBlockchainInfo, SaveMempool}, + v22::{Banned, ListBanned, ScriptPubkey}, + v23::{ + CreateMultisig, DecodeScript, DecodeScriptError, GetBlockchainInfo, Logging, SaveMempool, + }, }; diff --git a/types/src/v24/wallet/error.rs b/types/src/v24/wallet/error.rs new file mode 100644 index 00000000..7eed452a --- /dev/null +++ b/types/src/v24/wallet/error.rs @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: CC0-1.0 + +use core::fmt; + +use bitcoin::amount::ParseAmountError; +use bitcoin::consensus::encode; +use bitcoin::hex; + +use super::GetTransactionDetailError; +use crate::error::write_err; +use crate::NumericError; + +/// Error when converting a `GetTransaction` type into the model type. +#[derive(Debug)] +pub enum GetTransactionError { + /// Conversion of numeric type to expected type failed. + Numeric(NumericError), + /// Conversion of the `amount` field failed. + Amount(ParseAmountError), + /// Conversion of the `fee` field failed. + Fee(ParseAmountError), + /// Conversion of the `block_hash` field failed. + BlockHash(hex::HexToArrayError), + /// Conversion of the `txid` field failed. + Txid(hex::HexToArrayError), + /// Conversion of the `wtxid` field failed. + Wtxid(hex::HexToArrayError), + /// Conversion of the `wallet_conflicts` field failed. + WalletConflicts(hex::HexToArrayError), + /// Conversion of the `replaced_by_txid` field failed. + ReplacedByTxid(hex::HexToArrayError), + /// Conversion of the `replaces_txid` field failed. + ReplacesTxid(hex::HexToArrayError), + /// Conversion of the `mempool_conflicts` field failed. + MempoolConflicts(hex::HexToArrayError), + /// Conversion of the transaction `hex` field failed. + Tx(encode::FromHexError), + /// Conversion of the `details` field failed. + Details(GetTransactionDetailError), +} + +impl fmt::Display for GetTransactionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use GetTransactionError as E; + + match *self { + E::Numeric(ref e) => write_err!(f, "numeric"; e), + E::Amount(ref e) => write_err!(f, "conversion of the `amount` field failed"; e), + E::Fee(ref e) => write_err!(f, "conversion of the `fee` field failed"; e), + E::BlockHash(ref e) => write_err!(f, "conversion of the `block_hash` field failed"; e), + E::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e), + E::Wtxid(ref e) => write_err!(f, "conversion of the `wtxid` field failed"; e), + E::WalletConflicts(ref e) => + write_err!(f, "conversion of the `wallet_conflicts` field failed"; e), + E::ReplacedByTxid(ref e) => + write_err!(f, "conversion of the `replaced_by_txid` field failed"; e), + E::ReplacesTxid(ref e) => + write_err!(f, "conversion of the `replaces_txid` field failed"; e), + E::MempoolConflicts(ref e) => + write_err!(f, "conversion of the `mempool_conflicts` field failed"; e), + E::Tx(ref e) => write_err!(f, "conversion of the `hex` field failed"; e), + E::Details(ref e) => write_err!(f, "conversion of the `details` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for GetTransactionError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use GetTransactionError as E; + + match *self { + E::Numeric(ref e) => Some(e), + E::Amount(ref e) => Some(e), + E::Fee(ref e) => Some(e), + E::BlockHash(ref e) => Some(e), + E::Txid(ref e) => Some(e), + E::Wtxid(ref e) => Some(e), + E::WalletConflicts(ref e) => Some(e), + E::ReplacedByTxid(ref e) => Some(e), + E::ReplacesTxid(ref e) => Some(e), + E::MempoolConflicts(ref e) => Some(e), + E::Tx(ref e) => Some(e), + E::Details(ref e) => Some(e), + } + } +} + +impl From for GetTransactionError { + fn from(e: NumericError) -> Self { Self::Numeric(e) } +} diff --git a/types/src/v24/wallet/into.rs b/types/src/v24/wallet/into.rs new file mode 100644 index 00000000..8d4f8fdd --- /dev/null +++ b/types/src/v24/wallet/into.rs @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::consensus::encode; +use bitcoin::{Address, BlockHash, ScriptBuf, SignedAmount, Transaction, Txid}; + +use super::{ + GetTransaction, GetTransactionDetail, GetTransactionDetailError, GetTransactionError, + ListUnspent, ListUnspentItem, ListUnspentItemError, +}; +use crate::model; + +impl GetTransaction { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTransactionError as E; + + let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; + let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; + let block_hash = + self.block_hash.map(|s| s.parse::().map_err(E::BlockHash)).transpose()?; + let block_index = + self.block_index.map(|idx| crate::to_u32(idx, "block_index")).transpose()?; + let block_height = + self.block_height.map(|h| crate::to_u32(h, "block_height")).transpose()?; + let txid = self.txid.parse::().map_err(E::Txid)?; + let wtxid = self.wtxid.map(|s| s.parse::().map_err(E::Wtxid)).transpose()?; + let wallet_conflicts = self + .wallet_conflicts + .into_iter() + .map(|s| s.parse::().map_err(E::WalletConflicts)) + .collect::, _>>()?; + let replaced_by_txid = self + .replaced_by_txid + .map(|s| s.parse::().map_err(E::ReplacedByTxid)) + .transpose()?; + let replaces_txid = + self.replaces_txid.map(|s| s.parse::().map_err(E::ReplacesTxid)).transpose()?; + let tx = encode::deserialize_hex::(&self.hex).map_err(E::Tx)?; + let details = self + .details + .into_iter() + .map(|d| d.into_model().map_err(E::Details)) + .collect::, _>>()?; + + Ok(model::GetTransaction { + amount, + fee, + confirmations: self.confirmations, + generated: self.generated, + trusted: self.trusted, + block_hash, + block_height, + block_index, + block_time: self.block_time, + txid, + wtxid, + wallet_conflicts, + replaced_by_txid, + replaces_txid, + mempool_conflicts: None, // v28 and later only. + to: self.to, + time: self.time, + time_received: self.time_received, + comment: self.comment, + bip125_replaceable: self.bip125_replaceable.into_model(), + parent_descriptors: self.parent_descriptors, + details, + decoded: self.decoded, + last_processed_block: None, // v26 and later only. + tx, + }) + } +} + +impl GetTransactionDetail { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTransactionDetailError as E; + + let address = self.address.parse::>().map_err(E::Address)?; + let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; + let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; + + Ok(model::GetTransactionDetail { + involves_watchonly: self.involves_watchonly, + account: self.account, + address, + category: self.category.into_model(), + amount, + label: self.label, + vout: self.vout, + fee, + abandoned: self.abandoned, + parent_descriptors: self.parent_descriptors, + }) + } +} + +impl ListUnspent { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + self.0 + .into_iter() + .map(|item| item.into_model()) + .collect::, _>>() + .map(model::ListUnspent) + } +} + +impl ListUnspentItem { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use ListUnspentItemError as E; + + let txid = self.txid.parse::().map_err(E::Txid)?; + let vout = crate::to_u32(self.vout, "vout")?; + let address = self.address.parse::>().map_err(E::Address)?; + let script_pubkey = ScriptBuf::from_hex(&self.script_pubkey).map_err(E::ScriptPubkey)?; + + let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; + let confirmations = crate::to_u32(self.confirmations, "confirmations")?; + let redeem_script = self + .redeem_script + .map(|hex| ScriptBuf::from_hex(&hex).map_err(E::RedeemScript)) + .transpose()?; + + Ok(model::ListUnspentItem { + txid, + vout, + address, + label: self.label, + script_pubkey, + amount, + confirmations, + redeem_script, + spendable: self.spendable, + solvable: self.solvable, + descriptor: self.descriptor, + safe: self.safe, + parent_descriptors: self.parent_descriptors, + }) + } +} diff --git a/types/src/v24/wallet/mod.rs b/types/src/v24/wallet/mod.rs new file mode 100644 index 00000000..7a7b82ac --- /dev/null +++ b/types/src/v24/wallet/mod.rs @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v24` - wallet. +//! +//! Types for methods found under the `== Wallet ==` section of the API docs. + +mod error; +mod into; + +use bitcoin::Transaction; +use serde::{Deserialize, Serialize}; + +pub use self::error::GetTransactionError; +pub use super::{ + Bip125Replaceable, GetTransactionDetailError, ListUnspentItemError, TransactionCategory, +}; + +/// Result of the JSON-RPC method `gettransaction`. +/// +/// > gettransaction "txid" ( include_watchonly ) +/// > +/// > Get detailed information about in-wallet transaction `` +/// > +/// > Arguments: +/// > 1. txid (string, required) The transaction id +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTransaction { + /// The transaction amount in BTC. + pub amount: f64, + /// The amount of the fee in BTC. + /// + /// This is negative and only available for the 'send' category of transactions. + pub fee: Option, + /// The number of confirmations. + pub confirmations: i64, + /// Only present if the transaction's only input is a coinbase one. v20 and later only. + pub generated: Option, + /// Whether we consider the outputs of this unconfirmed transaction safe to spend. + pub trusted: Option, + /// The block hash. + #[serde(rename = "blockhash")] + pub block_hash: Option, + /// The block height containing the transaction. v20 and later only. + #[serde(rename = "blockheight")] + pub block_height: Option, + /// The index of the transaction in the block that includes it. + #[serde(rename = "blockindex")] + pub block_index: Option, + /// The time in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "blocktime")] + pub block_time: Option, + /// The transaction id. + pub txid: String, + /// The hash of serialized transaction, including witness data. v24 and later only. + pub wtxid: Option, + /// Confirmed transactions that have been detected by the wallet to conflict with this transaction. + #[serde(rename = "walletconflicts")] + pub wallet_conflicts: Vec, + /// Only if 'category' is 'send'. The txid if this tx was replaced. v23 and later only. + pub replaced_by_txid: Option, + /// Only if 'category' is 'send'. The txid if this tx replaces another. v23 and later only. + pub replaces_txid: Option, + /// If a comment to is associated with the transaction. v23 and later only. + pub to: Option, + /// The transaction time in seconds since epoch (1 Jan 1970 GMT). + pub time: u32, + /// The time received in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "timereceived")] + pub time_received: u32, + /// If a comment is associated with the transaction, only present if not empty. v20 to v24 only. + pub comment: Option, + /// Whether this transaction could be replaced due to BIP125 (replace-by-fee); + /// may be unknown for unconfirmed transactions not in the mempool + #[serde(rename = "bip125-replaceable")] + pub bip125_replaceable: Bip125Replaceable, + /// Only if 'category' is 'received'. List of parent descriptors for the output script of this + /// coin. v24 and later only. + #[serde(rename = "parent_descs")] + pub parent_descriptors: Option>, + /// Transaction details. + pub details: Vec, + /// Raw data for transaction. + pub hex: String, + /// The decoded transaction (only present when `verbose` is passed). v19 and later only. + pub decoded: Option, +} + +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTransactionDetail { + /// Only returns true if imported addresses were involved in transaction. v20 and later only. + #[serde(rename = "involvesWatchonly")] + pub involves_watchonly: Option, + /// DEPRECATED. The account name involved in the transaction, can be "" for the default account. + pub account: Option, // Docs are wrong, this is not documented as optional. + /// The bitcoin address involved in the transaction. + pub address: String, + /// The category, either 'send' or 'receive'. + pub category: TransactionCategory, + /// The amount in BTC. + pub amount: f64, + /// A comment for the address/transaction, if any. + pub label: Option, + /// the vout value. + pub vout: u32, + /// The amount of the fee. + /// + /// This is negative and only available for the 'send' category of transactions. + pub fee: Option, + /// If the transaction has been abandoned (inputs are respendable). + /// + /// Only available for the 'send' category of transactions. + pub abandoned: Option, + /// Only if 'category' is 'received'. List of parent descriptors for the output script of this + /// coin. v24 and later only. + #[serde(rename = "parent_descs")] + pub parent_descriptors: Option>, +} + +/// Result of the JSON-RPC method `listunspent`. +/// +/// > listunspent ( minconf maxconf ["addresses",...] `[include_unsafe]` `[query_options]`) +/// > +/// > Returns array of unspent transaction outputs +/// > with between minconf and maxconf (inclusive) confirmations. +/// > Optionally filter to only include txouts paid to specified addresses. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct ListUnspent(pub Vec); + +/// Unspent transaction output, returned as part of `listunspent`. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct ListUnspentItem { + /// The transaction id. + pub txid: String, + /// The vout value. + pub vout: i64, + /// The bitcoin address of the transaction. + pub address: String, + /// The associated label, or "" for the default label. + pub label: String, + /// The script key. + #[serde(rename = "scriptPubKey")] + pub script_pubkey: String, + /// The transaction amount in BTC. + pub amount: f64, + /// The number of confirmations. + pub confirmations: i64, + /// The redeemScript if scriptPubKey is P2SH. + #[serde(rename = "redeemScript")] + pub redeem_script: Option, + /// Whether we have the private keys to spend this output. + pub spendable: bool, + /// Whether we know how to spend this output, ignoring the lack of keys. + pub solvable: bool, + /// A descriptor for spending this output (only when solvable) + #[serde(rename = "desc")] + pub descriptor: Option, + /// Whether this output is considered safe to spend. Unconfirmed transactions from outside keys + /// and unconfirmed replacement transactions are considered unsafe and are not eligible for + /// spending by fundrawtransaction and sendtoaddress. + pub safe: bool, + /// List of parent descriptors for the scriptPubKey of this coin. v24 and later only. + #[serde(rename = "parent_descs")] + pub parent_descriptors: Option>, +} diff --git a/types/src/v25/blockchain/into.rs b/types/src/v25/blockchain/into.rs new file mode 100644 index 00000000..b00e37c3 --- /dev/null +++ b/types/src/v25/blockchain/into.rs @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::{Amount, BlockHash, FeeRate, Weight}; + +use super::{GetBlockStats, GetBlockStatsError}; +use crate::model; + +impl GetBlockStats { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetBlockStatsError as E; + + // `FeeRate::sat_per_vb` returns an option if value overflows. + let average_fee_rate = FeeRate::from_sat_per_vb(self.average_fee_rate); + let block_hash = self.block_hash.parse::().map_err(E::BlockHash)?; + let fee_rate_percentiles = self + .fee_rate_percentiles + .iter() + .map(|vb| FeeRate::from_sat_per_vb(*vb)) + .collect::>>(); + let max_fee_rate = FeeRate::from_sat_per_vb(self.max_fee_rate); + let minimum_fee_rate = FeeRate::from_sat_per_vb(self.minimum_fee_rate); + + // FIXME: Double check that these values are virtual bytes and not weight units. + let segwit_total_weight = Weight::from_vb(self.segwit_total_weight); + let total_weight = Weight::from_vb(self.total_weight); + + Ok(model::GetBlockStats { + average_fee: Amount::from_sat(self.average_fee), + average_fee_rate, + average_tx_size: crate::to_u32(self.average_tx_size, "average_tx_size")?, + block_hash, + fee_rate_percentiles, + height: crate::to_u32(self.height, "height")?, + inputs: crate::to_u32(self.inputs, "inputs")?, + max_fee: Amount::from_sat(self.max_fee), + max_fee_rate, + max_tx_size: crate::to_u32(self.max_tx_size, "max_tx_size")?, + median_fee: Amount::from_sat(self.median_fee), + median_time: crate::to_u32(self.median_time, "median_time")?, + median_tx_size: crate::to_u32(self.median_tx_size, "median_tx_size")?, + minimum_fee: Amount::from_sat(self.minimum_fee), + minimum_fee_rate, + minimum_tx_size: crate::to_u32(self.minimum_tx_size, "minimum_tx_size")?, + outputs: crate::to_u32(self.outputs, "outputs")?, + subsidy: Amount::from_sat(self.subsidy), + segwit_total_size: crate::to_u32(self.segwit_total_size, "segwit_total_size")?, + segwit_total_weight, + segwit_txs: crate::to_u32(self.segwit_txs, "segwit_txs")?, + time: crate::to_u32(self.time, "time")?, + total_out: Amount::from_sat(self.total_out), + total_size: crate::to_u32(self.total_size, "total_size")?, + total_weight, + total_fee: Amount::from_sat(self.total_fee), + txs: crate::to_u32(self.txs, "txs")?, + utxo_increase: self.utxo_increase, + utxo_size_increase: self.utxo_size_increase, + utxo_increase_actual: self.utxo_increase_actual, + utxo_size_increase_actual: self.utxo_size_increase_actual, + }) + } +} diff --git a/types/src/v25/blockchain/mod.rs b/types/src/v25/blockchain/mod.rs new file mode 100644 index 00000000..ca1124fb --- /dev/null +++ b/types/src/v25/blockchain/mod.rs @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v25` - blockchain. +//! +//! Types for methods found under the `== Blockchain ==` section of the API docs. + +mod into; + +use serde::{Deserialize, Serialize}; + +pub use super::GetBlockStatsError; + +/// Result of JSON-RPC method `getblockstats`. +/// +/// > getblockstats hash_or_height ( stats ) +/// +/// > Returns the number of blocks in the longest blockchain. +/// > getblockstats hash_or_height ( stats ) +/// > +/// > Compute per block statistics for a given window. All amounts are in satoshis. +/// > It won't work for some heights with pruning. +/// > It won't work without -txindex for utxo_size_inc, *fee or *feerate stats. +/// > +/// > Arguments: +/// > 1. "hash_or_height" (string or numeric, required) The block hash or height of the target block +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetBlockStats { + /// Average fee in the block. + #[serde(rename = "avgfee")] + pub average_fee: u64, + // FIXME: Remember these docs will become silently stale when unit changes in a later version of Core. + /// Average feerate (in satoshis per virtual byte). + #[serde(rename = "avgfeerate")] + pub average_fee_rate: u64, + /// Average transaction size. + #[serde(rename = "avgtxsize")] + pub average_tx_size: i64, + /// The block hash (to check for potential reorgs). + #[serde(rename = "blockhash")] + pub block_hash: String, + /// Feerates at the 10th, 25th, 50th, 75th, and 90th percentile weight unit (in satoshis per + /// virtual byte). + #[serde(rename = "feerate_percentiles")] + pub fee_rate_percentiles: [u64; 5], + /// The height of the block. + pub height: i64, + /// The number of inputs (excluding coinbase). + #[serde(rename = "ins")] + pub inputs: i64, + /// Maximum fee in the block. + #[serde(rename = "maxfee")] + pub max_fee: u64, + /// Maximum feerate (in satoshis per virtual byte). + #[serde(rename = "maxfeerate")] + pub max_fee_rate: u64, + /// Maximum transaction size. + #[serde(rename = "maxtxsize")] + pub max_tx_size: i64, + /// Truncated median fee in the block. + #[serde(rename = "medianfee")] + pub median_fee: u64, + /// The block median time past. + #[serde(rename = "mediantime")] + pub median_time: i64, + /// Truncated median transaction size + #[serde(rename = "mediantxsize")] + pub median_tx_size: i64, + /// Minimum fee in the block. + #[serde(rename = "minfee")] + pub minimum_fee: u64, + /// Minimum feerate (in satoshis per virtual byte). + #[serde(rename = "minfeerate")] + pub minimum_fee_rate: u64, + /// Minimum transaction size. + #[serde(rename = "mintxsize")] + pub minimum_tx_size: i64, + /// The number of outputs. + #[serde(rename = "outs")] + pub outputs: i64, + /// The block subsidy. + pub subsidy: u64, + /// Total size of all segwit transactions. + #[serde(rename = "swtotal_size")] + pub segwit_total_size: i64, + /// Total weight of all segwit transactions divided by segwit scale factor (4). + #[serde(rename = "swtotal_weight")] + pub segwit_total_weight: u64, + /// The number of segwit transactions. + #[serde(rename = "swtxs")] + pub segwit_txs: i64, + /// The block time. + pub time: i64, + /// Total amount in all outputs (excluding coinbase and thus reward [ie subsidy + totalfee]). + pub total_out: u64, + /// Total size of all non-coinbase transactions. + pub total_size: i64, + /// Total weight of all non-coinbase transactions divided by segwit scale factor (4). + pub total_weight: u64, + /// The fee total. + #[serde(rename = "totalfee")] + pub total_fee: u64, + /// The number of transactions (excluding coinbase). + pub txs: i64, + /// The increase/decrease in the number of unspent outputs. + pub utxo_increase: i32, + /// The increase/decrease in size for the utxo index (not discounting op_return and similar). + #[serde(rename = "utxo_size_inc")] + pub utxo_size_increase: i32, + /// The increase/decrease in the number of unspent outputs, not counting unspendables. + /// v25 and later only. + pub utxo_increase_actual: Option, + /// The increase/decrease in size for the utxo index, not counting unspendables. + /// v25 and later only. + #[serde(rename = "utxo_size_inc_actual")] + pub utxo_size_increase_actual: Option, +} diff --git a/types/src/v25/control.rs b/types/src/v25/control.rs new file mode 100644 index 00000000..4668cfc4 --- /dev/null +++ b/types/src/v25/control.rs @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v25` - control. +//! +//! Types for methods found under the `== Control ==` section of the API docs. + +use serde::{Deserialize, Serialize}; + +/// Result of JSON-RPC method `logging`. +/// +/// > logging ( `` `` ) +/// +/// > Gets and sets the logging configuration. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct Logging { + pub addrman: bool, + pub bench: bool, + pub blockstorage: bool, // v23 and later only + pub cmpctblock: bool, + pub coindb: bool, + pub estimatefee: bool, + pub http: bool, + pub i2p: bool, // v23 and later only + pub ipc: bool, // v23 and later only + pub leveldb: bool, + pub libevent: bool, + pub mempool: bool, + pub mempoolrej: bool, + pub net: bool, + pub prune: bool, + pub proxy: bool, + pub qt: bool, + pub rand: bool, + pub reindex: bool, + pub rpc: bool, + pub scan: bool, // v25 and later only + pub selectcoins: bool, + pub tor: bool, + pub txreconciliation: bool, // v25 and later only + pub util: bool, // v23 to v27 only + pub validation: bool, // v23 and later only + pub walletdb: bool, // v23 and later only + pub zmq: bool, +} diff --git a/types/src/v25/mod.rs b/types/src/v25/mod.rs index b322fc45..af35157b 100644 --- a/types/src/v25/mod.rs +++ b/types/src/v25/mod.rs @@ -240,32 +240,37 @@ //! //! +mod blockchain; +mod control; mod wallet; #[doc(inline)] -pub use self::wallet::{CreateWallet, LoadWallet, UnloadWallet}; +pub use self::{ + blockchain::GetBlockStats, + control::Logging, + wallet::{CreateWallet, LoadWallet, UnloadWallet}, +}; #[doc(inline)] pub use crate::{ v17::{ AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddedNode, AddedNodeAddress, AddressInformation, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, CreatePsbt, - CreateRawTransaction, DecodeRawTransaction, DecodeScript, DecodeScriptError, DumpPrivKey, - DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, - FundRawTransaction, FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, - GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, + CreateRawTransaction, DecodeRawTransaction, DumpPrivKey, DumpWallet, EncryptWallet, + EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, + FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, + GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderError, GetBlockHeaderVerbose, - GetBlockHeaderVerboseError, GetBlockStats, GetBlockStatsError, GetBlockTemplate, - GetBlockTemplateError, GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, - GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, + GetBlockHeaderVerboseError, GetBlockStatsError, GetBlockTemplate, GetBlockTemplateError, + GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, GetChainTips, + GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, GetMempoolInfoError, GetMiningInfo, GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, - GetRawTransactionVerboseError, GetReceivedByAddress, GetTransaction, GetTransactionDetail, - GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, GetTxOutSetInfo, - GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, - GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, + GetRawTransactionVerboseError, GetReceivedByAddress, GetTransactionDetailError, GetTxOut, + GetTxOutError, GetTxOutSetInfo, GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfo, + GetWalletInfoError, GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, @@ -281,22 +286,24 @@ pub use crate::{ v18::{ ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing, AnalyzePsbtInputMissingError, DeriveAddresses, GetNodeAddresses, GetReceivedByLabel, - JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListUnspent, ListUnspentItem, - ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, + JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListWalletDir, + ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetBlockchainInfoError, - GetChainTxStats, GetDescriptorInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, - GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, - MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, - Softfork, SoftforkType, + Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, + GetBalancesError, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, + GetBlockFilterError, GetBlockchainInfoError, GetChainTxStats, GetDescriptorInfo, + GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, + GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, MempoolEntry, + MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, Softfork, + SoftforkType, }, v21::GetNetworkInfo, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, - v23::{CreateMultisig, GetBlockchainInfo, SaveMempool}, + v22::{Banned, ListBanned, ScriptPubkey}, + v23::{CreateMultisig, DecodeScript, DecodeScriptError, GetBlockchainInfo, SaveMempool}, v24::{ - DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GetPeerInfo, GlobalXpub, + DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GetPeerInfo, GetTransaction, + GetTransactionDetail, GetTransactionError, GlobalXpub, ListUnspent, ListUnspentItem, Proprietary, PsbtInput, PsbtOutput, TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, }, diff --git a/types/src/v26/blockchain.rs b/types/src/v26/blockchain.rs index 485891a0..7b586f1a 100644 --- a/types/src/v26/blockchain.rs +++ b/types/src/v26/blockchain.rs @@ -37,6 +37,9 @@ pub struct GetTxOutSetInfo { pub disk_size: i64, /// The total amount. pub total_amount: f64, + /// The serialized hash (only present if 'hash_serialized_3' hash_type is chosen). + /// v26 and later only. + pub hash_serialized_3: Option, } impl GetTxOutSetInfo { @@ -49,7 +52,6 @@ impl GetTxOutSetInfo { let transactions = crate::to_u32(self.transactions, "transactions")?; let tx_outs = crate::to_u32(self.tx_outs, "tx_outs")?; let bogo_size = crate::to_u32(self.bogo_size, "bogo_size")?; - let hash_serialized_2 = None; // Removed in Core v26 let disk_size = crate::to_u32(self.disk_size, "disk_size")?; let total_amount = Amount::from_btc(self.total_amount).map_err(E::TotalAmount)?; @@ -59,7 +61,8 @@ impl GetTxOutSetInfo { transactions, tx_outs, bogo_size, - hash_serialized_2, + hash_serialized_2: None, // v17 to v25 only. + hash_serialized_3: self.hash_serialized_3, disk_size, total_amount, }) diff --git a/types/src/v26/control.rs b/types/src/v26/control.rs new file mode 100644 index 00000000..7925c898 --- /dev/null +++ b/types/src/v26/control.rs @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v26` - control. +//! +//! Types for methods found under the `== Control ==` section of the API docs. + +use serde::{Deserialize, Serialize}; + +/// Result of JSON-RPC method `logging`. +/// +/// > logging ( `` `` ) +/// +/// > Gets and sets the logging configuration. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct Logging { + pub addrman: bool, + pub bench: bool, + pub blockstorage: bool, // v23 and later only + pub cmpctblock: bool, + pub coindb: bool, + pub estimatefee: bool, + pub http: bool, + pub i2p: bool, // v23 and later only + pub ipc: bool, // v23 and later only + pub leveldb: bool, + pub libevent: bool, + pub mempool: bool, + pub mempoolrej: bool, + pub net: bool, + pub prune: bool, + pub proxy: bool, + pub qt: bool, + pub rand: bool, + pub reindex: bool, + pub rpc: bool, + pub scan: bool, // v25 and later only + pub selectcoins: bool, + pub tor: bool, + pub txpackages: bool, // v26 and later only + pub txreconciliation: bool, // v25 and later only + pub util: bool, // v23 to v27 only + pub validation: bool, // v23 and later only + pub walletdb: bool, // v23 and later only + pub zmq: bool, +} diff --git a/types/src/v26/mod.rs b/types/src/v26/mod.rs index 802dff24..87797764 100644 --- a/types/src/v26/mod.rs +++ b/types/src/v26/mod.rs @@ -249,6 +249,7 @@ //! mod blockchain; +mod control; mod mining; mod network; mod raw_transactions; @@ -257,6 +258,7 @@ mod wallet; #[doc(inline)] pub use self::{ blockchain::{GetTxOutSetInfo, GetTxOutSetInfoError}, + control::Logging, mining::{GetPrioritisedTransactions, PrioritisedTransaction}, network::GetPeerInfo, raw_transactions::{ @@ -264,49 +266,52 @@ pub use self::{ SubmitPackageTxResult, SubmitPackageTxResultError, SubmitPackageTxResultFees, SubmitPackageTxResultFeesError, }, - wallet::{CreateWallet, LoadWallet, UnloadWallet}, + wallet::{ + CreateWallet, GetBalances, GetBalancesError, GetTransaction, GetTransactionError, + LastProcessedBlock, LastProcessedBlockError, LoadWallet, UnloadWallet, + }, }; #[doc(inline)] pub use crate::{ v17::{ AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddedNode, AddedNodeAddress, - AddressInformation, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, - CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, CreatePsbt, - CreateRawTransaction, DecodeRawTransaction, DecodeScript, DecodeScriptError, DumpPrivKey, - DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, - FundRawTransaction, FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, - GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, + AddressInformation, Bip125Replaceable, BumpFee, BumpFeeError, ChainTips, ChainTipsError, + ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, + CreatePsbt, CreateRawTransaction, DecodeRawTransaction, DumpPrivKey, DumpWallet, + EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, + FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, + GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderError, GetBlockHeaderVerbose, - GetBlockHeaderVerboseError, GetBlockStats, GetBlockStatsError, GetBlockTemplate, - GetBlockTemplateError, GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, - GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, + GetBlockHeaderVerboseError, GetBlockStatsError, GetBlockTemplate, GetBlockTemplateError, + GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, GetChainTips, + GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, GetMempoolInfoError, GetMiningInfo, GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, - GetRawTransactionVerboseError, GetReceivedByAddress, GetTransaction, GetTransactionDetail, - GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, - GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, GetZmqNotifications, - ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, - ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, - ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, - ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, - ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, - PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, - RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, - SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, - SoftforkReject, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, - ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, - WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo, + GetRawTransactionVerboseError, GetReceivedByAddress, GetTransactionDetailError, GetTxOut, + GetTxOutError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, + GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, + ListAddressGroupingsItem, ListLabels, ListLockUnspent, ListLockUnspentItem, + ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, + ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, + ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, + ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, PruneBlockchain, + RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, + SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, + SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, + TransactionCategory, UploadTarget, ValidateAddress, ValidateAddressError, VerifyChain, + VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, + WalletProcessPsbt, WitnessUtxo, }, v18::{ ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing, AnalyzePsbtInputMissingError, DeriveAddresses, GetNodeAddresses, GetReceivedByLabel, - JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListUnspent, ListUnspentItem, - ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, + JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListWalletDir, + ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, + Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetBlockchainInfoError, GetChainTxStats, GetDescriptorInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, @@ -314,10 +319,12 @@ pub use crate::{ Softfork, SoftforkType, }, v21::GetNetworkInfo, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, - v23::{CreateMultisig, GetBlockchainInfo, SaveMempool}, + v22::{Banned, ListBanned, ScriptPubkey}, + v23::{CreateMultisig, DecodeScript, DecodeScriptError, GetBlockchainInfo, SaveMempool}, v24::{ - DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GlobalXpub, Proprietary, - PsbtInput, PsbtOutput, TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, + DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GetTransactionDetail, + GlobalXpub, ListUnspent, ListUnspentItem, Proprietary, PsbtInput, PsbtOutput, + TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, }, + v25::GetBlockStats, }; diff --git a/types/src/v26/wallet.rs b/types/src/v26/wallet.rs deleted file mode 100644 index c4d58f81..00000000 --- a/types/src/v26/wallet.rs +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -//! The JSON-RPC API for Bitcoin Core `v26` - wallet. -//! -//! Types for methods found under the `== Wallet ==` section of the API docs. - -use serde::{Deserialize, Serialize}; - -use crate::model; - -/// Result of the JSON-RPC method `createwallet`. -/// -/// > createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse descriptors load_on_startup external_signer ) -/// -/// > Creates and loads a new wallet. -/// -/// > Arguments: -/// > 1. wallet_name (string, required) The name for the new wallet. If this is a path, the wallet will be created at the path location. -/// > 2. disable_private_keys (boolean, optional, default=false) Disable the possibility of private keys (only watchonlys are possible in this mode). -/// > 3. blank (boolean, optional, default=false) Create a blank wallet. A blank wallet has no keys or HD seed. One can be set using sethdseed. -/// > 4. passphrase (string, optional) Encrypt the wallet with this passphrase. -/// > 5. avoid_reuse (boolean, optional, default=false) Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind. -/// > 6. descriptors (boolean, optional, default=true) Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation. Setting to "false" will create a legacy wallet; however, the legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future. -/// > 7. load_on_startup (boolean, optional) Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged. -/// > 8. external_signer (boolean, optional, default=false) Use an external signer such as a hardware wallet. Requires -signer to be configured. Wallet creation will fail if keys cannot be fetched. Requires disable_private_keys and descriptors set to true. -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct CreateWallet { - /// The wallet name if created successfully. - /// - /// If the wallet was created using a full path, the wallet_name will be the full path. - pub name: String, - /// Warning messages, if any, related to creating and loading the wallet. - pub warnings: Option>, -} - -impl CreateWallet { - /// Converts version specific type to a version nonspecific, more strongly typed type. - pub fn into_model(self) -> model::CreateWallet { - model::CreateWallet { name: self.name, warnings: self.warnings.unwrap_or_default() } - } - - /// Returns the created wallet name. - pub fn name(self) -> String { self.into_model().name } -} - -/// Result of the JSON-RPC method `loadwallet`. -/// -/// > loadwallet "filename" ( load_on_startup ) -/// -/// > Loads a wallet from a wallet file or directory. -/// > Note that all wallet command-line options used when starting bitcoind will be -/// > applied to the new wallet. -/// -/// > Arguments: -/// > 1. filename (string, required) The wallet directory or .dat file. -/// > 2. load_on_startup (boolean, optional) Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged. -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct LoadWallet { - /// The wallet name if loaded successfully. - pub name: String, - /// Warning messages, if any, related to loading the wallet. - pub warnings: Option>, -} - -impl LoadWallet { - /// Converts version specific type to a version nonspecific, more strongly typed type. - pub fn into_model(self) -> model::LoadWallet { - model::LoadWallet { name: self.name, warnings: self.warnings.unwrap_or_default() } - } - - /// Returns the loaded wallet name. - pub fn name(self) -> String { self.into_model().name } -} - -/// Result of the JSON-RPC method `unloadwallet`. -/// -/// > unloadwallet ( "wallet_name" load_on_startup ) -/// > -/// > Unloads the wallet referenced by the request endpoint, otherwise unloads the wallet specified in the argument. -/// > Specifying the wallet name on a wallet endpoint is invalid. -/// > -/// > Arguments: -/// > 1. wallet_name (string, optional, default=the wallet name from the RPC endpoint) The name of the wallet to unload. If provided both here and in the RPC endpoint, the two must be identical. -/// > 2. load_on_startup (boolean, optional) Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged. -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct UnloadWallet { - /// Warning messages, if any, related to loading the wallet. - pub warnings: Option>, -} - -impl UnloadWallet { - /// Converts version specific type to a version nonspecific, more strongly typed type. - pub fn into_model(self) -> model::UnloadWallet { - model::UnloadWallet { warnings: self.warnings.unwrap_or_default() } - } -} diff --git a/types/src/v26/wallet/error.rs b/types/src/v26/wallet/error.rs new file mode 100644 index 00000000..d5dc0a63 --- /dev/null +++ b/types/src/v26/wallet/error.rs @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: CC0-1.0 + +use core::fmt; + +use bitcoin::amount::ParseAmountError; +use bitcoin::consensus::encode; +use bitcoin::hex; + +use super::GetTransactionDetailError; +use crate::error::write_err; +use crate::NumericError; + +/// Error when converting a `GetBalances` type into the model type. +#[derive(Debug)] +pub enum GetBalancesError { + /// Conversion of the `mine` field failed. + Mine(ParseAmountError), + /// Conversion of the `watchonly` field failed. + WatchOnly(ParseAmountError), + /// Conversion of the `last_processed_block` field failed. + LastProcessedBlock(LastProcessedBlockError), +} + +impl fmt::Display for GetBalancesError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use GetBalancesError as E; + + match *self { + E::Mine(ref e) => write_err!(f, "conversion of the `mine` field failed"; e), + E::WatchOnly(ref e) => write_err!(f, "conversion of the `watchonly` field failed"; e), + E::LastProcessedBlock(ref e) => + write_err!(f, "conversion of the `last_processed_block` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for GetBalancesError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use GetBalancesError as E; + + match *self { + E::Mine(ref e) => Some(e), + E::WatchOnly(ref e) => Some(e), + E::LastProcessedBlock(ref e) => Some(e), + } + } +} + +/// Error when converting a `GetTransaction` type into the model type. +#[derive(Debug)] +pub enum GetTransactionError { + /// Conversion of numeric type to expected type failed. + Numeric(NumericError), + /// Conversion of the `amount` field failed. + Amount(ParseAmountError), + /// Conversion of the `fee` field failed. + Fee(ParseAmountError), + /// Conversion of the `block_hash` field failed. + BlockHash(hex::HexToArrayError), + /// Conversion of the `txid` field failed. + Txid(hex::HexToArrayError), + /// Conversion of the `wtxid` field failed. + Wtxid(hex::HexToArrayError), + /// Conversion of the `wallet_conflicts` field failed. + WalletConflicts(hex::HexToArrayError), + /// Conversion of the `replaced_by_txid` field failed. + ReplacedByTxid(hex::HexToArrayError), + /// Conversion of the `replaces_txid` field failed. + ReplacesTxid(hex::HexToArrayError), + /// Conversion of the `mempool_conflicts` field failed. + MempoolConflicts(hex::HexToArrayError), + /// Conversion of the transaction `hex` field failed. + Tx(encode::FromHexError), + /// Conversion of the `details` field failed. + Details(GetTransactionDetailError), + /// Conversion of the `last_processed_block` field failed. + LastProcessedBlock(LastProcessedBlockError), +} + +impl fmt::Display for GetTransactionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use GetTransactionError as E; + + match *self { + E::Numeric(ref e) => write_err!(f, "numeric"; e), + E::Amount(ref e) => write_err!(f, "conversion of the `amount` field failed"; e), + E::Fee(ref e) => write_err!(f, "conversion of the `fee` field failed"; e), + E::BlockHash(ref e) => write_err!(f, "conversion of the `block_hash` field failed"; e), + E::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e), + E::Wtxid(ref e) => write_err!(f, "conversion of the `wtxid` field failed"; e), + E::WalletConflicts(ref e) => + write_err!(f, "conversion of the `wallet_conflicts` field failed"; e), + E::ReplacedByTxid(ref e) => + write_err!(f, "conversion of the `replaced_by_txid` field failed"; e), + E::ReplacesTxid(ref e) => + write_err!(f, "conversion of the `replaces_txid` field failed"; e), + E::MempoolConflicts(ref e) => + write_err!(f, "conversion of the `mempool_conflicts` field failed"; e), + E::Tx(ref e) => write_err!(f, "conversion of the `hex` field failed"; e), + E::Details(ref e) => write_err!(f, "conversion of the `details` field failed"; e), + E::LastProcessedBlock(ref e) => + write_err!(f, "conversion of the `last_processed_block` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for GetTransactionError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use GetTransactionError as E; + + match *self { + E::Numeric(ref e) => Some(e), + E::Amount(ref e) => Some(e), + E::Fee(ref e) => Some(e), + E::BlockHash(ref e) => Some(e), + E::Txid(ref e) => Some(e), + E::Wtxid(ref e) => Some(e), + E::WalletConflicts(ref e) => Some(e), + E::ReplacedByTxid(ref e) => Some(e), + E::ReplacesTxid(ref e) => Some(e), + E::MempoolConflicts(ref e) => Some(e), + E::Tx(ref e) => Some(e), + E::Details(ref e) => Some(e), + E::LastProcessedBlock(ref e) => Some(e), + } + } +} + +impl From for GetTransactionError { + fn from(e: NumericError) -> Self { Self::Numeric(e) } +} + +/// Error when converting a `LastProcessedBlock` type into the model type. +#[derive(Debug)] +pub enum LastProcessedBlockError { + /// Conversion of the `hash` field failed. + Hash(hex::HexToArrayError), + /// Conversion of the `height` field failed. + Height(NumericError), +} + +impl fmt::Display for LastProcessedBlockError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use LastProcessedBlockError::*; + + match *self { + Hash(ref e) => write_err!(f, "conversion of the `hash` field failed"; e), + Height(ref e) => write_err!(f, "conversion of the `height` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for LastProcessedBlockError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use LastProcessedBlockError::*; + + match *self { + Hash(ref e) => Some(e), + Height(ref e) => Some(e), + } + } +} + +impl From for LastProcessedBlockError { + fn from(e: NumericError) -> Self { Self::Height(e) } +} diff --git a/types/src/v26/wallet/into.rs b/types/src/v26/wallet/into.rs new file mode 100644 index 00000000..f9a37fc4 --- /dev/null +++ b/types/src/v26/wallet/into.rs @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::consensus::encode; +use bitcoin::{BlockHash, SignedAmount, Transaction, Txid}; + +use super::{ + CreateWallet, GetBalances, GetBalancesError, GetTransaction, GetTransactionError, + LastProcessedBlock, LastProcessedBlockError, LoadWallet, UnloadWallet, +}; +use crate::model; + +impl CreateWallet { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> model::CreateWallet { + model::CreateWallet { name: self.name, warnings: self.warnings.unwrap_or_default() } + } + + /// Returns the created wallet name. + pub fn name(self) -> String { self.into_model().name } +} + +impl GetBalances { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetBalancesError as E; + + let mine = self.mine.into_model().map_err(E::Mine)?; + let watch_only = self + .watch_only + .map(|watch_only| watch_only.into_model()) + .transpose() + .map_err(E::WatchOnly)?; + let last_processed_block = self + .last_processed_block + .map(|l| l.into_model()) + .transpose() + .map_err(E::LastProcessedBlock)?; + + Ok(model::GetBalances { mine, watch_only, last_processed_block }) + } +} + +impl GetTransaction { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTransactionError as E; + + let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; + let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; + let block_hash = + self.block_hash.map(|s| s.parse::().map_err(E::BlockHash)).transpose()?; + let block_index = + self.block_index.map(|idx| crate::to_u32(idx, "block_index")).transpose()?; + let block_height = + self.block_height.map(|h| crate::to_u32(h, "block_height")).transpose()?; + let txid = self.txid.parse::().map_err(E::Txid)?; + let wtxid = self.wtxid.map(|s| s.parse::().map_err(E::Wtxid)).transpose()?; + let wallet_conflicts = self + .wallet_conflicts + .into_iter() + .map(|s| s.parse::().map_err(E::WalletConflicts)) + .collect::, _>>()?; + let replaced_by_txid = self + .replaced_by_txid + .map(|s| s.parse::().map_err(E::ReplacedByTxid)) + .transpose()?; + let replaces_txid = + self.replaces_txid.map(|s| s.parse::().map_err(E::ReplacesTxid)).transpose()?; + let tx = encode::deserialize_hex::(&self.hex).map_err(E::Tx)?; + let details = self + .details + .into_iter() + .map(|d| d.into_model().map_err(E::Details)) + .collect::, _>>()?; + let last_processed_block = self + .last_processed_block + .map(|l| l.into_model()) + .transpose() + .map_err(E::LastProcessedBlock)?; + + Ok(model::GetTransaction { + amount, + fee, + confirmations: self.confirmations, + generated: self.generated, + trusted: self.trusted, + block_hash, + block_height, + block_index, + block_time: self.block_time, + txid, + wtxid, + wallet_conflicts, + replaced_by_txid, + replaces_txid, + mempool_conflicts: None, // v28 and later only. + to: self.to, + time: self.time, + time_received: self.time_received, + comment: self.comment, + bip125_replaceable: self.bip125_replaceable.into_model(), + parent_descriptors: self.parent_descriptors, + details, + decoded: self.decoded, + last_processed_block, + tx, + }) + } +} + +impl LastProcessedBlock { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + let hash = self.hash.parse::().map_err(LastProcessedBlockError::Hash)?; + let height = crate::to_u32(self.height, "height")?; + Ok(model::LastProcessedBlock { height, hash }) + } +} + +impl LoadWallet { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> model::LoadWallet { + model::LoadWallet { name: self.name, warnings: self.warnings.unwrap_or_default() } + } + + /// Returns the loaded wallet name. + pub fn name(self) -> String { self.into_model().name } +} + +impl UnloadWallet { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> model::UnloadWallet { + model::UnloadWallet { warnings: self.warnings.unwrap_or_default() } + } +} diff --git a/types/src/v26/wallet/mod.rs b/types/src/v26/wallet/mod.rs new file mode 100644 index 00000000..2e6f73c2 --- /dev/null +++ b/types/src/v26/wallet/mod.rs @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v26` - wallet. +//! +//! Types for methods found under the `== Wallet ==` section of the API docs. + +mod error; +mod into; + +use bitcoin::Transaction; +use serde::{Deserialize, Serialize}; + +pub use self::error::{GetBalancesError, GetTransactionError, LastProcessedBlockError}; +pub use super::{ + Bip125Replaceable, GetBalancesMine, GetBalancesWatchOnly, GetTransactionDetail, + GetTransactionDetailError, +}; + +/// Result of the JSON-RPC method `createwallet`. +/// +/// > createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse descriptors load_on_startup external_signer ) +/// +/// > Creates and loads a new wallet. +/// +/// > Arguments: +/// > 1. wallet_name (string, required) The name for the new wallet. If this is a path, the wallet will be created at the path location. +/// > 2. disable_private_keys (boolean, optional, default=false) Disable the possibility of private keys (only watchonlys are possible in this mode). +/// > 3. blank (boolean, optional, default=false) Create a blank wallet. A blank wallet has no keys or HD seed. One can be set using sethdseed. +/// > 4. passphrase (string, optional) Encrypt the wallet with this passphrase. +/// > 5. avoid_reuse (boolean, optional, default=false) Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind. +/// > 6. descriptors (boolean, optional, default=true) Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation. Setting to "false" will create a legacy wallet; however, the legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future. +/// > 7. load_on_startup (boolean, optional) Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged. +/// > 8. external_signer (boolean, optional, default=false) Use an external signer such as a hardware wallet. Requires -signer to be configured. Wallet creation will fail if keys cannot be fetched. Requires disable_private_keys and descriptors set to true. +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct CreateWallet { + /// The wallet name if created successfully. + /// + /// If the wallet was created using a full path, the wallet_name will be the full path. + pub name: String, + /// Warning messages, if any, related to creating and loading the wallet. + pub warnings: Option>, +} + +/// Result of the JSON-RPC method `getbalances`. +/// +/// > getbalances +/// > +/// > Returns an object with all balances in BTC. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetBalances { + /// Balances from outputs that the wallet can sign. + pub mine: GetBalancesMine, + #[serde(rename = "watchonly")] + pub watch_only: Option, + /// Hash and height of the block this information was generated on. v26 and later only. + #[serde(rename = "lastprocessedblock")] + pub last_processed_block: Option, +} + +/// Result of the JSON-RPC method `gettransaction`. +/// +/// > gettransaction "txid" ( include_watchonly ) +/// > +/// > Get detailed information about in-wallet transaction `` +/// > +/// > Arguments: +/// > 1. txid (string, required) The transaction id +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTransaction { + /// The transaction amount in BTC. + pub amount: f64, + /// The amount of the fee in BTC. + /// + /// This is negative and only available for the 'send' category of transactions. + pub fee: Option, + /// The number of confirmations. + pub confirmations: i64, + /// Only present if the transaction's only input is a coinbase one. v20 and later only. + pub generated: Option, + /// Whether we consider the outputs of this unconfirmed transaction safe to spend. + pub trusted: Option, + /// The block hash. + #[serde(rename = "blockhash")] + pub block_hash: Option, + /// The block height containing the transaction. v20 and later only. + #[serde(rename = "blockheight")] + pub block_height: Option, + /// The index of the transaction in the block that includes it. + #[serde(rename = "blockindex")] + pub block_index: Option, + /// The time in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "blocktime")] + pub block_time: Option, + /// The transaction id. + pub txid: String, + /// The hash of serialized transaction, including witness data. v24 and later only. + pub wtxid: Option, + /// Confirmed transactions that have been detected by the wallet to conflict with this transaction. + #[serde(rename = "walletconflicts")] + pub wallet_conflicts: Vec, + /// Only if 'category' is 'send'. The txid if this tx was replaced. v23 and later only. + pub replaced_by_txid: Option, + /// Only if 'category' is 'send'. The txid if this tx replaces another. v23 and later only. + pub replaces_txid: Option, + /// If a comment to is associated with the transaction. v23 and later only. + pub to: Option, + /// The transaction time in seconds since epoch (1 Jan 1970 GMT). + pub time: u32, + /// The time received in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "timereceived")] + pub time_received: u32, + /// If a comment is associated with the transaction, only present if not empty. v20 to v24 only. + pub comment: Option, + /// Whether this transaction could be replaced due to BIP125 (replace-by-fee); + /// may be unknown for unconfirmed transactions not in the mempool + #[serde(rename = "bip125-replaceable")] + pub bip125_replaceable: Bip125Replaceable, + /// Only if 'category' is 'received'. List of parent descriptors for the output script of this + /// coin. v24 and later only. + #[serde(rename = "parent_descs")] + pub parent_descriptors: Option>, + /// Transaction details. + pub details: Vec, + /// Raw data for transaction. + pub hex: String, + /// The decoded transaction (only present when `verbose` is passed). v19 and later only. + pub decoded: Option, + /// Hash and height of the block this information was generated on. v26 and later only. + #[serde(rename = "lastprocessedblock")] + pub last_processed_block: Option, +} + +/// Item returned as part of of `gettransaction`. v26 and later only. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct LastProcessedBlock { + /// Hash of the block this information was generated on. + pub hash: String, + /// Height of the block this information was generated on. + pub height: i64, +} + +/// Result of the JSON-RPC method `loadwallet`. +/// +/// > loadwallet "filename" ( load_on_startup ) +/// +/// > Loads a wallet from a wallet file or directory. +/// > Note that all wallet command-line options used when starting bitcoind will be +/// > applied to the new wallet. +/// +/// > Arguments: +/// > 1. filename (string, required) The wallet directory or .dat file. +/// > 2. load_on_startup (boolean, optional) Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged. +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct LoadWallet { + /// The wallet name if loaded successfully. + pub name: String, + /// Warning messages, if any, related to loading the wallet. + pub warnings: Option>, +} + +/// Result of the JSON-RPC method `unloadwallet`. +/// +/// > unloadwallet ( "wallet_name" load_on_startup ) +/// > +/// > Unloads the wallet referenced by the request endpoint, otherwise unloads the wallet specified in the argument. +/// > Specifying the wallet name on a wallet endpoint is invalid. +/// > +/// > Arguments: +/// > 1. wallet_name (string, optional, default=the wallet name from the RPC endpoint) The name of the wallet to unload. If provided both here and in the RPC endpoint, the two must be identical. +/// > 2. load_on_startup (boolean, optional) Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged. +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct UnloadWallet { + /// Warning messages, if any, related to loading the wallet. + pub warnings: Option>, +} diff --git a/types/src/v27/mod.rs b/types/src/v27/mod.rs index 6dcf5cb1..6cceca81 100644 --- a/types/src/v27/mod.rs +++ b/types/src/v27/mod.rs @@ -254,41 +254,41 @@ pub use crate::{ AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddedNode, AddedNodeAddress, AddressInformation, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, CreatePsbt, - CreateRawTransaction, DecodeRawTransaction, DecodeScript, DecodeScriptError, DumpPrivKey, - DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, - FundRawTransaction, FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, - GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, + CreateRawTransaction, DecodeRawTransaction, DumpPrivKey, DumpWallet, EncryptWallet, + EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, + FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, + GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderError, GetBlockHeaderVerbose, - GetBlockHeaderVerboseError, GetBlockStats, GetBlockStatsError, GetBlockTemplate, - GetBlockTemplateError, GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, - GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, + GetBlockHeaderVerboseError, GetBlockStatsError, GetBlockTemplate, GetBlockTemplateError, + GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, GetChainTips, + GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, GetMempoolInfoError, GetMiningInfo, GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, - GetRawTransactionVerboseError, GetReceivedByAddress, GetTransaction, GetTransactionDetail, - GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, - GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, GetZmqNotifications, - ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, - ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, - ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, - ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, - ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, - PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, - RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, - SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, - SoftforkReject, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, - ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, - WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo, + GetRawTransactionVerboseError, GetReceivedByAddress, GetTransactionDetailError, GetTxOut, + GetTxOutError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, + GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, + ListAddressGroupingsItem, ListLabels, ListLockUnspent, ListLockUnspentItem, + ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, + ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, + ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, + ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, PruneBlockchain, + RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, + SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, + SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, + TransactionCategory, UploadTarget, ValidateAddress, ValidateAddressError, VerifyChain, + VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, + WalletProcessPsbt, WitnessUtxo, }, v18::{ ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing, AnalyzePsbtInputMissingError, DeriveAddresses, GetNodeAddresses, GetReceivedByLabel, - JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListUnspent, ListUnspentItem, - ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, + JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListWalletDir, + ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, + Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetBlockchainInfoError, GetChainTxStats, GetDescriptorInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, @@ -296,17 +296,20 @@ pub use crate::{ Softfork, SoftforkType, }, v21::GetNetworkInfo, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, - v23::{CreateMultisig, GetBlockchainInfo, SaveMempool}, + v22::{Banned, ListBanned, ScriptPubkey}, + v23::{CreateMultisig, DecodeScript, DecodeScriptError, GetBlockchainInfo, SaveMempool}, v24::{ - DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GlobalXpub, Proprietary, - PsbtInput, PsbtOutput, TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, + DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GetTransactionDetail, + GlobalXpub, ListUnspent, ListUnspentItem, Proprietary, PsbtInput, PsbtOutput, + TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, }, + v25::GetBlockStats, v26::{ - CreateWallet, DescriptorProcessPsbt, DescriptorProcessPsbtError, GetPeerInfo, - GetPrioritisedTransactions, GetTxOutSetInfo, GetTxOutSetInfoError, LoadWallet, - PrioritisedTransaction, SubmitPackage, SubmitPackageError, SubmitPackageTxResult, - SubmitPackageTxResultError, SubmitPackageTxResultFees, SubmitPackageTxResultFeesError, - UnloadWallet, + CreateWallet, DescriptorProcessPsbt, DescriptorProcessPsbtError, GetBalances, + GetBalancesError, GetPeerInfo, GetPrioritisedTransactions, GetTransaction, + GetTransactionError, GetTxOutSetInfo, GetTxOutSetInfoError, LastProcessedBlock, + LastProcessedBlockError, LoadWallet, Logging, PrioritisedTransaction, SubmitPackage, + SubmitPackageError, SubmitPackageTxResult, SubmitPackageTxResultError, + SubmitPackageTxResultFees, SubmitPackageTxResultFeesError, UnloadWallet, }, }; diff --git a/types/src/v28/control.rs b/types/src/v28/control.rs new file mode 100644 index 00000000..c18ece6f --- /dev/null +++ b/types/src/v28/control.rs @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v28` - control. +//! +//! Types for methods found under the `== Control ==` section of the API docs. + +use serde::{Deserialize, Serialize}; + +/// Result of JSON-RPC method `logging`. +/// +/// > logging ( `` `` ) +/// +/// > Gets and sets the logging configuration. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct Logging { + pub addrman: bool, + pub bench: bool, + pub blockstorage: bool, // v23 and later only + pub cmpctblock: bool, + pub coindb: bool, + pub estimatefee: bool, + pub http: bool, + pub i2p: bool, // v23 and later only + pub ipc: bool, // v23 and later only + pub leveldb: bool, + pub libevent: bool, + pub mempool: bool, + pub mempoolrej: bool, + pub net: bool, + pub prune: bool, + pub proxy: bool, + pub qt: bool, + pub rand: bool, + pub reindex: bool, + pub rpc: bool, + pub scan: bool, // v25 and later only + pub selectcoins: bool, + pub tor: bool, + pub txpackages: bool, // v26 and later only + pub txreconciliation: bool, // v25 and later only + pub validation: bool, // v23 and later only + pub walletdb: bool, // v23 and later only + pub zmq: bool, +} diff --git a/types/src/v28/mod.rs b/types/src/v28/mod.rs index 8a496c93..8c232899 100644 --- a/types/src/v28/mod.rs +++ b/types/src/v28/mod.rs @@ -251,76 +251,83 @@ //! mod blockchain; +mod control; mod mining; mod network; mod raw_transactions; +mod wallet; #[doc(inline)] pub use self::{ blockchain::GetBlockchainInfo, + control::Logging, mining::GetMiningInfo, network::GetNetworkInfo, raw_transactions::{ SubmitPackage, SubmitPackageError, SubmitPackageTxResult, SubmitPackageTxResultError, SubmitPackageTxResultFees, SubmitPackageTxResultFeesError, }, + wallet::GetTransaction, }; #[doc(inline)] pub use crate::{ v17::{ AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddedNode, AddedNodeAddress, - AddressInformation, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, - CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, CreatePsbt, - CreateRawTransaction, DecodeRawTransaction, DecodeScript, DecodeScriptError, DumpPrivKey, - DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, - FundRawTransaction, FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, - GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, + AddressInformation, Bip125Replaceable, BumpFee, BumpFeeError, ChainTips, ChainTipsError, + ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, + CreatePsbt, CreateRawTransaction, DecodeRawTransaction, DumpPrivKey, DumpWallet, + EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, + FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, + GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderError, GetBlockHeaderVerbose, - GetBlockHeaderVerboseError, GetBlockStats, GetBlockStatsError, GetBlockTemplate, - GetBlockTemplateError, GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, - GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, + GetBlockHeaderVerboseError, GetBlockStatsError, GetBlockTemplate, GetBlockTemplateError, + GetBlockVerboseOne, GetBlockVerboseOneError, GetBlockVerboseZero, GetChainTips, + GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, GetMempoolInfoError, GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, - GetRawTransactionVerboseError, GetReceivedByAddress, GetTransaction, GetTransactionDetail, - GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, - GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, GetZmqNotifications, - ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, - ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, - ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, - ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, - ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, - PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, - RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, - SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, - SoftforkReject, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, - ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, - WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo, + GetRawTransactionVerboseError, GetReceivedByAddress, GetTransactionDetailError, GetTxOut, + GetTxOutError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, + GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, + ListAddressGroupingsItem, ListLabels, ListLockUnspent, ListLockUnspentItem, + ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, + ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, + ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, + ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, PruneBlockchain, + RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, + SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, + SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, + TransactionCategory, UploadTarget, ValidateAddress, ValidateAddressError, VerifyChain, + VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, + WalletProcessPsbt, WitnessUtxo, }, v18::{ ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing, AnalyzePsbtInputMissingError, DeriveAddresses, GetNodeAddresses, GetReceivedByLabel, - JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListUnspent, ListUnspentItem, - ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, + JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListWalletDir, + ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, + Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetBlockchainInfoError, GetChainTxStats, GetDescriptorInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, Softfork, SoftforkType, }, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, - v23::{CreateMultisig, SaveMempool}, + v22::{Banned, ListBanned, ScriptPubkey}, + v23::{CreateMultisig, DecodeScript, DecodeScriptError, SaveMempool}, v24::{ - DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GlobalXpub, Proprietary, - PsbtInput, PsbtOutput, TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, + DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GetTransactionDetail, + GlobalXpub, ListUnspent, ListUnspentItem, Proprietary, PsbtInput, PsbtOutput, + TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, }, + v25::GetBlockStats, v26::{ - CreateWallet, DescriptorProcessPsbt, DescriptorProcessPsbtError, GetPeerInfo, - GetPrioritisedTransactions, GetTxOutSetInfo, GetTxOutSetInfoError, LoadWallet, - PrioritisedTransaction, UnloadWallet, + CreateWallet, DescriptorProcessPsbt, DescriptorProcessPsbtError, GetBalances, + GetBalancesError, GetPeerInfo, GetPrioritisedTransactions, GetTransactionError, + GetTxOutSetInfo, GetTxOutSetInfoError, LastProcessedBlock, LastProcessedBlockError, + LoadWallet, PrioritisedTransaction, UnloadWallet, }, }; diff --git a/types/src/v28/wallet/into.rs b/types/src/v28/wallet/into.rs new file mode 100644 index 00000000..341569b4 --- /dev/null +++ b/types/src/v28/wallet/into.rs @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::consensus::encode; +use bitcoin::{BlockHash, SignedAmount, Transaction, Txid}; + +use super::{GetTransaction, GetTransactionError}; +use crate::model; + +impl GetTransaction { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTransactionError as E; + + let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; + let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; + let block_hash = + self.block_hash.map(|s| s.parse::().map_err(E::BlockHash)).transpose()?; + let block_index = + self.block_index.map(|idx| crate::to_u32(idx, "block_index")).transpose()?; + let block_height = + self.block_height.map(|h| crate::to_u32(h, "block_height")).transpose()?; + let txid = self.txid.parse::().map_err(E::Txid)?; + let wtxid = self.wtxid.map(|s| s.parse::().map_err(E::Wtxid)).transpose()?; + let wallet_conflicts = self + .wallet_conflicts + .into_iter() + .map(|s| s.parse::().map_err(E::WalletConflicts)) + .collect::, _>>()?; + let replaced_by_txid = self + .replaced_by_txid + .map(|s| s.parse::().map_err(E::ReplacedByTxid)) + .transpose()?; + let replaces_txid = + self.replaces_txid.map(|s| s.parse::().map_err(E::ReplacesTxid)).transpose()?; + let tx = encode::deserialize_hex::(&self.hex).map_err(E::Tx)?; + let details = self + .details + .into_iter() + .map(|d| d.into_model().map_err(E::Details)) + .collect::, _>>()?; + let last_processed_block = self + .last_processed_block + .map(|l| l.into_model()) + .transpose() + .map_err(E::LastProcessedBlock)?; + + Ok(model::GetTransaction { + amount, + fee, + confirmations: self.confirmations, + generated: self.generated, + trusted: self.trusted, + block_hash, + block_height, + block_index, + block_time: self.block_time, + txid, + wtxid, + wallet_conflicts, + replaced_by_txid, + replaces_txid, + mempool_conflicts: None, // v28 and later only. + to: self.to, + time: self.time, + time_received: self.time_received, + comment: self.comment, + bip125_replaceable: self.bip125_replaceable.into_model(), + parent_descriptors: self.parent_descriptors, + details, + decoded: self.decoded, + last_processed_block, + tx, + }) + } +} diff --git a/types/src/v28/wallet/mod.rs b/types/src/v28/wallet/mod.rs new file mode 100644 index 00000000..587e537a --- /dev/null +++ b/types/src/v28/wallet/mod.rs @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v28` - wallet. +//! +//! Types for methods found under the `== Wallet ==` section of the API docs. + +mod into; + +use bitcoin::Transaction; +use serde::{Deserialize, Serialize}; + +pub use super::{Bip125Replaceable, GetTransactionDetail, GetTransactionError, LastProcessedBlock}; + +/// Result of the JSON-RPC method `gettransaction`. +/// +/// > gettransaction "txid" ( include_watchonly ) +/// > +/// > Get detailed information about in-wallet transaction `` +/// > +/// > Arguments: +/// > 1. txid (string, required) The transaction id +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTransaction { + /// The transaction amount in BTC. + pub amount: f64, + /// The amount of the fee in BTC. + /// + /// This is negative and only available for the 'send' category of transactions. + pub fee: Option, + /// The number of confirmations. + pub confirmations: i64, + /// Only present if the transaction's only input is a coinbase one. v20 and later only. + pub generated: Option, + /// Whether we consider the outputs of this unconfirmed transaction safe to spend. + pub trusted: Option, + /// The block hash. + #[serde(rename = "blockhash")] + pub block_hash: Option, + /// The block height containing the transaction. v20 and later only. + #[serde(rename = "blockheight")] + pub block_height: Option, + /// The index of the transaction in the block that includes it. + #[serde(rename = "blockindex")] + pub block_index: Option, + /// The time in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "blocktime")] + pub block_time: Option, + /// The transaction id. + pub txid: String, + /// The hash of serialized transaction, including witness data. v24 and later only. + pub wtxid: Option, + /// Confirmed transactions that have been detected by the wallet to conflict with this transaction. + #[serde(rename = "walletconflicts")] + pub wallet_conflicts: Vec, + /// Only if 'category' is 'send'. The txid if this tx was replaced. v23 and later only. + pub replaced_by_txid: Option, + /// Only if 'category' is 'send'. The txid if this tx replaces another. v23 and later only. + pub replaces_txid: Option, + /// Transactions in the mempool that directly conflict with either this transaction or an ancestor + /// transaction. v28 and later only. + #[serde(rename = "mempoolconflicts")] + pub mempool_conflicts: Option>, + /// If a comment to is associated with the transaction. v23 and later only. + pub to: Option, + /// The transaction time in seconds since epoch (1 Jan 1970 GMT). + pub time: u32, + /// The time received in seconds since epoch (1 Jan 1970 GMT). + #[serde(rename = "timereceived")] + pub time_received: u32, + /// If a comment is associated with the transaction, only present if not empty. v20 to v24 only. + pub comment: Option, + /// Whether this transaction could be replaced due to BIP125 (replace-by-fee); + /// may be unknown for unconfirmed transactions not in the mempool + #[serde(rename = "bip125-replaceable")] + pub bip125_replaceable: Bip125Replaceable, + /// Only if 'category' is 'received'. List of parent descriptors for the output script of this + /// coin. v24 and later only. + #[serde(rename = "parent_descs")] + pub parent_descriptors: Option>, + /// Transaction details. + pub details: Vec, + /// Raw data for transaction. + pub hex: String, + /// The decoded transaction (only present when `verbose` is passed). v19 and later only. + pub decoded: Option, + /// Hash and height of the block this information was generated on. v26 and later only. + #[serde(rename = "lastprocessedblock")] + pub last_processed_block: Option, +} diff --git a/types/src/v29/mod.rs b/types/src/v29/mod.rs index 4e9ee32f..1e338443 100644 --- a/types/src/v29/mod.rs +++ b/types/src/v29/mod.rs @@ -275,58 +275,62 @@ pub use crate::{ AbortRescan, AddMultisigAddress, AddMultisigAddressError, AddedNode, AddedNodeAddress, AddressInformation, BumpFee, BumpFeeError, ChainTips, ChainTipsError, ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, CreatePsbt, - CreateRawTransaction, DecodeRawTransaction, DecodeScript, DecodeScriptError, DumpPrivKey, - DumpWallet, EncryptWallet, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, - FundRawTransaction, FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, - GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, + CreateRawTransaction, DecodeRawTransaction, DumpPrivKey, DumpWallet, EncryptWallet, + EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, + FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, GetAddressInfo, + GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError, GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, - GetBlockHash, GetBlockStats, GetBlockStatsError, GetBlockTemplate, GetBlockTemplateError, + GetBlockHash, GetBlockStatsError, GetBlockTemplate, GetBlockTemplateError, GetBlockVerboseZero, GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, GetMemoryInfoStats, GetMempoolInfoError, GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose, - GetRawTransactionVerboseError, GetReceivedByAddress, GetTransaction, GetTransactionDetail, - GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, - GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, GetZmqNotifications, - ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, - ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress, - ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, - ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, - ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, - PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, - RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, - SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, - TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, - ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, - WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo, + GetRawTransactionVerboseError, GetReceivedByAddress, GetTransactionDetailError, GetTxOut, + GetTxOutError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError, + GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsError, + ListAddressGroupingsItem, ListLabels, ListLockUnspent, ListLockUnspentItem, + ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, + ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, + ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, + ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, PruneBlockchain, + RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, + SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, + SignRawTransaction, SignRawTransactionError, TestMempoolAccept, TransactionCategory, + UploadTarget, ValidateAddress, ValidateAddressError, VerifyChain, VerifyMessage, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, WalletProcessPsbt, + WitnessUtxo, }, v18::{ ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing, AnalyzePsbtInputMissingError, DeriveAddresses, GetNodeAddresses, GetReceivedByLabel, - JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListUnspent, ListUnspentItem, - ListWalletDir, ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, + JoinPsbts, ListReceivedByLabel, ListReceivedByLabelError, ListWalletDir, + ListWalletDirWallet, NodeAddress, UtxoUpdatePsbt, }, v19::{ - Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, + Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalancesMine, GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetChainTxStats, GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, Softfork, SoftforkType, }, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, - v23::{CreateMultisig, SaveMempool}, + v22::{Banned, ListBanned, ScriptPubkey}, + v23::{CreateMultisig, DecodeScript, DecodeScriptError, SaveMempool}, v24::{ - DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GlobalXpub, Proprietary, - PsbtInput, PsbtOutput, TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, + DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GetTransactionDetail, + GlobalXpub, ListUnspent, ListUnspentItem, Proprietary, PsbtInput, PsbtOutput, + TaprootBip32Deriv, TaprootLeaf, TaprootScript, TaprootScriptPathSig, }, + v25::GetBlockStats, v26::{ - CreateWallet, DescriptorProcessPsbt, DescriptorProcessPsbtError, - GetPrioritisedTransactions, GetTxOutSetInfo, GetTxOutSetInfoError, LoadWallet, + CreateWallet, DescriptorProcessPsbt, DescriptorProcessPsbtError, GetBalances, + GetBalancesError, GetPrioritisedTransactions, GetTransactionError, GetTxOutSetInfo, + GetTxOutSetInfoError, LastProcessedBlock, LastProcessedBlockError, LoadWallet, PrioritisedTransaction, UnloadWallet, }, v28::{ - GetNetworkInfo, GetPeerInfo, SubmitPackage, SubmitPackageError, SubmitPackageTxResult, - SubmitPackageTxResultError, SubmitPackageTxResultFees, SubmitPackageTxResultFeesError, + GetNetworkInfo, GetPeerInfo, GetTransaction, Logging, SubmitPackage, SubmitPackageError, + SubmitPackageTxResult, SubmitPackageTxResultError, SubmitPackageTxResultFees, + SubmitPackageTxResultFeesError, }, };