Skip to content

Add OpenAlias for Monero sends - #1456

Open
sneurlax wants to merge 17 commits into
stagingfrom
feat/openalias
Open

sneurlax wants to merge 17 commits into
stagingfrom
feat/openalias

Conversation

@sneurlax

@sneurlax sneurlax commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Adds a DohOpenAlias class for handling DNS requests for OpenAlias records. Adds a DnsProxyConnection because of issues with socks5_proxy et al

Parse oa1:xmr records, rejecting separate payment IDs and aliases with more
than one distinct address. Records are resolved with Google DNS-over-HTTPS
and only accepted when authenticated (AD set, CD and TC clear, exact
question match). When Tor is enabled the lookup is tunnelled through its
SOCKS port to the numeric resolver address, with no clearnet fallback.
@sneurlax
sneurlax marked this pull request as draft October 1, 2026 17:42
Add a Use OpenAlias lookup to the mobile and desktop send screens. The
accepted address is carried in TxData and shown on confirmation; editing the
destination drops it.
Record parsing, DoH response validation and transport, the lookup service,
the lookup dialog and the TxData recipient. The live lookup test is skipped
by default.
Retain the RawSocket across SOCKS negotiation and the TLS upgrade so a
lookup timeout can close the live connection before TLS completes. Expose
an independently completed result because closing a raw transport during
TLS can leave Dart's handshake future pending. Keep cancellation idempotent
and dispose of sockets that complete after cancellation.

Adapt raw sockets to the Socket/SecureSocket interfaces expected by
HttpClient, preserving stream backpressure, partial writes, certificate
inspection, dns.google verification and the numeric SOCKS destination.

Add regression tests that wait for ClientHello before cancellation and
assert peer disconnection before teardown, including repeated attempts
and the full lookup timeout. Cover immediate cancellation, a trusted local
TLS/HTTP exchange, and rejection of an untrusted certificate. The committed
certificate and private key are test-only fixtures, trusted only through
an isolated SecurityContext.

Validation: all 37 offline OpenAlias tests pass (3 opt-in live tests skipped);
static analysis of the changed Dart files reports no issues.

Remove the socks5_proxy comment from DnsProxyConnection and preserve its
rationale here: socks5_proxy resolves hostnames locally before CONNECT,
so the OpenAlias tunnel uses the numeric endpoint 8.8.8.8:443 instead.
TLS still verifies dns.google without performing a local hostname lookup.
Accept plausible OpenAlias input directly in the Monero destination field
without marking it as a valid literal address or looking it up while editing.
Combine screen-local alias eligibility with the existing amount/data gates
and retain each layout's applicable fee checks.

Resolve through OpenAliasService after Preview, validate the result for the
wallet, and prepare only the resolved literal address. Keep the source alias
in the field and attach attribution to that attempt's TxData. Returning from
confirmation resolves afresh; final send uses the prepared recipient.

Share a per-screen attempt controller to suppress duplicate previews and
ignore stale lookup/preparation results after edits, cancellation, disposal,
or wallet changes. A modal progress route protects the draft during lookup;
controller/provider edits invalidate it and source/wallet/fee checks guard
preparation and navigation. Close only the progress route owned by the
attempt, then reuse the existing transaction-failed presentation on errors.
Remove the separate OpenAlias buttons and acceptance handlers.

Add active tests of both real send screens and both confirmation layouts,
with injected DNS records and fake wallets. Cover eligibility, no lookup on
editing/fee estimation, duplicate clicks, fresh retries, error-route safety,
late success/failure, cancellation during preparation, wallet changes,
contact autofill, payment URIs, and final send without another lookup.
No address-book, token, transport, or literal-address validator changes.
Delete the unused lookup/accept dialog and its send-form attribution widget.
Confirmation continues to display attribution from the prepared TxData.
Remove the seven dialog-specific tests, now replaced by active mobile and
desktop tests of direct destination entry and Preview-time resolution.
Select mobile and desktop layouts explicitly in widget tests using a debug-only Util override, restored during teardown. This avoids relying on the Linux-only small-screen exception when the tests run on macOS.

Exercise the inline workflow at 390x844 and 1200x900 with a full-length Monero recipient. Constrain the balance columns and remove the unbounded destination-label row exposed by the phone viewport.
@codecov

codecov Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.25688% with 146 lines in your changes missing coverage. Please review.
✅ Project coverage is 9.05%. Comparing base (03ad880) to head (cca8fed).
⚠️ Report is 24 commits behind head on staging.

Files with missing lines Patch % Lines
lib/services/openalias/dns_proxy_socket.dart 66.94% 39 Missing ⚠️
lib/pages/send_view/send_view.dart 81.43% 31 Missing ⚠️
lib/pages/send_view/confirm_transaction_view.dart 68.75% 30 Missing ⚠️
...providers/ui/preview_tx_button_state_provider.dart 51.61% 15 Missing ⚠️
lib/services/openalias/doh_open_alias.dart 88.50% 10 Missing ⚠️
...ack_view/wallet_view/sub_widgets/desktop_send.dart 94.82% 6 Missing ⚠️
lib/services/openalias/open_alias_service.dart 62.50% 6 Missing ⚠️
..._view/sub_widgets/building_transaction_dialog.dart 25.00% 3 Missing ⚠️
lib/services/openalias/dns_proxy_connection.dart 96.22% 2 Missing ⚠️
lib/widgets/transaction_preview_dialog.dart 95.91% 2 Missing ⚠️
... and 2 more
Additional details and impacted files
@@             Coverage Diff             @@
##           staging    #1456      +/-   ##
===========================================
+ Coverage     6.72%    9.05%   +2.32%     
===========================================
  Files         1118     1130      +12     
  Lines       111939   113003    +1064     
===========================================
+ Hits          7533    10229    +2696     
+ Misses      104406   102774    -1632     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sneurlax
sneurlax marked this pull request as ready for review October 1, 2026 18:23
Aliases and CNAME targets are DNS names, not hostnames, and may contain
underscores (RFC 2181). A CNAME to a name such as _oa.pay.example
previously failed with the input validation message.
Names in a resolver answer were checked with the alias input validator,
so a malformed CNAME target told the user to enter a valid domain.
Replace the inline connection and lookup durations with named constants,
and let callers override them per DohOpenAlias instance.
Over Tor, the connection deadline covers the local SOCKS connect, the
exit stream to the resolver and the TLS handshake through Tor, so five
seconds was tight. Tor lookups now get 10 s to connect and 20 s overall;
direct lookups keep 5 s and 12 s. The overall deadline grows with the
connection deadline so a slow connect still leaves time for the response.
The confirmation showed the DNS name used for the lookup, so
dan@cypherstack.com appeared as dan.cypherstack.com. Keep the trimmed,
lowercased input for display; lookups and validation still use the DNS
name.
A failed alias lookup opened a "Transaction failed" dialog although no
transaction was built. Lookup failures now use "OpenAlias lookup
failed"; preparation failures keep the existing title.
The error asked users to enable external calls in privacy settings,
which has no such control. External calls follow the Stack Experience
choice under Advanced settings, so name that setting instead.
Include the DNS name that was looked up when no record exists, so a
typo such as dan@cypherstack (dan.cypherstack) is visible in the error.
Report a nonexistent name separately from other resolver failures.
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