feat(gui): Refund swap in the background (#154)

Swaps will now be refunded as soon as the cancel timelock expires if the GUI is running but the swap dialog is not open.
This commit is contained in:
binarybaron 2024-11-14 14:20:22 +01:00 committed by GitHub
parent 4cf5cf719a
commit e46be4a9ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 210 additions and 27 deletions

View file

@ -0,0 +1,42 @@
import { BackgroundRefundState } from "models/tauriModel";
import { useAppSelector } from "store/hooks";
import { LoadingSpinnerAlert } from "./LoadingSpinnerAlert";
import { AlertTitle } from "@material-ui/lab";
import TruncatedText from "../other/TruncatedText";
import { useSnackbar } from "notistack";
import { useEffect } from "react";
export default function BackgroundRefundAlert() {
const backgroundRefund = useAppSelector(state => state.rpc.state.backgroundRefund);
const notistack = useSnackbar();
useEffect(() => {
// If we failed to refund, show a notification
if (backgroundRefund?.state.type === "Failed") {
notistack.enqueueSnackbar(
<>
Our attempt to refund {backgroundRefund.swapId} in the background failed.
<br />
Error: {backgroundRefund.state.content.error}
</>,
{ variant: "error", autoHideDuration: 60 * 1000 }
);
}
// If we successfully refunded, show a notification as well
if (backgroundRefund?.state.type === "Completed") {
notistack.enqueueSnackbar(`The swap ${backgroundRefund.swapId} has been refunded in the background.`, { variant: "success", persist: true });
}
}, [backgroundRefund]);
if (backgroundRefund?.state.type === "Started") {
return <LoadingSpinnerAlert>
<AlertTitle>
Refund in progress
</AlertTitle>
The swap <TruncatedText>{backgroundRefund.swapId}</TruncatedText> is being refunded in the background.
</LoadingSpinnerAlert>
}
return null;
}

View file

@ -1,13 +1,10 @@
import { Button, CircularProgress } from "@material-ui/core";
import { Alert, AlertProps } from "@material-ui/lab";
import { Button } from "@material-ui/core";
import { Alert } from "@material-ui/lab";
import { TauriContextInitializationProgress } from "models/tauriModel";
import { useNavigate } from "react-router-dom";
import { useAppSelector } from "store/hooks";
import { exhaustiveGuard } from "utils/typescriptUtils";
function LoadingSpinnerAlert({ ...rest }: AlertProps) {
return <Alert icon={<CircularProgress size={22} />} {...rest} />;
}
import { LoadingSpinnerAlert } from "./LoadingSpinnerAlert";
export default function DaemonStatusAlert() {
const contextStatus = useAppSelector((s) => s.rpc.status);

View file

@ -0,0 +1,6 @@
import { CircularProgress } from "@material-ui/core";
import { AlertProps, Alert } from "@material-ui/lab";
export function LoadingSpinnerAlert({ ...rest }: AlertProps) {
return <Alert icon={<CircularProgress size={22} />} {...rest} />;
}

View file

@ -8,6 +8,7 @@ import UnfinishedSwapsAlert from "../alert/UnfinishedSwapsAlert";
import DiscordIcon from "../icons/DiscordIcon";
import LinkIconButton from "../icons/LinkIconButton";
import { DISCORD_URL } from "../pages/help/ContactInfoBox";
import BackgroundRefundAlert from "../alert/BackgroundRefundAlert";
const useStyles = makeStyles((theme) => ({
outer: {
@ -29,6 +30,7 @@ export default function NavigationFooter() {
<Box className={classes.outer}>
<FundsLeftInWalletAlert />
<UnfinishedSwapsAlert />
<BackgroundRefundAlert />
<DaemonStatusAlert />
<MoneroWalletRpcUpdatingAlert />
<Box className={classes.linksOuter}>

View file

@ -28,10 +28,12 @@ import {
CheckElectrumNodeArgs,
CheckElectrumNodeResponse,
GetMoneroAddressesResponse,
TauriBackgroundRefundEvent,
} from "models/tauriModel";
import {
contextStatusEventReceived,
receivedCliLog,
rpcSetBackgroundRefundState,
rpcSetBalance,
rpcSetSwapInfo,
timelockChangeEventReceived,
@ -100,6 +102,11 @@ export async function initEventListeners() {
console.log('Received timelock change event', event.payload);
store.dispatch(timelockChangeEventReceived(event.payload));
})
listen<TauriBackgroundRefundEvent>('background-refund', (event) => {
console.log('Received background refund event', event.payload);
store.dispatch(rpcSetBackgroundRefundState(event.payload));
})
}
async function invoke<ARGS, RESPONSE>(