Skip to content

Commit c085b5e

Browse files
committed
Merge #324: Address all TODO in v29
0458099 Add deriveaddresses multipath (Jamil Lambert, PhD) Pull request description: One TODO in v29 for `deriveaddresses` The change is that it now supports multipath descriptors when calling `deriveaddresses`. Add a new struct, model and client function for DeriveAddressesMultipath. Update the test for v29 to check a multipath descriptor. ACKs for top commit: tcharding: ACK 0458099 Tree-SHA512: 28656e14eede5b1e4d6af6b4256a07031d67177bff8a2c8498a6122854a091066ee7bfd3d6943437c548e1c3b429335a1c0d4e802277d12981eab7086f5596a4
2 parents 5af7bb0 + 0458099 commit c085b5e

File tree

7 files changed

+91
-4
lines changed

7 files changed

+91
-4
lines changed

client/src/client_sync/v29/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! We ignore option arguments unless they effect the shape of the returned JSON data.
66
77
pub mod blockchain;
8+
pub mod util;
89

910
use std::collections::BTreeMap;
1011
use std::path::Path;
@@ -126,7 +127,7 @@ crate::impl_client_v22__enumerate_signers!();
126127

127128
// == Util ==
128129
crate::impl_client_v17__create_multisig!();
129-
crate::impl_client_v18__derive_addresses!();
130+
crate::impl_client_v29__derive_addresses!();
130131
crate::impl_client_v17__estimate_smart_fee!();
131132
crate::impl_client_v18__get_descriptor_info!();
132133
crate::impl_client_v21__get_index_info!();

client/src/client_sync/v29/util.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
//! Macros for implementing JSON-RPC methods on a client.
4+
//!
5+
//! Specifically this is methods found under the `== Util ==` section of the
6+
//! API docs of Bitcoin Core `v29`.
7+
//!
8+
//! All macros require `Client` to be in scope.
9+
//!
10+
//! See or use the `define_jsonrpc_minreq_client!` macro to define a `Client`.
11+
12+
/// Implements Bitcoin Core JSON-RPC API method `deriveaddresses`.
13+
#[macro_export]
14+
macro_rules! impl_client_v29__derive_addresses {
15+
() => {
16+
impl Client {
17+
// For single derivation descriptors.
18+
pub fn derive_addresses(&self, descriptor: &str) -> Result<DeriveAddresses> {
19+
self.call("deriveaddresses", &[descriptor.into()])
20+
}
21+
22+
// For multipath descriptors.
23+
pub fn derive_addresses_multipath(
24+
&self,
25+
descriptor: &str,
26+
range: (u32, u32),
27+
) -> Result<DeriveAddressesMultipath> {
28+
let range = json!([range.0, range.1]);
29+
self.call("deriveaddresses", &[descriptor.into(), range.into()])
30+
}
31+
}
32+
};
33+
}

integration_test/tests/util.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,24 @@ fn util__derive_addresses__modelled() {
4141
let json: DeriveAddresses = node.client.derive_addresses(descriptor).expect("deriveaddresses");
4242
let res: Result<mtype::DeriveAddresses, _> = json.into_model();
4343
let _ = res.expect("DeriveAddresses into model");
44+
45+
// For v29 and above test a multipath descriptor.
46+
#[cfg(not(feature = "v28_and_below"))]
47+
{
48+
// Create a multipath descriptor taken from running `listdescriptors` on the node. With 2 derivation paths.
49+
let multipath_descriptor = "wpkh([26b4ed16/84h/1h/0h]tpubDDe7JUw2CGU1rYZxupmNrhDXuE1fv25gs4je3BBuWCFwTW9QHGgyh5cjAEugd14ysJXTVshPvnUVABfD66HZKCS9gp5AYFd5K2WN2oVFp8t/<0;1>/*)#grvmsm8m";
50+
51+
let range = (0, 3);
52+
let json: DeriveAddressesMultipath = node.client.derive_addresses_multipath(multipath_descriptor, range)
53+
.expect("deriveaddresses");
54+
let res: Result<mtype::DeriveAddressesMultipath, _> = json.into_model();
55+
let derived = res.expect("DeriveAddressesMultipath into model");
56+
57+
// Should return 2 `DeriveAddresses`, one for each derivation path (0 and 1).
58+
assert_eq!(derived.addresses.len(), 2);
59+
// Each `DeriveAddresses` should contain 4 addresses for range [0, 3].
60+
assert_eq!(derived.addresses[0].addresses.len(), 4);
61+
}
4462
}
4563

4664
#[test]

types/src/model/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ pub use self::{
4747
TestMempoolAccept, UtxoUpdatePsbt,
4848
},
4949
util::{
50-
CreateMultisig, DeriveAddresses, EstimateSmartFee, SignMessageWithPrivKey, ValidateAddress,
50+
CreateMultisig, DeriveAddresses, DeriveAddressesMultipath, EstimateSmartFee,
51+
SignMessageWithPrivKey, ValidateAddress,
5152
},
5253
wallet::{
5354
AddMultisigAddress, AddressInformation, AddressLabel, AddressPurpose, Bip125Replaceable,

types/src/model/util.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ pub struct DeriveAddresses {
4848
pub addresses: Vec<Address<NetworkUnchecked>>,
4949
}
5050

51+
/// Models the result of JSON-RPC method `deriveaddresses` for multipath descriptors.
52+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
53+
#[serde(deny_unknown_fields)]
54+
pub struct DeriveAddressesMultipath {
55+
/// The derived addresses for each of the multipath expansions of the descriptor, in multipath specifier order.
56+
pub addresses: Vec<DeriveAddresses>,
57+
}
58+
5159
/// Models the result of JSON-RPC method `signmessagewithprivkey`.
5260
#[derive(Clone, Debug, PartialEq, Eq)]
5361
pub struct SignMessageWithPrivKey(pub sign_message::MessageSignature);

types/src/v29/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@
156156
//! | JSON-RPC Method Name | Returns | Notes |
157157
//! |:-----------------------------------|:---------------:|:--------------------------------------:|
158158
//! | createmultisig | version + model | |
159-
//! | deriveaddresses | version + model | TODO |
159+
//! | deriveaddresses | version + model | |
160160
//! | estimatesmartfee | version + model | |
161161
//! | getdescriptorinfo | version | |
162162
//! | getindexinfo | version | |
@@ -267,7 +267,7 @@ pub use self::{
267267
BlockTemplateTransaction, GetMiningInfo, GetMiningInfoError, NextBlockInfo,
268268
NextBlockInfoError,
269269
},
270-
util::GetDescriptorInfo,
270+
util::{DeriveAddressesMultipath, GetDescriptorInfo},
271271
};
272272
#[doc(inline)]
273273
pub use crate::{

types/src/v29/util.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,34 @@
44
//!
55
//! Types for methods found under the `== Util ==` section of the API docs.
66
7+
use bitcoin::address;
78
use serde::{Deserialize, Serialize};
89

10+
use super::DeriveAddresses;
11+
use crate::model;
12+
13+
/// Result of JSON-RPC method `deriveaddresses` for multipath descriptors.
14+
///
15+
/// > deriveaddresses "descriptor" ( range )
16+
/// >
17+
/// > Derives one or more addresses corresponding to an output descriptor.
18+
/// > Returns an array of derived addresses.
19+
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
20+
#[serde(deny_unknown_fields)]
21+
pub struct DeriveAddressesMultipath(pub Vec<DeriveAddresses>);
22+
23+
impl DeriveAddressesMultipath {
24+
/// Converts version specific type to a version nonspecific, more strongly typed type.
25+
pub fn into_model(self) -> Result<model::DeriveAddressesMultipath, address::ParseError> {
26+
let derive_addresses = self
27+
.0
28+
.into_iter()
29+
.map(|derive_addresses| derive_addresses.into_model())
30+
.collect::<Result<Vec<_>, _>>()?;
31+
Ok(model::DeriveAddressesMultipath { addresses: derive_addresses })
32+
}
33+
}
34+
935
/// Result of JSON-RPC method `getdescriptorinfo`.
1036
///
1137
/// > getdescriptorinfo "descriptor"

0 commit comments

Comments
 (0)