import { ChevronDownIcon, InfoIcon } from "lucide-react"; import React from "react"; import { useNavigate } from "react-router"; import { toast } from "sonner"; import AppHeader from "src/components/AppHeader"; import ExternalLink from "src/components/ExternalLink"; import { FormattedBitcoinAmount } from "src/components/FormattedBitcoinAmount"; import Loading from "src/components/Loading"; import { Button } from "src/components/ui/button"; import { Checkbox } from "src/components/ui/checkbox"; import { LoadingButton } from "src/components/ui/custom/loading-button"; import { Label } from "src/components/ui/label"; import { Separator } from "src/components/ui/separator"; import { useChannels } from "src/hooks/useChannels"; import { useInfo } from "src/hooks/useInfo"; import { AutoChannelRequest, AutoChannelResponse, LSPChannelOfferPaymentMethod, } from "src/types"; import { request } from "src/utils/request"; import { Invoice } from "@getalby/lightning-tools"; import { MempoolAlert } from "src/components/MempoolAlert"; import { PayLightningInvoice } from "src/components/PayLightningInvoice"; import { Table, TableBody, TableCell, TableRow } from "src/components/ui/table"; import LightningNetworkDarkSVG from "public/images/illustrations/lightning-network-dark.svg"; import LightningNetworkLightSVG from "public/images/illustrations/lightning-network-light.svg"; import { LSPTermsDialog } from "src/components/channels/LSPTermsDialog"; import FormattedFiatAmount from "src/components/FormattedFiatAmount"; import { ExternalLinkButton } from "src/components/ui/custom/external-link-button"; import { LinkButton } from "src/components/ui/custom/link-button"; import { Field, FieldContent, FieldLabel, FieldTitle, } from "src/components/ui/field"; import { RadioGroup, RadioGroupItem } from "src/components/ui/radio-group"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "src/components/ui/tooltip"; import { useLSPChannelOffer } from "src/hooks/useLSPChannelOffer"; import { cn } from "src/lib/utils"; import { openLink } from "src/utils/openLink"; export function FirstChannel() { const { data: info } = useInfo(); const { data: channels } = useChannels(true); const [isLoading, setLoading] = React.useState(false); const [showAdvanced, setShowAdvanced] = React.useState(false); const [isPublic, setPublic] = React.useState(false); const { data: lspChannelOffer } = useLSPChannelOffer(); const navigate = useNavigate(); const [invoice, setInvoice] = React.useState(); const [channelSizeSat, setChannelSizeSat] = React.useState(); const [currentPaymentMethod, setCurrentPaymentMethod] = React.useState(); React.useEffect(() => { if (channels?.length) { navigate("/channels/first/opening"); } }, [channels, navigate]); React.useEffect(() => { if (info && !info.albyAccountConnected) { navigate("/channels/incoming"); } }, [info, navigate]); if (!info?.albyAccountConnected || !channels || !lspChannelOffer) { return ; } async function openChannel() { if (!info || !channels || !lspChannelOffer) { return; } if ( (lspChannelOffer.currentPaymentMethod === "card" || lspChannelOffer.currentPaymentMethod === "wallet") && currentPaymentMethod !== lspChannelOffer.currentPaymentMethod ) { toast.error("Payment method incorrectly configured", { description: currentPaymentMethod ? "Please switch the payment method and confirm the change in your Alby Account settings" : "Please choose a payment method", }); return; } setLoading(true); try { const newInstantChannelInvoiceRequest: AutoChannelRequest = { isPublic, }; const autoChannelResponse = await request( "/api/alby/auto-channel", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(newInstantChannelInvoiceRequest), } ); if (!autoChannelResponse) { throw new Error("unexpected auto channel response"); } setInvoice(autoChannelResponse.invoice); setChannelSizeSat(autoChannelResponse.channelSizeSat); } catch (error) { setLoading(false); console.error(error); toast.error("Something went wrong. Please try again"); } } return ( <> {invoice && channelSizeSat && (

Alby Hub works with selected service providers (LSPs) which provide the best network connectivity and liquidity to receive payments. To quickly get started you can buy a channel from an LSP by paying the lightning invoice below.

Incoming Liquidity {invoice && ( Amount to pay )}

Other options

Open Channel with On-Chain Bitcoin Buy Bitcoin
)} {!invoice && ( <>

You're now going to open your first lightning channel and can begin using your Hub in the booming bitcoin economy!

Alby Hub works with selected service providers (LSPs) which provide the best network connectivity and liquidity to receive payments.

Purchase Your First Channel

A payment is required to purchase a channel from{" "} {lspChannelOffer.lspName} . Once your channel is opened, you'll immediately be able to receive and send bitcoin with your Hub.

{lspChannelOffer.currentPaymentMethod !== "prepaid" && lspChannelOffer.currentPaymentMethod !== "included" && (

Payment method

{ if ( newPaymentMethod !== lspChannelOffer.currentPaymentMethod ) { openLink("https://getalby.com/payment_details"); } setCurrentPaymentMethod(newPaymentMethod); }} > Bitcoin Credit / Debit Card
)} {showAdvanced && ( <>
setPublic(!isPublic)} className="mr-2" />

Not recommended for most users.{" "} Learn more

)} {!showAdvanced && (
)}
You'll be able to receive up to{" "}
The amount you will be able to receive when funds are on your counterparty's side of the channel.
{/* */}
Channel Cost {lspChannelOffer.currentPaymentMethod === "included" && " (Included in your plan)"}

{new Intl.NumberFormat(undefined, { style: "currency", currency: "USD", }).format(lspChannelOffer.feeTotalUsd / 100)} {lspChannelOffer.currentPaymentMethod === "included" && ( $0.00 )}

By continuing, you consent to the{" "} LSP terms} />{" "} and that the channel opens immediately and that you lose the right to revoke once it is open.

{lspChannelOffer.currentPaymentMethod === "prepaid" ? ( <>Review Order ) : lspChannelOffer.currentPaymentMethod === "included" ? ( <>Open Channel ) : ( <> Pay{" "} {new Intl.NumberFormat(undefined, { style: "currency", currency: "USD", }).format(lspChannelOffer.feeTotalUsd / 100)}{" "} and Open Channel )}
)} ); }