Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Commit 9bb50a5

Browse files
Check esplora after fedimint withdraw
1 parent 7c19958 commit 9bb50a5

File tree

3 files changed

+99
-12
lines changed

3 files changed

+99
-12
lines changed

mutiny-core/src/federation.rs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use bitcoin::{
2727
Address, Network, Txid,
2828
};
2929
use core::fmt;
30+
use esplora_client::AsyncClient;
3031
use fedimint_bip39::Bip39RootSecretStrategy;
3132
use fedimint_client::{
3233
derivable_secret::DerivableSecret,
@@ -194,6 +195,7 @@ pub(crate) struct FederationClient<S: MutinyStorage> {
194195
#[allow(dead_code)]
195196
fedimint_storage: FedimintStorage<S>,
196197
gateway: Arc<RwLock<Option<LightningGateway>>>,
198+
esplora: Arc<AsyncClient>,
197199
network: Network,
198200
stop: Arc<AtomicBool>,
199201
pub(crate) logger: Arc<MutinyLogger>,
@@ -206,6 +208,7 @@ impl<S: MutinyStorage> FederationClient<S> {
206208
federation_code: InviteCode,
207209
xprivkey: ExtendedPrivKey,
208210
storage: S,
211+
esplora: Arc<AsyncClient>,
209212
network: Network,
210213
stop: Arc<AtomicBool>,
211214
logger: Arc<MutinyLogger>,
@@ -335,6 +338,7 @@ impl<S: MutinyStorage> FederationClient<S> {
335338
storage,
336339
logger,
337340
invite_code: federation_code,
341+
esplora,
338342
network,
339343
stop,
340344
gateway,
@@ -421,6 +425,7 @@ impl<S: MutinyStorage> FederationClient<S> {
421425
entry,
422426
operation_id,
423427
self.fedimint_client.clone(),
428+
self.esplora.clone(),
424429
self.logger.clone(),
425430
self.stop.clone(),
426431
self.storage.clone(),
@@ -471,6 +476,7 @@ impl<S: MutinyStorage> FederationClient<S> {
471476
let fedimint_client_clone = self.fedimint_client.clone();
472477
let logger_clone = self.logger.clone();
473478
let storage_clone = self.storage.clone();
479+
let esplora_clone = self.esplora.clone();
474480
let stop = self.stop.clone();
475481
spawn(async move {
476482
let operation = fedimint_client_clone
@@ -483,6 +489,7 @@ impl<S: MutinyStorage> FederationClient<S> {
483489
operation,
484490
id,
485491
fedimint_client_clone,
492+
esplora_clone,
486493
logger_clone,
487494
stop,
488495
storage_clone,
@@ -630,6 +637,7 @@ impl<S: MutinyStorage> FederationClient<S> {
630637
let fedimint_client_clone = self.fedimint_client.clone();
631638
let logger_clone = self.logger.clone();
632639
let storage_clone = self.storage.clone();
640+
let esplora_clone = self.esplora.clone();
633641
let stop = self.stop.clone();
634642
spawn(async move {
635643
let operation = fedimint_client_clone
@@ -642,6 +650,7 @@ impl<S: MutinyStorage> FederationClient<S> {
642650
operation,
643651
id,
644652
fedimint_client_clone,
653+
esplora_clone,
645654
logger_clone,
646655
stop,
647656
storage_clone,
@@ -708,6 +717,7 @@ impl<S: MutinyStorage> FederationClient<S> {
708717
op_id,
709718
self.fedimint_client.clone(),
710719
self.storage.clone(),
720+
self.esplora.clone(),
711721
Some(DEFAULT_PAYMENT_TIMEOUT * 1_000),
712722
self.stop.clone(),
713723
)
@@ -809,6 +819,7 @@ fn subscribe_operation_ext<S: MutinyStorage>(
809819
entry: OperationLogEntry,
810820
operation_id: OperationId,
811821
fedimint_client: ClientHandleArc,
822+
esplora: Arc<AsyncClient>,
812823
logger: Arc<MutinyLogger>,
813824
stop: Arc<AtomicBool>,
814825
storage: S,
@@ -820,6 +831,7 @@ fn subscribe_operation_ext<S: MutinyStorage>(
820831
operation_id,
821832
fedimint_client,
822833
storage,
834+
esplora,
823835
None,
824836
stop,
825837
)
@@ -940,6 +952,7 @@ async fn process_operation_until_timeout<S: MutinyStorage>(
940952
operation_id: OperationId,
941953
fedimint_client: ClientHandleArc,
942954
storage: S,
955+
esplora: Arc<AsyncClient>,
943956
timeout: Option<u64>,
944957
stop: Arc<AtomicBool>,
945958
) {
@@ -1073,6 +1086,7 @@ async fn process_operation_until_timeout<S: MutinyStorage>(
10731086
fee.amount(),
10741087
operation_id,
10751088
storage,
1089+
esplora,
10761090
timeout,
10771091
stop,
10781092
logger,
@@ -1206,6 +1220,7 @@ async fn process_onchain_withdraw_outcome<S: MutinyStorage>(
12061220
fee: fedimint_ln_common::bitcoin::Amount,
12071221
operation_id: OperationId,
12081222
storage: S,
1223+
esplora: Arc<AsyncClient>,
12091224
timeout: Option<u64>,
12101225
stop: Arc<AtomicBool>,
12111226
logger: Arc<MutinyLogger>,
@@ -1268,8 +1283,10 @@ async fn process_onchain_withdraw_outcome<S: MutinyStorage>(
12681283
},
12691284
}
12701285

1271-
// TODO we need to get confirmations for this txid and update
1272-
break;
1286+
// we need to get confirmations for this txid and update
1287+
subscribe_onchain_confirmation_check(storage.clone(), esplora.clone(), txid, updated_transaction_details, stop, logger.clone()).await;
1288+
1289+
break
12731290
},
12741291
WithdrawState::Failed(e) => {
12751292
// TODO delete
@@ -1299,6 +1316,49 @@ async fn process_onchain_withdraw_outcome<S: MutinyStorage>(
12991316
}
13001317
}
13011318

1319+
async fn subscribe_onchain_confirmation_check<S: MutinyStorage>(
1320+
storage: S,
1321+
esplora: Arc<AsyncClient>,
1322+
txid: Txid,
1323+
mut transaction_details: TransactionDetails,
1324+
stop: Arc<AtomicBool>,
1325+
logger: Arc<MutinyLogger>,
1326+
) {
1327+
spawn(async move {
1328+
loop {
1329+
if stop.load(Ordering::Relaxed) {
1330+
break;
1331+
};
1332+
1333+
match esplora.get_tx_status(&txid).await {
1334+
Ok(s) => {
1335+
if s.confirmed {
1336+
log_info!(logger, "Transaction confirmed");
1337+
transaction_details.confirmation_time = ConfirmationTime::Confirmed {
1338+
height: s.block_height.expect("confirmed"),
1339+
time: now().as_secs(),
1340+
};
1341+
match persist_transaction_details(&storage, &transaction_details) {
1342+
Ok(_) => {
1343+
log_info!(logger, "Transaction updated");
1344+
break;
1345+
}
1346+
Err(e) => {
1347+
log_error!(logger, "Error updating transaction: {e}");
1348+
}
1349+
}
1350+
}
1351+
}
1352+
Err(e) => {
1353+
log_error!(logger, "Error updating transaction: {e}");
1354+
}
1355+
}
1356+
1357+
sleep(5_000).await;
1358+
}
1359+
});
1360+
}
1361+
13021362
async fn process_onchain_deposit_outcome<S: MutinyStorage>(
13031363
stream_or_outcome: UpdateStreamOrOutcome<fedimint_wallet_client::DepositState>,
13041364
original_transaction_details: Option<TransactionDetails>,

mutiny-core/src/lib.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,6 @@ mod test_utils;
4646
pub use crate::gossip::{GOSSIP_SYNC_TIME_KEY, NETWORK_GRAPH_KEY, PROB_SCORER_KEY};
4747
pub use crate::keymanager::generate_seed;
4848
pub use crate::ldkstorage::{CHANNEL_CLOSURE_PREFIX, CHANNEL_MANAGER_KEY, MONITORS_PREFIX_KEY};
49-
use crate::storage::{
50-
get_payment_hash_from_key, get_transaction_details, list_payment_info, persist_payment_info,
51-
update_nostr_contact_list, IndexItem, MutinyStorage, DEVICE_ID_KEY, EXPECTED_NETWORK_KEY,
52-
NEED_FULL_SYNC_KEY, ONCHAIN_PREFIX, PAYMENT_INBOUND_PREFIX_KEY, PAYMENT_OUTBOUND_PREFIX_KEY,
53-
SUBSCRIPTION_TIMESTAMP, TRANSACTION_DETAILS_PREFIX_KEY,
54-
};
5549
use crate::utils::spawn;
5650
use crate::{auth::MutinyAuthClient, hermes::HermesClient, logging::MutinyLogger};
5751
use crate::{blindauth::BlindAuthClient, cashu::CashuHttpClient};
@@ -83,6 +77,15 @@ use crate::{
8377
storage::get_invoice_by_hash,
8478
};
8579
use crate::{nostr::NostrManager, utils::sleep};
80+
use crate::{
81+
onchain::get_esplora_url,
82+
storage::{
83+
get_payment_hash_from_key, get_transaction_details, list_payment_info,
84+
persist_payment_info, update_nostr_contact_list, IndexItem, MutinyStorage, DEVICE_ID_KEY,
85+
EXPECTED_NETWORK_KEY, NEED_FULL_SYNC_KEY, ONCHAIN_PREFIX, PAYMENT_INBOUND_PREFIX_KEY,
86+
PAYMENT_OUTBOUND_PREFIX_KEY, SUBSCRIPTION_TIMESTAMP, TRANSACTION_DETAILS_PREFIX_KEY,
87+
},
88+
};
8689
use ::nostr::nips::nip47::Method;
8790
use ::nostr::nips::nip57;
8891
#[cfg(target_arch = "wasm32")]
@@ -101,6 +104,7 @@ use bitcoin::{
101104
use bitcoin::{bip32::ExtendedPrivKey, Transaction};
102105
use bitcoin::{hashes::sha256, Network, Txid};
103106
use bitcoin::{hashes::Hash, Address};
107+
use esplora_client::AsyncClient;
104108
use fedimint_core::{api::InviteCode, config::FederationId};
105109
use futures::{pin_mut, select, FutureExt};
106110
use futures_util::join;
@@ -924,11 +928,16 @@ impl<S: MutinyStorage> MutinyWalletBuilder<S> {
924928
}
925929
});
926930

931+
let esplora_server_url = get_esplora_url(network, config.user_esplora_url.clone());
932+
let esplora = esplora_client::Builder::new(&esplora_server_url).build_async()?;
933+
let esplora = Arc::new(esplora);
934+
927935
let start = Instant::now();
928936

929937
let mut nm_builder = NodeManagerBuilder::new(self.xprivkey, self.storage.clone())
930938
.with_config(config.clone());
931939
nm_builder.with_logger(logger.clone());
940+
nm_builder.with_esplora(esplora.clone());
932941
let node_manager = Arc::new(nm_builder.build().await?);
933942

934943
log_trace!(
@@ -976,6 +985,7 @@ impl<S: MutinyStorage> MutinyWalletBuilder<S> {
976985
federation_storage.clone(),
977986
&config,
978987
self.storage.clone(),
988+
esplora.clone(),
979989
stop.clone(),
980990
&logger,
981991
)
@@ -1164,6 +1174,7 @@ impl<S: MutinyStorage> MutinyWalletBuilder<S> {
11641174
subscription_client,
11651175
blind_auth_client,
11661176
hermes_client,
1177+
esplora,
11671178
auth,
11681179
stop,
11691180
logger,
@@ -1236,6 +1247,7 @@ pub struct MutinyWallet<S: MutinyStorage> {
12361247
subscription_client: Option<Arc<MutinySubscriptionClient>>,
12371248
blind_auth_client: Option<Arc<BlindAuthClient<S>>>,
12381249
hermes_client: Option<Arc<HermesClient<S>>>,
1250+
esplora: Arc<AsyncClient>,
12391251
pub stop: Arc<AtomicBool>,
12401252
pub logger: Arc<MutinyLogger>,
12411253
network: Network,
@@ -2623,6 +2635,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
26232635
self.federation_storage.clone(),
26242636
self.federations.clone(),
26252637
self.hermes_client.clone(),
2638+
self.esplora.clone(),
26262639
federation_code,
26272640
self.stop.clone(),
26282641
)
@@ -3280,6 +3293,7 @@ async fn create_federations<S: MutinyStorage>(
32803293
federation_storage: FederationStorage,
32813294
c: &MutinyWalletConfig,
32823295
storage: S,
3296+
esplora: Arc<AsyncClient>,
32833297
stop: Arc<AtomicBool>,
32843298
logger: &Arc<MutinyLogger>,
32853299
) -> Result<Arc<RwLock<HashMap<FederationId, Arc<FederationClient<S>>>>>, MutinyError> {
@@ -3290,6 +3304,7 @@ async fn create_federations<S: MutinyStorage>(
32903304
federation_index.federation_code,
32913305
c.xprivkey,
32923306
storage.clone(),
3307+
esplora.clone(),
32933308
c.network,
32943309
stop.clone(),
32953310
logger.clone(),
@@ -3314,6 +3329,7 @@ pub(crate) async fn create_new_federation<S: MutinyStorage>(
33143329
federation_storage: Arc<RwLock<FederationStorage>>,
33153330
federations: Arc<RwLock<HashMap<FederationId, Arc<FederationClient<S>>>>>,
33163331
hermes_client: Option<Arc<HermesClient<S>>>,
3332+
esplora: Arc<AsyncClient>,
33173333
federation_code: InviteCode,
33183334
stop: Arc<AtomicBool>,
33193335
) -> Result<FederationIdentity, MutinyError> {
@@ -3343,6 +3359,7 @@ pub(crate) async fn create_new_federation<S: MutinyStorage>(
33433359
federation_code.clone(),
33443360
xprivkey,
33453361
storage.clone(),
3362+
esplora,
33463363
network,
33473364
stop.clone(),
33483365
logger.clone(),

mutiny-core/src/nodemanager.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ pub struct NodeBalance {
232232
pub struct NodeManagerBuilder<S: MutinyStorage> {
233233
xprivkey: ExtendedPrivKey,
234234
storage: S,
235+
esplora: Option<Arc<AsyncClient>>,
235236
config: Option<MutinyWalletConfig>,
236237
stop: Option<Arc<AtomicBool>>,
237238
logger: Option<Arc<MutinyLogger>>,
@@ -242,6 +243,7 @@ impl<S: MutinyStorage> NodeManagerBuilder<S> {
242243
NodeManagerBuilder::<S> {
243244
xprivkey,
244245
storage,
246+
esplora: None,
245247
config: None,
246248
stop: None,
247249
logger: None,
@@ -257,6 +259,10 @@ impl<S: MutinyStorage> NodeManagerBuilder<S> {
257259
self.stop = Some(stop);
258260
}
259261

262+
pub fn with_esplora(&mut self, esplora: Arc<AsyncClient>) {
263+
self.esplora = Some(esplora);
264+
}
265+
260266
pub fn with_logger(&mut self, logger: Arc<MutinyLogger>) {
261267
self.logger = Some(logger);
262268
}
@@ -271,6 +277,13 @@ impl<S: MutinyStorage> NodeManagerBuilder<S> {
271277
.map_or_else(|| Err(MutinyError::InvalidArgumentsError), Ok)?;
272278
let logger = self.logger.unwrap_or(Arc::new(MutinyLogger::default()));
273279
let stop = self.stop.unwrap_or(Arc::new(AtomicBool::new(false)));
280+
let esplora = if let Some(e) = self.esplora {
281+
e
282+
} else {
283+
let esplora_server_url = get_esplora_url(c.network, c.user_esplora_url);
284+
let esplora = Builder::new(&esplora_server_url).build_async()?;
285+
Arc::new(esplora)
286+
};
274287

275288
#[cfg(target_arch = "wasm32")]
276289
let websocket_proxy_addr = c
@@ -280,14 +293,11 @@ impl<S: MutinyStorage> NodeManagerBuilder<S> {
280293
let start = Instant::now();
281294
log_info!(logger, "Building node manager components");
282295

283-
let esplora_server_url = get_esplora_url(c.network, c.user_esplora_url);
284-
let esplora = Builder::new(&esplora_server_url).build_async()?;
285296
let tx_sync = Arc::new(EsploraSyncClient::from_client(
286-
esplora.clone(),
297+
esplora.as_ref().clone(),
287298
logger.clone(),
288299
));
289300

290-
let esplora = Arc::new(esplora);
291301
let fee_estimator = Arc::new(MutinyFeeEstimator::new(
292302
self.storage.clone(),
293303
esplora.clone(),

0 commit comments

Comments
 (0)