Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion client/src/client_sync/v17/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,11 @@ macro_rules! impl_client_v17__send_many {
impl Client {
pub fn send_many(&self, amounts: BTreeMap<Address, Amount>) -> Result<SendMany> {
let dummy = ""; // Must be set to "" for backwards compatibility.
self.call("sendmany", &[into_json(dummy)?, into_json(amounts)?])
let amount_btc: BTreeMap<String, f64> = amounts
.into_iter()
.map(|(addr, amount)| (addr.to_string(), amount.to_btc()))
.collect();
self.call("sendmany", &[into_json(dummy)?, into_json(amount_btc)?])
}
}
};
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v21/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ crate::impl_client_v17__remove_pruned_funds!();
crate::impl_client_v17__rescan_blockchain!();
crate::impl_client_v21__send!();
crate::impl_client_v17__send_many!();
crate::impl_client_v21__send_many_verbose!();
crate::impl_client_v17__send_to_address!();
crate::impl_client_v17__set_hd_seed!();
crate::impl_client_v17__set_tx_fee!();
Expand Down
42 changes: 42 additions & 0 deletions client/src/client_sync/v21/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,48 @@ macro_rules! impl_client_v21__send {
};
}

/// Implements Bitcoin Core JSON-RPC API method `sendmany` with `verbose=true` (v21+).
#[macro_export]
macro_rules! impl_client_v21__send_many_verbose {
() => {
impl Client {
pub fn send_many_verbose(
&self,
amounts: BTreeMap<Address, Amount>,
) -> Result<SendManyVerbose> {
let dummy = ""; // Backwards compatibility dummy.
let amount_btc: BTreeMap<String, f64> = amounts
.into_iter()
.map(|(addr, amount)| (addr.to_string(), amount.to_btc()))
.collect();
let minconf = 1u64;
let comment = "";
let subtract_fee_from: Vec<String> = Vec::new();
let replaceable = true;
let conf_target = 1u64;
let estimate_mode = "unset";
let fee_rate = serde_json::Value::Null;
let verbose = true;
self.call(
"sendmany",
&[
into_json(dummy)?,
into_json(amount_btc)?,
minconf.into(),
comment.into(),
into_json(subtract_fee_from)?,
replaceable.into(),
conf_target.into(),
estimate_mode.into(),
fee_rate,
verbose.into(),
],
)
}
}
};
}

/// Implements Bitcoin Core JSON-RPC API method `unloadwallet`.
#[macro_export]
macro_rules! impl_client_v21__unload_wallet {
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v22/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ crate::impl_client_v17__remove_pruned_funds!();
crate::impl_client_v17__rescan_blockchain!();
crate::impl_client_v21__send!();
crate::impl_client_v17__send_many!();
crate::impl_client_v21__send_many_verbose!();
crate::impl_client_v17__send_to_address!();
crate::impl_client_v17__set_hd_seed!();
crate::impl_client_v17__set_tx_fee!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v23/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ crate::impl_client_v17__rescan_blockchain!();
crate::impl_client_v23__restore_wallet!();
crate::impl_client_v21__send!();
crate::impl_client_v17__send_many!();
crate::impl_client_v21__send_many_verbose!();
crate::impl_client_v17__send_to_address!();
crate::impl_client_v17__set_hd_seed!();
crate::impl_client_v17__set_tx_fee!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v24/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ crate::impl_client_v23__restore_wallet!();
crate::impl_client_v21__send!();
crate::impl_client_v24__send_all!();
crate::impl_client_v17__send_many!();
crate::impl_client_v21__send_many_verbose!();
crate::impl_client_v17__send_to_address!();
crate::impl_client_v17__set_hd_seed!();
crate::impl_client_v17__set_tx_fee!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v25/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ crate::impl_client_v23__restore_wallet!();
crate::impl_client_v21__send!();
crate::impl_client_v24__send_all!();
crate::impl_client_v17__send_many!();
crate::impl_client_v21__send_many_verbose!();
crate::impl_client_v17__send_to_address!();
crate::impl_client_v17__set_hd_seed!();
crate::impl_client_v17__set_tx_fee!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v26/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ crate::impl_client_v23__restore_wallet!();
crate::impl_client_v21__send!();
crate::impl_client_v24__send_all!();
crate::impl_client_v17__send_many!();
crate::impl_client_v21__send_many_verbose!();
crate::impl_client_v17__send_to_address!();
crate::impl_client_v17__set_hd_seed!();
crate::impl_client_v17__set_tx_fee!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v27/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ crate::impl_client_v23__restore_wallet!();
crate::impl_client_v21__send!();
crate::impl_client_v24__send_all!();
crate::impl_client_v17__send_many!();
crate::impl_client_v21__send_many_verbose!();
crate::impl_client_v17__send_to_address!();
crate::impl_client_v17__set_hd_seed!();
crate::impl_client_v17__set_tx_fee!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v28/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ crate::impl_client_v23__restore_wallet!();
crate::impl_client_v21__send!();
crate::impl_client_v24__send_all!();
crate::impl_client_v17__send_many!();
crate::impl_client_v21__send_many_verbose!();
crate::impl_client_v17__send_to_address!();
crate::impl_client_v17__set_hd_seed!();
crate::impl_client_v17__set_tx_fee!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v29/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ crate::impl_client_v23__restore_wallet!();
crate::impl_client_v21__send!();
crate::impl_client_v24__send_all!();
crate::impl_client_v17__send_many!();
crate::impl_client_v21__send_many_verbose!();
crate::impl_client_v17__send_to_address!();
crate::impl_client_v17__set_hd_seed!();
crate::impl_client_v17__set_tx_fee!();
Expand Down
27 changes: 27 additions & 0 deletions integration_test/tests/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,33 @@ fn wallet__unload_wallet() {
create_load_unload_wallet();
}

#[test]
fn wallet__send_many__modelled() {
let node = Node::with_wallet(Wallet::Default, &[]);
node.fund_wallet();

let addr1 = node.client.new_address().expect("newaddress");
let addr2 = node.client.new_address().expect("newaddress");

let mut amounts = BTreeMap::new();
amounts.insert(addr1, Amount::from_sat(100_000));
amounts.insert(addr2, Amount::from_sat(100_000));

let json: SendMany = node.client.send_many(amounts.clone()).expect("sendmany");
let model: Result<mtype::SendMany, _> = json.into_model();
model.unwrap();

#[cfg(not(feature = "v20_and_below"))]
{
let json_verbose: SendManyVerbose = node
.client
.send_many_verbose(amounts)
.expect("sendmany verbose");
let model_verbose: Result<mtype::SendManyVerbose, _> = json_verbose.into_model();
model_verbose.unwrap();
}
}

#[cfg(not(feature = "v20_and_below"))]
#[test]
fn wallet__send__modelled() {
Expand Down
6 changes: 3 additions & 3 deletions types/src/model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ pub use self::{
ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListReceivedByLabel,
ListReceivedByLabelItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions,
ListTransactionsItem, ListUnspent, ListUnspentItem, ListWallets, LoadWallet, PsbtBumpFee,
RescanBlockchain, ScriptType, Send, SendAll, SendMany, SendToAddress, SignMessage,
SimulateRawTransaction, TransactionCategory, UnloadWallet, WalletCreateFundedPsbt,
WalletDisplayAddress, WalletProcessPsbt,
RescanBlockchain, ScriptType, Send, SendAll, SendMany, SendManyVerbose, SendToAddress,
SignMessage, SimulateRawTransaction, TransactionCategory, UnloadWallet,
WalletCreateFundedPsbt, WalletDisplayAddress, WalletProcessPsbt,
},
};
10 changes: 10 additions & 0 deletions types/src/model/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,16 @@ pub struct SendAll {
#[serde(deny_unknown_fields)]
pub struct SendMany(pub Txid);

/// Models the verbose result of JSON-RPC method `sendmany` when `verbose=true`.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct SendManyVerbose {
/// The transaction id for the send. Only 1 transaction is created regardless of the number of addresses.
pub txid: Txid,
/// The transaction fee reason.
pub fee_reason: String,
}

/// Models the result of JSON-RPC method `sendtoaddress`.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
Expand Down
2 changes: 1 addition & 1 deletion types/src/v17/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@
//! | removeprunedfunds | returns nothing | |
//! | rescanblockchain | version + model | |
//! | sendfrom | returns nothing | |
//! | sendmany | version + model | UNTESTED |
//! | sendmany | version + model | |
//! | sendtoaddress | version + model | |
//! | setaccount | returns nothing | |
//! | sethdseed | returns nothing | |
Expand Down
2 changes: 1 addition & 1 deletion types/src/v18/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@
//! | lockunspent | version | |
//! | removeprunedfunds | returns nothing | |
//! | rescanblockchain | version + model | |
//! | sendmany | version + model | UNTESTED |
//! | sendmany | version + model | |
//! | sendtoaddress | version + model | |
//! | sethdseed | returns nothing | |
//! | setlabel | returns nothing | |
Expand Down
2 changes: 1 addition & 1 deletion types/src/v19/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@
//! | lockunspent | version | |
//! | removeprunedfunds | returns nothing | |
//! | rescanblockchain | version + model | |
//! | sendmany | version + model | UNTESTED |
//! | sendmany | version + model | |
//! | sendtoaddress | version + model | |
//! | sethdseed | returns nothing | |
//! | setlabel | returns nothing | |
Expand Down
2 changes: 1 addition & 1 deletion types/src/v20/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@
//! | lockunspent | version | |
//! | removeprunedfunds | returns nothing | |
//! | rescanblockchain | version + model | |
//! | sendmany | version + model | UNTESTED |
//! | sendmany | version + model | |
//! | sendtoaddress | version + model | |
//! | sethdseed | returns nothing | |
//! | setlabel | returns nothing | |
Expand Down
14 changes: 7 additions & 7 deletions types/src/v21/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@
//! | removeprunedfunds | returns nothing | |
//! | rescanblockchain | version + model | |
//! | send | version + model | |
//! | sendmany | version + model | UNTESTED |
//! | sendmany | version + model | |
//! | sendtoaddress | version + model | |
//! | sethdseed | returns nothing | |
//! | setlabel | returns nothing | |
Expand Down Expand Up @@ -256,7 +256,7 @@ pub use self::{
util::{GetIndexInfo, GetIndexInfoName},
wallet::{
ImportDescriptors, ImportDescriptorsResult, PsbtBumpFee, PsbtBumpFeeError, Send, SendError,
UnloadWallet, UpgradeWallet,
SendMany, SendManyVerbose, UnloadWallet, UpgradeWallet,
},
};
#[doc(inline)]
Expand Down Expand Up @@ -285,11 +285,11 @@ pub use crate::{
ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem,
ListTransactionsItemError, ListUnspentItemError, ListWallets, LoadWallet, LockUnspent,
Locked, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput,
RescanBlockchain, ScriptType, SendMany, SendRawTransaction, SendToAddress,
SetNetworkActive, SetTxFee, SignMessage, SignMessageWithPrivKey, SignRawTransaction,
SignRawTransactionError, SoftforkReject, TransactionCategory, UploadTarget,
ValidateAddress, ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof,
WalletCreateFundedPsbt, WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo,
RescanBlockchain, ScriptType, SendRawTransaction, SendToAddress, SetNetworkActive,
SetTxFee, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError,
SoftforkReject, TransactionCategory, UploadTarget, ValidateAddress, ValidateAddressError,
VerifyChain, VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt,
WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo,
},
v18::{
ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing,
Expand Down
22 changes: 21 additions & 1 deletion types/src/v21/wallet/into.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// SPDX-License-Identifier: CC0-1.0

use super::{PsbtBumpFee, PsbtBumpFeeError, Send, SendError, UnloadWallet};
use bitcoin::{hex, Txid};

use super::{
PsbtBumpFee, PsbtBumpFeeError, Send, SendError, SendMany, SendManyVerbose, UnloadWallet,
};
use crate::model;

impl UnloadWallet {
Expand Down Expand Up @@ -42,3 +46,19 @@ impl Send {
Ok(model::Send { complete: self.complete, txid, hex, psbt })
}
}

impl SendMany {
/// Converts version specific type to a version nonspecific, more strongly typed type.
pub fn into_model(self) -> Result<model::SendMany, hex::HexToArrayError> {
let txid = self.0.parse::<Txid>()?;
Ok(model::SendMany(txid))
}
}

impl SendManyVerbose {
/// Converts version specific type to a version nonspecific, more strongly typed type.
pub fn into_model(self) -> Result<model::SendManyVerbose, hex::HexToArrayError> {
let txid = self.txid.parse::<Txid>()?;
Ok(model::SendManyVerbose { txid, fee_reason: self.fee_reason })
}
}
30 changes: 30 additions & 0 deletions types/src/v21/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,36 @@ pub struct Send {
pub psbt: Option<String>,
}

/// Result of JSON-RPC method `sendmany` when `verbose=false`.
///
/// > sendmany "" {"address":amount}
/// >
/// > Send multiple times. Amounts are double-precision floating point numbers.
/// > Requires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.
/// >
/// > Arguments:
/// > 1. dummy (string, required) Must be set to "" for backwards compatibility.
/// > 2. amounts (json object, required) The addresses and amounts
/// > { "address": amount, (numeric or string, required) The bitcoin address is the key, the numeric amount (can be string) in BTC is the value }
/// > ...
/// > 10. verbose (boolean, optional, default=false) If true, return extra infomration about the transaction.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct SendMany(
/// The transaction id for the send.
pub String,
);

/// Result of JSON-RPC method `sendmany` when `verbose=true`.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct SendManyVerbose {
/// The transaction id for the send. Only 1 transaction is created regardless of the number of addresses.
pub txid: String,
/// The transaction fee reason.
pub fee_reason: String,
}

/// Result of the JSON-RPC method `unloadwallet`.
///
/// > unloadwallet ( "wallet_name" load_on_startup )
Expand Down
6 changes: 3 additions & 3 deletions types/src/v22/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@
//! | removeprunedfunds | returns nothing | |
//! | rescanblockchain | version + model | |
//! | send | version + model | |
//! | sendmany | version + model | UNTESTED |
//! | sendmany | version + model | |
//! | sendtoaddress | version + model | |
//! | sethdseed | returns nothing | |
//! | setlabel | returns nothing | |
Expand Down Expand Up @@ -287,7 +287,7 @@ pub use crate::{
ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError,
ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError,
ListWallets, LoadWallet, LockUnspent, Locked, PruneBlockchain, RawTransactionError,
RawTransactionInput, RawTransactionOutput, RescanBlockchain, ScriptType, SendMany,
RawTransactionInput, RawTransactionOutput, RescanBlockchain, ScriptType,
SendRawTransaction, SendToAddress, SetNetworkActive, SetTxFee, SignMessage,
SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, SoftforkReject,
TransactionCategory, UploadTarget, ValidateAddress, ValidateAddressError, VerifyChain,
Expand Down Expand Up @@ -317,7 +317,7 @@ pub use crate::{
GetIndexInfoName, GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants,
GetMempoolDescendantsVerbose, GetMempoolEntry, GetNetworkInfo, ImportDescriptors,
ImportDescriptorsResult, MempoolEntry, PsbtBumpFee, PsbtBumpFeeError, Send, SendError,
Softfork, SoftforkType, UnloadWallet, UpgradeWallet,
SendMany, SendManyVerbose, Softfork, SoftforkType, UnloadWallet, UpgradeWallet,
},
ScriptPubkey,
};
Loading