Skip to content

Commit

Permalink
add wallet type
Browse files Browse the repository at this point in the history
  • Loading branch information
reez committed Sep 29, 2023
1 parent acb29ce commit 0cfd63b
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 1 deletion.
33 changes: 33 additions & 0 deletions bdk-ffi/src/bdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,37 @@ interface Descriptor {
string as_string();

string as_string_private();
};


interface Wallet {
[Throws=BdkError]
constructor(Descriptor descriptor, Descriptor? change_descriptor, Network network, WalletType wallet_type);

AddressInfo get_address(AddressIndex address_index);
};

enum WalletType {
"Memory",
"FlatFile",
};

interface Address {
[Throws=BdkError]
constructor(string address, Network network);

string as_string();
};

dictionary AddressInfo {
u32 index;
Address address;
KeychainKind keychain;
};

[Enum]
interface AddressIndex {
New();
LastUnused();
Peek(u32 index);
};
100 changes: 100 additions & 0 deletions bdk-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,106 @@ use crate::keys::DescriptorSecretKey;
// inner: BdkAddress,
// }
//

use std::sync::Arc;

use bdk::bitcoin::Address as BdkAddress;
use bdk::wallet::AddressIndex as BdkAddressIndex;
use bdk::wallet::AddressInfo as BdkAddressInfo;
use bdk::bitcoin::address::{NetworkChecked, NetworkUnchecked};
use crate::wallet::Wallet;
use crate::wallet::WalletType;
/// A derived address and the index it was found at.
pub struct AddressInfo {
/// Child index of this address.
pub index: u32,
/// Address.
pub address: Arc<Address>,
/// Type of keychain.
pub keychain: KeychainKind,
}


impl From<BdkAddressInfo> for AddressInfo {
fn from(address_info: BdkAddressInfo) -> Self {
AddressInfo {
index: address_info.index,
address: Arc::new(address_info.address.into()),
keychain: address_info.keychain,
}
}
}

/// The address index selection strategy to use to derived an address from the wallet's external
/// descriptor.
pub enum AddressIndex {
/// Return a new address after incrementing the current descriptor index.
New,
/// Return the address for the current descriptor index if it has not been used in a received
/// transaction. Otherwise return a new address as with AddressIndex::New.
/// Use with caution, if the wallet has not yet detected an address has been used it could
/// return an already used address. This function is primarily meant for situations where the
/// caller is untrusted; for example when deriving donation addresses on-demand for a public
/// web page.
LastUnused,
/// Return the address for a specific descriptor index. Does not change the current descriptor
/// index used by `AddressIndex::New` and `AddressIndex::LastUsed`.
/// Use with caution, if an index is given that is less than the current descriptor index
/// then the returned address may have already been used.
Peek { index: u32 },
}

impl From<AddressIndex> for BdkAddressIndex {
fn from(address_index: AddressIndex) -> Self {
match address_index {
AddressIndex::New => BdkAddressIndex::New,
AddressIndex::LastUnused => BdkAddressIndex::LastUnused,
AddressIndex::Peek { index } => BdkAddressIndex::Peek(index),
}
}
}

/// A Bitcoin address.
#[derive(Debug, PartialEq, Eq)]
pub struct Address {
inner: BdkAddress<NetworkChecked>,
}


impl Address {
fn new(
address: String,
network: Network,
) -> Result<Self, BdkError> {
Ok(Address {
inner: address
.parse::<bdk::bitcoin::Address<NetworkUnchecked>>()
.unwrap() // TODO 7: Handle error correctly by rethrowing it as a BdkError
.require_network(network.into())
.map_err(|e| BdkError::Generic(e.to_string()))?,
})
}
fn to_qr_uri(&self) -> String {
self.inner.to_qr_uri()
}

fn as_string(&self) -> String {
self.inner.to_string()
}
}

impl From<BdkAddress> for Address {
fn from(address: BdkAddress) -> Self {
Address { inner: address }
}
}

impl From<Address> for BdkAddress {
fn from(address: Address) -> Self {
address.inner
}
}

// impl Address {
// fn new(address: String) -> Result<Self, BdkError> {
// BdkAddress::from_str(address.as_str())
Expand Down
53 changes: 52 additions & 1 deletion bdk-ffi/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
// RbfValue, Script, ScriptAmount, TransactionDetails, TxBuilderResult,
// };
//
use crate::BdkError;
// #[derive(Debug)]
// pub(crate) struct Wallet {
// pub(crate) inner_mutex: Mutex<BdkWallet<AnyDatabase>>,
Expand Down Expand Up @@ -858,3 +857,55 @@ use crate::BdkError;
// assert_matches!(is_mine_2, false);
// }
// }
use std::sync::{Arc, Mutex, MutexGuard};
use bdk::Wallet as BdkWallet;
use crate::descriptor::Descriptor;
use crate::{AddressIndex, AddressInfo, Network};
use bdk::wallet::AddressIndex as BdkAddressIndex;
use bdk::Error as BdkError;
pub enum WalletType {
Memory,
FlatFile,
}

pub(crate) struct Wallet {
pub(crate) inner_mutex: Mutex<BdkWallet>,
}

impl Wallet {
pub fn new(
descriptor: Arc<Descriptor>,
change_descriptor: Option<Arc<Descriptor>>,
network: Network,
wallet_type: WalletType,
) -> Result<Self, BdkError> {
let descriptor = descriptor.as_string_private();
let change_descriptor = change_descriptor.map(|d| d.as_string_private());

match wallet_type {
WalletType::Memory => {
let wallet = BdkWallet::new_no_persist(
&descriptor,
change_descriptor.as_ref(),
network.into(),
)?;
Ok(Wallet {
inner_mutex: Mutex::new(wallet),
})
}
WalletType::FlatFile => {
panic!("FlatFile wallet type not yet implemented")
}
}
}

pub fn get_address(&self, address_index: AddressIndex) -> AddressInfo {
self.get_wallet().get_address(address_index.into()).into()
}

// TODO 10: Do we need this mutex
pub(crate) fn get_wallet(&self) -> MutexGuard<BdkWallet> {
self.inner_mutex.lock().expect("wallet")
}

}

0 comments on commit 0cfd63b

Please sign in to comment.