Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
FROM node:20-alpine as frontend

# Set the base path for the frontend build
# This can be overridden at build time with --build-arg BASE_PATH=<url> e.g. --build-arg BASE_PATH=/hub
# Allows to build a frontend that can be served from a subpath, e.g. /hub
ARG BASE_PATH
WORKDIR /build
COPY frontend ./frontend
RUN echo "Building frontend with base path $BASE_PATH"
RUN cd frontend && yarn install --network-timeout 3000000 && yarn build:http

FROM golang:1.24 as builder
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ Go to `/frontend`
1. `yarn install`
2. `yarn dev`

### HTTP Production build

$ yarn build:http

If you plan to run Alby Hub on a subpath behind a reverse proxy, you can do:

$ BASE_PATH="/hub" yarn build:http

### Wails (Backend + Frontend)

_Make sure to have [wails](https://wails.io/docs/gettingstarted/installation) installed and all platform-specific dependencies installed (see wails doctor)_
Expand Down
6 changes: 6 additions & 0 deletions frontend/platform_specific/http/src/utils/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import { ErrorResponse } from "src/types";
export const request = async <T>(
...args: Parameters<typeof fetch>
): Promise<T | undefined> => {
if (import.meta.env.BASE_URL !== "/") {
// if running on a subpath, include the subpath in the request URL
// BASE_URL is set via process.env.BASE_PATH, see https://vite.dev/guide/build#public-base-path
args[0] = import.meta.env.BASE_URL + args[0];
}

const token = getAuthToken();
if (token) {
if (!args[1]) {
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import routes from "src/routes.tsx";
import { isHttpMode } from "src/utils/isHttpMode";

const createRouterFunc = isHttpMode() ? createBrowserRouter : createHashRouter;
const router = createRouterFunc(routes);
const router = createRouterFunc(routes, {
// if running on a subpath, use the subpath as the router basename
// BASE_URL is set via process.env.BASE_PATH, see https://vite.dev/guide/build#public-base-path
basename:
import.meta.env.BASE_URL !== "/" ? import.meta.env.BASE_URL : undefined,
});

function App() {
const { data: info } = useInfo();
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/components/connections/AlbyConnectionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ import { useAlbyMe } from "src/hooks/useAlbyMe";
import { LinkStatus, useLinkAccount } from "src/hooks/useLinkAccount";
import { App, BudgetRenewalType } from "src/types";

import AlbyAccountDarkSVG from "public/images/illustrations/alby-account-dark.svg";
import AlbyAccountLightSVG from "public/images/illustrations/alby-account-light.svg";

function AlbyConnectionCard({ connection }: { connection?: App }) {
const { data: albyMe } = useAlbyMe();
const { loading, linkStatus, loadingLinkStatus, linkAccount } =
Expand Down Expand Up @@ -109,11 +112,11 @@ function AlbyConnectionCard({ connection }: { connection?: App }) {
every app you access through your Alby Account will
handle payments via the Hub.
<img
src="/images/illustrations/alby-account-dark.svg"
src={AlbyAccountDarkSVG}
className="w-full hidden dark:block"
/>
<img
src="/images/illustrations/alby-account-light.svg"
src={AlbyAccountLightSVG}
className="w-full dark:hidden"
/>
You can add a budget that will restrict how much can be
Expand Down
25 changes: 17 additions & 8 deletions frontend/src/components/layouts/TwoColumnFullScreenLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ import { AlbyHubLogo } from "src/components/icons/AlbyHubLogo";
import { Button } from "src/components/ui/button.tsx";
import { useInfo } from "src/hooks/useInfo";

import AntonopoulosSVG from "public/images/quotes/antonopoulos.svg";
import BackSVG from "public/images/quotes/back.svg";
import FinneySVG from "public/images/quotes/finney.svg";
import HayekSVG from "public/images/quotes/hayek.svg";
import NakamotoSVG from "public/images/quotes/nakamoto.svg";
import ObamaSVG from "public/images/quotes/obama.svg";
import RolandSVG from "public/images/quotes/roland.svg";
import WilsonSVG from "public/images/quotes/wilson.svg";

const quotes = [
{
content: `This isn't about nation-states anymore. This isn't about who adopts
Expand All @@ -13,42 +22,42 @@ const quotes = [
largest economy. It is the first transnational economy, and it needs a
transnational currency.`,
author: "Andreas M. Antonopoulos",
imageUrl: "/images/quotes/antonopoulos.svg",
imageUrl: AntonopoulosSVG,
},
{
content: `It might make sense just to get some in case it catches on. If enough people think the same way, that becomes a self fulfilling prophecy. Once it gets bootstrapped, there are so many applications if you could effortlessly pay a few cents to a website as easily as dropping coins in a vending machine.`,
author: "Satoshi Nakamoto",
imageUrl: "/images/quotes/nakamoto.svg",
imageUrl: NakamotoSVG,
},
{
content: `Since we're all rich with bitcoins, or we will be once they're worth a million dollars like everyone expects, we ought to put some of this unearned wealth to good use.`,
author: "Hal Finney",
imageUrl: "/images/quotes/finney.svg",
imageUrl: FinneySVG,
},
{
content: `I don't believe we shall ever have a good money again before we take the thing out of the hands of government, that is, we can't take it violently out of the hands of government, all we can do is by some sly roundabout way introduce something that they can't stop.`,
author: "Friedrich August von Hayek",
imageUrl: "/images/quotes/hayek.svg",
imageUrl: HayekSVG,
},
{
content: `Bitcoin is what they fear it is.`,
author: "Cody Wilson",
imageUrl: "/images/quotes/wilson.svg",
imageUrl: WilsonSVG,
},
{
content: `If in fact you can't crack that at all, government can't get in then —everybody's walking around with a Swiss bank account in their pocket.`,
author: "Barack Obama",
imageUrl: "/images/quotes/obama.svg",
imageUrl: ObamaSVG,
},
{
content: `Bitcoin is the new wonder of the world, more work and human ingenuity, than went into the great pyramids of Egypt. The biggest computation ever done, a digital monument, a verifiable artefact of digital gold - the foundation of a new digital age.`,
author: "Adam Back",
imageUrl: "/images/quotes/back.svg",
imageUrl: BackSVG,
},
{
content: `We who choose Bitcoin, are pioneers of a new world. A world filled with freedom, hope and peace.`,
author: "Roland",
imageUrl: "/images/quotes/roland.svg",
imageUrl: RolandSVG,
},
];

Expand Down
10 changes: 5 additions & 5 deletions frontend/src/screens/channels/IncreaseIncomingCapacity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ import {
RecommendedChannelPeer,
} from "src/types";

import LightningNetworkDarkSVG from "public/images/illustrations/lightning-network-dark.svg";
import LightningNetworkLightSVG from "public/images/illustrations/lightning-network-light.svg";

function getPeerKey(peer: RecommendedChannelPeer) {
return JSON.stringify(peer);
}
Expand Down Expand Up @@ -229,13 +232,10 @@ function NewChannelInternal({
/>
<div className="md:max-w-md max-w-full flex flex-col gap-5 flex-1">
<img
src="/images/illustrations/lightning-network-dark.svg"
src={LightningNetworkDarkSVG}
className="w-full hidden dark:block"
/>
<img
src="/images/illustrations/lightning-network-light.svg"
className="w-full dark:hidden"
/>
<img src={LightningNetworkLightSVG} className="w-full dark:hidden" />
<p className="text-muted-foreground">
Alby Hub works with selected service providers (LSPs) which provide
the best network connectivity and liquidity to receive payments.{" "}
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ import {
} from "src/types";
import { request } from "src/utils/request";

import LightningNetworkDarkSVG from "public/images/illustrations/lightning-network-dark.svg";
import LightningNetworkLightSVG from "public/images/illustrations/lightning-network-light.svg";

function getPeerKey(peer: RecommendedChannelPeer) {
return JSON.stringify(peer);
}
Expand Down Expand Up @@ -200,13 +203,10 @@ function NewChannelInternal({ network }: { network: Network }) {
/>
<div className="md:max-w-md max-w-full flex flex-col gap-5 flex-1">
<img
src="/images/illustrations/lightning-network-dark.svg"
src={LightningNetworkDarkSVG}
className="w-full hidden dark:block"
/>
<img
src="/images/illustrations/lightning-network-light.svg"
className="w-full dark:hidden"
/>
<img src={LightningNetworkLightSVG} className="w-full dark:hidden" />
<p className="text-muted-foreground">
Open a channel with on-chain funds. Both parties are free to close the
channel at any time. However, by keeping more funds on your side of
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/screens/channels/auto/AutoChannel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import { MempoolAlert } from "src/components/MempoolAlert";
import { PayLightningInvoice } from "src/components/PayLightningInvoice";
import { ChannelPublicPrivateAlert } from "src/components/channels/ChannelPublicPrivateAlert";

import LightningNetworkDarkSVG from "public/images/illustrations/lightning-network-dark.svg";
import LightningNetworkLightSVG from "public/images/illustrations/lightning-network-light.svg";

export function AutoChannel() {
const { data: info } = useInfo();
const { data: channels } = useChannels(true);
Expand Down Expand Up @@ -134,11 +137,11 @@ export function AutoChannel() {
<>
<div className="flex flex-col gap-6 max-w-md text-muted-foreground">
<img
src="/images/illustrations/lightning-network-dark.svg"
src={LightningNetworkDarkSVG}
className="w-full hidden dark:block"
/>
<img
src="/images/illustrations/lightning-network-light.svg"
src={LightningNetworkLightSVG}
className="w-full dark:hidden"
/>

Expand Down
7 changes: 5 additions & 2 deletions frontend/src/screens/channels/first/FirstChannel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import { PayLightningInvoice } from "src/components/PayLightningInvoice";
import { Table, TableBody, TableCell, TableRow } from "src/components/ui/table";
import { ALBY_MIN_HOSTED_BALANCE_FOR_FIRST_CHANNEL } from "src/constants";

import LightningNetworkDarkSVG from "public/images/illustrations/lightning-network-dark.svg";
import LightningNetworkLightSVG from "public/images/illustrations/lightning-network-light.svg";

export function FirstChannel() {
const { data: info } = useInfo();
const { data: channels } = useChannels(true);
Expand Down Expand Up @@ -167,11 +170,11 @@ export function FirstChannel() {
<>
<div className="flex flex-col gap-6 max-w-md text-muted-foreground">
<img
src="/images/illustrations/lightning-network-dark.svg"
src={LightningNetworkDarkSVG}
className="w-full hidden dark:block"
/>
<img
src="/images/illustrations/lightning-network-light.svg"
src={LightningNetworkLightSVG}
className="w-full dark:hidden"
/>
{canPayForFirstChannel ? (
Expand Down
13 changes: 5 additions & 8 deletions frontend/src/screens/subwallets/SubwalletIntro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import ExternalLink from "src/components/ExternalLink";
import ResponsiveButton from "src/components/ResponsiveButton";
import { Button } from "src/components/ui/button";

import SubWalletDarkSVG from "public/images/illustrations/sub-wallet-dark.svg";
import SubWalletLightSVG from "public/images/illustrations/sub-wallet-light.svg";

export function SubwalletIntro() {
return (
<div className="grid gap-4">
Expand All @@ -33,14 +36,8 @@ export function SubwalletIntro() {
<div>
<div className="flex flex-col gap-6 max-w-screen-md">
<div className="mb-2">
<img
src="/images/illustrations/sub-wallet-dark.svg"
className="w-72 hidden dark:block"
/>
<img
src="/images/illustrations/sub-wallet-light.svg"
className="w-72 dark:hidden"
/>
<img src={SubWalletDarkSVG} className="w-72 hidden dark:block" />
<img src={SubWalletLightSVG} className="w-72 dark:hidden" />
</div>
<div>
<div className="flex flex-row gap-3">
Expand Down
5 changes: 5 additions & 0 deletions frontend/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ export default defineConfig(({ command }) => ({
alias: {
src: path.resolve(__dirname, "./src"),
wailsjs: path.resolve(__dirname, "./wailsjs"),
// used to refrence public assets when importing images or other
// assets from the public folder
// this is necessary to inject the base path during build
public: "",
},
},
build: {
Expand All @@ -75,6 +79,7 @@ export default defineConfig(({ command }) => ({
cspNonce: "DEVELOPMENT",
}
: undefined,
base: process.env.BASE_PATH || "/",
}));

const DEVELOPMENT_NONCE = "'nonce-DEVELOPMENT'";
Expand Down
8 changes: 8 additions & 0 deletions scripts/caddy-subpath/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# FOR TESTING ONLY, do not use internal tls!
https://your-domain.com {
redir /example-path /example-path/ 301
handle_path /example-path* {
reverse_proxy localhost:8080
}
tls internal
}
17 changes: 17 additions & 0 deletions scripts/caddy-subpath/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Caddy Subpath

This is an example of how to run Alby Hub on a subpath using Caddy

To test locally edit `sudo nano /etc/hosts` and add `127.0.0.1 your-domain.com`

Use the following environment variables when building the frontend:

```bash
BASE_PATH="/example-path" yarn build:http
```

Then run Alby Hub as normal. (if default port is not 8080 you will need to update the Caddyfile)

Then start caddy: `sudo caddy run -c ./Caddyfile`

and visit `http://your-domain.com/example-path