feat(albyhub): vendor v1.24.0 LND-only, no-frontend build

Replace the nixpkgs albyhub overrideAttrs patch-chain with a fully
vendored package at packages/albyhub for v1.24.0.

- modules/core/sovran-hub.nix: bump fallback version 1.8.0 -> 1.24.0
- modules/nwc-wallets.nix: build via pkgs.callPackage ../packages/albyhub
- packages/albyhub:
  - drop 0002-isolated-invoice-app-id.patch (fixed upstream)
  - add 0004-lnd-only.patch: strip LDK/Bark/Cashu/CLN/Phoenix backends
    from service/start.go, leaving only the LND case
  - add 0005-no-frontend.patch: remove //go:embed dist and the
    frontend handler registration
  - add default.nix: buildGoModule for v1.24.0 with no nodejs/yarn/
    bark-ffi-go/ldk-node deps (only stdenv.cc.cc), subPackages cmd/http

Keeps 0001-private-route-hints and 0003-loopback-bind-host. Does not
touch flake.nix, VERSION, or CHANGELOG.
This commit is contained in:
2026-08-25 19:11:25 -05:00
parent 14db4282b7
commit d600198049
6 changed files with 244 additions and 79 deletions
+1 -1
View File
@@ -143,7 +143,7 @@ let
# module. Read the configured package here rather than pkgs.btcpayserver # module. Read the configured package here rather than pkgs.btcpayserver
# (unstable), otherwise the Hub can advertise a version that is not running. # (unstable), otherwise the Hub can advertise a version that is not running.
"btcpayserver.service" = lib.getVersion config.services.btcpayserver.package; "btcpayserver.service" = lib.getVersion config.services.btcpayserver.package;
"albyhub.service" = if pkgs ? albyhub then pkgs.albyhub.version else "1.8.0"; "albyhub.service" = if pkgs ? albyhub then pkgs.albyhub.version else "1.24.0";
"mempool.service" = if pkgs ? mempool then pkgs.mempool.version else "3.2.1"; "mempool.service" = if pkgs ? mempool then pkgs.mempool.version else "3.2.1";
"matrix-synapse.service" = if pkgs ? matrix-synapse then pkgs.matrix-synapse.version else "1.115.0"; "matrix-synapse.service" = if pkgs ? matrix-synapse then pkgs.matrix-synapse.version else "1.115.0";
"livekit.service" = if pkgs ? livekit then pkgs.livekit.version else "1.5.2"; "livekit.service" = if pkgs ? livekit then pkgs.livekit.version else "1.5.2";
+2 -7
View File
@@ -3,13 +3,8 @@
let let
albyHubPort = 18080; albyHubPort = 18080;
albyHubApiBase = "http://127.0.0.1:${toString albyHubPort}"; albyHubApiBase = "http://127.0.0.1:${toString albyHubPort}";
patchedAlbyHub = pkgs.albyhub.overrideAttrs (old: { vendoredAlbyHub = pkgs.callPackage ../packages/albyhub {};
patches = (old.patches or []) ++ [ patchedAlbyHub = vendoredAlbyHub;
../packages/albyhub/0001-private-route-hints.patch
../packages/albyhub/0002-isolated-invoice-app-id.patch
../packages/albyhub/0003-loopback-bind-host.patch
];
});
lndRpcAddress = lib.attrByPath [ "services" "lnd" "rpcAddress" ] "127.0.0.1" config; lndRpcAddress = lib.attrByPath [ "services" "lnd" "rpcAddress" ] "127.0.0.1" config;
lndRpcPort = toString (lib.attrByPath [ "services" "lnd" "rpcPort" ] 10009 config); lndRpcPort = toString (lib.attrByPath [ "services" "lnd" "rpcPort" ] 10009 config);
@@ -1,71 +0,0 @@
diff --git a/api/models.go b/api/models.go
index 28bd117..dceb79a 100644
--- a/api/models.go
+++ b/api/models.go
@@ -46,7 +46,7 @@ type API interface {
ListTransactions(ctx context.Context, appId *uint, limit uint64, offset uint64) (*ListTransactionsResponse, error)
ListOnchainTransactions(ctx context.Context) ([]OnchainTransaction, error)
SendPayment(ctx context.Context, invoice string, amountMsat *uint64, metadata map[string]interface{}, fromAppId *uint) (*SendPaymentResponse, error)
- CreateInvoice(ctx context.Context, amountMsat uint64, description string) (*MakeInvoiceResponse, error)
+ CreateInvoice(ctx context.Context, amountMsat uint64, description string, appId *uint) (*MakeInvoiceResponse, error)
LookupInvoice(ctx context.Context, paymentHash string) (*LookupInvoiceResponse, error)
SetTransactionUserLabels(ctx context.Context, id uint, labels map[string]string) error
RequestMempoolApi(ctx context.Context, endpoint string) (interface{}, error)
@@ -586,6 +586,7 @@ type MakeInvoiceRequest struct {
AmountSat *uint64 `json:"amountSat"`
AmountMsat *uint64 `json:"amountMsat"`
Description string `json:"description"`
+ AppId *uint `json:"appId"`
}
type ResetRouterRequest struct {
diff --git a/api/transactions.go b/api/transactions.go
index aaf9380..3f9850a 100644
--- a/api/transactions.go
+++ b/api/transactions.go
@@ -12,12 +12,12 @@ import (
"github.com/sirupsen/logrus"
)
-func (api *api) CreateInvoice(ctx context.Context, amountMsat uint64, description string) (*MakeInvoiceResponse, error) {
+func (api *api) CreateInvoice(ctx context.Context, amountMsat uint64, description string, appId *uint) (*MakeInvoiceResponse, error) {
lnClient := api.svc.GetLNClient()
if lnClient == nil {
return nil, ErrLNClientNotStarted
}
- transaction, err := api.svc.GetTransactionsService().MakeInvoice(ctx, amountMsat, description, "", 0, nil, lnClient, nil, nil, nil)
+ transaction, err := api.svc.GetTransactionsService().MakeInvoice(ctx, amountMsat, description, "", 0, nil, lnClient, appId, nil, nil)
if err != nil {
return nil, err
}
diff --git a/http/http_service.go b/http/http_service.go
index bf650b9..cf61250 100644
--- a/http/http_service.go
+++ b/http/http_service.go
@@ -687,7 +687,12 @@ func (httpSvc *HttpService) makeInvoiceHandler(c echo.Context) error {
amountMsat = *resolvedAmountMsat
}
- invoice, err := httpSvc.api.CreateInvoice(c.Request().Context(), amountMsat, makeInvoiceRequest.Description)
+ invoice, err := httpSvc.api.CreateInvoice(
+ c.Request().Context(),
+ amountMsat,
+ makeInvoiceRequest.Description,
+ makeInvoiceRequest.AppId,
+ )
if err != nil {
return c.JSON(http.StatusInternalServerError, ErrorResponse{
diff --git a/wails/wails_handlers.go b/wails/wails_handlers.go
index d25259b..c9fe4e8 100644
--- a/wails/wails_handlers.go
+++ b/wails/wails_handlers.go
@@ -600,7 +600,7 @@ func (app *WailsApp) WailsRequestRouter(route string, method string, body string
if resolvedAmountMsat != nil {
amountMsat = *resolvedAmountMsat
}
- invoice, err := app.api.CreateInvoice(ctx, amountMsat, makeInvoiceRequest.Description)
+ invoice, err := app.api.CreateInvoice(ctx, amountMsat, makeInvoiceRequest.Description, nil)
if err != nil {
return WailsRequestRouterResponse{Body: nil, Error: err.Error()}
}
+141
View File
@@ -0,0 +1,141 @@
diff --git a/service/start.go b/service/start.go
index 8c9786a..4b992c7 100644
--- a/service/start.go
+++ b/service/start.go
@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
- "path"
"strconv"
"time"
@@ -349,63 +348,12 @@ func (svc *service) launchLNBackend(ctx context.Context, encryptionKey string) e
logger.Logger.Infof("Launching LN Backend: %s", lnBackend)
var lnClient lnclient.LNClient
var err error
- vssEnabled := false
switch lnBackend {
case config.LNDBackendType:
LNDAddress, _ := svc.cfg.Get("LNDAddress", encryptionKey)
LNDCertHex, _ := svc.cfg.Get("LNDCertHex", encryptionKey)
LNDMacaroonHex, _ := svc.cfg.Get("LNDMacaroonHex", encryptionKey)
lnClient, err = lnd.NewLNDService(ctx, svc.eventPublisher, LNDAddress, LNDCertHex, LNDMacaroonHex)
- case config.LDKBackendType:
- mnemonic, _ := svc.cfg.Get("Mnemonic", encryptionKey)
- ldkWorkdir := path.Join(svc.cfg.GetEnv().Workdir, "ldk")
- var vssToken string
- vssToken, err = svc.requestVssToken(ctx)
- if err != nil {
- logger.Logger.WithError(err).Error("Failed to request VSS token")
- return err
- }
- vssEnabled = vssToken != ""
-
- svc.startupState = "Launching Node"
- setStartupState := func(startupState string) {
- svc.startupState = startupState
- }
-
- channelPeerSuggestions, suggestionsErr := svc.albySvc.GetChannelPeerSuggestions(ctx)
- if suggestionsErr != nil {
- logger.Logger.WithError(suggestionsErr).Warn("Failed to fetch channel peer suggestions for LSPS2 liquidity source")
- }
- lnClient, err = ldk.NewLDKService(ctx, svc.cfg, svc.eventPublisher, mnemonic, ldkWorkdir, vssToken, setStartupState, channelPeerSuggestions)
- case config.PhoenixBackendType:
- PhoenixdAddress, _ := svc.cfg.Get("PhoenixdAddress", encryptionKey)
- PhoenixdAuthorization, _ := svc.cfg.Get("PhoenixdAuthorization", encryptionKey)
-
- lnClient, err = phoenixd.NewPhoenixService(ctx, PhoenixdAddress, PhoenixdAuthorization)
- case config.CashuBackendType:
- mnemonic, _ := svc.cfg.Get("Mnemonic", encryptionKey)
- cashuMintUrl, _ := svc.cfg.Get("CashuMintUrl", encryptionKey)
- cashuWorkdir := path.Join(svc.cfg.GetEnv().Workdir, "cashu")
-
- lnClient, err = cashu.NewCashuService(svc.cfg, cashuWorkdir, mnemonic, cashuMintUrl)
- case config.BarkBackendType:
- mnemonic, _ := svc.cfg.Get("Mnemonic", encryptionKey)
- env := svc.cfg.GetEnv()
- barkWorkdir := path.Join(env.Workdir, "bark")
-
- lnClient, err = bark.NewBarkService(ctx, svc.eventPublisher, barkWorkdir, mnemonic, bark.Config{
- Network: svc.cfg.GetNetwork(),
- ServerAddress: env.BarkServer,
- EsploraAddress: env.BarkEsploraServer,
- ServerAccessToken: env.BarkServerAccessToken,
- LogLevel: env.BarkLogLevel,
- LogToFile: env.LogToFile,
- })
- case config.CLNBackendType:
- CLNAddress, _ := svc.cfg.Get("CLNAddress", encryptionKey)
- CLNLightningDir, _ := svc.cfg.Get("CLNLightningDir", encryptionKey)
- CLNAddressHold, _ := svc.cfg.Get("CLNAddressHold", encryptionKey)
- lnClient, err = cln.NewCLNService(ctx, svc.eventPublisher, CLNAddress, CLNLightningDir, CLNAddressHold)
default:
logger.Logger.WithField("backend_type", lnBackend).Error("Unsupported LNBackendType")
return fmt.Errorf("unsupported backend type: %s", lnBackend)
@@ -439,63 +387,9 @@ func (svc *service) launchLNBackend(ctx context.Context, encryptionKey string) e
svc.eventPublisher.Publish(&events.Event{
Event: "nwc_node_started",
Properties: map[string]interface{}{
- "node_type": lnBackend,
- "vss_enabled": vssEnabled,
+ "node_type": lnBackend,
},
})
return nil
}
-
-func (svc *service) requestVssToken(ctx context.Context) (string, error) {
- nodeLastStartTime, _ := svc.cfg.Get("NodeLastStartTime", "")
-
- // for brand new nodes, consider enabling VSS
- if nodeLastStartTime == "" && svc.cfg.GetEnv().LDKVssUrl != "" {
- svc.startupState = "Checking Subscription"
- albyUserIdentifier, err := svc.albyOAuthSvc.GetUserIdentifier()
- if err != nil {
- logger.Logger.WithError(err).Error("Failed to fetch alby user identifier")
- return "", err
- }
- if albyUserIdentifier != "" {
- me, err := svc.albyOAuthSvc.GetMe(ctx)
- if err != nil {
- logger.Logger.WithError(err).Error("Failed to fetch alby user")
- return "", err
- }
- // only activate VSS for Alby paid subscribers
- if me.Subscription.PlanCode != "" {
- svc.cfg.SetUpdate("LdkVssEnabled", "true", "")
- }
- }
- }
-
- vssToken := ""
- vssEnabled, _ := svc.cfg.Get("LdkVssEnabled", "")
- if vssEnabled == "true" {
- svc.startupState = "Fetching VSS token"
- vssNodeIdentifier, err := ldk.GetVssNodeIdentifier(svc.keys)
- if err != nil {
- logger.Logger.WithError(err).Error("Failed to get VSS node identifier")
- return "", err
- }
- vssToken, err = svc.albyOAuthSvc.GetVssAuthToken(ctx, vssNodeIdentifier)
- if err != nil {
- logger.Logger.WithError(err).Error("Failed to fetch VSS JWT token")
-
- existingVssToken, _ := svc.cfg.Get("VssToken", "")
- if existingVssToken != "" {
- logger.Logger.Warn("Using stored VSS JWT token")
- return existingVssToken, nil
- }
-
- return "", err
- }
- err = svc.cfg.SetUpdate("VssToken", vssToken, "")
- if err != nil {
- logger.Logger.WithError(err).Error("Failed to save VSS JWT token to user config")
- }
- }
- return vssToken, nil
-}
+45
View File
@@ -0,0 +1,45 @@
diff --git a/frontend/frontend.go b/frontend/frontend.go
index 203dd9b..9c7f6da 100644
--- a/frontend/frontend.go
+++ b/frontend/frontend.go
@@ -1,26 +1,7 @@
package frontend
import (
- "embed"
- "net/http"
-
"github.com/labstack/echo/v4"
- "github.com/labstack/echo/v4/middleware"
)
-//go:embed dist
-var embeddedReactAssets embed.FS
-
-func RegisterHandlers(e *echo.Echo) {
- e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
- Skipper: nil,
- // Root directory from where the static content is served.
- Root: "dist",
- // Enable HTML5 mode by forwarding all not-found requests to root so that
- // SPA (single-page application) can handle the routing.
- HTML5: true,
- Browse: false,
- IgnoreBase: false,
- Filesystem: http.FS(embeddedReactAssets),
- }))
-}
+func RegisterHandlers(e *echo.Echo) {}
diff --git a/http/http_service.go b/http/http_service.go
index 63d0ffc..0621bf5 100644
--- a/http/http_service.go
+++ b/http/http_service.go
@@ -114,8 +114,6 @@ func (httpSvc *HttpService) RegisterSharedRoutes(e *echo.Echo) {
e.POST("/api/backup", httpSvc.createBackupHandler, unlockRateLimiter)
e.GET("/logout", httpSvc.logoutHandler)
- frontend.RegisterHandlers(e)
-
// restricted routes
// Configure middleware with the custom claims type
jwtConfig := echojwt.Config{
+55
View File
@@ -0,0 +1,55 @@
{ lib
, buildGoModule
, fetchFromGitHub
, stdenv
}:
buildGoModule (finalAttrs: {
pname = "albyhub";
version = "1.24.0";
src = fetchFromGitHub {
owner = "getAlby";
repo = "hub";
tag = "v${finalAttrs.version}";
hash = "sha256-IC3rl/9aJ88GgvGfhcJb1/pQb3xIkhYih1hLPJ8itP8=";
};
vendorHash = "sha256-A4OsntoJUDkvWJxnZFFxw5AjUPmwRl764nQ5FEA2yeo=";
patches = [
./0001-private-route-hints.patch
./0003-loopback-bind-host.patch
./0004-lnd-only.patch
./0005-no-frontend.patch
];
# LND-only, no-frontend build: the only native dependency needed for
# cgo (sqlite3) is the C/C++ runtime from stdenv.cc.cc. No nodejs/yarn
# (no frontend), no bark-ffi-go or ldk-node (removed backends).
buildInputs = [
(lib.getLib stdenv.cc.cc)
];
subPackages = [
"cmd/http"
];
ldflags = [
"-X github.com/getAlby/hub/version.Tag=v${finalAttrs.version}"
"-s"
"-w"
];
postInstall = ''
mv $out/bin/http $out/bin/albyhub
'';
meta = {
description = "Control lightning wallets over nostr";
homepage = "https://github.com/getAlBy/hub";
license = lib.licenses.asl20;
platforms = lib.platforms.linux;
mainProgram = "albyhub";
};
})