Naming: user-facing 'Wallet Connections' -> 'Lightning Wallet Connections' across the Hub, feature registry, tile, and NixOS modules. Internal ids (nwc-wallets, albyhub.service, /api/nwc/*) are unchanged. UX: the service-detail modal put status, domain diagnostics, router ports, the enable/disable toggle, restart, the liquidity guide and the whole wallet manager in one cramped scrolling column. For this feature the modal is now 980px wide and split into two tabs: - Wallets: wallet grid, create/share/verify flows, collapsible liquidity guide - Service & Setup: description, status, domain checklist, ports, enable, restart A status dot and domain chip sit in the tab bar so state is visible from both tabs, and the modal opens on Setup when the service is off or the Lightning Address domain is unconfigured. Wallet cards gain a balance chip, pending badge, a prominent address row, and separated destructive actions. Non-NWC services keep the original single-column layout and width. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
174 lines
5.7 KiB
Nix
174 lines
5.7 KiB
Nix
{ 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
|
|
];
|
|
});
|
|
|
|
lndRpcAddress = lib.attrByPath [ "services" "lnd" "rpcAddress" ] "127.0.0.1" config;
|
|
lndRpcPort = toString (lib.attrByPath [ "services" "lnd" "rpcPort" ] 10009 config);
|
|
lndCertPath = config.services.lnd.certPath;
|
|
pythonManagerEnvironment = {
|
|
NWC_ALBY_HUB_API_BASE = albyHubApiBase;
|
|
NWC_LND_ADDRESS = "${lndRpcAddress}:${lndRpcPort}";
|
|
NWC_LND_CERT_FILE = lndCertPath;
|
|
NWC_LND_MACAROON_FILE = "/run/lnd/albyhub.macaroon";
|
|
};
|
|
wrappedNwcWallet = lib.hiPrio (pkgs.writeShellScriptBin "nwc-wallet" ''
|
|
export NWC_ALBY_HUB_API_BASE='${pythonManagerEnvironment.NWC_ALBY_HUB_API_BASE}'
|
|
export NWC_LND_ADDRESS='${pythonManagerEnvironment.NWC_LND_ADDRESS}'
|
|
export NWC_LND_CERT_FILE='${pythonManagerEnvironment.NWC_LND_CERT_FILE}'
|
|
export NWC_LND_MACAROON_FILE='${pythonManagerEnvironment.NWC_LND_MACAROON_FILE}'
|
|
exec ${config.services.sovranHub.webPackage}/bin/nwc-wallet "$@"
|
|
'');
|
|
|
|
albyhubWrapper = pkgs.writeShellScript "albyhub-wrapper" ''
|
|
set -euo pipefail
|
|
password_file="/var/lib/albyhub/unlock-password"
|
|
if [ ! -s "$password_file" ]; then
|
|
umask 077
|
|
${pkgs.openssl}/bin/openssl rand -hex 32 > "$password_file"
|
|
fi
|
|
export AUTO_UNLOCK_PASSWORD="$(cat "$password_file")"
|
|
exec ${lib.getExe patchedAlbyHub}
|
|
'';
|
|
in
|
|
lib.mkIf config.sovran_systemsOS.features."nwc-wallets" {
|
|
assertions = [
|
|
{
|
|
assertion = config.services.lnd.enable;
|
|
message = "Lightning Wallet Connections requires services.lnd.enable = true.";
|
|
}
|
|
{
|
|
assertion = !(lib.attrByPath [ "nix-bitcoin" "netns-isolation" "enable" ] false config);
|
|
message = "Lightning 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 = { };
|
|
users.users.albyhub = {
|
|
isSystemUser = true;
|
|
group = "albyhub";
|
|
home = "/var/lib/albyhub";
|
|
createHome = false;
|
|
extraGroups = [ ];
|
|
};
|
|
|
|
systemd.tmpfiles.rules = [
|
|
"d /var/lib/albyhub 0700 albyhub albyhub -"
|
|
];
|
|
|
|
services.lnd.macaroons.albyhub = {
|
|
user = "albyhub";
|
|
permissions = lib.concatStringsSep "," [
|
|
''{"entity":"info","action":"read"}''
|
|
''{"entity":"offchain","action":"read"}''
|
|
''{"entity":"offchain","action":"write"}''
|
|
''{"entity":"invoices","action":"read"}''
|
|
''{"entity":"invoices","action":"write"}''
|
|
''{"entity":"onchain","action":"read"}''
|
|
''{"entity":"address","action":"read"}''
|
|
''{"entity":"message","action":"read"}''
|
|
''{"entity":"message","action":"write"}''
|
|
];
|
|
};
|
|
|
|
systemd.services.albyhub = {
|
|
description = "Alby Hub — NWC wallet server";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "network.target" "lnd.service" ];
|
|
requires = [ "lnd.service" ];
|
|
|
|
environment = {
|
|
HOME = "/var/lib/albyhub";
|
|
HOST = "127.0.0.1";
|
|
LN_BACKEND_TYPE = "LND";
|
|
ENABLE_ADVANCED_SETUP = "false";
|
|
LND_ADDRESS = "${lndRpcAddress}:${lndRpcPort}";
|
|
LND_CERT_FILE = lndCertPath;
|
|
LND_MACAROON_FILE = "/run/lnd/albyhub.macaroon";
|
|
WORK_DIR = "/var/lib/albyhub";
|
|
DATABASE_URI = "/var/lib/albyhub/nwc.db";
|
|
PORT = toString albyHubPort;
|
|
RELAY = "wss://relay.getalby.com,wss://relay2.getalby.com";
|
|
AUTO_LINK_ALBY_ACCOUNT = "false";
|
|
SEND_EVENTS_TO_ALBY = "false";
|
|
LOG_TO_FILE = "false";
|
|
HIDE_UPDATE_BANNER = "true";
|
|
};
|
|
|
|
serviceConfig = {
|
|
Type = "simple";
|
|
User = "albyhub";
|
|
Group = "albyhub";
|
|
WorkingDirectory = "/var/lib/albyhub";
|
|
ExecStart = albyhubWrapper;
|
|
Restart = "on-failure";
|
|
RestartSec = "10s";
|
|
UMask = "0077";
|
|
NoNewPrivileges = true;
|
|
PrivateTmp = true;
|
|
ProtectHome = true;
|
|
ProtectSystem = "strict";
|
|
ReadWritePaths = [ "/var/lib/albyhub" ];
|
|
ReadOnlyPaths = [ lndCertPath "/run/lnd" ];
|
|
};
|
|
};
|
|
|
|
systemd.services.nwc-lnurl = {
|
|
description = "Lightning Wallet Connections public LNURL service";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "albyhub.service" "sovran-hub-web.service" ];
|
|
wants = [ "albyhub.service" ];
|
|
environment = pythonManagerEnvironment;
|
|
|
|
serviceConfig = {
|
|
Type = "simple";
|
|
User = "albyhub";
|
|
Group = "albyhub";
|
|
ExecStart = "${config.services.sovranHub.webPackage}/bin/nwc-lnurl";
|
|
Restart = "on-failure";
|
|
RestartSec = "10s";
|
|
UMask = "0027";
|
|
NoNewPrivileges = true;
|
|
PrivateTmp = true;
|
|
ProtectHome = true;
|
|
ProtectSystem = "strict";
|
|
ReadOnlyPaths = [
|
|
"/var/lib/domains/lightning"
|
|
"/var/lib/albyhub/unlock-password"
|
|
];
|
|
};
|
|
};
|
|
|
|
systemd.services.sovran-hub-web.environment = pythonManagerEnvironment;
|
|
environment.systemPackages = lib.mkBefore [ wrappedNwcWallet ];
|
|
|
|
sovran_systemsOS.domainRequirements = [
|
|
{
|
|
name = "lightning";
|
|
label = "Lightning Address Domain";
|
|
example = "pay.yourdomain.com";
|
|
needsDDNS = true;
|
|
}
|
|
];
|
|
}
|