Skip to content

feat(ln): verify LNURL-pay before saving ln_address and AddInvoice - Phase 2#60

Merged
arkanoider merged 2 commits into
mainfrom
feat/ln-address-lnurl-verify-and-docs
May 4, 2026
Merged

feat(ln): verify LNURL-pay before saving ln_address and AddInvoice - Phase 2#60
arkanoider merged 2 commits into
mainfrom
feat/ln-address-lnurl-verify-and-docs

Conversation

@arkanoider

@arkanoider arkanoider commented May 4, 2026

Copy link
Copy Markdown
Collaborator
  • Add util/ln_address.rs: resolve lnurlp URL, GET metadata, require tag payRequest
  • spawn_verify_and_save_ln_address_task: async verify then persist settings
  • Settings confirm and y-shortcut: show verifying toast, save only after success
  • execute_add_invoice: same check for Lightning address input before DM
  • Remove unused sync save_ln_address_to_settings
  • Docs: STARTUP_AND_CONFIG, TUI, SETTINGS_ANALYSIS, MESSAGE_FLOW, buy/sell flows, docs README

Summary by CodeRabbit

  • New Features

    • Added Lightning address support: save an optional address in settings and reuse it across orders.
    • Added LNURL verification: all Lightning addresses are automatically validated before saving or use.
    • Expanded invoice input: buyers can submit either BOLT11 invoices or Lightning addresses.
  • Documentation

    • Updated guides with Lightning address setup and LNURL verification behavior.

- Add util/ln_address.rs: resolve lnurlp URL, GET metadata, require tag payRequest
- spawn_verify_and_save_ln_address_task: async verify then persist settings
- Settings confirm and y-shortcut: show verifying toast, save only after success
- execute_add_invoice: same check for Lightning address input before DM
- Remove unused sync save_ln_address_to_settings
- Docs: STARTUP_AND_CONFIG, TUI, SETTINGS_ANALYSIS, MESSAGE_FLOW, buy/sell flows, docs README

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@arkanoider has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 42 minutes and 48 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7f749685-90bd-4ac7-81fb-43ec01586e4c

📥 Commits

Reviewing files that changed from the base of the PR and between 76d412b and 2cd82f2.

📒 Files selected for processing (12)
  • docs/CODING_STANDARDS.md
  • docs/SETTINGS_ANALYSIS.md
  • docs/STARTUP_AND_CONFIG.md
  • docs/TUI_INTERFACE.md
  • src/main.rs
  • src/ui/key_handler/async_tasks.rs
  • src/ui/key_handler/confirmation.rs
  • src/ui/key_handler/enter_handlers.rs
  • src/ui/key_handler/mod.rs
  • src/ui/mod.rs
  • src/ui/orders.rs
  • src/ui/state.rs

Walkthrough

This PR adds Lightning address (LNURL-pay) verification to Mostrix. Users can now save a Lightning address in settings with LNURL-pay metadata reachability validation before persistence, and the execute_add_invoice flow verifies addresses via LNURL endpoints before constructing payment requests. Supporting changes include a new async verification task, LNURL-pay metadata utilities, UI/help text updates, and documentation.

Changes

Lightning Address Verification Feature

Layer / File(s) Summary
Data Shape
docs/STARTUP_AND_CONFIG.md, src/ui/key_handler/settings.rs
Settings struct adds ln_address: String field with #[serde(default)] for optional buyer Lightning address persistence.
Utility Foundation
src/util/ln_address.rs, src/util/mod.rs
New ln_address module with ln_address_pay_request_reachable async function to fetch LNURL-pay metadata, parse JSON, and validate tag: "payRequest"; helper resolves both LNURL URLs and Lightning addresses to metadata endpoints.
Settings Validation
src/ui/key_handler/settings.rs
Added validate_ln_address_format to trim and validate Lightning address shape (user@domain.com format via LightningAddress::from_str); removed synchronous save_ln_address_to_settings function.
Async Verification Task
src/ui/key_handler/async_tasks.rs
New spawn_verify_and_save_ln_address_task spawns Tokio task that trims address, verifies LNURL-pay reachability, loads/updates Settings.ln_address, persists to disk, and sends OperationResult feedback via channel.
Confirmation & Key Handling
src/ui/key_handler/confirmation.rs, src/ui/key_handler/enter_handlers.rs
Updated ConfirmLnAddress YES handler to spawn async verification task instead of synchronous save; imports reorganized to use spawn_verify_and_save_ln_address_task and remove direct save_ln_address_to_settings reference.
UI/UX Updates
src/ui/draw.rs, src/ui/help_popup.rs
Confirmation popup text updated to "Verify LNURL endpoint and save this address to settings.toml?"; Settings help text clarified that verification happens before save and failures block persistence.
Execution Integration
src/util/order_utils/execute_add_invoice.rs
Lightning-address branch now trims input and calls ln_address_pay_request_reachable(...).await to verify address before constructing Payload::PaymentRequest; errors mapped to "Lightning address not verified: {e}".
Documentation
docs/README.md, docs/SETTINGS_ANALYSIS.md, docs/MESSAGE_FLOW_AND_PROTOCOL.md, docs/STARTUP_AND_CONFIG.md, docs/TUI_INTERFACE.md, docs/buy order flow.md, docs/sell order flow.md
Comprehensive updates documenting Lightning address field semantics, LNURL-pay metadata verification flow, user-mode-only UI, confirm-save behavior, optional address persistence, and integration into order flows.

Sequence Diagram

sequenceDiagram
    participant User as User (TUI)
    participant UI as Settings UI
    participant AsyncTask as Async Verify Task
    participant LNURL as LNURL Endpoint
    participant Disk as Settings File
    participant Modal as OperationResult Modal

    User->>UI: Enter Lightning address (user@domain.com)
    UI->>UI: validate_ln_address_format()
    UI->>User: Show confirmation prompt
    User->>UI: Confirm (YES)
    UI->>AsyncTask: spawn_verify_and_save_ln_address_task()
    UI->>Modal: Display "Verifying Lightning address..."
    AsyncTask->>LNURL: ln_address_pay_request_reachable() <br/> (fetch metadata JSON)
    alt LNURL Valid (tag: "payRequest")
        LNURL-->>AsyncTask: Metadata OK
        AsyncTask->>Disk: Load settings.toml
        AsyncTask->>Disk: Update ln_address field
        AsyncTask->>Disk: Persist to disk
        AsyncTask-->>Modal: OperationResult::Info("Saved")
        Modal->>User: Show success message
    else LNURL Failed
        LNURL-->>AsyncTask: HTTP error / JSON parse error / tag mismatch
        AsyncTask-->>Modal: OperationResult::Error("Lightning address not verified: {e}")
        Modal->>User: Show error (settings NOT updated)
    end
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • MostroP2P/mostrix#59: Introduced initial ln_address settings field; this PR extends it with LNURL-pay verification before persistence.
  • MostroP2P/mostrix#22: Previously modified execute_add_invoice; this PR adds trimming and LNURL reachability checks to the same function.
  • MostroP2P/mostrix#51: Also touches execute_add_invoice; related at the file level for payment request construction logic.

Suggested Reviewers

  • grunch
  • mostronatorcoder

Poem

A rabbit hops through LNURL domains, ✓
Verifying each address with care,
Settings saved when metadata reigns,
Lightning flows without a glare,
Pay requests bloom in the air! 🐰⚡

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: LNURL-pay verification before saving ln_address in settings and before AddInvoice, with Phase 2 indicating continuation of prior work.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ln-address-lnurl-verify-and-docs

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
Review rate limit: 0/1 reviews remaining, refill in 42 minutes and 48 seconds.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/ui/key_handler/enter_handlers.rs (1)

773-781: ⚖️ Poor tradeoff

order_result_tx reused for a settings-domain task — consider a dedicated channel.

spawn_verify_and_save_ln_address_task passes ctx.order_result_tx to report a Lightning-address verification result, but order_result_tx is semantically scoped to order/dispute operation results. The OperationResult variants it sends will be processed by the main-loop's handle_operation_result, which may have order-specific side effects for certain variants.

Other settings-adjacent tasks already have dedicated channels (key_rotation_tx, mostro_info_tx, seed_words_tx); introducing a ln_address_result_tx (or a purpose-specific OperationResult::LnAddressVerified variant with a matching handler) would keep channel semantics clean and avoid future cross-flow coupling.

Based on learnings: "Do not reuse order_result_tx for flows unrelated to its semantic purpose (order/dispute operation results). This guidance applies across Rust files in the codebase to ensure consistent channel usage and avoid cross-flow coupling." (PR #31, src/ui/key_handler/enter_handlers.rs)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ui/key_handler/enter_handlers.rs` around lines 773 - 781, Replace the
reused ctx.order_result_tx with a purpose-specific channel: add a new
ln_address_result_tx to the context and change
spawn_verify_and_save_ln_address_task to accept that channel instead of
ctx.order_result_tx; send a dedicated result type (either a new
OperationResult::LnAddressVerified variant or a small enum specific to
ln_address_result_tx) from the spawned task, and update the main-loop handler
(handle_operation_result or add a new handler for ln_address_result_tx) to
process the Lightning-address verification results; update the call site in
enter_handlers.rs (where create_key_input_state and UiMode::OperationResult are
set) to clone and pass ctx.ln_address_result_tx rather than ctx.order_result_tx
so settings-domain flows are kept separate from order/dispute flows.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/ui/key_handler/enter_handlers.rs`:
- Around line 773-781: Replace the reused ctx.order_result_tx with a
purpose-specific channel: add a new ln_address_result_tx to the context and
change spawn_verify_and_save_ln_address_task to accept that channel instead of
ctx.order_result_tx; send a dedicated result type (either a new
OperationResult::LnAddressVerified variant or a small enum specific to
ln_address_result_tx) from the spawned task, and update the main-loop handler
(handle_operation_result or add a new handler for ln_address_result_tx) to
process the Lightning-address verification results; update the call site in
enter_handlers.rs (where create_key_input_state and UiMode::OperationResult are
set) to clone and pass ctx.ln_address_result_tx rather than ctx.order_result_tx
so settings-domain flows are kept separate from order/dispute flows.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 526189d8-9cd3-4817-a244-d461f31f8453

📥 Commits

Reviewing files that changed from the base of the PR and between 6482f6c and 76d412b.

📒 Files selected for processing (16)
  • docs/MESSAGE_FLOW_AND_PROTOCOL.md
  • docs/README.md
  • docs/SETTINGS_ANALYSIS.md
  • docs/STARTUP_AND_CONFIG.md
  • docs/TUI_INTERFACE.md
  • docs/buy order flow.md
  • docs/sell order flow.md
  • src/ui/draw.rs
  • src/ui/help_popup.rs
  • src/ui/key_handler/async_tasks.rs
  • src/ui/key_handler/confirmation.rs
  • src/ui/key_handler/enter_handlers.rs
  • src/ui/key_handler/settings.rs
  • src/util/ln_address.rs
  • src/util/mod.rs
  • src/util/order_utils/execute_add_invoice.rs

@mostronatorcoder mostronatorcoder Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I reviewed this one carefully and I do not see a blocker in the current diff.

What I checked:

  • the new LNURL verification helper and its tag == payRequest guard
  • the async settings flow for verifying an address before persisting it
  • the updated AddInvoice path, to ensure Lightning addresses are verified before the DM is sent
  • confirm / Esc / y shortcut behavior around the new async verification step
  • docs and UI copy, to make sure they now describe verification instead of plain format validation

The implementation looks coherent to me:

  • format validation still happens first in the UI
  • persistence moved behind async LNURL verification, which is the right place for a network-dependent check
  • execute_add_invoice now rejects Lightning addresses whose LNURL-pay endpoint cannot be verified
  • clear-address flow stayed simple and synchronous, which makes sense

Checks are green too, so this looks good from my side. Nice step forward, this closes the biggest hole left by phase 1.

@arkanoider arkanoider merged commit ad2ef05 into main May 4, 2026
11 checks passed
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.

1 participant