Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: lightning channel flows #1000

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
102f382
feat: make stepper component ready
pavanjoshi914 Jan 13, 2025
8292eb3
feat: lightning channel flows using stepper component
pavanjoshi914 Jan 16, 2025
73dac76
chore: make certain fields optional
pavanjoshi914 Jan 17, 2025
484b845
Merge remote-tracking branch 'upstream/master' into lightning-channel…
pavanjoshi914 Jan 17, 2025
e6c2ae1
feat: previous and back step buttons
pavanjoshi914 Jan 17, 2025
bbbede4
chore: make text label large
pavanjoshi914 Jan 17, 2025
d3c9d65
fix: callback to submit step form
pavanjoshi914 Jan 17, 2025
d066b40
chore: button overflows
pavanjoshi914 Jan 17, 2025
aaba82a
Merge remote-tracking branch 'upstream/master' into lightning-channel…
pavanjoshi914 Jan 17, 2025
cf6b3e1
feat: update grid layout billing table. make alert destructive
pavanjoshi914 Jan 24, 2025
89cf2e8
chore: colspan for table
pavanjoshi914 Jan 24, 2025
19cb364
Merge remote-tracking branch 'upstream/master' into lightning-channel…
pavanjoshi914 Feb 3, 2025
b9e0e7b
fix: pass text color classes explicitly for fiat amount
pavanjoshi914 Feb 3, 2025
fa783d5
chore: make duplicate channel alert destructive
pavanjoshi914 Feb 3, 2025
db01421
Merge remote-tracking branch 'upstream/master' into lightning-channel…
pavanjoshi914 Feb 17, 2025
437edcb
fix: remove props and canPayinternally logic in lightningPayInvoice
pavanjoshi914 Feb 18, 2025
067e6f1
Merge remote-tracking branch 'upstream/master' into lightning-channel…
pavanjoshi914 Mar 5, 2025
6774f5c
fix: position of mempool alert + update stylings
pavanjoshi914 Mar 5, 2025
720e77f
fix: remove custom peer checks as no longer required
pavanjoshi914 Mar 5, 2025
5cbe8fd
chore: correct props for payLightningInvoice
pavanjoshi914 Mar 5, 2025
a533380
chore: text color for fiat amount in wallet screen
pavanjoshi914 Mar 5, 2025
8986c9c
fix: revert mempool alert as default alert, remove link to mempool fr…
pavanjoshi914 Mar 5, 2025
eb9d194
fix: show duplicate channel alert in show advanced section
pavanjoshi914 Mar 5, 2025
124c989
feat: always shift to second step while channel is opening
pavanjoshi914 Mar 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-collapsible": "^1.1.2",
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/assets/images/confirmation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/src/components/FormattedFiatAmount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function FormattedFiatAmount({
}

return (
<div className={cn("text-sm text-muted-foreground", className)}>
<div className={cn("text-sm", className)}>
{!bitcoinRate ? (
<Skeleton className="w-20">&nbsp;</Skeleton>
) : (
Expand Down
11 changes: 2 additions & 9 deletions frontend/src/components/MempoolAlert.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TriangleAlertIcon } from "lucide-react";
import { AlertCircleIcon } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "src/components/ui/alert";
import { ExternalLinkButton } from "src/components/ui/button";
import { useMempoolApi } from "src/hooks/useMempoolApi";
Expand Down Expand Up @@ -27,7 +27,7 @@ export function MempoolAlert() {
}
return (
<Alert>
<TriangleAlertIcon className="h-4 w-4" />
<AlertCircleIcon className="h-4 w-4" />
<AlertTitle>
Mempool Fees are currently{" "}
<span className="font-semibold">{matchedFee[0]}</span>
Expand All @@ -41,13 +41,6 @@ export function MempoolAlert() {
>
Learn more
</ExternalLinkButton>
<ExternalLinkButton
to="https://mempool.space"
size={"sm"}
variant="secondary"
>
View fees on mempool
</ExternalLinkButton>
</div>
</AlertDescription>
</Alert>
Expand Down
84 changes: 71 additions & 13 deletions frontend/src/components/PayLightningInvoice.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { Invoice, fiat } from "@getalby/lightning-tools";
import { CopyIcon, LightbulbIcon } from "lucide-react";
import React from "react";
import React, { useState } from "react";
import { LightningIcon } from "src/components/icons/Lightning";
import Loading from "src/components/Loading";
import QRCode from "src/components/QRCode";
import { Button, ExternalLinkButton } from "src/components/ui/button";
import { LoadingButton } from "src/components/ui/loading-button";
import { useToast } from "src/components/ui/use-toast";
import { useChannels } from "src/hooks/useChannels";
import { copyToClipboard } from "src/lib/clipboard";
import useChannelOrderStore from "src/state/ChannelOrderStore";
import { request } from "src/utils/request";

type PayLightningInvoiceProps = {
invoice: string;
Expand All @@ -17,6 +21,8 @@ export function PayLightningInvoice({ invoice }: PayLightningInvoiceProps) {
pr: invoice,
}).satoshi;
const [fiatAmount, setFiatAmount] = React.useState(0);
const { data: channels, mutate: reloadChannels } = useChannels();

React.useEffect(() => {
fiat
.getFiatValue({ satoshi: amount, currency: "USD" })
Expand All @@ -27,11 +33,48 @@ export function PayLightningInvoice({ invoice }: PayLightningInvoiceProps) {
copyToClipboard(invoice, toast);
};

const [isPaying, setPaying] = useState(false);

const handlePayment = async () => {
try {
setPaying(true);

await request(`/api/payments/${invoice}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});

useChannelOrderStore.getState().updateOrder({
status: "paid",
});

reloadChannels();

toast({
title: "Channel successfully requested",
});
} catch (e) {
toast({
variant: "destructive",
title: "Failed to send: " + e,
});
console.error(e);
} finally {
setPaying(false);
}
};

const canPayInternally =
channels &&
channels.some((channel) => channel.localSpendableBalance / 1000 > amount);

return (
<div className="w-96 flex flex-col gap-6 p-6 items-center justify-center">
<div className="flex items-center justify-center gap-2 text-muted-foreground">
<div className="w-80 flex flex-col gap-6 px-8 py-6 items-center justify-center border rounded-xl">
<div className="flex items-center justify-center gap-2">
<Loading variant="loader" />
<p>Waiting for lightning payment...</p>
<p className="text-secondary-foreground">Waiting for payment...</p>
</div>
<div className="w-full relative flex items-center justify-center">
<QRCode value={invoice} className="w-full" />
Expand All @@ -43,7 +86,7 @@ export function PayLightningInvoice({ invoice }: PayLightningInvoiceProps) {
<p className="text-lg font-semibold">
{new Intl.NumberFormat().format(amount)} sats
</p>
<p className="flex flex-col items-center justify-center">
<p className="flex flex-col items-center justify-center text-muted-foreground">
{new Intl.NumberFormat("en-US", {
currency: "USD",
style: "currency",
Expand All @@ -54,18 +97,33 @@ export function PayLightningInvoice({ invoice }: PayLightningInvoiceProps) {
<Button
onClick={copy}
variant="outline"
size={"sm"}
className="flex-1 flex gap-2 items-center justify-center"
>
<CopyIcon className="w-4 h-4 mr-2" />
Copy Invoice
Copy
</Button>
<ExternalLinkButton
to="https://guides.getalby.com/user-guide/alby-account-and-browser-extension/alby-hub/wallet/open-your-first-channel"
variant="secondary"
className="flex-1 flex gap-2 items-center justify-center"
>
<LightbulbIcon className="w-4 h-4" /> How to pay
</ExternalLinkButton>
<>
{canPayInternally ? (
<LoadingButton
loading={isPaying}
className="whitespace-nowrap"
size={"sm"}
onClick={handlePayment}
>
Pay and open channel
</LoadingButton>
) : (
<ExternalLinkButton
to="https://guides.getalby.com/user-guide/alby-account-and-browser-extension/alby-hub/wallet/open-your-first-channel"
variant="secondary"
className="flex-1 flex gap-2 items-center justify-center"
>
<LightbulbIcon className="w-4 h-4" />
How to pay
</ExternalLinkButton>
)}
</>
</div>
</div>
);
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/components/TransactionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,10 @@ function TransactionItem({ tx }: Props) {
</p>
</div>

<FormattedFiatAmount amount={Math.floor(tx.amount / 1000)} />
<FormattedFiatAmount
amount={Math.floor(tx.amount / 1000)}
className="text-muted-foreground"
/>
</div>
</div>
</div>
Expand All @@ -192,7 +195,10 @@ function TransactionItem({ tx }: Props) {
{new Intl.NumberFormat().format(Math.floor(tx.amount / 1000))}{" "}
{Math.floor(tx.amount / 1000) == 1 ? "sat" : "sats"}
</p>
<FormattedFiatAmount amount={Math.floor(tx.amount / 1000)} />
<FormattedFiatAmount
amount={Math.floor(tx.amount / 1000)}
className="text-muted-foreground"
/>
</div>
</div>
{app && (
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/channels/ChannelPeerNote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type ChannelPeerNoteProps = {

export function ChannelPeerNote({ peer }: ChannelPeerNoteProps) {
return (
<Alert>
<Alert variant={"destructive"}>
<AlertCircleIcon className="h-4 w-4" />
<AlertTitle>
Please note when opening a channel with {peer.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Alert, AlertDescription, AlertTitle } from "src/components/ui/alert";

export function ChannelPublicPrivateAlert() {
return (
<Alert>
<Alert variant={"destructive"}>
<AlertCircleIcon className="h-4 w-4" />
<AlertTitle>Conflicting Private / Public Channels</AlertTitle>
<AlertDescription>
Expand Down
58 changes: 32 additions & 26 deletions frontend/src/components/channels/ChannelWaitingForConfirmations.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Footprints } from "lucide-react";
import EmptyState from "src/components/EmptyState";
import Lottie from "react-lottie";
import animationData from "src/assets/lotties/loading.json";
import Loading from "src/components/Loading";
import {
Card,
Expand All @@ -20,31 +20,37 @@ export function ChannelWaitingForConfirmations({
return <Loading />;
}

const defaultOptions = {
loop: true,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio: "xMidYMid slice",
},
};

return (
<div className="flex flex-col justify-center gap-2">
<Card>
<CardHeader>
<CardTitle>Your channel is being opened</CardTitle>
<CardDescription>
Waiting for {channel.confirmationsRequired} confirmations
</CardDescription>
</CardHeader>
<CardContent>
<div className="flex flex-row gap-2">
<Loading />
{channel.confirmations ?? "0"} /{" "}
{channel.confirmationsRequired ?? "unknown"} confirmations
</div>
</CardContent>
</Card>
<div className="w-full mt-40 flex flex-col items-center justify-center">
<EmptyState
icon={Footprints}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shall we keep this. i removed as per designs

title="Browse While You Wait"
description="Feel free to leave this page or browse around Alby Hub! We'll send you an email as soon as your channel is active."
buttonText="Explore Apps"
buttonLink="/appstore"
/>
<div className="flex flex-col gap-4">
<p className="text-muted-foreground ">
You can now leave this page.We’ll notify your by email once your channel
is active.
</p>
<div className="w-80 flex justify-center">
<Card className="text-center">
<CardHeader>
<CardTitle>Opening new lightning channel...</CardTitle>
<CardDescription>
Waiting for {channel.confirmationsRequired} confirmations
</CardDescription>
</CardHeader>
<CardContent>
<div className="flex flex-col gap-5 justify-center text-center">
<Lottie options={defaultOptions} height={256} width={256} />
{channel.confirmations ?? "0"} /{" "}
{channel.confirmationsRequired ?? "unknown"} confirmations
</div>
</CardContent>
</Card>
</div>
</div>
);
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/channels/DuplicateChannelAlert.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TriangleAlertIcon } from "lucide-react";
import { AlertCircleIcon } from "lucide-react";
import ExternalLink from "src/components/ExternalLink";
import { Alert, AlertDescription, AlertTitle } from "src/components/ui/alert";
import { useChannels } from "src/hooks/useChannels";
Expand All @@ -22,8 +22,8 @@ export function DuplicateChannelAlert({ pubkey, name }: PeerAlertProps) {
}

return (
<Alert>
<TriangleAlertIcon className="h-4 w-4" />
<Alert variant={"destructive"}>
<AlertCircleIcon className="h-4 w-4" />
<AlertTitle>
You already have a channel with{" "}
{name && name !== "Custom" ? (
Expand Down
Loading
Loading