Skip to content

feat(dashpay): show the username people typed, not the normalized form - #933

Merged
QuantumExplorer merged 1 commit into
developfrom
claude/voting-display-names
Aug 7, 2026
Merged

feat(dashpay): show the username people typed, not the normalized form#933
QuantumExplorer merged 1 commit into
developfrom
claude/voting-display-names

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Aug 7, 2026

Copy link
Copy Markdown
Member

Why

The voting screens render Platform's homograph-normalized label, so a contest for pizza shows as p1zza. That reads as a typo to the very people whose username is being voted on.

This was written as part of #923 but landed after that PR was squash-merged, so it never reached develop — hence this follow-up PR.

Why it needed an SDK change first

Normalization maps o0 and i/l1. It is lossy and ambiguous — p1zza could be pizza, plzza or p1zza — so no client can recover the spelling by guessing.

dashpay/platform#4331 (merged, 8f98180c55) decodes the spelling from each contender's domain document, where it was already on the wire, and derives the ordered, de-duplicated label list in Rust.

What changes

  • List row leads with the typed spelling; the stored form sits beneath it in small monospace only when the two differ.
  • Detail screen titles on the typed spelling and adds a "Stored as" row plus a one-line explanation of why they differ.
  • Contender rows show each requester's own spelling, falling back to the truncated identity id when their document could not be decoded.
  • Search matches both forms, so typing pizza finds the contest whether the row reads pizza or p1zza.

Contenders who typed different spellings

That is the situation a contest exists to resolve, so all distinct spellings are shown joined by "or" (pizza or p1zza) rather than arbitrarily picking one. The ordering and de-duplication happen in Rust (DashSDKContestInfo.requested_labels); Swift copies the result verbatim, per packages/swift-sdk/CLAUDE.md's thin-bridge rule.

Nothing is guessed

A contest with no decodable contender document keeps showing the normalized form. The normalized label is never reverse-engineered, and never hidden — it stays visible as supporting information wherever it differs.

Testing

Clean dashpay build against merged v4.2-dev (8f98180c55) with the xcframework rebuilt for both slices.

⚠️ develop does not currently build against merged v4.2-dev, independent of this PR. a9ff688a8 calls ManagedPlatformWallet.invitationProspectiveIdentityId, which does not exist in any merged platform branch — so that cross-repo change is still in flight. Verified plain origin/develop fails identically, then temporarily stubbed that one call locally (not committed) to confirm this branch's own code compiles clean. Worth resolving before merging anything that needs a green app build.

Runtime behaviour is still unverified — whether real contests carry decodable labels needs a testnet check.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Contest and username voting screens now show more recognizable contender names, with identity details as a fallback.
    • Contest titles display both the user-entered name and normalized name when they differ.
    • Contest search matches both entered and normalized spellings.
  • Bug Fixes
    • Improved handling of unreadable contender information and incomplete search results.
  • Documentation
    • Added clearer explanations for normalized names, invalid input, and related voting states.

The voting screens rendered Platform's homograph-normalized label, so a contest
for "pizza" appeared as "p1zza" — which reads as a typo to the people whose
name is being voted on. The normalization is not reversible client-side, so
this needed the spelling to come off the wire; dashpay/platform#4331 decodes it
from each contender's `domain` document.

Contests now lead with what people actually typed, and keep the normalized form
as supporting information rather than dropping it:

- The list row shows the typed spelling, with the stored form beneath it in
  small monospace whenever the two differ.
- The detail screen titles on the typed spelling and adds a "Stored as" row
  plus a one-line explanation of why they differ.
- Contender rows show each requester's own spelling, falling back to the
  truncated identity id when their document could not be decoded.
- When contenders typed *different* spellings that normalize to the same value
  — the situation a contest exists to resolve — all of them are shown joined by
  "or", rather than arbitrarily picking one.

Search now matches both forms, so typing "pizza" finds the contest whether the
row reads "pizza" or "p1zza".

Nothing is reverse-engineered from the normalized label: `0`→`o` and `1`→`i`/`l`
are ambiguous, so a contest with no decodable contender document keeps showing
the normalized form rather than a guessed one.

Requires dashpay/platform#4331 (adds `label` to `DashSDKContender`, so the
xcframework must be rebuilt).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 87cdc7f7-9811-41bb-868b-819a86c231b4

📥 Commits

Reviewing files that changed from the base of the PR and between 2521e22 and aa112ec.

📒 Files selected for processing (6)
  • DashWallet/Sources/Infrastructure/SwiftDashSDK/Voting/ContestedNamesService.swift
  • DashWallet/Sources/UI/DashPay/Usernames/UsernameRequestStatusScreen.swift
  • DashWallet/Sources/UI/DashPay/Voting/ContestDetailScreen.swift
  • DashWallet/Sources/UI/DashPay/Voting/UsernameVotingScreen.swift
  • DashWallet/Sources/UI/DashPay/Voting/VotingViewModel.swift
  • DashWallet/en.lproj/Localizable.strings

📝 Walkthrough

Walkthrough

The change adds contest display-title helpers, contender display-name fallbacks, updated voting-screen presentation, and search matching for both normalized and submitted username labels.

Changes

Contest display and search

Layer / File(s) Summary
Display title and contender identity contracts
DashWallet/Sources/Infrastructure/SwiftDashSDK/Voting/ContestedNamesService.swift
DPNSContest derives a preferred display title and detects differences from the normalized label. DPNSContender returns a decoded display name or truncated identity.
Voting screen display integration
DashWallet/Sources/UI/DashPay/Usernames/UsernameRequestStatusScreen.swift, DashWallet/Sources/UI/DashPay/Voting/ContestDetailScreen.swift, DashWallet/Sources/UI/DashPay/Voting/UsernameVotingScreen.swift
Voting screens show preferred contest titles and contender display names. Normalized labels and monospaced styling appear only when required.
Contest search and localized messages
DashWallet/Sources/UI/DashPay/Voting/VotingViewModel.swift, DashWallet/en.lproj/Localizable.strings
Contest search matches normalized labels and submitted labels. New voting-related messages are localized.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • dashpay/dashwallet-ios#923: This change builds on its contest service, voting screens, username status screen, and voting view model.
🚥 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 clearly summarizes the main change: showing the username spelling entered by users instead of only the normalized form.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/voting-display-names

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

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