From ec86fa13cda66c8c36f192f8ef3fe6b54aee7e4c Mon Sep 17 00:00:00 2001 From: binarybaron <86064887+binarybaron@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:17:46 +0600 Subject: [PATCH] fix(tauri): Emit 'Initiated' progress event once swap lock is aquired (#112) * fix(tauri): Emit 'Initiated' progress event once swap lock is aquired --- .../modal/swap/SwapStateStepper.tsx | 28 +++++++++++-------- .../modal/swap/pages/SwapStatePage.tsx | 7 +++-- .../modal/swap/pages/init/InitiatedPage.tsx | 21 -------------- swap/src/cli/api/request.rs | 18 +++++++++++- swap/src/cli/api/tauri_bindings.rs | 3 +- 5 files changed, 39 insertions(+), 38 deletions(-) delete mode 100644 src-gui/src/renderer/components/modal/swap/pages/init/InitiatedPage.tsx diff --git a/src-gui/src/renderer/components/modal/swap/SwapStateStepper.tsx b/src-gui/src/renderer/components/modal/swap/SwapStateStepper.tsx index 2424a6ab2..74d5ac19d 100644 --- a/src-gui/src/renderer/components/modal/swap/SwapStateStepper.tsx +++ b/src-gui/src/renderer/components/modal/swap/SwapStateStepper.tsx @@ -15,13 +15,13 @@ type PathStep = [type: PathType, step: number, isError: boolean]; * @param latestState - The latest state of the swap process * @returns A tuple containing [PathType, activeStep, errorFlag] */ -function getActiveStep(state: SwapState | null): PathStep { +function getActiveStep(state: SwapState | null): PathStep | null { // In case we cannot infer a correct step from the state function fallbackStep(reason: string) { console.error( `Unable to choose correct stepper type (reason: ${reason}, state: ${JSON.stringify(state)}`, ); - return [PathType.HAPPY_PATH, 0, true] as PathStep; + return null; } if (state === null) { @@ -52,7 +52,7 @@ function getActiveStep(state: SwapState | null): PathStep { // Step 0: Initializing the swap // These states represent the very beginning of the swap process // No funds have been locked - case "Initiated": + case "RequestingQuote": case "ReceivedQuote": case "WaitingForBtcDeposit": case "Started": @@ -86,12 +86,7 @@ function getActiveStep(state: SwapState | null): PathStep { // XMR redemption transaction is in mempool, swap is essentially complete case "XmrRedeemInMempool": return [PathType.HAPPY_PATH, 4, false]; - - // Edge Case of Happy Path where the swap is safely aborted. We "fail" at the first step. - // TODO: There's no equivalent for this with the Tauri events - // case BobStateName.SafelyAborted: - // return [PathType.HAPPY_PATH, 0, true]; - + // Unhappy Path States // Step 1: Cancel timelock has expired. Waiting for cancel transaction to be published @@ -117,10 +112,13 @@ function getActiveStep(state: SwapState | null): PathStep { return [PathType.UNHAPPY_PATH, 1, isReleased]; case "CooperativeRedeemRejected": return [PathType.UNHAPPY_PATH, 1, true]; + + case "Resuming": + return null; default: return fallbackStep("No step is assigned to the current state"); - // TODO: Make this guard work. It should force the compiler to check if we have covered all possible cases. - // return exhaustiveGuard(latestState.type); + // TODO: Make this guard work. It should force the compiler to check if we have covered all possible cases. + // return exhaustiveGuard(latestState.type); } } @@ -168,7 +166,13 @@ export default function SwapStateStepper({ }: { state: SwapState | null; }) { - const [pathType, activeStep, error] = getActiveStep(state); + const result = getActiveStep(state); + + if (result === null) { + return null; + } + + const [pathType, activeStep, error] = result; const steps = pathType === PathType.HAPPY_PATH diff --git a/src-gui/src/renderer/components/modal/swap/pages/SwapStatePage.tsx b/src-gui/src/renderer/components/modal/swap/pages/SwapStatePage.tsx index 821cf8adf..f0253aba2 100644 --- a/src-gui/src/renderer/components/modal/swap/pages/SwapStatePage.tsx +++ b/src-gui/src/renderer/components/modal/swap/pages/SwapStatePage.tsx @@ -14,7 +14,6 @@ import ReceivedQuotePage from "./in_progress/ReceivedQuotePage"; import StartedPage from "./in_progress/StartedPage"; import XmrLockedPage from "./in_progress/XmrLockedPage"; import XmrLockTxInMempoolPage from "./in_progress/XmrLockInMempoolPage"; -import InitiatedPage from "./init/InitiatedPage"; import InitPage from "./init/InitPage"; import WaitingForBitcoinDepositPage from "./init/WaitingForBitcoinDepositPage"; @@ -24,8 +23,10 @@ export default function SwapStatePage({ state }: { state: SwapState | null }) { } switch (state.curr.type) { - case "Initiated": - return ; + case "RequestingQuote": + return ; + case "Resuming": + return ; case "ReceivedQuote": return ; case "WaitingForBtcDeposit": diff --git a/src-gui/src/renderer/components/modal/swap/pages/init/InitiatedPage.tsx b/src-gui/src/renderer/components/modal/swap/pages/init/InitiatedPage.tsx deleted file mode 100644 index da46af35c..000000000 --- a/src-gui/src/renderer/components/modal/swap/pages/init/InitiatedPage.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { SwapSpawnType } from "models/cliModel"; -import { useAppSelector } from "store/hooks"; -import CircularProgressWithSubtitle from "../../CircularProgressWithSubtitle"; - -export default function InitiatedPage() { - const description = useAppSelector((s) => { - switch (s.swap.spawnType) { - case SwapSpawnType.INIT: - return "Requesting quote from provider..."; - case SwapSpawnType.RESUME: - return "Resuming swap..."; - case SwapSpawnType.CANCEL_REFUND: - return "Attempting to cancel & refund swap..."; - default: - // Should never be hit - return "Initiating swap..."; - } - }); - - return ; -} diff --git a/swap/src/cli/api/request.rs b/swap/src/cli/api/request.rs index e5dba3102..9195a7e9e 100644 --- a/swap/src/cli/api/request.rs +++ b/swap/src/cli/api/request.rs @@ -570,12 +570,14 @@ pub async fn buy_xmr( .as_ref() .context("Could not get Monero wallet")?, ); + let env_config = context.config.env_config; let seed = context.config.seed.clone().context("Could not get seed")?; let seller_peer_id = seller .extract_peer_id() .context("Seller address must contain peer ID")?; + context .db .insert_address(seller_peer_id, seller.clone()) @@ -587,6 +589,7 @@ pub async fn buy_xmr( bitcoin_wallet.clone(), (seed.derive_libp2p_identity(), context.config.namespace), ); + let mut swarm = swarm::cli( seed.derive_libp2p_identity(), context.config.tor_socks5_port, @@ -605,6 +608,10 @@ pub async fn buy_xmr( context.swap_lock.acquire_swap_lock(swap_id).await?; + context + .tauri_handle + .emit_swap_progress_event(swap_id, TauriSwapProgressEvent::RequestingQuote); + let initialize_swap = tokio::select! { biased; _ = context.swap_lock.listen_for_swap_force_suspension() => { @@ -632,6 +639,7 @@ pub async fn buy_xmr( Ok(result) => result, Err(error) => { tracing::error!(%swap_id, "Swap initialization failed: {:#}", error); + context .swap_lock .release_swap_lock() @@ -750,7 +758,6 @@ pub async fn resume_swap( context: Arc, ) -> Result { let ResumeSwapArgs { swap_id } = resume; - context.swap_lock.acquire_swap_lock(swap_id).await?; let seller_peer_id = context.db.get_peer_id(swap_id).await?; let seller_addresses = context.db.get_addresses(seller_peer_id).await?; @@ -778,6 +785,7 @@ pub async fn resume_swap( tracing::debug!(peer_id = %our_peer_id, "Network layer initialized"); + // Fetch the seller's addresses from the database and add them to the swarm for seller_address in seller_addresses { swarm .behaviour_mut() @@ -786,7 +794,9 @@ pub async fn resume_swap( let (event_loop, event_loop_handle) = EventLoop::new(swap_id, swarm, seller_peer_id, context.db.clone())?; + let monero_receive_address = context.db.get_monero_address(swap_id).await?; + let swap = Swap::from_db( Arc::clone(&context.db), swap_id, @@ -809,6 +819,12 @@ pub async fn resume_swap( .await? .with_event_emitter(context.tauri_handle.clone()); + context.swap_lock.acquire_swap_lock(swap_id).await?; + + context + .tauri_handle + .emit_swap_progress_event(swap_id, TauriSwapProgressEvent::Resuming); + context.tasks.clone().spawn( async move { let handle = tokio::spawn(event_loop.run().in_current_span()); diff --git a/swap/src/cli/api/tauri_bindings.rs b/swap/src/cli/api/tauri_bindings.rs index 3dee7b2d0..ebf61e538 100644 --- a/swap/src/cli/api/tauri_bindings.rs +++ b/swap/src/cli/api/tauri_bindings.rs @@ -118,7 +118,8 @@ pub struct TauriSwapProgressEventWrapper { #[serde(tag = "type", content = "content")] #[typeshare] pub enum TauriSwapProgressEvent { - Initiated, + RequestingQuote, + Resuming, ReceivedQuote(BidQuote), WaitingForBtcDeposit { #[typeshare(serialized_as = "string")]