Skip to content

feat(dashpay): add contact via QR code (My QR / Scan QR) - #1554

Draft
PastaPastaPasta wants to merge 3 commits into
masterfrom
feature/dashpay-user-qr
Draft

feat(dashpay): add contact via QR code (My QR / Scan QR)#1554
PastaPastaPasta wants to merge 3 commits into
masterfrom
feature/dashpay-user-qr

Conversation

@PastaPastaPasta

Copy link
Copy Markdown
Member

What

Ports the iOS "add contact via QR" feature to Android: a user can show a QR code identifying their DashPay identity, and scan another user's code to land on the send-contact-request sheet.

  • Wire contract parserDashPayUserLink implements the shared dashpay://user?id=<base58-identity-id>&username=<label> payload, mirroring iOS DashPayUserLink.swift exactly (case-insensitive scheme/host/param names; rejects userinfo/port/path/fragment/duplicate/unknown params; id must decode to 32 bytes; trailing .dash tolerated and stripped). DashPayUserLinkTest ports the iOS acceptance/rejection vectors byte-for-byte — these tests are the cross-platform contract and should stay in sync with DashPayUserLinkTests.swift.
  • UI entry points — a "My QR" / "Scan QR" button row under the search field on the Add a New Contact screen (both ConstraintSet layout variants). "My QR" shows only with a registered identity + username; "Scan QR" whenever an identity exists.
  • My QR sheet — Compose bottom sheet with display name, username, the QR on a forced-white card (deliberately white in dark mode too, for camera scanner contrast — same as iOS), and a caption.
  • Scan → verify → sheet — scanned payloads are parsed strictly (payment URIs / invitation links get a targeted "isn't a DashPay user QR" dialog rather than falling through to InputParser); own-QR shows a notice; known contacts skip straight to the sheet; everyone else is verified against Platform via PlatformRepo.updateDashPayProfile() — only Platform-resolved profile/DPNS data is displayed, with the QR's username param used solely as a mismatch check. Loading state + retryable error dialog on failure. On success the existing DashPayUserBottomSheet handles send-request and refresh.
  • Strings for Transifex, AnalyticsConstants.UsersContacts events for show-my-QR / scan / scan-success.

Deferred (as planned): the OS-level dashpay://user manifest deep link — iOS only ever emits this URI inside a QR, and in-app scanning covers the feature.

Also includes a standalone commit repairing the master build (current master HEAD fails CI): a duplicate Configuration import in MenuItem.kt and subtitleMaxLines arguments passed to ActionItem, which has no such parameter (its subtitle is already single-line).

Verification

  • :wallet:compile_testNet3DebugKotlin passes
  • DashPayUserLinkTest 6/6 passes (:wallet:test_testNet3DebugUnitTest)
  • ktlintCheck passes

QA notes

Suggested two-device testnet smoke:

  • Android shows / iOS scans, and iOS shows / Android scans
  • Scan your own QR (expect "This is your QR code" notice)
  • Scan a payment QR and an invitation QR from this screen (expect the targeted error, not the payment flow)
  • Scan a QR whose username no longer matches the identity's DPNS name, and a testnet QR on mainnet (both expect the "couldn't be verified" retry dialog)
  • Scan an existing contact (expect the sheet in established-contact state, no Platform round-trip)

🤖 Generated with Claude Code

PastaPastaPasta and others added 3 commits August 29, 2026 18:07
Remove a duplicate android.content.res.Configuration import in MenuItem.kt and drop the subtitleMaxLines arguments passed to ActionItem, which has no such parameter (its subtitle is already limited to a single line). Both were introduced in 74bd90a and fail compilation (master CI is red on that commit).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Strict parser/codec for the dashpay://user?id=<base58-identity-id>&username=<label> payload shared with iOS DashPayUserLink.swift: scheme/host/param names case-insensitive; userinfo, port, path, fragment, duplicate and unknown params rejected; id must decode to 32 bytes; a trailing .dash is tolerated and stripped. The JUnit vectors mirror the iOS DashPayUserLinkTests byte for byte - they are the cross-platform contract and must stay in sync between the repositories.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…reen

My QR opens a bottom sheet with the user's dashpay://user link rendered on a forced-white card (kept white in dark mode for scanner contrast, matching iOS); it requires a registered identity with a username. Scan QR launches ScanActivity; scanned payloads are parsed strictly (payment/invitation QRs get a targeted error instead of falling through to InputParser), own-QR shows a notice, known contacts open the user sheet directly, and everyone else is verified against Platform (profile + DPNS via PlatformRepo.updateDashPayProfile) before the DashPayUserBottomSheet opens - only Platform-verified data is displayed, the QR's username param is just an early mismatch check. Includes loading and retryable-error states, Transifex strings, and UsersContacts analytics events.

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

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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

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