Skip to content

feat: Add Tor hidden service support for incoming peer connections #2035

@sat-engineer

Description

@sat-engineer

Problem

Alby Hub's LDK backend only makes outbound connections to peers - it doesn't listen for incoming connections. This means:

  • Two Alby Hub users cannot open direct channels to each other
  • Users must rely entirely on LSPs for channel connectivity
  • The "Connect Peer" feature only works if the other node has a public address
    This is a significant limitation for users who want peer-to-peer Lightning channels without intermediaries.

Proposed Solution

Add optional Tor hidden service support so Alby Hub nodes can accept incoming connections. This would give each node a .onion address that peers can connect to, similar to how LND handles Tor.

The node URI would look like:

<pubkey>@<generated>.onion:9735

Technical Approach

Based on research into LND's implementation (tor/tor.go, ~600 lines), the MVP would:

  1. Add Tor control port integration using github.com/cretz/bine (Go library for Tor)
  2. Optionally embed Tor via berty.tech/go-libtor for self-contained deployments
  3. Create a v3 onion service that forwards to LDK's peer handler
  4. Persist the onion private key so the address survives restarts
  5. Announce the .onion address in node gossip

Files likely affected:

  • ldk/ldk.go or ldk/service.go - Tor listener initialization
  • Config/environment handling for new options like LDK_TOR_LISTEN=true
  • Potentially upstream changes to ldk-node-go bindings
  • React frontend components for settings UI

Prior art:

MVP Scope

In scope:

  • Accept incoming Tor connections
  • Generate and persist .onion address
  • Settings UI toggle to enable/disable Tor listening
  • Display node URI (with .onion address) in UI so users can share it
  • Copy-to-clipboard for easy sharing
  • Works on Linux/Docker (Umbrel use case)

Out of scope for MVP:

  • Clearnet listening (IPv4/IPv6)
  • Hybrid Tor+clearnet

Questions for Maintainers

  1. Is this something you'd accept as a contribution?
  2. Any preferences on Tor integration approach (embedded vs external daemon)?
  3. Should this live entirely in ldk-node-go, or partially in the Hub Go code?
  4. Are there architectural constraints I should know about?
  5. Any preferences on where the UI toggle should live (Settings > Node, or elsewhere)?

Estimated Effort

5-7 weeks part-time for an experienced contributor (including UI work).


Happy to discuss the approach before starting implementation. I'm motivated to work on this because I want to open direct channels with friends who also run Alby Hub.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions