InsufficientLightningBalanceAlert.tsx raw
1 import { AlertTriangleIcon } from "lucide-react";
2 import { FormattedBitcoinAmount } from "src/components/FormattedBitcoinAmount";
3 import { Alert, AlertDescription, AlertTitle } from "src/components/ui/alert";
4 import { LinkButton } from "src/components/ui/custom/link-button";
5 import { useBalances } from "src/hooks/useBalances";
6 import { useInfo } from "src/hooks/useInfo";
7
8 export function InsufficientLightningBalanceAlert({
9 className,
10 amountSat,
11 }: {
12 className?: string;
13 amountSat: number;
14 }) {
15 const { hasChannelManagement } = useInfo();
16 const { data: balances } = useBalances();
17
18 if (!balances) {
19 return null;
20 }
21
22 const maxSpendableMsat = Math.max(
23 balances.lightning.nextMaxSpendableMPPMsat -
24 Math.max(
25 0.01 * balances.lightning.nextMaxSpendableMPPMsat,
26 10000 /* fee reserve */
27 ),
28 0
29 );
30
31 const exceedsBalance =
32 hasChannelManagement && amountSat * 1000 > maxSpendableMsat;
33
34 if (!exceedsBalance) {
35 return null;
36 }
37
38 return (
39 <Alert className={className}>
40 <AlertTriangleIcon className="h-4 w-4" />
41 <AlertTitle>Maximum Spendable Balance Too Low</AlertTitle>
42 <AlertDescription>
43 <p>
44 Your payment will likely fail because your maximum spendable balance
45 in your lightning channels for the next payment is currently{" "}
46 <FormattedBitcoinAmount amountMsat={maxSpendableMsat} />.
47 </p>
48 <div className="flex gap-2 mt-2 items-center justify-center">
49 <LinkButton
50 to="/wallet/swap?type=in"
51 size="sm"
52 variant="secondary"
53 className="flex-1"
54 >
55 Swap In
56 </LinkButton>
57 <p>or</p>
58 <LinkButton
59 to="/channels/outgoing"
60 size="sm"
61 variant="secondary"
62 className="flex-1"
63 >
64 Open Outbound Channel
65 </LinkButton>
66 </div>
67 </AlertDescription>
68 </Alert>
69 );
70 }
71