Skip to content

Comments

feat: add node alias setting to General settings page#2039

Closed
sat-engineer wants to merge 1 commit intogetAlby:masterfrom
sat-engineer:feat/node-alias-settings
Closed

feat: add node alias setting to General settings page#2039
sat-engineer wants to merge 1 commit intogetAlby:masterfrom
sat-engineer:feat/node-alias-settings

Conversation

@sat-engineer
Copy link

@sat-engineer sat-engineer commented Feb 7, 2026

Summary

  • Adds inline node alias editing on the Settings > General page so self-hosted users (e.g. Umbrel) can change their Lightning node alias without needing an Alby paid plan
  • Input pre-populates from useInfo().nodeAlias, POSTs to existing /api/node/alias endpoint, and shows a restart reminder toast
  • Only rendered when backendType === "LDK"
  • Adds Go doc comments to exported types in api/models.go, config/models.go, and lnclient/models.go to satisfy the 80% docstring coverage CI check

Test plan

  • Navigate to Settings > General, verify "Node" section appears at the bottom with alias input
  • Change alias, click Save, verify toast "Node alias updated. Restart your node to apply the change."
  • Verify POST /api/node/alias is called with correct payload (browser network tab)
  • Reload page, verify alias persists in input
  • Verify node alias section does NOT appear for non-LDK backends
  • go test ./... passes

Depends on #2038

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Added node alias configuration option for personalized node identification
    • Enhanced app management with expanded settings and controls
    • Improved swap operations with auto-swap configuration support
    • Added health monitoring and diagnostic features
    • Enriched transaction details with metadata and payment information support
    • Expanded wallet capabilities and settings management

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 7, 2026

📝 Walkthrough

Walkthrough

The PR significantly expands the public API surface across multiple layers: introducing comprehensive new data types and request/response structures for apps, swaps, transactions, and node operations; enhancing the LNClient interface with extensive new method signatures and model types for channels, balances, and custom commands; extending the Config interface with additional management methods; and adding frontend UI support for setting node aliases. Additionally, test coverage is added for the new node alias functionality.

Changes

Cohort / File(s) Summary
API Surface Expansion
api/models.go
Added ~97 lines introducing extensive new public types including App with expanded fields, request/response types for swaps (InitiateSwapRequest, RefundSwapRequest, GetAutoSwapConfigResponse, SwapInfoResponse, Swap), node operations (StartRequest, UnlockRequest, SetupRequest, MnemonicRequest/Response), transactions (ListTransactionsResponse, Transaction with enriched fields, Boostagram), health diagnostics (HealthAlarm, HealthResponse, HealthAlarmKind constants), custom node commands (CustomNodeCommandArgDef, CustomNodeCommandDef, ExecuteCustomNodeCommandRequest), and numerous aliases to lnclient types (ConnectPeerRequest, OpenChannelRequest, OnchainBalanceResponse, BalancesResponse). Also added Metadata alias and helper types for probing payments (SendPaymentProbesRequest/Response).
Configuration Management
config/models.go
Extended Config interface with new methods (SetIgnore, GetJWTSecret, GetRelayUrls, GetNetwork, GetMempoolUrl, CheckUnlockPassword, ChangeUnlockPassword, SetAutoUnlockPassword, SetupCompleted, GetCurrency, SetCurrency, GetBitcoinDisplayFormat, SetBitcoinDisplayFormat); added AppConfig struct type with IsDefaultClientId() and GetBaseFrontendUrl() methods; added documentation comments to backend type constants.
Lightning Client Models
lnclient/models.go
Expanded LNClient interface with ~24 new method signatures and added supporting types including Channel (with balance, funding, and policy details), NodeStatus, PeerDetails, OnchainTransaction, multiple balance response types (BalancesResponse, updated OnchainBalanceResponse and LightningBalanceResponse), payment response types (PayInvoiceResponse, PayOfferResponse, PayKeysendResponse), custom node command types (CustomNodeCommandArgDef, CustomNodeCommandDef, CustomNodeCommandArg, CustomNodeCommandRequest, CustomNodeCommandResponse), event property types (PaymentFailedEventProperties, PaymentForwardedEventProperties), and error handling (holdInvoiceCanceledError with constructor). Also added Metadata alias and DEFAULT_INVOICE_EXPIRY constant.
Frontend Node Configuration
frontend/src/screens/settings/Settings.tsx
Added React component state for nodeAlias and isSavingAlias with effect hook to initialize from info.nodeAlias; introduced saveNodeAlias function to POST to /api/node/alias endpoint with error handling and toast notifications; added new conditional Node section (visible for LDK backend) with input field, explanatory text, and save button with loading state.
Test Coverage
api/api_test.go
Added TestMain for logger initialization and new test cases for SetNodeAlias functionality covering success and error scenarios; updated helper function to initialize API service field.

Poem

🐰 A rabbit hops through types galore,
Expanding APIs to the core,
Swaps and apps and configs too,
Node aliases shining bright and new!
From client models to UI's grace,
New features light up every space!

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately describes the main feature: adding a node alias setting to the General settings page. It matches the primary UI enhancement across the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Add inline node alias editing on the Settings > General page so
self-hosted users can change their Lightning node alias without
needing an Alby paid plan. The alias input pre-populates from
useInfo().nodeAlias and POSTs to /api/node/alias. A toast reminds
the user to restart for the change to take effect.

Also adds Go doc comments to exported types in api/models.go,
config/models.go, and lnclient/models.go to satisfy the 80%
docstring coverage threshold. Includes tests for SetNodeAlias API
covering success, empty alias, and config error scenarios.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sat-engineer sat-engineer force-pushed the feat/node-alias-settings branch from 4cafde5 to 6da3bbe Compare February 7, 2026 22:29
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@tor/tor.go`:
- Around line 155-161: In Start(), if the concurrent-start branch detects
s.running true, ensure the onion created earlier is removed before closing the
control connection: call ctrl.DelOnion(resp.ServiceID) (checking resp != nil and
handling/logging any returned error) prior to ctrl.Close(); this will prevent
leaving an orphaned hidden service when the losing goroutine exits. Use the
existing resp variable from the AddOnion call and keep the existing ctrl.Close()
cleanup after attempting DelOnion.
🧹 Nitpick comments (7)
lnclient/models.go (1)

202-203: Nit: missing blank line between PeerDetails and LightningBalanceResponse.

There's a missing blank line separator between the closing brace of PeerDetails (line 202) and the doc comment for LightningBalanceResponse (line 203), which is inconsistent with the rest of the file.

Proposed fix
 }
+
 // LightningBalanceResponse contains the Lightning channel balance breakdown.
 type LightningBalanceResponse struct {
api/api.go (1)

1251-1252: Backend TorEnabled logic is correct; consider conditional frontend menu visibility for consistency.

The backend correctly gates TorEnabled on both LDKBackendType and LDKTorEnabled. However, the Tor menu item in SettingsLayout.tsx (lines 121-123) is shown for all LDK backends (info?.backendType === "LDK"), not conditionally on info.torEnabled.

The TorSettings.tsx component already handles both states—showing a disabled message when torEnabled is false and settings when true. For frontend consistency with the backend gating logic, consider using info?.torEnabled as the menu visibility condition instead of checking only backendType. This would prevent showing the Tor menu item for LDK backends that don't have Tor configured.

frontend/src/screens/settings/Settings.tsx (2)

43-47: Nit: Use the already-destructured useEffect instead of React.useEffect.

Line 2 destructures useEffect from React, but line 43 uses React.useEffect. Use the destructured version for consistency with the rest of the file.

♻️ Suggested fix
-  React.useEffect(() => {
+  useEffect(() => {
     if (info?.nodeAlias !== undefined) {
       setNodeAlias(info.nodeAlias);
     }
   }, [info?.nodeAlias]);

261-268: Add maxLength={32} to the node alias input to prevent user confusion.

Lightning node aliases are limited to 32 bytes by the BOLT #7 protocol specification. Without client-side validation, users could enter a longer string that may be silently truncated or handled unexpectedly by the backend.

🛡️ Suggested fix
             <Input
               id="nodeAlias"
               type="text"
               value={nodeAlias}
               onChange={(e) => setNodeAlias(e.target.value)}
               placeholder="Alby Hub"
               className="w-full md:w-60"
+              maxLength={32}
             />
lnclient/ldk/ldk.go (2)

353-383: Tor hidden service start: soft-fail is reasonable, but verify the listening port parse.

The Tor startup continues on error (line 378), which aligns with the design intent. However, the listening-port parsing at lines 358–364 silently falls back to DefaultOnionServicePort if the address format is unexpected or LDKListeningAddresses is blank. If the LDK node actually listens on a non-default port, the onion service would forward to the wrong port.

Consider logging a warning when the port parse fails to fall back to the default, so operators can diagnose connectivity issues.

🔍 Suggested diagnostic logging
 		if addrs := strings.Split(cfg.GetEnv().LDKListeningAddresses, ","); len(addrs) > 0 {
 			addr := strings.TrimSpace(addrs[0])
 			if idx := strings.LastIndex(addr, ":"); idx >= 0 {
 				if p, err := strconv.Atoi(addr[idx+1:]); err == nil {
 					localPort = p
+				} else {
+					logger.Logger.WithError(err).WithField("addr", addr).Warn("Failed to parse LDK listening port for Tor, using default")
 				}
 			}
 		}

936-942: Optional: Extract alias resolution to a small helper to reduce duplication.

The same cfg.Get("NodeAlias", "") + default-to-"Alby Hub" pattern appears both here and in NewLDKService (lines 137–140). A tiny helper (e.g., func (ls *LDKService) getNodeAlias() string) would centralize the default.

api/models.go (1)

354-358: Nit: Missing blank line between ChangeUnlockPasswordRequest and AutoUnlockRequest.

Go convention places a blank line between type declarations (especially when each has a doc comment). Same issue between RebalanceChannelRequest and RebalanceChannelResponse at lines 379–383.

♻️ Suggested fix
 type ChangeUnlockPasswordRequest struct {
 	CurrentUnlockPassword string `json:"currentUnlockPassword"`
 	NewUnlockPassword     string `json:"newUnlockPassword"`
 }
+
 // AutoUnlockRequest contains the password used for automatic unlock on startup.
 type AutoUnlockRequest struct {
 	UnlockPassword string `json:"unlockPassword"`
 }
 type RebalanceChannelRequest struct {
 	ReceiveThroughNodePubkey string `json:"receiveThroughNodePubkey"`
 	AmountSat                uint64 `json:"amountSat"`
 }
+
 // RebalanceChannelResponse contains the fee paid for the channel rebalance.
 type RebalanceChannelResponse struct {
 	TotalFeeSat uint64 `json:"totalFeeSat"`
 }

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@lnclient/models.go`:
- Around line 58-63: The struct comment for NodeConnectionInfo incorrectly
mentions "including optional Tor address" even though the struct only defines
Pubkey, Address, and Port; update the doc comment above the NodeConnectionInfo
type to accurately describe the current fields (Pubkey, Address, Port) and
remove the Tor reference, or if Tor support is intended now, add a TorAddress
(or Onion) field to NodeConnectionInfo and document it accordingly; ensure
references to NodeConnectionInfo, Pubkey, Address, and Port are consistent.
🧹 Nitpick comments (3)
frontend/src/screens/settings/Settings.tsx (1)

43-47: Inconsistent hook usage: React.useEffect vs. bare useEffect.

Line 43 uses React.useEffect while line 49 uses useEffect (the named import from line 2). Pick one style — since useEffect and useState are already destructured in the import, use the bare form here too.

♻️ Suggested fix
-  React.useEffect(() => {
+  useEffect(() => {
     if (info?.nodeAlias !== undefined) {
       setNodeAlias(info.nodeAlias);
     }
   }, [info?.nodeAlias]);
lnclient/models.go (1)

200-201: Missing blank line before LightningBalanceResponse doc comment.

Every other type in this file has a blank line separating it from the preceding type. This one is missing it after the PeerDetails closing brace.

♻️ Suggested fix
 type PeerDetails struct {
 	NodeId      string `json:"nodeId"`
 	Address     string `json:"address"`
 	IsPersisted bool   `json:"isPersisted"`
 	IsConnected bool   `json:"isConnected"`
 }
+
 // LightningBalanceResponse contains the Lightning channel balance breakdown.
 type LightningBalanceResponse struct {
api/models.go (1)

353-357: Missing blank line before AutoUnlockRequest doc comment.

Same formatting inconsistency as in lnclient/models.go — the rest of the file separates types with blank lines.

♻️ Suggested fix
 type ChangeUnlockPasswordRequest struct {
 	CurrentUnlockPassword string `json:"currentUnlockPassword"`
 	NewUnlockPassword     string `json:"newUnlockPassword"`
 }
+
 // AutoUnlockRequest contains the password used for automatic unlock on startup.
 type AutoUnlockRequest struct {

Comment on lines +58 to 63
// NodeConnectionInfo contains the connection details for a Lightning node, including optional Tor address.
type NodeConnectionInfo struct {
Pubkey string `json:"pubkey"`
Address string `json:"address"`
Port int `json:"port"`
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Doc comment references Tor address that doesn't exist on this struct.

The comment says "including optional Tor address," but NodeConnectionInfo has only Pubkey, Address, and Port. If Tor support is coming in a follow-up PR/commit, keep the doc accurate for the current state of the code.

♻️ Suggested fix
-// NodeConnectionInfo contains the connection details for a Lightning node, including optional Tor address.
+// NodeConnectionInfo contains the connection details for a Lightning node.
 type NodeConnectionInfo struct {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// NodeConnectionInfo contains the connection details for a Lightning node, including optional Tor address.
type NodeConnectionInfo struct {
Pubkey string `json:"pubkey"`
Address string `json:"address"`
Port int `json:"port"`
}
// NodeConnectionInfo contains the connection details for a Lightning node.
type NodeConnectionInfo struct {
Pubkey string `json:"pubkey"`
Address string `json:"address"`
Port int `json:"port"`
}
🤖 Prompt for AI Agents
In `@lnclient/models.go` around lines 58 - 63, The struct comment for
NodeConnectionInfo incorrectly mentions "including optional Tor address" even
though the struct only defines Pubkey, Address, and Port; update the doc comment
above the NodeConnectionInfo type to accurately describe the current fields
(Pubkey, Address, Port) and remove the Tor reference, or if Tor support is
intended now, add a TorAddress (or Onion) field to NodeConnectionInfo and
document it accordingly; ensure references to NodeConnectionInfo, Pubkey,
Address, and Port are consistent.

sat-engineer added a commit to sat-engineer/hub that referenced this pull request Feb 8, 2026
The node alias settings UI belongs in PR getAlby#2039. Removed
Settings.tsx changes to keep this PR focused on the network graph.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rolznz
Copy link
Contributor

rolznz commented Feb 9, 2026

Hi, thanks for the PR but we already have a feature to change the node alias. I will close this PR for now.

@rolznz rolznz closed this Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants