Merge pull request #342 from naturallaw777/copilot/fix-lnd-alby-hub-port-collision
Resolve deterministic LND/Alby Hub port collision and enforce loopback-only binding
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
name: Wallet Connections Nix Validation
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 180
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@v16
|
||||
|
||||
- name: Targeted Wallet Connections tests
|
||||
run: python3 -m unittest app/tests/test_wallet_connections.py
|
||||
|
||||
- name: Full Python tests
|
||||
run: python3 -m unittest discover -s app/tests -p 'test_*.py'
|
||||
|
||||
- name: JavaScript syntax checks
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for f in app/sovran_systemsos_web/static/js/*.js; do
|
||||
node --check "$f"
|
||||
done
|
||||
|
||||
- name: Verify Alby Hub patches apply to v1.23.0
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tmpdir="$(mktemp -d)"
|
||||
curl -fsSL https://github.com/getAlby/hub/archive/refs/tags/v1.23.0.tar.gz | tar -xz -C "$tmpdir"
|
||||
srcdir="$(find "$tmpdir" -maxdepth 1 -type d -name 'hub-*' | head -n1)"
|
||||
test -n "$srcdir"
|
||||
cd "$srcdir"
|
||||
git init -q
|
||||
git add -A
|
||||
git commit -q -m "snapshot"
|
||||
git apply --check "$GITHUB_WORKSPACE/packages/albyhub/0001-private-route-hints.patch"
|
||||
git apply --check "$GITHUB_WORKSPACE/packages/albyhub/0002-isolated-invoice-app-id.patch"
|
||||
git apply --check "$GITHUB_WORKSPACE/packages/albyhub/0003-loopback-bind-host.patch"
|
||||
|
||||
- name: Build patched Alby Hub
|
||||
run: |
|
||||
nix --extra-experimental-features 'nix-command flakes' build \
|
||||
--no-link --print-build-logs --impure --expr \
|
||||
'let
|
||||
flake = builtins.getFlake (toString ./.);
|
||||
pkgs = import flake.inputs.nixpkgs { system = "x86_64-linux"; };
|
||||
patchedAlbyHub = pkgs.albyhub.overrideAttrs (old: {
|
||||
patches = (old.patches or []) ++ [
|
||||
./packages/albyhub/0001-private-route-hints.patch
|
||||
./packages/albyhub/0002-isolated-invoice-app-id.patch
|
||||
./packages/albyhub/0003-loopback-bind-host.patch
|
||||
];
|
||||
});
|
||||
in patchedAlbyHub'
|
||||
|
||||
- name: Run real NixOS listener test
|
||||
run: |
|
||||
nix --extra-experimental-features 'nix-command flakes' build \
|
||||
'.#checks.x86_64-linux.nwc-wallets-port-collision' \
|
||||
--no-link --print-build-logs
|
||||
|
||||
- name: Build full system closure
|
||||
run: |
|
||||
nix --extra-experimental-features 'nix-command flakes' build \
|
||||
'.#nixosConfigurations.nixos.config.system.build.toplevel' \
|
||||
--no-link --print-build-logs
|
||||
@@ -1,7 +1,8 @@
|
||||
"""
|
||||
Alby Hub manager — shared backend for Wallet Connections API and recovery CLI.
|
||||
|
||||
Interfaces with the local Alby Hub instance at http://127.0.0.1:8080.
|
||||
Interfaces with the local Alby Hub instance at
|
||||
http://127.0.0.1:18080 by default (override with NWC_ALBY_HUB_API_BASE).
|
||||
All sensitive values (passwords, bearer tokens, pairing URIs, macaroon
|
||||
contents, Nostr private keys) are redacted from any exception messages
|
||||
or log output.
|
||||
@@ -24,7 +25,10 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# ── Constants ──────────────────────────────────────────────────────
|
||||
|
||||
DEFAULT_API_BASE = "http://127.0.0.1:8080"
|
||||
DEFAULT_API_BASE = os.environ.get(
|
||||
"NWC_ALBY_HUB_API_BASE",
|
||||
"http://127.0.0.1:18080",
|
||||
)
|
||||
DEFAULT_UNLOCK_PASSWORD_FILE = "/var/lib/albyhub/unlock-password"
|
||||
DEFAULT_MACAROON_FILE = os.environ.get(
|
||||
"NWC_LND_MACAROON_FILE", "/run/lnd/albyhub.macaroon"
|
||||
|
||||
@@ -25,6 +25,8 @@ Tests cover:
|
||||
"""
|
||||
|
||||
import json
|
||||
import importlib
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
@@ -169,6 +171,28 @@ def _fresh_manager() -> mgr.AlbyHubManager:
|
||||
)
|
||||
|
||||
|
||||
class ManagerApiBaseConfigurationTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._original_api_base = os.environ.get("NWC_ALBY_HUB_API_BASE")
|
||||
|
||||
def tearDown(self):
|
||||
if self._original_api_base is None:
|
||||
os.environ.pop("NWC_ALBY_HUB_API_BASE", None)
|
||||
else:
|
||||
os.environ["NWC_ALBY_HUB_API_BASE"] = self._original_api_base
|
||||
importlib.reload(mgr)
|
||||
|
||||
def test_default_api_base_falls_back_to_18080(self):
|
||||
os.environ.pop("NWC_ALBY_HUB_API_BASE", None)
|
||||
reloaded_mgr = importlib.reload(mgr)
|
||||
self.assertEqual(reloaded_mgr.DEFAULT_API_BASE, "http://127.0.0.1:18080")
|
||||
|
||||
def test_env_api_base_overrides_default(self):
|
||||
os.environ["NWC_ALBY_HUB_API_BASE"] = "http://127.0.0.1:19999"
|
||||
reloaded_mgr = importlib.reload(mgr)
|
||||
self.assertEqual(reloaded_mgr.DEFAULT_API_BASE, "http://127.0.0.1:19999")
|
||||
|
||||
|
||||
# ── Feature registry tests ────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -1113,6 +1137,7 @@ class NixPatchContractTests(unittest.TestCase):
|
||||
"patchedAlbyHub = pkgs.albyhub.overrideAttrs (old: { patches = (old.patches or []) ++ [ "
|
||||
"./packages/albyhub/0001-private-route-hints.patch "
|
||||
"./packages/albyhub/0002-isolated-invoice-app-id.patch "
|
||||
"./packages/albyhub/0003-loopback-bind-host.patch "
|
||||
"]; }); "
|
||||
f"in {result_expr}"
|
||||
)
|
||||
@@ -1124,10 +1149,13 @@ class NixPatchContractTests(unittest.TestCase):
|
||||
self.assertIn("pkgs.albyhub.overrideAttrs", text)
|
||||
self.assertIn("../packages/albyhub/0001-private-route-hints.patch", text)
|
||||
self.assertIn("../packages/albyhub/0002-isolated-invoice-app-id.patch", text)
|
||||
self.assertIn("../packages/albyhub/0003-loopback-bind-host.patch", text)
|
||||
self.assertNotIn("sha256-AAAA", text)
|
||||
self.assertNotIn("lib.fakeHash", text)
|
||||
self.assertIn("AUTO_UNLOCK_PASSWORD", text)
|
||||
self.assertNotIn("AUTO_UNLOCK_PASSWORD_FILE", text)
|
||||
self.assertIn("albyHubPort = 18080;", text)
|
||||
self.assertIn('albyHubApiBase = "http://127.0.0.1:${toString albyHubPort}";', text)
|
||||
|
||||
def test_nwc_module_uses_lib_getexe_for_albyhub_binary(self):
|
||||
repo_root = Path(__file__).resolve().parents[2]
|
||||
@@ -1215,6 +1243,43 @@ class NixPatchContractTests(unittest.TestCase):
|
||||
self.assertIn("MakeInvoice(ctx, amountMsat, description,", text)
|
||||
self.assertIn(", appId, nil, nil)", text)
|
||||
|
||||
def test_loopback_bind_host_patch_contains_required_changes(self):
|
||||
repo_root = Path(__file__).resolve().parents[2]
|
||||
patch_path = repo_root / "packages" / "albyhub" / "0003-loopback-bind-host.patch"
|
||||
text = patch_path.read_text()
|
||||
self.assertIn("diff --git a/cmd/http/main.go b/cmd/http/main.go", text)
|
||||
self.assertIn("diff --git a/config/models.go b/config/models.go", text)
|
||||
self.assertIn('Host string `envconfig:"HOST" default:"127.0.0.1"`', text)
|
||||
self.assertIn("bindAddress := net.JoinHostPort", text)
|
||||
self.assertIn("if err := e.Start(bindAddress);", text)
|
||||
|
||||
def test_nwc_services_share_authoritative_alby_hub_api_base(self):
|
||||
repo_root = Path(__file__).resolve().parents[2]
|
||||
module_path = repo_root / "modules" / "nwc-wallets.nix"
|
||||
text = module_path.read_text()
|
||||
self.assertIn("environment.NWC_ALBY_HUB_API_BASE = albyHubApiBase;", text)
|
||||
self.assertIn("NWC_ALBY_HUB_API_BASE = albyHubApiBase;", text)
|
||||
|
||||
def test_albyhub_port_contract_and_assertions(self):
|
||||
repo_root = Path(__file__).resolve().parents[2]
|
||||
module_path = repo_root / "modules" / "nwc-wallets.nix"
|
||||
text = module_path.read_text()
|
||||
self.assertIn("PORT = toString albyHubPort;", text)
|
||||
self.assertNotIn('PORT = "8080";', text)
|
||||
self.assertIn("assertion = albyHubPort != config.services.lnd.restPort;", text)
|
||||
self.assertIn("assertion = albyHubPort != 8181;", text)
|
||||
self.assertIn("assertion = !(lib.elem albyHubPort config.networking.firewall.allowedTCPPorts);", text)
|
||||
|
||||
def test_recovery_cli_uses_manager_default_endpoint(self):
|
||||
repo_root = Path(__file__).resolve().parents[2]
|
||||
cli_path = repo_root / "app" / "sovran_systemsos_web" / "nwc_wallet_cli.py"
|
||||
manager_path = repo_root / "app" / "sovran_systemsos_web" / "nwc_hub_manager.py"
|
||||
cli_text = cli_path.read_text()
|
||||
manager_text = manager_path.read_text()
|
||||
self.assertIn("get_manager()", cli_text)
|
||||
self.assertNotIn("127.0.0.1:8080", cli_text)
|
||||
self.assertIn('"http://127.0.0.1:18080"', manager_text)
|
||||
|
||||
def test_nwc_lnurl_service_runs_as_albyhub(self):
|
||||
"""nwc-lnurl.service must run as albyhub to read /var/lib/albyhub/unlock-password."""
|
||||
repo_root = Path(__file__).resolve().parents[2]
|
||||
|
||||
@@ -36,7 +36,7 @@ Guardrails:
|
||||
|
||||
```
|
||||
Authenticated Hub management API
|
||||
-> local Alby Hub (port 8080, loopback only)
|
||||
-> local Alby Hub (port 18080, loopback only)
|
||||
-> local LND
|
||||
|
||||
Public Lightning Address
|
||||
@@ -48,7 +48,7 @@ Public Lightning Address
|
||||
|
||||
Security invariants:
|
||||
|
||||
- Alby Hub management port (8080) is never opened to the public firewall.
|
||||
- Alby Hub management port (18080) is never opened to the public firewall.
|
||||
- Dedicated LNURL service port (8181) is never opened to the public firewall.
|
||||
- LNURL callback and discovery are exposed only through Caddy on 80/443.
|
||||
- Management APIs are authenticated and remain under `/api/nwc/`.
|
||||
@@ -68,10 +68,11 @@ Security invariants:
|
||||
|
||||
## Alby Hub package and patches
|
||||
|
||||
Wallet Connections uses `pkgs.albyhub` from the repository's pinned `nixpkgs` input and applies two conventional patches via `overrideAttrs`:
|
||||
Wallet Connections uses `pkgs.albyhub` from the repository's pinned `nixpkgs` input and applies three conventional patches via `overrideAttrs`:
|
||||
|
||||
1. **Private route hints** (`packages/albyhub/0001-private-route-hints.patch`): changes regular LND invoice creation from `Private: !hasPublicChannels` to `Private: true` and leaves hold-invoice logic unchanged.
|
||||
2. **Invoice app attribution** (`packages/albyhub/0002-isolated-invoice-app-id.patch`): updates `api/models.go`, `api/transactions.go`, `http/http_service.go`, and `wails/wails_handlers.go` so invoice creation accepts and forwards optional `appId`.
|
||||
3. **Loopback bind host** (`packages/albyhub/0003-loopback-bind-host.patch`): adds `HOST` to config and binds Echo to `HOST:PORT` instead of `:PORT`.
|
||||
|
||||
No placeholder source/vendor hashes are used in the Wallet Connections module.
|
||||
|
||||
|
||||
@@ -57,5 +57,14 @@
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
nixosTests.nwc-wallets-port-collision =
|
||||
import ./nix/tests/nwc-wallets-port-collision.nix {
|
||||
inherit nixpkgs;
|
||||
system = "x86_64-linux";
|
||||
};
|
||||
|
||||
checks.x86_64-linux.nwc-wallets-port-collision =
|
||||
self.nixosTests.nwc-wallets-port-collision;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ EOF
|
||||
$LIGHTNING {
|
||||
# LNURL discovery and callback are served by the dedicated
|
||||
# nwc-lnurl service on loopback port 8181. Only these paths
|
||||
# are proxied; the Alby Hub management port (8080) is never exposed.
|
||||
# are proxied; the Alby Hub management port (18080) is never exposed.
|
||||
reverse_proxy /.well-known/lnurlp/* http://127.0.0.1:8181
|
||||
reverse_proxy /lnurlp/* http://127.0.0.1:8181
|
||||
}
|
||||
|
||||
+18
-1
@@ -1,10 +1,13 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
albyHubPort = 18080;
|
||||
albyHubApiBase = "http://127.0.0.1:${toString albyHubPort}";
|
||||
patchedAlbyHub = pkgs.albyhub.overrideAttrs (old: {
|
||||
patches = (old.patches or []) ++ [
|
||||
../packages/albyhub/0001-private-route-hints.patch
|
||||
../packages/albyhub/0002-isolated-invoice-app-id.patch
|
||||
../packages/albyhub/0003-loopback-bind-host.patch
|
||||
];
|
||||
});
|
||||
|
||||
@@ -33,6 +36,18 @@ lib.mkIf config.sovran_systemsOS.features."nwc-wallets" {
|
||||
assertion = !(lib.attrByPath [ "nix-bitcoin" "netns-isolation" "enable" ] false config);
|
||||
message = "Wallet Connections requires nix-bitcoin.netns-isolation.enable = false.";
|
||||
}
|
||||
{
|
||||
assertion = albyHubPort != config.services.lnd.restPort;
|
||||
message = "Alby Hub and LND REST must use different ports.";
|
||||
}
|
||||
{
|
||||
assertion = albyHubPort != 8181;
|
||||
message = "Alby Hub and the public LNURL service must use different ports.";
|
||||
}
|
||||
{
|
||||
assertion = !(lib.elem albyHubPort config.networking.firewall.allowedTCPPorts);
|
||||
message = "Alby Hub management port must not be opened on the public TCP firewall.";
|
||||
}
|
||||
];
|
||||
|
||||
users.groups.albyhub = { };
|
||||
@@ -79,7 +94,7 @@ lib.mkIf config.sovran_systemsOS.features."nwc-wallets" {
|
||||
LND_MACAROON_FILE = "/run/lnd/albyhub.macaroon";
|
||||
WORK_DIR = "/var/lib/albyhub";
|
||||
DATABASE_URI = "/var/lib/albyhub/nwc.db";
|
||||
PORT = "8080";
|
||||
PORT = toString albyHubPort;
|
||||
RELAY = "wss://relay.getalby.com,wss://relay2.getalby.com";
|
||||
AUTO_LINK_ALBY_ACCOUNT = "false";
|
||||
SEND_EVENTS_TO_ALBY = "false";
|
||||
@@ -110,6 +125,7 @@ lib.mkIf config.sovran_systemsOS.features."nwc-wallets" {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "albyhub.service" "sovran-hub-web.service" ];
|
||||
wants = [ "albyhub.service" ];
|
||||
environment.NWC_ALBY_HUB_API_BASE = albyHubApiBase;
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
@@ -131,6 +147,7 @@ lib.mkIf config.sovran_systemsOS.features."nwc-wallets" {
|
||||
};
|
||||
|
||||
systemd.services.sovran-hub-web.environment = {
|
||||
NWC_ALBY_HUB_API_BASE = albyHubApiBase;
|
||||
NWC_LND_ADDRESS = "${lndRpcAddress}:${lndRpcPort}";
|
||||
NWC_LND_CERT_FILE = lndCertPath;
|
||||
NWC_LND_MACAROON_FILE = "/run/lnd/albyhub.macaroon";
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
{ nixpkgs, system ? "x86_64-linux" }:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
in
|
||||
pkgs.testers.runNixOSTest {
|
||||
name = "nwc-wallets-port-collision";
|
||||
|
||||
nodes.machine = { lib, pkgs, ... }: {
|
||||
imports = [ ../../modules/nwc-wallets.nix ];
|
||||
|
||||
options = {
|
||||
sovran_systemsOS.features = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.bool;
|
||||
default = { };
|
||||
};
|
||||
sovran_systemsOS.domainRequirements = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
default = [ ];
|
||||
};
|
||||
services.sovranHub.webPackage = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
};
|
||||
services.lnd = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
rpcAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
};
|
||||
rpcPort = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10009;
|
||||
};
|
||||
restPort = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 8080;
|
||||
};
|
||||
certPath = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/lnd/tls.cert";
|
||||
};
|
||||
macaroons = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
system.stateVersion = "24.11";
|
||||
networking.firewall.enable = true;
|
||||
|
||||
sovran_systemsOS.features."nwc-wallets" = true;
|
||||
services.lnd.enable = true;
|
||||
services.lnd.restPort = 8080;
|
||||
|
||||
services.sovranHub.webPackage = pkgs.writeShellApplication {
|
||||
name = "stub-sovran-hub-web";
|
||||
runtimeInputs = [ pkgs.python3 ];
|
||||
text = ''
|
||||
if [ "$(basename "$0")" = "nwc-lnurl" ]; then
|
||||
exec ${pkgs.python3}/bin/python -m http.server "''${NWC_LNURL_PORT:-8181}" --bind 127.0.0.1
|
||||
fi
|
||||
exec ${pkgs.coreutils}/bin/sleep infinity
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.sovran-hub-web = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.coreutils}/bin/sleep infinity";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.lnd-prepare = {
|
||||
description = "Prepare mock LND cert and macaroon files";
|
||||
before = [ "lnd.service" "albyhub.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
mkdir -p /var/lib/lnd /run/lnd /var/lib/domains
|
||||
printf 'stub-cert\n' > /var/lib/lnd/tls.cert
|
||||
printf 'stub-macaroon\n' > /run/lnd/albyhub.macaroon
|
||||
printf 'lightning.example.com\n' > /var/lib/domains/lightning
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.lnd = {
|
||||
description = "Mock LND REST listener";
|
||||
after = [ "network.target" "lnd-prepare.service" ];
|
||||
requires = [ "lnd-prepare.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.python3}/bin/python -m http.server 8080 --bind 127.0.0.1";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
machine.wait_for_unit("lnd.service")
|
||||
machine.wait_for_unit("sovran-hub-web.service")
|
||||
machine.wait_for_unit("albyhub.service")
|
||||
machine.wait_for_unit("nwc-lnurl.service")
|
||||
|
||||
machine.wait_for_open_port(8080)
|
||||
machine.wait_for_open_port(18080)
|
||||
machine.wait_for_open_port(8181)
|
||||
|
||||
machine.succeed("ss -ltn '( sport = :8080 )' | grep -F '127.0.0.1:8080'")
|
||||
machine.succeed("ss -ltn '( sport = :18080 )' | grep -F '127.0.0.1:18080'")
|
||||
machine.succeed("ss -ltn '( sport = :8181 )' | grep -F '127.0.0.1:8181'")
|
||||
|
||||
machine.fail("ss -ltn '( sport = :18080 )' | grep -E '0\\.0\\.0\\.0:18080|\\[::\\]:18080'")
|
||||
machine.fail("ss -ltn '( sport = :8181 )' | grep -E '0\\.0\\.0\\.0:8181|\\[::\\]:8181'")
|
||||
|
||||
machine.succeed("${pkgs.curl}/bin/curl --fail --silent http://127.0.0.1:18080/api/info | ${pkgs.gnugrep}/bin/grep -q 'setupCompleted'")
|
||||
|
||||
machine.succeed("systemctl show -p Environment nwc-lnurl.service | grep -q 'NWC_ALBY_HUB_API_BASE=http://127.0.0.1:18080'")
|
||||
machine.succeed("systemctl show -p Environment sovran-hub-web.service | grep -q 'NWC_ALBY_HUB_API_BASE=http://127.0.0.1:18080'")
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
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"`
|
||||
Reference in New Issue
Block a user