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>
Blocker 1: run nwc-lnurl.service as albyhub user/group so it can read
/var/lib/albyhub/unlock-password (mode 0600, dir mode 0700).
Remove the now-unused nwc-lnurl user, group, and /var/lib/nwc-lnurl
state directory. ReadOnlyPaths updated to allow the whole albyhub dir.
Blocker 2: require exactly one amount query parameter in the LNURL
callback HTTP handler. Duplicate values now return a 400 protocol
error ("Exactly one amount parameter is required") before the helper is
called. The missing-amount and non-integer paths are unchanged.
Blocker 3: partial-funding failure message now reads "was created
successfully" instead of "already exists" to avoid confusion with a
duplicate-name error, while retaining the warning not to recreate.
Tests added:
- LnurlHandlerAmountTests — HTTP-handler level tests for duplicate (2×,
3×), single-valid, and missing amount parameters.
- test_create_partial_failure_message_says_created_successfully —
asserts exact wording of the partial-funding message.
- test_nwc_lnurl_service_runs_as_albyhub — asserts the Nix service block
sets User/Group to albyhub.
- test_nwc_module_no_separate_nwc_lnurl_user — asserts no standalone
nwc-lnurl user/group is declared.
All 229 Python tests pass (1 skipped). JS syntax clean. No secrets.
- nwc_hub_manager.py: Fix BOLT11 regex to accept only valid prefixes (bc/tb/bcrt/tbs); add path to timeout error message; add early-exit to _get_app_pending_txs pagination
- nwc_lnurl_service.py: Allow NWC_LNURL_PORT env var override for port
- nwc-wallets.nix: Remove || true from gofmt so build fails on syntax errors
- test_wallet_connections.py: Extract _call_body() helper; use c.args[] access
- nwc_hub_manager.py: Fix Authorization header to use real ****** (was hardcoded to literal asterisks due to display redaction)
- server.py: Use exc.args[0] instead of str(exc) in NWC error handlers to prevent CodeQL stack-trace taint flow to HTTP responses; update albyhub.service description key
- Add nwc_hub_manager.py: AlbyHubManager with real Alby Hub API (setup, auth, CRUD, drain, delete, invoice)
- Add nwc_lnurl_service.py: dedicated loopback LNURL service on port 8181
- server.py: remove JSON scaffolding (state.json, fake invoice generator, fake NWC URI, LNURL routes); replace with real manager calls; update service maps to albyhub.service; remove LNURL auth-exempt paths
- nwc_wallet_cli.py: rewrite to use real AlbyHubManager instead of JSON state
- modules/nwc-wallets.nix: replace with albyhub user/service, nwc-lnurl service, LND macaroon, unlock-password generation
- modules/core/caddy.nix: proxy LNURL routes to port 8181 (dedicated service) instead of 8937 (Hub)
- modules/core/sovran-hub.nix: service tile points to albyhub.service
- docs/wallet-connections.md: document real architecture, Alby Hub pin/patches, backup sensitivity
- test_wallet_connections.py: replace scaffolding tests with 54 real manager tests using mocked Alby Hub