Skip to content

Conversation

@openoms
Copy link

@openoms openoms commented Nov 4, 2025

Introduce a configurable first hop preference for outgoing Lightning payments, enabling operators to route payments through specific channels while ensuring reliability with automatic fallback. This feature includes YAML configuration, intelligent error categorization, comprehensive observability, and full test coverage. No breaking changes introduced, and backward compatibility is maintained.

…yments

Implement a configurable first hop preference for outgoing Lightning payments
with intelligent fallback logic. This allows operators to route payments through
specific channels while maintaining reliability through automatic fallback.

Features:
- YAML configuration for preferred outgoing channels
- Intelligent error categorization (retry-able vs non-retry-able)
- Automatic fallback to any route when preferred channel fails
- Comprehensive observability with tracing and logging
- Full test coverage (unit + integration tests)

Configuration:
Add to galoy.yaml:
```yaml
preferredFirstHopConfig:
  enabled: true
  outgoingChannels:
    - "123456789012345678"  # Channel ID
  fallbackOnError: true
```

Use Cases:
- Route through specific trusted peers
- Liquidity management (use channels needing rebalancing)
- Privacy (specific routing paths)
- Fee optimization (prefer low-fee channels)

Implementation Details:

1. Configuration Layer:
   - Added preferredFirstHopConfig schema with validation
   - Type-safe configuration with PreferredFirstHopConfig type
   - Getter function getPreferredFirstHopConfig()

2. LND Service Updates:
   - Extended probeForRoute() to accept outgoingChannel parameter
   - Extended findRouteForInvoice() to pass through outgoingChannel
   - Extended findRouteForNoAmountInvoice() to pass through outgoingChannel
   - Extended payInvoiceViaPaymentDetails() to accept outgoingChannel
   - All changes maintain backward compatibility (optional parameters)

3. Fallback Logic:
   - Created shouldRetryWithoutFirstHop() function for error categorization
   - Retry-able errors: RouteNotFoundError, InsufficientBalanceForRoutingError,
     TemporaryChannelFailureError, TemporaryNodeFailureError,
     ProbeForRouteTimedOutError, UnknownNextPeerError
   - Non-retry-able errors: LnAlreadyPaidError, InvoiceExpiredOrBadPaymentHashError,
     PaymentRejectedByDestinationError, InsufficientBalanceForLnPaymentError,
     PaymentAttemptsTimedOutError, LnPaymentPendingError

4. Payment Execution:
   - Created executePaymentWithFirstHopFallback() function
   - Two-attempt pattern: try with preferred channel, fallback without constraint
   - Fast-fail on non-retry-able errors (no unnecessary retries)
   - Integrated into lockedPaymentViaLnSteps()

5. Observability:
   - Added tracing attributes: payment.firstHop.preferredChannel,
     payment.firstHop.fallbackEnabled, payment.firstHop.result,
     payment.firstHop.error, payment.firstHop.fallbackAttempted,
     payment.firstHop.fallbackResult
   - Detailed logging for debugging and monitoring

6. Tests:
   - Unit tests for shouldRetryWithoutFirstHop() covering all error types
   - Integration tests for complete payment flow with fallback scenarios
   - Tests verify: successful fallback, no retry on non-retry-able errors,
     disabled config behavior

Files Changed:
- core/api/src/config/schema.ts
- core/api/src/config/schema.types.d.ts
- core/api/src/config/types.d.ts
- core/api/src/config/yaml.ts
- core/api/src/domain/bitcoin/lightning/first-hop-fallback.ts (NEW)
- core/api/src/domain/bitcoin/lightning/index.ts
- core/api/src/domain/bitcoin/lightning/index.types.d.ts
- core/api/src/app/payments/send-lightning.ts
- core/api/src/services/lnd/index.ts
- core/api/test/unit/domain/bitcoin/lightning/first-hop-fallback.spec.ts (NEW)
- core/api/test/integration/app/wallets/send-lightning-first-hop.spec.ts (NEW)

Breaking Changes: None
Backward Compatibility: Full (feature is opt-in via configuration)
@github-actions github-actions bot added the core label Nov 4, 2025
@openoms openoms changed the title Add configurable first hop with fallback logic for Lightning payments feat: add configurable first hop with fallback logic for lightning payments Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants