Skip to content

Commit f71f48b

Browse files
feat: add KeyRing type
1 parent 680e66a commit f71f48b

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

wallet/src/keyring/mod.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Bitcoin Dev Kit
2+
// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
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+
mod changeset;
17+
18+
use crate::descriptor::IntoWalletDescriptor;
19+
use crate::keyring::changeset::ChangeSet;
20+
use bitcoin::secp256k1::{All, Secp256k1};
21+
use bitcoin::Network;
22+
use miniscript::{Descriptor, DescriptorPublicKey};
23+
use std::collections::BTreeMap;
24+
25+
/// KeyRing.
26+
#[derive(Debug, Clone)]
27+
pub struct KeyRing<K> {
28+
pub(crate) secp: Secp256k1<All>,
29+
pub(crate) network: Network,
30+
pub(crate) descriptors: BTreeMap<K, Descriptor<DescriptorPublicKey>>,
31+
pub(crate) default_keychain: K,
32+
}
33+
34+
impl<K> KeyRing<K>
35+
where
36+
K: Ord + Clone,
37+
{
38+
/// Construct a new [`KeyRing`] with the provided `network` and a descriptor. This descriptor
39+
/// will automatically become your default keychain. You can change your default keychain
40+
/// upon adding new ones with [`KeyRing::add_descriptor`]. Note that you cannot use a
41+
/// multipath descriptor here.
42+
pub fn new(network: Network, keychain: K, descriptor: impl IntoWalletDescriptor) -> Self {
43+
let secp = Secp256k1::new();
44+
let descriptor = descriptor
45+
.into_wallet_descriptor(&secp, network)
46+
.expect("err: invalid descriptor")
47+
.0;
48+
assert!(
49+
!descriptor.is_multipath(),
50+
"err: Use `add_multipath_descriptor` instead"
51+
);
52+
Self {
53+
secp: Secp256k1::new(),
54+
network,
55+
descriptors: BTreeMap::from([(keychain.clone(), descriptor)]),
56+
default_keychain: keychain.clone(),
57+
}
58+
}
59+
60+
/// Add a descriptor. Must not be [multipath](miniscript::Descriptor::is_multipath).
61+
pub fn add_descriptor(
62+
&mut self,
63+
keychain: K,
64+
descriptor: impl IntoWalletDescriptor,
65+
default: bool,
66+
) {
67+
let descriptor = descriptor
68+
.into_wallet_descriptor(&self.secp, self.network)
69+
.expect("err: invalid descriptor")
70+
.0;
71+
assert!(
72+
!descriptor.is_multipath(),
73+
"err: Use `add_multipath_descriptor` instead"
74+
);
75+
76+
if default {
77+
self.default_keychain = keychain.clone();
78+
}
79+
self.descriptors.insert(keychain, descriptor);
80+
}
81+
82+
/// Returns the specified default keychain on the KeyRing.
83+
pub fn default_keychain(&self) -> K {
84+
self.default_keychain.clone()
85+
}
86+
87+
/// Change the default keychain on this `KeyRing`.
88+
pub fn set_default_keychain(&mut self, keychain: K) {
89+
self.default_keychain = keychain;
90+
}
91+
92+
/// Return all keychains on this `KeyRing`.
93+
pub fn list_keychains(&self) -> &BTreeMap<K, Descriptor<DescriptorPublicKey>> {
94+
&self.descriptors
95+
}
96+
}

0 commit comments

Comments
 (0)