Skip to content

Commit e4d5b6a

Browse files
thunderbiscuit110CodingP
authored andcommitted
feat: add KeyRing type
1 parent e2cf34d commit e4d5b6a

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

src/keyring/mod.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Bitcoin Dev Kit
2+
// Written in 2020 by Alekos Filini <[email protected]>
3+
//
4+
// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
5+
//
6+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
7+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
9+
// You may not use this file except in accordance with one or both of these
10+
// licenses.
11+
12+
//! The KeyRing is a utility type used to streamline the building of wallets that handle any number
13+
//! of descriptors. It ensures descriptors are usable together, consistent with a given network,
14+
//! and will work with a BDK `Wallet`.
15+
16+
use crate::descriptor::IntoWalletDescriptor;
17+
use alloc::collections::BTreeMap;
18+
use bitcoin::secp256k1::{All, Secp256k1};
19+
use bitcoin::Network;
20+
use miniscript::{Descriptor, DescriptorPublicKey};
21+
22+
/// KeyRing.
23+
#[derive(Debug, Clone)]
24+
pub struct KeyRing<K> {
25+
pub(crate) secp: Secp256k1<All>,
26+
pub(crate) network: Network,
27+
pub(crate) descriptors: BTreeMap<K, Descriptor<DescriptorPublicKey>>,
28+
pub(crate) default_keychain: K,
29+
}
30+
31+
impl<K> KeyRing<K>
32+
where
33+
K: Ord + Clone,
34+
{
35+
/// Construct a new [`KeyRing`] with the provided `network` and a descriptor. This descriptor
36+
/// will automatically become your default keychain. You can change your default keychain
37+
/// upon adding new ones with [`KeyRing::add_descriptor`]. Note that you cannot use a
38+
/// multipath descriptor here.
39+
pub fn new(network: Network, keychain: K, descriptor: impl IntoWalletDescriptor) -> Self {
40+
let secp = Secp256k1::new();
41+
let descriptor = descriptor
42+
.into_wallet_descriptor(&secp, network)
43+
.expect("err: invalid descriptor")
44+
.0;
45+
assert!(
46+
!descriptor.is_multipath(),
47+
"err: Use `add_multipath_descriptor` instead"
48+
);
49+
Self {
50+
secp: Secp256k1::new(),
51+
network,
52+
descriptors: BTreeMap::from([(keychain.clone(), descriptor)]),
53+
default_keychain: keychain.clone(),
54+
}
55+
}
56+
57+
/// Add a descriptor. Must not be [multipath](miniscript::Descriptor::is_multipath).
58+
pub fn add_descriptor(
59+
&mut self,
60+
keychain: K,
61+
descriptor: impl IntoWalletDescriptor,
62+
default: bool,
63+
) {
64+
let descriptor = descriptor
65+
.into_wallet_descriptor(&self.secp, self.network)
66+
.expect("err: invalid descriptor")
67+
.0;
68+
assert!(
69+
!descriptor.is_multipath(),
70+
"err: Use `add_multipath_descriptor` instead"
71+
);
72+
73+
if default {
74+
self.default_keychain = keychain.clone();
75+
}
76+
self.descriptors.insert(keychain, descriptor);
77+
}
78+
79+
/// Returns the specified default keychain on the KeyRing.
80+
pub fn default_keychain(&self) -> K {
81+
self.default_keychain.clone()
82+
}
83+
84+
/// Change the default keychain on this `KeyRing`.
85+
pub fn set_default_keychain(&mut self, keychain: K) {
86+
self.default_keychain = keychain;
87+
}
88+
89+
/// Return all keychains on this `KeyRing`.
90+
pub fn list_keychains(&self) -> &BTreeMap<K, Descriptor<DescriptorPublicKey>> {
91+
&self.descriptors
92+
}
93+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub extern crate serde;
2727
pub extern crate serde_json;
2828

2929
pub mod descriptor;
30+
pub mod keyring;
3031
pub mod keys;
3132
pub mod psbt;
3233
#[cfg(feature = "test-utils")]

0 commit comments

Comments
 (0)