From ed2e4059c16dc7c319bf6b694a9b62dd007d1f83 Mon Sep 17 00:00:00 2001 From: naturallaw77 Date: Thu, 27 Aug 2026 00:50:35 -0500 Subject: [PATCH] albyhub: build from sovran fork tag (LND-only, no frontend) --- .../albyhub/0001-private-route-hints.patch | 13 -- .../albyhub/0003-loopback-bind-host.patch | 37 ----- packages/albyhub/0004-lnd-only.patch | 141 ------------------ packages/albyhub/0005-no-frontend.patch | 45 ------ packages/albyhub/default.nix | 76 +++++----- 5 files changed, 39 insertions(+), 273 deletions(-) delete mode 100644 packages/albyhub/0001-private-route-hints.patch delete mode 100644 packages/albyhub/0003-loopback-bind-host.patch delete mode 100644 packages/albyhub/0004-lnd-only.patch delete mode 100644 packages/albyhub/0005-no-frontend.patch diff --git a/packages/albyhub/0001-private-route-hints.patch b/packages/albyhub/0001-private-route-hints.patch deleted file mode 100644 index e360635..0000000 --- a/packages/albyhub/0001-private-route-hints.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/lnclient/lnd/lnd.go b/lnclient/lnd/lnd.go -index bad532f..ba35b7b 100644 ---- a/lnclient/lnd/lnd.go -+++ b/lnclient/lnd/lnd.go -@@ -708,7 +708,7 @@ func (svc *LNDService) MakeInvoice(ctx context.Context, amountMsat int64, descri - DescriptionHash: descriptionHashBytes, - Expiry: expiry, - RouteHints: hints, -- Private: !hasPublicChannels, // use private channel hints in the invoice -+ Private: true, // always include private channel hints in the invoice - } - - resp, err := svc.client.AddInvoice(ctx, addInvoiceRequest) diff --git a/packages/albyhub/0003-loopback-bind-host.patch b/packages/albyhub/0003-loopback-bind-host.patch deleted file mode 100644 index e01d241..0000000 --- a/packages/albyhub/0003-loopback-bind-host.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff --git a/cmd/http/main.go b/cmd/http/main.go -index ed31f96..4d31212 100644 ---- a/cmd/http/main.go -+++ b/cmd/http/main.go -@@ -2,8 +2,8 @@ package main - - import ( - "context" -- "fmt" - nethttp "net/http" -+ "net" - "os" - "os/signal" - "syscall" -@@ -51,8 +51,9 @@ func main() { - httpSvc := http.NewHttpService(svc, svc.GetEventPublisher()) - httpSvc.RegisterSharedRoutes(e) - //start Echo server -+ bindAddress := net.JoinHostPort(svc.GetConfig().GetEnv().Host, svc.GetConfig().GetEnv().Port) - go func() { -- if err := e.Start(fmt.Sprintf(":%v", svc.GetConfig().GetEnv().Port)); err != nil && err != nethttp.ErrServerClosed { -+ if err := e.Start(bindAddress); err != nil && err != nethttp.ErrServerClosed { - logger.Logger.WithError(err).Error("echo server failed to start") - cancel() - } -diff --git a/config/models.go b/config/models.go -index 0fb8870..dc11afd 100644 ---- a/config/models.go -+++ b/config/models.go -@@ -24,6 +24,7 @@ type AppConfig struct { - LNDAddress string `envconfig:"LND_ADDRESS"` - LNDCertFile string `envconfig:"LND_CERT_FILE"` - LNDMacaroonFile string `envconfig:"LND_MACAROON_FILE"` -+ Host string `envconfig:"HOST" default:"127.0.0.1"` - Workdir string `envconfig:"WORK_DIR"` - Port string `envconfig:"PORT" default:"8080"` - DatabaseUri string `envconfig:"DATABASE_URI" default:"nwc.db"` diff --git a/packages/albyhub/0004-lnd-only.patch b/packages/albyhub/0004-lnd-only.patch deleted file mode 100644 index 01e1f0c..0000000 --- a/packages/albyhub/0004-lnd-only.patch +++ /dev/null @@ -1,141 +0,0 @@ -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 --} diff --git a/packages/albyhub/0005-no-frontend.patch b/packages/albyhub/0005-no-frontend.patch deleted file mode 100644 index c7426cf..0000000 --- a/packages/albyhub/0005-no-frontend.patch +++ /dev/null @@ -1,45 +0,0 @@ -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{ diff --git a/packages/albyhub/default.nix b/packages/albyhub/default.nix index 93ea49e..2c1dd93 100644 --- a/packages/albyhub/default.nix +++ b/packages/albyhub/default.nix @@ -4,47 +4,57 @@ , stdenv }: -buildGoModule (finalAttrs: { +buildGoModule rec { pname = "albyhub"; version = "1.24.0"; + # sovran fork = upstream v1.24.0 + LND-only, no frontend, HOST bind, + # always-private route hints (the customization lives in the fork's commits) src = fetchFromGitHub { - owner = "getAlby"; + owner = "naturallaw777"; repo = "hub"; - tag = "v${finalAttrs.version}"; - hash = "sha256-IC3rl/9aJ88GgvGfhcJb1/pQb3xIkhYih1hLPJ8itP8="; + tag = "sovran-1.24.0"; + # round 1: copy the "got: sha256-..." from the build error + hash = "sha256-PLACEHOLDER-SRC"; }; - vendorHash = "sha256-A4OsntoJUDkvWJxnZFFxw5AjUPmwRl764nQ5FEA2yeo="; - - # Use the Go module cache instead of `go mod vendor`. The - # vulpemventures/go-secp256k1-zkp dependency (pulled in transitively) ships - # cgo bindings whose C headers live in an `include/` subdirectory; those - # non-Go files are stripped by `go mod vendor`, which makes the build fail - # with `include/secp256k1_ecdh.h: No such file or directory`. The proxy - # tarballs retain the full file set, so the cgo compile succeeds. + # `go mod vendor` strips the secp256k1-zkp cgo headers (include/), so use + # the full module cache. Round 2: copy the "got: sha256-..." from the error proxyVendor = true; + vendorHash = "sha256-PLACEHOLDER-VENDOR"; - patches = [ - ./0001-private-route-hints.patch - ./0003-loopback-bind-host.patch - ./0004-lnd-only.patch - ./0005-no-frontend.patch - ]; + subPackages = [ "cmd/http" ]; - # 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) - ]; + # LND client needs cgo (secp256k1-zkp) + buildInputs = [ (lib.getLib stdenv.cc.cc) ]; - subPackages = [ - "cmd/http" - ]; + # pin module downloads to a hermetic proxy and the local toolchain + # (otherwise GOPROXY/GOTOOLCHAIN can leak into the builder env and the + # cache comes back incomplete — the original failure) + overrideModAttrs = (finalAttrs: previousAttrs: { + modBuildPhase = '' + runHook preBuild + + export GIT_SSL_CAINFO=$NIX_SSL_CERT_FILE + export GOPROXY=https://proxy.golang.org,direct + export GOSUMDB=sum.golang.org + export GOTOOLCHAIN=local + + mkdir -p "$GOPATH/pkg/mod/cache/download" + go mod download all + + export GOPROXY="file://$GOPATH/pkg/mod/cache/download" + + go list ./cmd/http + + mkdir -p vendor + + runHook postBuild + ''; + }); ldflags = [ - "-X github.com/getAlby/hub/version.Tag=v${finalAttrs.version}" + "-X github.com/getAlby/hub/version.Tag=${version}" "-s" "-w" ]; @@ -52,12 +62,4 @@ buildGoModule (finalAttrs: { 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"; - }; -}) +}