Skip to content

Commit 5e0c36a

Browse files
committed
impl wallet no persist
1 parent 81c8bdb commit 5e0c36a

File tree

3 files changed

+170
-110
lines changed

3 files changed

+170
-110
lines changed

bdk-ffi/src/bdk.udl

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,8 @@ interface Wallet {
377377
[Name=create, Throws=FfiGenericError]
378378
constructor(Descriptor descriptor, Descriptor change_descriptor, Network network, Connection connection);
379379

380-
// [Name=load, Throws=FfiGenericError]
381-
// constructor(Descriptor descriptor, Descriptor change_descriptor, Network network, Connection connection);
380+
[Name=load, Throws=FfiGenericError]
381+
constructor(Descriptor descriptor, Descriptor change_descriptor, Connection connection);
382382

383383
AddressInfo reveal_next_address(KeychainKind keychain);
384384

@@ -418,6 +418,46 @@ interface Wallet {
418418
boolean persist(Connection connection);
419419
};
420420

421+
interface WalletNoPersist {
422+
[Name=create, Throws=FfiGenericError]
423+
constructor(Descriptor descriptor, Descriptor change_descriptor, Network network);
424+
425+
AddressInfo reveal_next_address(KeychainKind keychain);
426+
427+
Network network();
428+
429+
Balance balance();
430+
431+
[Throws=CannotConnectError]
432+
void apply_update(Update update);
433+
434+
boolean is_mine(Script script);
435+
436+
[Throws=SignerError]
437+
boolean sign(Psbt psbt);
438+
439+
SentAndReceivedValues sent_and_received([ByRef] Transaction tx);
440+
441+
sequence<CanonicalTx> transactions();
442+
443+
[Throws=TxidParseError]
444+
CanonicalTx? get_tx(string txid);
445+
446+
[Throws=CalculateFeeError]
447+
Amount calculate_fee([ByRef] Transaction tx);
448+
449+
[Throws=CalculateFeeError]
450+
FeeRate calculate_fee_rate([ByRef] Transaction tx);
451+
452+
sequence<LocalOutput> list_unspent();
453+
454+
sequence<LocalOutput> list_output();
455+
456+
FullScanRequest start_full_scan();
457+
458+
SyncRequest start_sync_with_revealed_spks();
459+
};
460+
421461
interface Update {};
422462

423463
interface TxBuilder {

bdk-ffi/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ use crate::wallet::SentAndReceivedValues;
6565
use crate::wallet::TxBuilder;
6666
use crate::wallet::Update;
6767
use crate::wallet::Wallet;
68+
use crate::wallet::WalletNoPersist;
6869
use crate::error::FfiGenericError;
6970

7071
use bdk_wallet::bitcoin::Network;

bdk-ffi/src/wallet.rs

Lines changed: 127 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use bdk_wallet::Wallet as BdkWallet;
2222
use bdk_wallet::{KeychainKind, SignOptions};
2323
use bdk_wallet::Update as BdkUpdate;
2424
use bdk_wallet::rusqlite::Connection as BdkConnection;
25-
use bdk_wallet::TxBuilder as BdkTxBuilder;
2625

2726
use std::collections::HashSet;
2827
use std::str::FromStr;
@@ -63,18 +62,20 @@ impl Wallet {
6362
pub fn load(
6463
descriptor: Arc<Descriptor>,
6564
change_descriptor: Arc<Descriptor>,
66-
connection: Connection,
67-
) -> Result<Option<Wallet>, FfiGenericError> {
65+
connection: Arc<Connection>,
66+
) -> Result<Wallet, FfiGenericError> {
6867
let descriptor = descriptor.to_string_with_secret();
6968
let change_descriptor = change_descriptor.to_string_with_secret();
7069
let mut binding = connection.get_store();
7170
let db: &mut BdkConnection = binding.borrow_mut();
7271

73-
let wallet: Option<Persisted<BdkWallet>> = BdkWallet::load()
72+
let wallet: Persisted<BdkWallet> = BdkWallet::load()
7473
.descriptors(descriptor, change_descriptor)
75-
.load_wallet(db)?;
74+
.load_wallet(db).map_err(|_| FfiGenericError::GenericError)
75+
.unwrap()
76+
.ok_or(FfiGenericError::GenericError)?;
7677

77-
Some(Wallet {
78+
Ok(Wallet {
7879
inner_mutex: Mutex::new(wallet),
7980
})
8081
}
@@ -83,104 +84,138 @@ impl Wallet {
8384
self.inner_mutex.lock().expect("wallet")
8485
}
8586

86-
pub fn reveal_next_address(&self, keychain_kind: KeychainKind) -> AddressInfo {
87-
self.get_wallet().reveal_next_address(keychain_kind).into()
88-
}
89-
90-
pub fn apply_update(&self, update: Arc<Update>) -> Result<(), CannotConnectError> {
87+
// pub fn persist(&self, connection: Connection) -> Result<bool, FfiGenericError> {
88+
pub fn persist(&self, connection: Arc<Connection>) -> bool {
89+
let mut binding = connection.get_store();
90+
let db: &mut BdkConnection = binding.borrow_mut();
9191
self.get_wallet()
92-
.apply_update(update.0.clone())
93-
.map_err(CannotConnectError::from)
92+
.persist(db)
93+
.expect("persist failed")
9494
}
95+
}
9596

96-
pub fn network(&self) -> Network {
97-
self.get_wallet().network()
98-
}
97+
impl WalletNoPersist {
98+
pub fn create(
99+
descriptor: Arc<Descriptor>,
100+
change_descriptor: Arc<Descriptor>,
101+
network: Network,
102+
) -> Result<Self, FfiGenericError> {
103+
// ) -> Result<Self, WalletCreationError> {
104+
let descriptor = descriptor.to_string_with_secret();
105+
let change_descriptor = change_descriptor.to_string_with_secret();
99106

100-
pub fn balance(&self) -> Balance {
101-
let bdk_balance = self.get_wallet().balance();
102-
Balance::from(bdk_balance)
103-
}
107+
let wallet: BdkWallet = BdkWallet::create(descriptor, change_descriptor)
108+
.network(network)
109+
.create_wallet_no_persist()
110+
.expect("wallet creation failed");
104111

105-
pub fn is_mine(&self, script: Arc<Script>) -> bool {
106-
self.get_wallet().is_mine(script.0.clone())
112+
Ok(WalletNoPersist {
113+
inner_mutex: Mutex::new(wallet),
114+
})
107115
}
108116

109-
pub(crate) fn sign(
110-
&self,
111-
psbt: Arc<Psbt>,
112-
// sign_options: Option<SignOptions>,
113-
) -> Result<bool, SignerError> {
114-
let mut psbt = psbt.0.lock().unwrap();
115-
self.get_wallet()
116-
.sign(&mut psbt, SignOptions::default())
117-
.map_err(SignerError::from)
117+
pub(crate) fn get_wallet(&self) -> MutexGuard<BdkWallet> {
118+
self.inner_mutex.lock().expect("wallet")
118119
}
120+
}
119121

120-
pub fn sent_and_received(&self, tx: &Transaction) -> SentAndReceivedValues {
121-
let (sent, received) = self.get_wallet().sent_and_received(&tx.into());
122-
SentAndReceivedValues {
123-
sent: Arc::new(sent.into()),
124-
received: Arc::new(received.into()),
122+
macro_rules! impl_wallet {
123+
($w:ident) => {
124+
impl $w {
125+
pub fn reveal_next_address(&self, keychain_kind: KeychainKind) -> AddressInfo {
126+
self.get_wallet().reveal_next_address(keychain_kind).into()
127+
}
128+
129+
pub fn apply_update(&self, update: Arc<Update>) -> Result<(), CannotConnectError> {
130+
self.get_wallet()
131+
.apply_update(update.0.clone())
132+
.map_err(CannotConnectError::from)
133+
}
134+
135+
pub fn network(&self) -> Network {
136+
self.get_wallet().network()
137+
}
138+
139+
pub fn balance(&self) -> Balance {
140+
let bdk_balance = self.get_wallet().balance();
141+
Balance::from(bdk_balance)
142+
}
143+
144+
pub fn is_mine(&self, script: Arc<Script>) -> bool {
145+
self.get_wallet().is_mine(script.0.clone())
146+
}
147+
148+
pub(crate) fn sign(
149+
&self,
150+
psbt: Arc<Psbt>,
151+
// sign_options: Option<SignOptions>,
152+
) -> Result<bool, SignerError> {
153+
let mut psbt = psbt.0.lock().unwrap();
154+
self.get_wallet()
155+
.sign(&mut psbt, SignOptions::default())
156+
.map_err(SignerError::from)
157+
}
158+
159+
pub fn sent_and_received(&self, tx: &Transaction) -> SentAndReceivedValues {
160+
let (sent, received) = self.get_wallet().sent_and_received(&tx.into());
161+
SentAndReceivedValues {
162+
sent: Arc::new(sent.into()),
163+
received: Arc::new(received.into()),
164+
}
165+
}
166+
167+
pub fn transactions(&self) -> Vec<CanonicalTx> {
168+
self.get_wallet()
169+
.transactions()
170+
.map(|tx| tx.into())
171+
.collect()
172+
}
173+
174+
pub fn get_tx(&self, txid: String) -> Result<Option<CanonicalTx>, TxidParseError> {
175+
let txid =
176+
Txid::from_str(txid.as_str()).map_err(|_| TxidParseError::InvalidTxid { txid })?;
177+
Ok(self.get_wallet().get_tx(txid).map(|tx| tx.into()))
178+
}
179+
180+
pub fn calculate_fee(&self, tx: &Transaction) -> Result<Arc<Amount>, CalculateFeeError> {
181+
self.get_wallet()
182+
.calculate_fee(&tx.into())
183+
.map(Amount::from)
184+
.map(Arc::new)
185+
.map_err(|e| e.into())
186+
}
187+
188+
pub fn calculate_fee_rate(&self, tx: &Transaction) -> Result<Arc<FeeRate>, CalculateFeeError> {
189+
self.get_wallet()
190+
.calculate_fee_rate(&tx.into())
191+
.map(|bdk_fee_rate| Arc::new(FeeRate(bdk_fee_rate)))
192+
.map_err(|e| e.into())
193+
}
194+
195+
pub fn list_unspent(&self) -> Vec<LocalOutput> {
196+
self.get_wallet().list_unspent().map(|o| o.into()).collect()
197+
}
198+
199+
pub fn list_output(&self) -> Vec<LocalOutput> {
200+
self.get_wallet().list_output().map(|o| o.into()).collect()
201+
}
202+
203+
pub fn start_full_scan(&self) -> Arc<FullScanRequest> {
204+
let request = self.get_wallet().start_full_scan();
205+
Arc::new(FullScanRequest(Mutex::new(Some(request))))
206+
}
207+
208+
pub fn start_sync_with_revealed_spks(&self) -> Arc<SyncRequest> {
209+
let request = self.get_wallet().start_sync_with_revealed_spks();
210+
Arc::new(SyncRequest(Mutex::new(Some(request))))
211+
}
125212
}
126-
}
127-
128-
pub fn transactions(&self) -> Vec<CanonicalTx> {
129-
self.get_wallet()
130-
.transactions()
131-
.map(|tx| tx.into())
132-
.collect()
133-
}
134-
135-
pub fn get_tx(&self, txid: String) -> Result<Option<CanonicalTx>, TxidParseError> {
136-
let txid =
137-
Txid::from_str(txid.as_str()).map_err(|_| TxidParseError::InvalidTxid { txid })?;
138-
Ok(self.get_wallet().get_tx(txid).map(|tx| tx.into()))
139-
}
140-
141-
pub fn calculate_fee(&self, tx: &Transaction) -> Result<Arc<Amount>, CalculateFeeError> {
142-
self.get_wallet()
143-
.calculate_fee(&tx.into())
144-
.map(Amount::from)
145-
.map(Arc::new)
146-
.map_err(|e| e.into())
147-
}
148-
149-
pub fn calculate_fee_rate(&self, tx: &Transaction) -> Result<Arc<FeeRate>, CalculateFeeError> {
150-
self.get_wallet()
151-
.calculate_fee_rate(&tx.into())
152-
.map(|bdk_fee_rate| Arc::new(FeeRate(bdk_fee_rate)))
153-
.map_err(|e| e.into())
154-
}
155-
156-
pub fn list_unspent(&self) -> Vec<LocalOutput> {
157-
self.get_wallet().list_unspent().map(|o| o.into()).collect()
158-
}
159-
160-
pub fn list_output(&self) -> Vec<LocalOutput> {
161-
self.get_wallet().list_output().map(|o| o.into()).collect()
162-
}
163-
164-
pub fn start_full_scan(&self) -> Arc<FullScanRequest> {
165-
let request = self.get_wallet().start_full_scan();
166-
Arc::new(FullScanRequest(Mutex::new(Some(request))))
167-
}
168-
169-
pub fn start_sync_with_revealed_spks(&self) -> Arc<SyncRequest> {
170-
let request = self.get_wallet().start_sync_with_revealed_spks();
171-
Arc::new(SyncRequest(Mutex::new(Some(request))))
172-
}
173-
174-
// pub fn persist(&self, connection: Connection) -> Result<bool, FfiGenericError> {
175-
pub fn persist(&self, connection: Arc<Connection>) -> bool {
176-
// self.get_wallet().persist(connection.get_store())
177-
// self.get_wallet().persist(connection.get_store()).map_err(FfiGenericError::GenericError)
178-
self.get_wallet()
179-
.persist(&mut *connection.get_store())
180-
.expect("persist failed")
181-
}
213+
};
182214
}
183215

216+
impl_wallet!(Wallet);
217+
impl_wallet!(WalletNoPersist);
218+
184219
pub struct SentAndReceivedValues {
185220
pub sent: Arc<Amount>,
186221
pub received: Arc<Amount>,
@@ -392,22 +427,6 @@ impl TxBuilder {
392427
}
393428
}
394429

395-
// pub trait CanTxBuild: Send + Sync + 'static {
396-
// fn build_tx(&self) -> BdkTxBuilder<bdk_wallet::coin_selection::BranchAndBoundCoinSelection>;
397-
// }
398-
//
399-
// impl CanTxBuild for Wallet {
400-
// fn build_tx(&self) -> BdkTxBuilder<bdk_wallet::coin_selection::BranchAndBoundCoinSelection> {
401-
// self.get_wallet().build_tx()
402-
// }
403-
// }
404-
//
405-
// impl CanTxBuild for WalletNoPersist {
406-
// fn build_tx(&self) -> BdkTxBuilder<bdk_wallet::coin_selection::BranchAndBoundCoinSelection> {
407-
// self.get_wallet().build_tx()
408-
// }
409-
// }
410-
411430
#[derive(Clone)]
412431
pub(crate) struct BumpFeeTxBuilder {
413432
pub(crate) txid: String,

0 commit comments

Comments
 (0)