Skip to content

Commit 268457b

Browse files
committed
feat: expose Wallet::keychains
1 parent 7230490 commit 268457b

3 files changed

Lines changed: 78 additions & 1 deletion

File tree

bdk-ffi/src/tests/wallet.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,39 @@ fn test_create_wallet() {
4646
assert_eq!(wallet.next_derivation_index(KeychainKind::External), 0);
4747
}
4848

49+
#[test]
50+
fn test_keychains() {
51+
let wallet = build_wallet();
52+
53+
let keychains = wallet.keychains();
54+
55+
assert_eq!(keychains.len(), 2);
56+
57+
let external = keychains
58+
.iter()
59+
.find(|keychain| keychain.keychain == KeychainKind::External)
60+
.unwrap();
61+
let internal = keychains
62+
.iter()
63+
.find(|keychain| keychain.keychain == KeychainKind::Internal)
64+
.unwrap();
65+
let external_public_descriptor = external.public_descriptor.to_string();
66+
let internal_public_descriptor = internal.public_descriptor.to_string();
67+
68+
assert_eq!(
69+
external_public_descriptor,
70+
wallet.public_descriptor(KeychainKind::External)
71+
);
72+
assert_eq!(
73+
internal_public_descriptor,
74+
wallet.public_descriptor(KeychainKind::Internal)
75+
);
76+
assert!(external.public_descriptor.has_wildcard());
77+
assert!(internal.public_descriptor.has_wildcard());
78+
assert!(!external_public_descriptor.contains("tprv"));
79+
assert!(!internal_public_descriptor.contains("tprv"));
80+
}
81+
4982
#[test]
5083
fn test_reveal_next_address() {
5184
let wallet = build_wallet();
@@ -69,6 +102,18 @@ fn test_create_single_wallet() {
69102

70103
assert_eq!(wallet.derivation_index(KeychainKind::External), None);
71104

105+
let keychains = wallet.keychains();
106+
107+
assert_eq!(keychains.len(), 1);
108+
assert_eq!(keychains[0].keychain, KeychainKind::External);
109+
let public_descriptor = keychains[0].public_descriptor.to_string();
110+
assert_eq!(
111+
public_descriptor,
112+
wallet.public_descriptor(KeychainKind::External)
113+
);
114+
assert!(keychains[0].public_descriptor.has_wildcard());
115+
assert!(!public_descriptor.contains("tprv"));
116+
72117
let address_info = wallet.reveal_next_address(KeychainKind::External);
73118

74119
assert_eq!(address_info.index, 0);

bdk-ffi/src/types.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,22 @@ impl From<BdkAddressInfo> for AddressInfo {
209209
}
210210
}
211211

212+
/// A wallet keychain and its public descriptor.
213+
#[uniffi::export(Display)]
214+
#[derive(uniffi::Record)]
215+
pub struct WalletKeychain {
216+
/// Type of keychain.
217+
pub keychain: KeychainKind,
218+
/// Public descriptor for the keychain.
219+
pub public_descriptor: Arc<Descriptor>,
220+
}
221+
222+
impl Display for WalletKeychain {
223+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224+
write!(f, "{:?}: {}", self.keychain, self.public_descriptor)
225+
}
226+
}
227+
212228
/// Balance, differentiated into various categories.
213229
#[derive(uniffi::Record)]
214230
pub struct Balance {

bdk-ffi/src/wallet.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ use crate::store::{PersistenceType, Persister};
88
use crate::types::{
99
AddressInfo, Balance, BlockId, CanonicalTx, ChangeSet, EvictedTx, FullScanRequestBuilder,
1010
KeychainAndIndex, KeychainKind, LocalOutput, Policy, SentAndReceivedValues, SignOptions,
11-
SyncRequestBuilder, UnconfirmedTx, Update, WalletEvent,
11+
SyncRequestBuilder, UnconfirmedTx, Update, WalletEvent, WalletKeychain,
1212
};
1313

1414
use bdk_wallet::bitcoin::Network;
15+
use bdk_wallet::keys::KeyMap;
1516
#[allow(deprecated)]
1617
use bdk_wallet::signer::SignOptions as BdkSignOptions;
1718
use bdk_wallet::{PersistedWallet, Wallet as BdkWallet};
@@ -424,6 +425,21 @@ impl Wallet {
424425
self.get_wallet().network()
425426
}
426427

428+
/// Iterator over all keychains in this wallet
429+
pub fn keychains(&self) -> Vec<WalletKeychain> {
430+
let wallet = self.get_wallet();
431+
wallet
432+
.keychains()
433+
.map(|(keychain, descriptor)| WalletKeychain {
434+
keychain,
435+
public_descriptor: Arc::new(Descriptor {
436+
extended_descriptor: descriptor.clone(),
437+
key_map: KeyMap::default(),
438+
}),
439+
})
440+
.collect()
441+
}
442+
427443
/// Return the balance, separated into available, trusted-pending, untrusted-pending and
428444
/// immature values.
429445
pub fn balance(&self) -> Balance {

0 commit comments

Comments
 (0)