Skip to content

Commit aada498

Browse files
committed
Implement methods in raw transactions section
Have a decent crack at implementing stuff from the rawtransaction section. Still needs more testing and a few more methods doing. Includes removing key from types version specific modules.
1 parent 870efdf commit aada498

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2749
-763
lines changed

client/src/client_sync/mod.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ pub mod v26;
1616
pub mod v27;
1717
pub mod v28;
1818

19+
use std::collections::HashMap;
1920
use std::fs::File;
2021
use std::io::{BufRead, BufReader};
2122
use std::path::PathBuf;
2223

23-
use bitcoin::Txid;
24+
use bitcoin::{Address, Amount, Txid};
2425
use serde::{Deserialize, Serialize};
2526

2627
pub use crate::client_sync::error::Error;
@@ -235,6 +236,23 @@ pub struct Input {
235236
pub sequence: Option<bitcoin::Sequence>,
236237
}
237238

239+
/// Output used as parameter to `create_raw_transaction`.
240+
// Abuse `HashMap` so we can derive serialize to get the correct JSON object.
241+
#[derive(Debug, Serialize)]
242+
pub struct Output(
243+
/// Map of address to value. Always only has a single item in it.
244+
HashMap<String, f64>,
245+
);
246+
247+
impl Output {
248+
/// Creates a single output that serializes as Core expects.
249+
pub fn new(addr: Address, value: Amount) -> Self {
250+
let mut map = HashMap::new();
251+
map.insert(addr.to_string(), value.to_btc());
252+
Output(map)
253+
}
254+
}
255+
238256
/// An element in the `inputs` argument of method `walletcreatefundedpsbt`.
239257
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
240258
pub struct WalletCreateFundedPsbtInput {

client/src/client_sync/v17/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,21 @@ crate::impl_client_v17__getnetworkinfo!();
7676
crate::impl_client_v17__getpeerinfo!();
7777

7878
// == Rawtransactions ==
79+
crate::impl_client_v17__combinepsbt!();
80+
crate::impl_client_v17__combinerawtransaction!();
81+
crate::impl_client_v17__converttopsbt!();
82+
crate::impl_client_v17__createpsbt!();
7983
crate::impl_client_v17__createrawtransaction!();
84+
crate::impl_client_v17__decodepsbt!();
85+
crate::impl_client_v17__decoderawtransaction!();
86+
crate::impl_client_v17__decodescript!();
87+
crate::impl_client_v17__finalizepsbt!();
8088
crate::impl_client_v17__fundrawtransaction!();
89+
crate::impl_client_v17__getrawtransaction!();
8190
crate::impl_client_v17__sendrawtransaction!();
91+
crate::impl_client_v17__signrawtransaction!();
92+
crate::impl_client_v17__signrawtransactionwithkey!();
93+
crate::impl_client_v17__testmempoolaccept!();
8294

8395
// == Wallet ==
8496
crate::impl_client_v17__addmultisigaddress!();

client/src/client_sync/v17/raw_transactions.rs

+191-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,67 @@
99
//!
1010
//! See or use the `define_jsonrpc_minreq_client!` macro to define a `Client`.
1111
12+
/// Implements Bitcoin Core JSON-RPC API method `combinepsbt`
13+
#[macro_export]
14+
macro_rules! impl_client_v17__combinepsbt {
15+
() => {
16+
impl Client {
17+
pub fn combine_psbt(&self, txs: &[bitcoin::Psbt]) -> Result<CombinePsbt> {
18+
let txs = txs.iter().map(|psbt| format!("{}", psbt)).collect::<Vec<String>>();
19+
self.call("combinepsbt", &[txs.into()])
20+
}
21+
}
22+
};
23+
}
24+
25+
/// Implements Bitcoin Core JSON-RPC API method `combinerawtransaction`
26+
#[macro_export]
27+
macro_rules! impl_client_v17__combinerawtransaction {
28+
() => {
29+
impl Client {
30+
pub fn combine_raw_transaction(
31+
&self,
32+
txs: &[bitcoin::Transaction],
33+
) -> Result<CombineRawTransaction> {
34+
let encoded = txs
35+
.iter()
36+
.map(|tx| bitcoin::consensus::encode::serialize_hex(tx))
37+
.collect::<Vec<String>>();
38+
self.call("combinerawtransaction", &[into_json(encoded)?])
39+
}
40+
}
41+
};
42+
}
43+
44+
/// Implements Bitcoin Core JSON-RPC API method `converttopsbt`
45+
#[macro_export]
46+
macro_rules! impl_client_v17__converttopsbt {
47+
() => {
48+
impl Client {
49+
pub fn convert_to_psbt(&self, tx: &bitcoin::Transaction) -> Result<ConvertToPsbt> {
50+
let hex = bitcoin::consensus::encode::serialize_hex(tx);
51+
self.call("converttopsbt", &[hex.into()])
52+
}
53+
}
54+
};
55+
}
56+
57+
/// Implements Bitcoin Core JSON-RPC API method `createpsbt`
58+
#[macro_export]
59+
macro_rules! impl_client_v17__createpsbt {
60+
() => {
61+
impl Client {
62+
pub fn create_psbt(
63+
&self,
64+
inputs: &[$crate::client_sync::Input],
65+
outputs: &[$crate::client_sync::Output],
66+
) -> Result<CreatePsbt> {
67+
self.call("createpsbt", &[into_json(inputs)?, into_json(outputs)?])
68+
}
69+
}
70+
};
71+
}
72+
1273
/// Implements Bitcoin Core JSON-RPC API method `createrawtransaction`
1374
#[macro_export]
1475
macro_rules! impl_client_v17__createrawtransaction {
@@ -17,24 +78,98 @@ macro_rules! impl_client_v17__createrawtransaction {
1778
pub fn create_raw_transaction(
1879
&self,
1980
inputs: &[$crate::client_sync::Input],
20-
outputs: &std::collections::BTreeMap<String, f64>, // Map of address to amount.
81+
outputs: &[$crate::client_sync::Output],
2182
) -> Result<CreateRawTransaction> {
2283
self.call("createrawtransaction", &[into_json(inputs)?, into_json(outputs)?])
2384
}
2485
}
2586
};
2687
}
2788

89+
/// Implements Bitcoin Core JSON-RPC API method `decodepsbt`
90+
#[macro_export]
91+
macro_rules! impl_client_v17__decodepsbt {
92+
() => {
93+
impl Client {
94+
pub fn decode_psbt(&self, psbt: &str) -> Result<DecodePsbt> {
95+
self.call("decodepsbt", &[psbt.into()])
96+
}
97+
}
98+
};
99+
}
100+
101+
/// Implements Bitcoin Core JSON-RPC API method `finalizepsbt`
102+
#[macro_export]
103+
macro_rules! impl_client_v17__finalizepsbt {
104+
() => {
105+
impl Client {
106+
pub fn finalize_psbt(&self, psbt: &bitcoin::Psbt) -> Result<FinalizePsbt> {
107+
let psbt = format!("{}", psbt);
108+
self.call("finalizepsbt", &[psbt.into()])
109+
}
110+
}
111+
};
112+
}
113+
114+
/// Implements Bitcoin Core JSON-RPC API method `decoderawtransaction`
115+
#[macro_export]
116+
macro_rules! impl_client_v17__decoderawtransaction {
117+
() => {
118+
impl Client {
119+
pub fn decode_raw_transaction(
120+
&self,
121+
tx: &bitcoin::Transaction,
122+
) -> Result<DecodeRawTransaction> {
123+
let hex = bitcoin::consensus::encode::serialize_hex(tx);
124+
self.call("decoderawtransaction", &[hex.into()])
125+
}
126+
}
127+
};
128+
}
129+
130+
/// Implements Bitcoin Core JSON-RPC API method `decodescript`
131+
#[macro_export]
132+
macro_rules! impl_client_v17__decodescript {
133+
() => {
134+
impl Client {
135+
// Arg is the hex encoded script we want to decode.
136+
pub fn decode_script(&self, script: &str) -> Result<DecodeScript> {
137+
self.call("decodescript", &[script.into()])
138+
}
139+
}
140+
};
141+
}
142+
28143
/// Implements Bitcoin Core JSON-RPC API method `fundrawtransaction`
29144
#[macro_export]
30145
macro_rules! impl_client_v17__fundrawtransaction {
31146
() => {
32147
impl Client {
33148
pub fn fund_raw_transaction(
34149
&self,
35-
hex: &str, // Hex encoded transaction.
150+
tx: &bitcoin::Transaction,
36151
) -> Result<FundRawTransaction> {
37-
self.call("fundrawtransaction", &[into_json(hex)?])
152+
let hex = bitcoin::consensus::encode::serialize_hex(tx);
153+
self.call("fundrawtransaction", &[hex.into()])
154+
}
155+
}
156+
};
157+
}
158+
159+
/// Implements Bitcoin Core JSON-RPC API method `getrawtransaction`
160+
#[macro_export]
161+
macro_rules! impl_client_v17__getrawtransaction {
162+
() => {
163+
impl Client {
164+
pub fn get_raw_transaction(&self, txid: bitcoin::Txid) -> Result<GetRawTransaction> {
165+
self.call("getrawtransaction", &[into_json(&txid)?, false.into()])
166+
}
167+
168+
pub fn get_raw_transaction_verbose(
169+
&self,
170+
txid: Txid,
171+
) -> Result<GetRawTransactionVerbose> {
172+
self.call("getrawtransaction", &[into_json(&txid)?, true.into()])
38173
}
39174
}
40175
};
@@ -55,3 +190,56 @@ macro_rules! impl_client_v17__sendrawtransaction {
55190
}
56191
};
57192
}
193+
194+
/// Implements Bitcoin Core JSON-RPC API method `signrawtransaction`
195+
#[macro_export]
196+
macro_rules! impl_client_v17__signrawtransaction {
197+
() => {
198+
impl Client {
199+
pub fn sign_raw_transaction(
200+
&self,
201+
tx: &bitcoin::Transaction,
202+
) -> Result<SignRawTransaction> {
203+
let hex = bitcoin::consensus::encode::serialize_hex(tx);
204+
self.call("signrawtransaction", &[hex.into()])
205+
}
206+
}
207+
};
208+
}
209+
210+
/// Implements Bitcoin Core JSON-RPC API method `signrawtransactionwithkey`
211+
#[macro_export]
212+
macro_rules! impl_client_v17__signrawtransactionwithkey {
213+
() => {
214+
impl Client {
215+
pub fn sign_raw_transaction_with_key(
216+
&self,
217+
tx: &bitcoin::Transaction,
218+
keys: &[bitcoin::PrivateKey],
219+
) -> Result<SignRawTransaction> {
220+
let hex = bitcoin::consensus::encode::serialize_hex(tx);
221+
let keys = keys.iter().map(|k| format!("{}", k)).collect::<Vec<String>>();
222+
self.call("signrawtransactionwithkey", &[hex.into(), into_json(keys)?])
223+
}
224+
}
225+
};
226+
}
227+
228+
/// Implements Bitcoin Core JSON-RPC API method `testmempoolaccept`
229+
#[macro_export]
230+
macro_rules! impl_client_v17__testmempoolaccept {
231+
() => {
232+
impl Client {
233+
pub fn test_mempool_accept(
234+
&self,
235+
txs: &[bitcoin::Transaction],
236+
) -> Result<TestMempoolAccept> {
237+
let encoded = txs
238+
.iter()
239+
.map(|tx| bitcoin::consensus::encode::serialize_hex(tx))
240+
.collect::<Vec<String>>();
241+
self.call("testmempoolaccept", &[into_json(encoded)?])
242+
}
243+
}
244+
};
245+
}

client/src/client_sync/v17/wallet.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,9 @@ macro_rules! impl_client_v17__signrawtransactionwithwallet {
424424
// `hexstring`: The transaction hex string.
425425
pub fn sign_raw_transaction_with_wallet(
426426
&self,
427-
hex: &str,
428-
) -> Result<SignRawTransactionWithWallet> {
427+
tx: &bitcoin::Transaction,
428+
) -> Result<SignRawTransaction> {
429+
let hex = bitcoin::consensus::encode::serialize_hex(tx);
429430
self.call("signrawtransactionwithwallet", &[into_json(hex)?])
430431
}
431432
}

client/src/client_sync/v18/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,21 @@ crate::impl_client_v17__getnetworkinfo!();
7070
crate::impl_client_v17__getpeerinfo!();
7171

7272
// == Rawtransactions ==
73+
crate::impl_client_v17__combinepsbt!();
74+
crate::impl_client_v17__combinerawtransaction!();
75+
crate::impl_client_v17__converttopsbt!();
76+
crate::impl_client_v17__createpsbt!();
7377
crate::impl_client_v17__createrawtransaction!();
78+
crate::impl_client_v17__decodepsbt!();
79+
crate::impl_client_v17__decoderawtransaction!();
80+
crate::impl_client_v17__decodescript!();
81+
crate::impl_client_v17__finalizepsbt!();
7482
crate::impl_client_v17__fundrawtransaction!();
83+
crate::impl_client_v17__getrawtransaction!();
7584
crate::impl_client_v17__sendrawtransaction!();
85+
crate::impl_client_v17__signrawtransaction!();
86+
crate::impl_client_v17__signrawtransactionwithkey!();
87+
crate::impl_client_v17__testmempoolaccept!();
7688

7789
// == Wallet ==
7890
crate::impl_client_v17__addmultisigaddress!();

client/src/client_sync/v19/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,21 @@ crate::impl_client_check_expected_server_version!({ [190100] });
6969
crate::impl_client_v17__getpeerinfo!();
7070

7171
// == Rawtransactions ==
72+
crate::impl_client_v17__combinepsbt!();
73+
crate::impl_client_v17__combinerawtransaction!();
74+
crate::impl_client_v17__converttopsbt!();
75+
crate::impl_client_v17__createpsbt!();
7276
crate::impl_client_v17__createrawtransaction!();
77+
crate::impl_client_v17__decodepsbt!();
78+
crate::impl_client_v17__decoderawtransaction!();
79+
crate::impl_client_v17__decodescript!();
80+
crate::impl_client_v17__finalizepsbt!();
7381
crate::impl_client_v17__fundrawtransaction!();
82+
crate::impl_client_v17__getrawtransaction!();
7483
crate::impl_client_v17__sendrawtransaction!();
84+
crate::impl_client_v17__signrawtransaction!();
85+
crate::impl_client_v17__signrawtransactionwithkey!();
86+
crate::impl_client_v17__testmempoolaccept!();
7587

7688
// == Wallet ==
7789
crate::impl_client_v17__addmultisigaddress!();

client/src/client_sync/v20.rs

+12
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,21 @@ crate::impl_client_check_expected_server_version!({ [200200] });
6666
crate::impl_client_v17__getpeerinfo!();
6767

6868
// == Rawtransactions ==
69+
crate::impl_client_v17__combinepsbt!();
70+
crate::impl_client_v17__combinerawtransaction!();
71+
crate::impl_client_v17__converttopsbt!();
72+
crate::impl_client_v17__createpsbt!();
6973
crate::impl_client_v17__createrawtransaction!();
74+
crate::impl_client_v17__decodepsbt!();
75+
crate::impl_client_v17__decoderawtransaction!();
76+
crate::impl_client_v17__decodescript!();
77+
crate::impl_client_v17__finalizepsbt!();
7078
crate::impl_client_v17__fundrawtransaction!();
79+
crate::impl_client_v17__getrawtransaction!();
7180
crate::impl_client_v17__sendrawtransaction!();
81+
crate::impl_client_v17__signrawtransaction!();
82+
crate::impl_client_v17__signrawtransactionwithkey!();
83+
crate::impl_client_v17__testmempoolaccept!();
7284

7385
// == Wallet ==
7486
crate::impl_client_v17__addmultisigaddress!();

client/src/client_sync/v21/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,21 @@ crate::impl_client_check_expected_server_version!({ [210200] });
6868
crate::impl_client_v17__getpeerinfo!();
6969

7070
// == Rawtransactions ==
71+
crate::impl_client_v17__combinepsbt!();
72+
crate::impl_client_v17__combinerawtransaction!();
73+
crate::impl_client_v17__converttopsbt!();
74+
crate::impl_client_v17__createpsbt!();
7175
crate::impl_client_v17__createrawtransaction!();
76+
crate::impl_client_v17__decodepsbt!();
77+
crate::impl_client_v17__decoderawtransaction!();
78+
crate::impl_client_v17__decodescript!();
79+
crate::impl_client_v17__finalizepsbt!();
7280
crate::impl_client_v17__fundrawtransaction!();
81+
crate::impl_client_v17__getrawtransaction!();
7382
crate::impl_client_v17__sendrawtransaction!();
83+
crate::impl_client_v17__signrawtransaction!();
84+
crate::impl_client_v17__signrawtransactionwithkey!();
85+
crate::impl_client_v17__testmempoolaccept!();
7486

7587
// == Wallet ==
7688
crate::impl_client_v17__addmultisigaddress!();

0 commit comments

Comments
 (0)