Skip to content

Commit

Permalink
Merge bitcoindevkit#1533: [wallet] Enable support for single descript…
Browse files Browse the repository at this point in the history
…or wallets

13e7008 doc(wallet): clarify docs for `Wallet::load` (valued mammal)
3951110 fix(wallet)!: Change method `LoadParams::descriptors` (valued mammal)
b802714 example(wallet): simplify miniscript compiler example (valued mammal)
2ca8b6f test(wallet): Add tests for single descriptor wallet (valued mammal)
31f1c2d fix(wallet): Change FromSql type to `Option<_>` (valued mammal)
75155b7 feat(wallet): Add method `Wallet::create_single` (valued mammal)

Pull request description:

  The change descriptor is made optional, making this an effective reversion of bitcoindevkit#1390 and enables creating wallets with a single descriptor.

  fixes bitcoindevkit#1511

  ### Notes to the reviewers

  PR 1390 also removed an error case [`ChangePolicyDescriptor`](https://github.com/bitcoindevkit/bdk/blob/8eef350bd08057acc39b6fc50b1217db5e29b968/crates/wallet/src/wallet/mod.rs#L1529-L1533) and this can possibly be added back. In the case the wallet only has a single descriptor we allow any utxos to fund a tx that aren't specifically marked unspendable regardless of the change spend policy.

  ### Changelog notice

  * Added method `Wallet::create_single` that expects a single `D: IntoWalletDescriptor` as input and enables building a wallet with no internal keychain.

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  #### New Features:

  * [x] This pull request breaks the existing API
  * [x] I've added tests for the new feature
  * [x] I've added docs for the new feature

ACKs for top commit:
  evanlinjin:
    ACK 13e7008

Tree-SHA512: 3e6fe5d9165d62332ac1863ec769c4bc5c7cd3c7f3fbdb8f505906bcdc681fa73b3fef2571adb0e52e9a23d4257f66a6145838b90ec68596b5f4c64054a047fa
  • Loading branch information
evanlinjin committed Aug 14, 2024
2 parents 74b24d3 + 13e7008 commit 76aec62
Show file tree
Hide file tree
Showing 12 changed files with 417 additions and 151 deletions.
7 changes: 7 additions & 0 deletions crates/chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ pub type KeychainIndexed<K, T> = ((K, u32), T);
/// A wrapper that we use to impl remote traits for types in our crate or dependency crates.
pub struct Impl<T>(pub T);

impl<T> Impl<T> {
/// Returns the inner `T`.
pub fn into_inner(self) -> T {
self.0
}
}

impl<T> From<T> for Impl<T> {
fn from(value: T) -> Self {
Self(value)
Expand Down
4 changes: 3 additions & 1 deletion crates/wallet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,10 @@ let network = Network::Testnet;
let descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/0/*)";
let change_descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/1/*)";
let wallet_opt = Wallet::load()
.descriptors(descriptor, change_descriptor)
.network(network)
.descriptor(KeychainKind::External, Some(descriptor))
.descriptor(KeychainKind::Internal, Some(change_descriptor))
.extract_keys()
.load_wallet(&mut db)
.expect("wallet");
let mut wallet = match wallet_opt {
Expand Down
22 changes: 1 addition & 21 deletions crates/wallet/examples/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,28 +56,8 @@ fn main() -> Result<(), Box<dyn Error>> {

println!("Compiled into Descriptor: \n{}", descriptor);

// Do the same for another (internal) keychain
let policy_str = "or(
10@thresh(2,
pk(029ffbe722b147f3035c87cb1c60b9a5947dd49c774cc31e94773478711a929ac0),pk(025f05815e3a1a8a83bfbb03ce016c9a2ee31066b98f567f6227df1d76ec4bd143),pk(025625f41e4a065efc06d5019cbbd56fe8c07595af1231e7cbc03fafb87ebb71ec)
),1@and(
pk(03deae92101c790b12653231439f27b8897264125ecb2f46f48278603102573165),
older(12960)
)
)"
.replace(&[' ', '\n', '\t'][..], "");

println!("Compiling internal policy: \n{}", policy_str);

let policy = Concrete::<String>::from_str(&policy_str)?;
let internal_descriptor = Descriptor::new_wsh(policy.compile()?)?.to_string();
println!(
"Compiled into internal Descriptor: \n{}",
internal_descriptor
);

// Create a new wallet from descriptors
let mut wallet = Wallet::create(descriptor, internal_descriptor)
let mut wallet = Wallet::create_single(descriptor)
.network(Network::Regtest)
.create_wallet_no_persist()?;

Expand Down
16 changes: 9 additions & 7 deletions crates/wallet/src/wallet/changeset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,18 @@ impl ChangeSet {
let row = wallet_statement
.query_row([], |row| {
Ok((
row.get::<_, Impl<Descriptor<DescriptorPublicKey>>>("descriptor")?,
row.get::<_, Impl<Descriptor<DescriptorPublicKey>>>("change_descriptor")?,
row.get::<_, Impl<bitcoin::Network>>("network")?,
row.get::<_, Option<Impl<Descriptor<DescriptorPublicKey>>>>("descriptor")?,
row.get::<_, Option<Impl<Descriptor<DescriptorPublicKey>>>>(
"change_descriptor",
)?,
row.get::<_, Option<Impl<bitcoin::Network>>>("network")?,
))
})
.optional()?;
if let Some((Impl(desc), Impl(change_desc), Impl(network))) = row {
changeset.descriptor = Some(desc);
changeset.change_descriptor = Some(change_desc);
changeset.network = Some(network);
if let Some((desc, change_desc, network)) = row {
changeset.descriptor = desc.map(Impl::into_inner);
changeset.change_descriptor = change_desc.map(Impl::into_inner);
changeset.network = network.map(Impl::into_inner);
}

changeset.local_chain = local_chain::ChangeSet::from_sqlite(db_tx)?;
Expand Down
Loading

0 comments on commit 76aec62

Please sign in to comment.