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

Make Alby Account Optional #639

Merged
merged 17 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
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
10 changes: 2 additions & 8 deletions alby/alby_oauth_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,15 +839,9 @@ func (svc *albyOAuthService) activateAlbyAccountNWCNode(ctx context.Context) err

func (svc *albyOAuthService) GetChannelPeerSuggestions(ctx context.Context) ([]ChannelPeerSuggestion, error) {

token, err := svc.fetchUserToken(ctx)
if err != nil {
logger.Logger.WithError(err).Error("Failed to fetch user token")
return nil, err
}

client := svc.oauthConf.Client(ctx, token)
client := &http.Client{Timeout: 10 * time.Second}

req, err := http.NewRequest("GET", fmt.Sprintf("%s/internal/channel_suggestions", svc.cfg.GetEnv().AlbyAPIURL), nil)
req, err := http.NewRequest("GET", "https://getalby.com/api/internal/channel_suggestions", nil)
rolznz marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
logger.Logger.WithError(err).Error("Error creating request to channel_suggestions endpoint")
return nil, err
Expand Down
59 changes: 46 additions & 13 deletions frontend/src/components/layouts/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Megaphone,
Menu,
MessageCircleQuestion,
PlugZapIcon,
Settings,
ShieldAlertIcon,
ShieldCheckIcon,
Expand Down Expand Up @@ -88,15 +89,28 @@ export default function AppLayout() {
return (
<DropdownMenuContent align="end">
<DropdownMenuGroup>
<DropdownMenuItem>
<ExternalLink
to="https://getalby.com/settings"
className="w-full flex flex-row items-center gap-2"
>
<ExternalLinkIcon className="w-4 h-4" />
<p>Alby Account Settings</p>
</ExternalLink>
</DropdownMenuItem>
{!info?.albyAccountConnected && (
<DropdownMenuItem>
<Link
to="/alby/account"
className="w-full flex flex-row items-center gap-2"
>
<PlugZapIcon className="w-4 h-4" />
<p>Connect Alby Account</p>
</Link>
</DropdownMenuItem>
)}
{info?.albyAccountConnected && (
<DropdownMenuItem>
<ExternalLink
to="https://getalby.com/settings"
className="w-full flex flex-row items-center gap-2"
>
<ExternalLinkIcon className="w-4 h-4" />
<p>Alby Account Settings</p>
</ExternalLink>
</DropdownMenuItem>
)}
</DropdownMenuGroup>
<DropdownMenuSeparator />
{isHttpMode && (
Expand Down Expand Up @@ -183,7 +197,7 @@ export default function AppLayout() {
<MessageCircleQuestion className="h-4 w-4" />
Live Support
</MenuItem>
{!albyMe?.hub.name && (
{!albyMe?.hub.name && info?.albyAccountConnected && (
<MenuItem
to="/"
onClick={(e) => {
Expand Down Expand Up @@ -220,13 +234,15 @@ export default function AppLayout() {
<SidebarHint />
<MainNavSecondary />
<div className="flex h-14 items-center px-4 gap-3 border-t border-border justify-between">
<div className="grid grid-flow-col gap-2">
<div className="grid grid-flow-col gap-2 items-center">
<UserAvatar className="h-8 w-8" />
<Link
to="#"
className="font-semibold text-lg whitespace-nowrap overflow-hidden text-ellipsis"
>
{albyMe?.name || albyMe?.email}
{albyMe?.name ||
albyMe?.email ||
(!info.albyAccountConnected && "Satoshi Nakamoto")}
</Link>
</div>
<DropdownMenu modal={false}>
Expand Down Expand Up @@ -301,7 +317,24 @@ export default function AppLayout() {
function AppVersion() {
const { data: albyMe } = useAlbyMe();
const { data: info } = useInfo();
if (!info || !albyMe) {
if (!info) {
return null;
}

if (!info.albyAccountConnected) {
return (
<ExternalLink
to={`https://getalby.com/update/hub?version=${info.version}`}
className="font-semibold text-xl"
>
<span className="text-xs flex items-center text-muted-foreground">
{info.version && <>{info.version}&nbsp;</>}
</span>
</ExternalLink>
);
}

if (!albyMe) {
return null;
}

Expand Down
14 changes: 12 additions & 2 deletions frontend/src/components/layouts/SettingsLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ import { cn } from "src/lib/utils";
import { request } from "src/utils/request";

export default function SettingsLayout() {
const { mutate: refetchInfo, hasMnemonic, hasNodeBackup } = useInfo();
const {
data: info,
mutate: refetchInfo,
hasMnemonic,
hasNodeBackup,
} = useInfo();
const navigate = useNavigate();
const { toast } = useToast();
const [shuttingDown, setShuttingDown] = useState(false);
Expand Down Expand Up @@ -102,7 +107,12 @@ export default function SettingsLayout() {
{hasNodeBackup && (
<MenuItem to="/settings/node-backup">Migrate Node</MenuItem>
)}
<MenuItem to="/settings/alby-account">Alby Account</MenuItem>
{info?.albyAccountConnected && (
<MenuItem to="/settings/alby-account">Your Alby Account</MenuItem>
)}
{info && !info.albyAccountConnected && (
<MenuItem to="/alby/account">Alby Account</MenuItem>
)}
<MenuItem to="/settings/developer">Developer</MenuItem>
<MenuItem to="/settings/debug-tools">Debug Tools</MenuItem>
</nav>
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/components/redirects/DefaultRedirect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ export function DefaultRedirect() {
const navigate = useNavigate();

React.useEffect(() => {
if (!info || (info.running && info.unlocked && info.albyAccountConnected)) {
if (
!info ||
(info.running &&
info.unlocked &&
(info.albyAccountConnected || !info.albyUserIdentifier))
) {
return;
}
const returnTo = location.pathname + location.search;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/redirects/HomeRedirect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function HomeRedirect() {
let to: string | undefined;
if (info.setupCompleted && info.running) {
if (info.unlocked) {
if (info.albyAccountConnected) {
if (info.albyAccountConnected || !info.albyUserIdentifier) {
const returnTo = window.localStorage.getItem(
localStorageKeys.returnTo
);
Expand Down
23 changes: 0 additions & 23 deletions frontend/src/components/redirects/OnboardingRedirect.tsx

This file was deleted.

12 changes: 9 additions & 3 deletions frontend/src/hooks/useAlbyBalance.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import useSWR from "swr";

import { useInfo } from "src/hooks/useInfo";
import { AlbyBalance } from "src/types";
import { swrFetcher } from "src/utils/swr";

export function useAlbyBalance() {
return useSWR<AlbyBalance>("/api/alby/balance", swrFetcher, {
dedupingInterval: 5 * 60 * 1000, // 5 minutes
});
const { data: info } = useInfo();
return useSWR<AlbyBalance>(
info?.albyAccountConnected ? "/api/alby/balance" : undefined,
swrFetcher,
{
dedupingInterval: 5 * 60 * 1000, // 5 minutes
}
);
}
13 changes: 10 additions & 3 deletions frontend/src/hooks/useAlbyMe.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import useSWR from "swr";

import { useInfo } from "src/hooks/useInfo";
import { AlbyMe } from "src/types";
import { swrFetcher } from "src/utils/swr";

export function useAlbyMe() {
return useSWR<AlbyMe>("/api/alby/me", swrFetcher, {
dedupingInterval: 5 * 60 * 1000, // 5 minutes
});
const { data: info } = useInfo();

return useSWR<AlbyMe>(
info?.albyAccountConnected ? "/api/alby/me" : undefined,
swrFetcher,
{
dedupingInterval: 5 * 60 * 1000, // 5 minutes
}
);
}
30 changes: 17 additions & 13 deletions frontend/src/hooks/useOnboardingData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,19 @@ export const useOnboardingData = (): UseOnboardingDataResponse => {
const { data: transactions } = useTransactions(false, 1);

const isLoading =
!albyMe ||
!apps ||
!channels ||
!info ||
!nodeConnectionInfo ||
!transactions ||
!albyBalance;
(info.albyAccountConnected && (!albyMe || !albyBalance));

if (isLoading) {
return { isLoading: true, checklistItems: [] };
}

const isLinked =
albyMe &&
!!albyMe &&
nodeConnectionInfo &&
albyMe?.keysend_pubkey === nodeConnectionInfo?.pubkey;
const hasChannel =
Expand All @@ -60,27 +59,32 @@ export const useOnboardingData = (): UseOnboardingDataResponse => {

const checklistItems: Omit<ChecklistItem, "disabled">[] = [
{
title: "1. Open your first channel",
title: "Open your first channel",
description:
"Establish a new Lightning channel to enable fast and low-fee Bitcoin transactions.",
checked: hasChannel,
to: "/channels/first",
},
...(info.albyAccountConnected
? [
{
title: "Link to your Alby Account",
description:
"Link your lightning address & other apps to this Hub.",
checked: isLinked,
to: "/apps",
},
]
: []),
{
title: "2. Link to your Alby Account",
description: "Link your lightning address & other apps to this Hub.",
checked: isLinked,
to: "/apps",
},
{
title: "3. Send or receive your first payment",
title: "Send or receive your first payment",
description:
"Use your newly opened channel to make a transaction on the Lightning Network.",
checked: hasTransaction,
to: "/wallet",
},
{
title: "4. Connect your first app",
title: "Connect your first app",
description:
"Seamlessly connect apps and integrate your wallet with other apps from your Hub.",
checked: hasCustomApp,
Expand All @@ -89,7 +93,7 @@ export const useOnboardingData = (): UseOnboardingDataResponse => {
...(hasMnemonic
? [
{
title: "5. Backup your keys",
title: "Backup your keys",
description:
"Secure your keys by creating a backup to ensure you don't lose access.",
checked: hasBackedUp === true,
Expand Down
17 changes: 5 additions & 12 deletions frontend/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import SettingsLayout from "src/components/layouts/SettingsLayout";
import TwoColumnFullScreenLayout from "src/components/layouts/TwoColumnFullScreenLayout";
import { DefaultRedirect } from "src/components/redirects/DefaultRedirect";
import { HomeRedirect } from "src/components/redirects/HomeRedirect";
import { OnboardingRedirect } from "src/components/redirects/OnboardingRedirect";
import { SetupRedirect } from "src/components/redirects/SetupRedirect";
import { StartRedirect } from "src/components/redirects/StartRedirect";
import { BackupMnemonic } from "src/screens/BackupMnemonic";
import { BackupNode } from "src/screens/BackupNode";
import { BackupNodeSuccess } from "src/screens/BackupNodeSuccess";
import { ConnectAlbyAccount } from "src/screens/ConnectAlbyAccount";
import Home from "src/screens/Home";
import { Intro } from "src/screens/Intro";
import NotFound from "src/screens/NotFound";
Expand All @@ -35,7 +35,6 @@ import { OpenedFirstChannel } from "src/screens/channels/first/OpenedFirstChanne
import { OpeningFirstChannel } from "src/screens/channels/first/OpeningFirstChannel";
import { BuzzPay } from "src/screens/internal-apps/BuzzPay";
import { UncleJim } from "src/screens/internal-apps/UncleJim";
import { Success } from "src/screens/onboarding/Success";
import BuyBitcoin from "src/screens/onchain/BuyBitcoin";
import DepositBitcoin from "src/screens/onchain/DepositBitcoin";
import ConnectPeer from "src/screens/peers/ConnectPeer";
Expand Down Expand Up @@ -331,6 +330,10 @@ const routes = [
</StartRedirect>
),
},
{
path: "alby/account",
element: <ConnectAlbyAccount />,
},
{
path: "alby/auth",
element: <AlbyAuthRedirect />,
Expand Down Expand Up @@ -409,16 +412,6 @@ const routes = [
},
],
},
{
path: "onboarding",
element: <OnboardingRedirect />,
children: [
{
path: "success",
element: <Success />,
},
],
},
{
path: "alby/auth",
element: <AlbyAuthRedirect />,
Expand Down
29 changes: 29 additions & 0 deletions frontend/src/screens/ConnectAlbyAccount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { LinkButton } from "src/components/ui/button";

export function ConnectAlbyAccount() {
return (
<div className="w-full h-full flex flex-col items-center justify-center gap-5">
<div className="w-full max-w-screen-sm">
<img
src="/images/illustrations/alby-account-dark.svg"
className="w-full hidden dark:block"
/>
<img
src="/images/illustrations/alby-account-light.svg"
className="w-full dark:hidden"
/>
</div>
<p className="max-w-md text-muted-foreground text-center">
Your Alby Account gives your hub a lightning address, Nostr address and
zaps, email notifications, automatic channel backups, access to
podcasting apps & more.
</p>
<div className="flex flex-col items-center justify-center mt-5 gap-2">
<LinkButton to="/alby/auth">Connect now</LinkButton>
<LinkButton variant="ghost" to="/">
Maybe later
</LinkButton>
</div>
</div>
);
}
Loading
Loading