mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-05-11 19:25:02 -04:00
feat: swap history tauri connector
This commit is contained in:
parent
cdd6635c8f
commit
2e1b6f6b43
22 changed files with 1315 additions and 1297 deletions
|
@ -1,86 +1,98 @@
|
|||
import {
|
||||
Box,
|
||||
Collapse,
|
||||
IconButton,
|
||||
makeStyles,
|
||||
TableCell,
|
||||
TableRow,
|
||||
} from '@material-ui/core';
|
||||
import { useState } from 'react';
|
||||
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
|
||||
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
|
||||
import KeyboardArrowUpIcon from '@material-ui/icons/KeyboardArrowUp';
|
||||
Box,
|
||||
Collapse,
|
||||
IconButton,
|
||||
makeStyles,
|
||||
TableCell,
|
||||
TableRow,
|
||||
} from "@material-ui/core";
|
||||
import { useState } from "react";
|
||||
import ArrowForwardIcon from "@material-ui/icons/ArrowForward";
|
||||
import KeyboardArrowDownIcon from "@material-ui/icons/KeyboardArrowDown";
|
||||
import KeyboardArrowUpIcon from "@material-ui/icons/KeyboardArrowUp";
|
||||
import {
|
||||
getHumanReadableDbStateType,
|
||||
getSwapBtcAmount,
|
||||
getSwapXmrAmount,
|
||||
GetSwapInfoResponse,
|
||||
} from '../../../../../models/rpcModel';
|
||||
import HistoryRowActions from './HistoryRowActions';
|
||||
import HistoryRowExpanded from './HistoryRowExpanded';
|
||||
import { BitcoinAmount, MoneroAmount } from '../../../other/Units';
|
||||
getHumanReadableDbStateType,
|
||||
getSwapBtcAmount,
|
||||
getSwapXmrAmount,
|
||||
GetSwapInfoResponse,
|
||||
} from "../../../../../models/rpcModel";
|
||||
import HistoryRowActions from "./HistoryRowActions";
|
||||
import HistoryRowExpanded from "./HistoryRowExpanded";
|
||||
import { BitcoinAmount, MoneroAmount } from "../../../other/Units";
|
||||
|
||||
type HistoryRowProps = {
|
||||
swap: GetSwapInfoResponse;
|
||||
swap: GetSwapInfoResponse;
|
||||
};
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
amountTransferContainer: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: theme.spacing(1),
|
||||
},
|
||||
amountTransferContainer: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
||||
function AmountTransfer({
|
||||
btcAmount,
|
||||
xmrAmount,
|
||||
btcAmount,
|
||||
xmrAmount,
|
||||
}: {
|
||||
xmrAmount: number;
|
||||
btcAmount: number;
|
||||
xmrAmount: number;
|
||||
btcAmount: number;
|
||||
}) {
|
||||
const classes = useStyles();
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Box className={classes.amountTransferContainer}>
|
||||
<BitcoinAmount amount={btcAmount} />
|
||||
<ArrowForwardIcon />
|
||||
<MoneroAmount amount={xmrAmount} />
|
||||
</Box>
|
||||
);
|
||||
return (
|
||||
<Box className={classes.amountTransferContainer}>
|
||||
<BitcoinAmount amount={btcAmount} />
|
||||
<ArrowForwardIcon />
|
||||
<MoneroAmount amount={xmrAmount} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default function HistoryRow({ swap }: HistoryRowProps) {
|
||||
const btcAmount = getSwapBtcAmount(swap);
|
||||
const xmrAmount = getSwapXmrAmount(swap);
|
||||
const btcAmount = getSwapBtcAmount(swap);
|
||||
const xmrAmount = getSwapXmrAmount(swap);
|
||||
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<IconButton size="small" onClick={() => setExpanded(!expanded)}>
|
||||
{expanded ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
<TableCell>{swap.swapId.substring(0, 5)}...</TableCell>
|
||||
<TableCell>
|
||||
<AmountTransfer xmrAmount={xmrAmount} btcAmount={btcAmount} />
|
||||
</TableCell>
|
||||
<TableCell>{getHumanReadableDbStateType(swap.stateName)}</TableCell>
|
||||
<TableCell>
|
||||
<HistoryRowActions swap={swap} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
return (
|
||||
<>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
>
|
||||
{expanded ? (
|
||||
<KeyboardArrowUpIcon />
|
||||
) : (
|
||||
<KeyboardArrowDownIcon />
|
||||
)}
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
<TableCell>{swap.swap_id.substring(0, 5)}...</TableCell>
|
||||
<TableCell>
|
||||
<AmountTransfer
|
||||
xmrAmount={xmrAmount}
|
||||
btcAmount={btcAmount}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{getHumanReadableDbStateType(swap.state_name)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<HistoryRowActions swap={swap} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
<TableCell style={{ padding: 0 }} colSpan={6}>
|
||||
<Collapse in={expanded} timeout="auto">
|
||||
{expanded && <HistoryRowExpanded swap={swap} />}
|
||||
</Collapse>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
<TableRow>
|
||||
<TableCell style={{ padding: 0 }} colSpan={6}>
|
||||
<Collapse in={expanded} timeout="auto">
|
||||
{expanded && <HistoryRowExpanded swap={swap} />}
|
||||
</Collapse>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,90 +1,90 @@
|
|||
import { Tooltip } from '@material-ui/core';
|
||||
import Button, { ButtonProps } from '@material-ui/core/Button/Button';
|
||||
import DoneIcon from '@material-ui/icons/Done';
|
||||
import ErrorIcon from '@material-ui/icons/Error';
|
||||
import { green, red } from '@material-ui/core/colors';
|
||||
import PlayArrowIcon from '@material-ui/icons/PlayArrow';
|
||||
import IpcInvokeButton from '../../../IpcInvokeButton';
|
||||
import { Tooltip } from "@material-ui/core";
|
||||
import Button, { ButtonProps } from "@material-ui/core/Button/Button";
|
||||
import DoneIcon from "@material-ui/icons/Done";
|
||||
import ErrorIcon from "@material-ui/icons/Error";
|
||||
import { green, red } from "@material-ui/core/colors";
|
||||
import PlayArrowIcon from "@material-ui/icons/PlayArrow";
|
||||
import IpcInvokeButton from "../../../IpcInvokeButton";
|
||||
import {
|
||||
GetSwapInfoResponse,
|
||||
SwapStateName,
|
||||
isSwapStateNamePossiblyCancellableSwap,
|
||||
isSwapStateNamePossiblyRefundableSwap,
|
||||
} from '../../../../../models/rpcModel';
|
||||
GetSwapInfoResponse,
|
||||
SwapStateName,
|
||||
isSwapStateNamePossiblyCancellableSwap,
|
||||
isSwapStateNamePossiblyRefundableSwap,
|
||||
} from "../../../../../models/rpcModel";
|
||||
|
||||
export function SwapResumeButton({
|
||||
swap,
|
||||
...props
|
||||
swap,
|
||||
...props
|
||||
}: { swap: GetSwapInfoResponse } & ButtonProps) {
|
||||
return (
|
||||
<IpcInvokeButton
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={swap.completed}
|
||||
ipcChannel="spawn-resume-swap"
|
||||
ipcArgs={[swap.swapId]}
|
||||
endIcon={<PlayArrowIcon />}
|
||||
requiresRpc
|
||||
{...props}
|
||||
>
|
||||
Resume
|
||||
</IpcInvokeButton>
|
||||
);
|
||||
return (
|
||||
<IpcInvokeButton
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={swap.completed}
|
||||
ipcChannel="spawn-resume-swap"
|
||||
ipcArgs={[swap.swap_id]}
|
||||
endIcon={<PlayArrowIcon />}
|
||||
requiresRpc
|
||||
{...props}
|
||||
>
|
||||
Resume
|
||||
</IpcInvokeButton>
|
||||
);
|
||||
}
|
||||
|
||||
export function SwapCancelRefundButton({
|
||||
swap,
|
||||
...props
|
||||
swap,
|
||||
...props
|
||||
}: { swap: GetSwapInfoResponse } & ButtonProps) {
|
||||
const cancelOrRefundable =
|
||||
isSwapStateNamePossiblyCancellableSwap(swap.stateName) ||
|
||||
isSwapStateNamePossiblyRefundableSwap(swap.stateName);
|
||||
const cancelOrRefundable =
|
||||
isSwapStateNamePossiblyCancellableSwap(swap.state_name) ||
|
||||
isSwapStateNamePossiblyRefundableSwap(swap.state_name);
|
||||
|
||||
if (!cancelOrRefundable) {
|
||||
return <></>;
|
||||
}
|
||||
if (!cancelOrRefundable) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<IpcInvokeButton
|
||||
ipcChannel="spawn-cancel-refund"
|
||||
ipcArgs={[swap.swapId]}
|
||||
requiresRpc
|
||||
displayErrorSnackbar={false}
|
||||
{...props}
|
||||
>
|
||||
Attempt manual Cancel & Refund
|
||||
</IpcInvokeButton>
|
||||
);
|
||||
return (
|
||||
<IpcInvokeButton
|
||||
ipcChannel="spawn-cancel-refund"
|
||||
ipcArgs={[swap.swap_id]}
|
||||
requiresRpc
|
||||
displayErrorSnackbar={false}
|
||||
{...props}
|
||||
>
|
||||
Attempt manual Cancel & Refund
|
||||
</IpcInvokeButton>
|
||||
);
|
||||
}
|
||||
|
||||
export default function HistoryRowActions({
|
||||
swap,
|
||||
swap,
|
||||
}: {
|
||||
swap: GetSwapInfoResponse;
|
||||
swap: GetSwapInfoResponse;
|
||||
}) {
|
||||
if (swap.stateName === SwapStateName.XmrRedeemed) {
|
||||
return (
|
||||
<Tooltip title="The swap is completed because you have redeemed the XMR">
|
||||
<DoneIcon style={{ color: green[500] }} />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
if (swap.state_name === SwapStateName.XmrRedeemed) {
|
||||
return (
|
||||
<Tooltip title="The swap is completed because you have redeemed the XMR">
|
||||
<DoneIcon style={{ color: green[500] }} />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
if (swap.stateName === SwapStateName.BtcRefunded) {
|
||||
return (
|
||||
<Tooltip title="The swap is completed because your BTC have been refunded">
|
||||
<DoneIcon style={{ color: green[500] }} />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
if (swap.state_name === SwapStateName.BtcRefunded) {
|
||||
return (
|
||||
<Tooltip title="The swap is completed because your BTC have been refunded">
|
||||
<DoneIcon style={{ color: green[500] }} />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
if (swap.stateName === SwapStateName.BtcPunished) {
|
||||
return (
|
||||
<Tooltip title="The swap is completed because you have been punished">
|
||||
<ErrorIcon style={{ color: red[500] }} />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
if (swap.state_name === SwapStateName.BtcPunished) {
|
||||
return (
|
||||
<Tooltip title="The swap is completed because you have been punished">
|
||||
<ErrorIcon style={{ color: red[500] }} />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return <SwapResumeButton swap={swap} />;
|
||||
return <SwapResumeButton swap={swap} />;
|
||||
}
|
||||
|
|
|
@ -1,134 +1,143 @@
|
|||
import {
|
||||
Box,
|
||||
Link,
|
||||
makeStyles,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow,
|
||||
} from '@material-ui/core';
|
||||
import { getBitcoinTxExplorerUrl } from 'utils/conversionUtils';
|
||||
import { isTestnet } from 'store/config';
|
||||
Box,
|
||||
Link,
|
||||
makeStyles,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow,
|
||||
} from "@material-ui/core";
|
||||
import { getBitcoinTxExplorerUrl } from "utils/conversionUtils";
|
||||
import { isTestnet } from "store/config";
|
||||
import {
|
||||
getHumanReadableDbStateType,
|
||||
getSwapBtcAmount,
|
||||
getSwapExchangeRate,
|
||||
getSwapTxFees,
|
||||
getSwapXmrAmount,
|
||||
GetSwapInfoResponse,
|
||||
} from '../../../../../models/rpcModel';
|
||||
import SwapLogFileOpenButton from './SwapLogFileOpenButton';
|
||||
import { SwapCancelRefundButton } from './HistoryRowActions';
|
||||
import { SwapMoneroRecoveryButton } from './SwapMoneroRecoveryButton';
|
||||
getHumanReadableDbStateType,
|
||||
getSwapBtcAmount,
|
||||
getSwapExchangeRate,
|
||||
getSwapTxFees,
|
||||
getSwapXmrAmount,
|
||||
GetSwapInfoResponse,
|
||||
} from "../../../../../models/rpcModel";
|
||||
import SwapLogFileOpenButton from "./SwapLogFileOpenButton";
|
||||
import { SwapCancelRefundButton } from "./HistoryRowActions";
|
||||
import { SwapMoneroRecoveryButton } from "./SwapMoneroRecoveryButton";
|
||||
import {
|
||||
BitcoinAmount,
|
||||
MoneroAmount,
|
||||
MoneroBitcoinExchangeRate,
|
||||
} from 'renderer/components/other/Units';
|
||||
BitcoinAmount,
|
||||
MoneroAmount,
|
||||
MoneroBitcoinExchangeRate,
|
||||
} from "renderer/components/other/Units";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
outer: {
|
||||
display: 'grid',
|
||||
padding: theme.spacing(1),
|
||||
gap: theme.spacing(1),
|
||||
},
|
||||
actionsOuter: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
gap: theme.spacing(1),
|
||||
},
|
||||
outer: {
|
||||
display: "grid",
|
||||
padding: theme.spacing(1),
|
||||
gap: theme.spacing(1),
|
||||
},
|
||||
actionsOuter: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
||||
export default function HistoryRowExpanded({
|
||||
swap,
|
||||
swap,
|
||||
}: {
|
||||
swap: GetSwapInfoResponse;
|
||||
swap: GetSwapInfoResponse;
|
||||
}) {
|
||||
const classes = useStyles();
|
||||
const classes = useStyles();
|
||||
|
||||
const { seller, startDate } = swap;
|
||||
const btcAmount = getSwapBtcAmount(swap);
|
||||
const xmrAmount = getSwapXmrAmount(swap);
|
||||
const txFees = getSwapTxFees(swap);
|
||||
const exchangeRate = getSwapExchangeRate(swap);
|
||||
const { seller, start_date: startDate } = swap;
|
||||
const btcAmount = getSwapBtcAmount(swap);
|
||||
const xmrAmount = getSwapXmrAmount(swap);
|
||||
const txFees = getSwapTxFees(swap);
|
||||
const exchangeRate = getSwapExchangeRate(swap);
|
||||
|
||||
return (
|
||||
<Box className={classes.outer}>
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell>Started on</TableCell>
|
||||
<TableCell>{startDate}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Swap ID</TableCell>
|
||||
<TableCell>{swap.swapId}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>State Name</TableCell>
|
||||
<TableCell>
|
||||
{getHumanReadableDbStateType(swap.stateName)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Monero Amount</TableCell>
|
||||
<TableCell>
|
||||
<MoneroAmount amount={xmrAmount} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Bitcoin Amount</TableCell>
|
||||
<TableCell>
|
||||
<BitcoinAmount amount={btcAmount} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Exchange Rate</TableCell>
|
||||
<TableCell>
|
||||
<MoneroBitcoinExchangeRate rate={exchangeRate} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Bitcoin Network Fees</TableCell>
|
||||
<TableCell>
|
||||
<BitcoinAmount amount={txFees} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Provider Address</TableCell>
|
||||
<TableCell>
|
||||
<Box>{seller.addresses.join(', ')}</Box>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Bitcoin lock transaction</TableCell>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={getBitcoinTxExplorerUrl(swap.txLockId, isTestnet())}
|
||||
target="_blank"
|
||||
>
|
||||
{swap.txLockId}
|
||||
</Link>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Box className={classes.actionsOuter}>
|
||||
<SwapLogFileOpenButton
|
||||
swapId={swap.swapId}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
/>
|
||||
<SwapCancelRefundButton swap={swap} variant="contained" size="small" />
|
||||
<SwapMoneroRecoveryButton
|
||||
swap={swap}
|
||||
variant="contained"
|
||||
size="small"
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
return (
|
||||
<Box className={classes.outer}>
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell>Started on</TableCell>
|
||||
<TableCell>{startDate}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Swap ID</TableCell>
|
||||
<TableCell>{swap.swap_id}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>State Name</TableCell>
|
||||
<TableCell>
|
||||
{getHumanReadableDbStateType(swap.state_name)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Monero Amount</TableCell>
|
||||
<TableCell>
|
||||
<MoneroAmount amount={xmrAmount} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Bitcoin Amount</TableCell>
|
||||
<TableCell>
|
||||
<BitcoinAmount amount={btcAmount} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Exchange Rate</TableCell>
|
||||
<TableCell>
|
||||
<MoneroBitcoinExchangeRate
|
||||
rate={exchangeRate}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Bitcoin Network Fees</TableCell>
|
||||
<TableCell>
|
||||
<BitcoinAmount amount={txFees} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Provider Address</TableCell>
|
||||
<TableCell>
|
||||
<Box>{seller.addresses.join(", ")}</Box>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Bitcoin lock transaction</TableCell>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={getBitcoinTxExplorerUrl(
|
||||
swap.tx_lock_id,
|
||||
isTestnet(),
|
||||
)}
|
||||
target="_blank"
|
||||
>
|
||||
{swap.tx_lock_id}
|
||||
</Link>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Box className={classes.actionsOuter}>
|
||||
<SwapLogFileOpenButton
|
||||
swapId={swap.swap_id}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
/>
|
||||
<SwapCancelRefundButton
|
||||
swap={swap}
|
||||
variant="contained"
|
||||
size="small"
|
||||
/>
|
||||
<SwapMoneroRecoveryButton
|
||||
swap={swap}
|
||||
variant="contained"
|
||||
size="small"
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
import {
|
||||
Box,
|
||||
makeStyles,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
} from '@material-ui/core';
|
||||
import { sortBy } from 'lodash';
|
||||
import { parseDateString } from 'utils/parseUtils';
|
||||
Box,
|
||||
makeStyles,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
} from "@material-ui/core";
|
||||
import { sortBy } from "lodash";
|
||||
import { parseDateString } from "utils/parseUtils";
|
||||
import {
|
||||
useAppSelector,
|
||||
useSwapInfosSortedByDate,
|
||||
} from '../../../../../store/hooks';
|
||||
import HistoryRow from './HistoryRow';
|
||||
useAppSelector,
|
||||
useSwapInfosSortedByDate,
|
||||
} from "../../../../../store/hooks";
|
||||
import HistoryRow from "./HistoryRow";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
outer: {
|
||||
paddingTop: theme.spacing(1),
|
||||
paddingBottom: theme.spacing(1),
|
||||
},
|
||||
outer: {
|
||||
paddingTop: theme.spacing(1),
|
||||
paddingBottom: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
||||
export default function HistoryTable() {
|
||||
const classes = useStyles();
|
||||
const swapSortedByDate = useSwapInfosSortedByDate();
|
||||
const classes = useStyles();
|
||||
const swapSortedByDate = useSwapInfosSortedByDate();
|
||||
|
||||
return (
|
||||
<Box className={classes.outer}>
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell />
|
||||
<TableCell>ID</TableCell>
|
||||
<TableCell>Amount</TableCell>
|
||||
<TableCell>State</TableCell>
|
||||
<TableCell />
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{swapSortedByDate.map((swap) => (
|
||||
<HistoryRow swap={swap} key={swap.swapId} />
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
);
|
||||
return (
|
||||
<Box className={classes.outer}>
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell />
|
||||
<TableCell>ID</TableCell>
|
||||
<TableCell>Amount</TableCell>
|
||||
<TableCell>State</TableCell>
|
||||
<TableCell />
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{swapSortedByDate.map((swap) => (
|
||||
<HistoryRow swap={swap} key={swap.swap_id} />
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,119 +1,120 @@
|
|||
import { ButtonProps } from '@material-ui/core/Button/Button';
|
||||
import { ButtonProps } from "@material-ui/core/Button/Button";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
Link,
|
||||
} from '@material-ui/core';
|
||||
import { useAppDispatch, useAppSelector } from 'store/hooks';
|
||||
import { rpcResetMoneroRecoveryKeys } from 'store/features/rpcSlice';
|
||||
Box,
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
Link,
|
||||
} from "@material-ui/core";
|
||||
import { useAppDispatch, useAppSelector } from "store/hooks";
|
||||
import { rpcResetMoneroRecoveryKeys } from "store/features/rpcSlice";
|
||||
import {
|
||||
GetSwapInfoResponse,
|
||||
isSwapMoneroRecoverable,
|
||||
} from '../../../../../models/rpcModel';
|
||||
import IpcInvokeButton from '../../../IpcInvokeButton';
|
||||
import DialogHeader from '../../../modal/DialogHeader';
|
||||
import ScrollablePaperTextBox from '../../../other/ScrollablePaperTextBox';
|
||||
GetSwapInfoResponse,
|
||||
isSwapMoneroRecoverable,
|
||||
} from "../../../../../models/rpcModel";
|
||||
import IpcInvokeButton from "../../../IpcInvokeButton";
|
||||
import DialogHeader from "../../../modal/DialogHeader";
|
||||
import ScrollablePaperTextBox from "../../../other/ScrollablePaperTextBox";
|
||||
|
||||
function MoneroRecoveryKeysDialog({ swap }: { swap: GetSwapInfoResponse }) {
|
||||
const dispatch = useAppDispatch();
|
||||
const keys = useAppSelector((s) => s.rpc.state.moneroRecovery);
|
||||
const dispatch = useAppDispatch();
|
||||
const keys = useAppSelector((s) => s.rpc.state.moneroRecovery);
|
||||
|
||||
function onClose() {
|
||||
dispatch(rpcResetMoneroRecoveryKeys());
|
||||
}
|
||||
function onClose() {
|
||||
dispatch(rpcResetMoneroRecoveryKeys());
|
||||
}
|
||||
|
||||
if (keys === null || keys.swapId !== swap.swapId) {
|
||||
return <></>;
|
||||
}
|
||||
if (keys === null || keys.swapId !== swap.swap_id) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open onClose={onClose} maxWidth="sm" fullWidth>
|
||||
<DialogHeader
|
||||
title={`Recovery Keys for swap ${swap.swapId.substring(0, 5)}...`}
|
||||
/>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
You can use the keys below to manually redeem the Monero funds from
|
||||
the multi-signature wallet.
|
||||
<ul>
|
||||
<li>
|
||||
This is useful if the swap daemon fails to redeem the funds itself
|
||||
</li>
|
||||
<li>
|
||||
If you have come this far, there is no risk of losing funds. You
|
||||
are the only one with access to these keys and can use them to
|
||||
access your funds
|
||||
</li>
|
||||
<li>
|
||||
View{' '}
|
||||
<Link
|
||||
href="https://www.getmonero.org/resources/user-guides/restore_from_keys.html"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
this guide
|
||||
</Link>{' '}
|
||||
for a detailed description on how to import the keys and spend the
|
||||
funds.
|
||||
</li>
|
||||
</ul>
|
||||
</DialogContentText>
|
||||
<Box
|
||||
style={{
|
||||
display: 'flex',
|
||||
gap: '0.5rem',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
{[
|
||||
['Primary Address', keys.keys.address],
|
||||
['View Key', keys.keys.view_key],
|
||||
['Spend Key', keys.keys.spend_key],
|
||||
['Restore Height', keys.keys.restore_height.toString()],
|
||||
].map(([title, value]) => (
|
||||
<ScrollablePaperTextBox
|
||||
minHeight="2rem"
|
||||
title={title}
|
||||
copyValue={value}
|
||||
rows={[value]}
|
||||
return (
|
||||
<Dialog open onClose={onClose} maxWidth="sm" fullWidth>
|
||||
<DialogHeader
|
||||
title={`Recovery Keys for swap ${swap.swap_id.substring(0, 5)}...`}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} color="primary" variant="contained">
|
||||
Done
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
You can use the keys below to manually redeem the Monero
|
||||
funds from the multi-signature wallet.
|
||||
<ul>
|
||||
<li>
|
||||
This is useful if the swap daemon fails to redeem
|
||||
the funds itself
|
||||
</li>
|
||||
<li>
|
||||
If you have come this far, there is no risk of
|
||||
losing funds. You are the only one with access to
|
||||
these keys and can use them to access your funds
|
||||
</li>
|
||||
<li>
|
||||
View{" "}
|
||||
<Link
|
||||
href="https://www.getmonero.org/resources/user-guides/restore_from_keys.html"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
this guide
|
||||
</Link>{" "}
|
||||
for a detailed description on how to import the keys
|
||||
and spend the funds.
|
||||
</li>
|
||||
</ul>
|
||||
</DialogContentText>
|
||||
<Box
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: "0.5rem",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
{[
|
||||
["Primary Address", keys.keys.address],
|
||||
["View Key", keys.keys.view_key],
|
||||
["Spend Key", keys.keys.spend_key],
|
||||
["Restore Height", keys.keys.restore_height.toString()],
|
||||
].map(([title, value]) => (
|
||||
<ScrollablePaperTextBox
|
||||
minHeight="2rem"
|
||||
title={title}
|
||||
copyValue={value}
|
||||
rows={[value]}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} color="primary" variant="contained">
|
||||
Done
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export function SwapMoneroRecoveryButton({
|
||||
swap,
|
||||
...props
|
||||
swap,
|
||||
...props
|
||||
}: { swap: GetSwapInfoResponse } & ButtonProps) {
|
||||
const isRecoverable = isSwapMoneroRecoverable(swap.stateName);
|
||||
const isRecoverable = isSwapMoneroRecoverable(swap.state_name);
|
||||
|
||||
if (!isRecoverable) {
|
||||
return <></>;
|
||||
}
|
||||
if (!isRecoverable) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<IpcInvokeButton
|
||||
ipcChannel="spawn-monero-recovery"
|
||||
ipcArgs={[swap.swapId]}
|
||||
requiresRpc
|
||||
{...props}
|
||||
>
|
||||
Display Monero Recovery Keys
|
||||
</IpcInvokeButton>
|
||||
<MoneroRecoveryKeysDialog swap={swap} />
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<IpcInvokeButton
|
||||
ipcChannel="spawn-monero-recovery"
|
||||
ipcArgs={[swap.swap_id]}
|
||||
requiresRpc
|
||||
{...props}
|
||||
>
|
||||
Display Monero Recovery Keys
|
||||
</IpcInvokeButton>
|
||||
<MoneroRecoveryKeysDialog swap={swap} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue