Skip to content

fix: copy and share USDT receiving addresses - #997

Merged
ovitrif merged 2 commits into
masterfrom
fix/usdt-receive-sharing
Oct 17, 2026
Merged

ovitrif merged 2 commits into
masterfrom
fix/usdt-receive-sharing

Conversation

@ben-kaufman

Copy link
Copy Markdown
Contributor

Fixes #995

This PR makes USDT receive copying and sharing work with exchanges and plain address fields.

Description

  • Copy below the QR and tapping the QR copy the plain receiving address, including the selected network’s bridge deposit address.
  • Share from the QR or address details includes the address, explicit network, optional requested USDT amount and the payment QR image.
  • Reuse the existing QR generator and receive components so the QR still carries the token, network and exact amount.

Out of Scope

  • Bitcoin/Lightning receive behavior, internal Paykit routing and Earn/Locks authorization remain unchanged.

Design

USDT receive flow. Existing layout and styling are unchanged; copy/share behavior follows #995 and the agreed receive-sharing requirements.

Preview

Copy: 0x…

Shared text:

Network: Arbitrum One
0x…
3.5 USDT

The attached QR retains the payment URI and uint256=3500000.

QA Notes

Journeys

  • updated usdt-receive-amount-and-units.xml — plain-address copying, exact requested amount, network label and payment QR sharing from both views.
  • updated usdt-wallet-navigation.xml — the receive QR copies its address while retaining the payment URI for scanning.

Manual Tests

  • With an enabled bridge provider, Receive → select Polygon → prepare a deposit → copy and share from both views → all actions use the Polygon deposit address and requested amount, and the QR retains its original URI; switch back to Arbitrum and repeat — a live bridge provider is absent from the standard journey environment.

Automated Checks

  • added UsdtReceiveSharingTests.swift — verifies exact optional amounts and decodes the shared QR for Arbitrum, Polygon, Bitcoin and Lightning URIs.
  • ran UsdtReceiveSharingTests.swift, UsdtPaymentLinkTests.swift and ReceiveEditTests.swift on iOS 26.1 — 11 tests passed.

@greptile-apps

greptile-apps Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The changes mainly reach USDT receiving, with QR image generation also used in regular receive sharing.

The PR appears safe to merge, with a non-blocking test issue on devices using another language.

Findings

  1. P2 Test assumes English labels ▶

Summary

USDT receive now copies the plain address and shares the network, optional amount, and payment QR from both views.

  • USDT receive screens copy addresses and share payment details.

Reviews (1) · Last reviewed commit: "fix: copy and share usdt receiving addre..." · Reviewed by Greptile

Comment thread BitkitTests/UsdtReceiveSharingTests.swift Outdated

@talosmachina talosmachina left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No findings. On the USDT receive screen, Copy and a tap on the QR now copy the plain receiving address (the selected network's deposit address included). Share, from the QR and from Show Details, sends the network, the address, the optional requested amount and a QR image that still encodes the payment URI. Reviewed 1294b7e, full tier, reasoned from the code and CI (iOS does not build on this reviewer's Linux host).

What I checked, and 5 candidates I ruled out

Read in full: UsdtReceiveView.swift, QrArea.swift, QR.swift, CopyAddressCard.swift, UsdtReceiveSharingTests.swift, UsdtReceiveAmountView.swift
Call sites traced: CopyAddressCard (ReceiveQr.swift:579 passes no onShare, so it keeps its ShareLink), QrArea (the three ReceiveQr.swift callers pass no copyValue, so they still copy the URI), UsdtReceiveAddressContent (one caller)
CI: validate green; Run Tests and Run Integration Tests still running at review time

Ruled out

  • Share text amount disagrees with the deposit QR: amount is set to draftAmount only after prepareDeposit returns, and bitkit-core's receive rejects a response whose amount differs from the request, so the text and the uint256 in the deposit URI come from the same value.
  • Stale amount after switching network: networkRow clears amount, draftAmount and deposit when the network changes.
  • Tap on the QR still copies the URI: QR(content:) { onCopy() } goes through QrArea.onCopy, which uses copyValue (now address).
  • QR.shareImage behaves differently from the removed generateShareQrImage: same body moved out, only the uri capture became a parameter; QR.swift already imports CoreImage.CIFilterBuiltins.
  • Locale-dependent test expectation: fixed in 1294b7e, the expected network line now comes from t("usdt__receive_network").

Merge confidence: 4/5, the unit tests and integration tests had not finished at review time and the share-sheet path was reasoned, not run.

@ovi-reviewer ovi-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict: ✅ Approve

Findings: none.

QA for 1294b7e:
Tested on iOS 26.5 simulator (iPhone 17 Pro, comma-decimal region), against the bitkit-docker USDT fixture. I read each copy from the simulator clipboard, saved each share through the share sheet's Save to Files (a text file and a PNG), and decoded the PNG and the on-screen QR.

Test 1: Arbitrum QR with 3.5 USDT ✅ Copy and a QR tap copy only the address; Share sends the network, address, 3.5 USDT and a QR of the payment URI.
  • Edit, 3,5 on the comma keypad, Continue. The QR decodes to the Arbitrum USDT URI with uint256=3500000.
  • Copy and a tap on the QR each left only 0xE960e9111Ce5dd70e4d3aCF37fb91Ed0B8d783e0 on the clipboard.
  • Share saved Network: Arbitrum One, the address and 3.5 USDT on three lines, and a PNG that decodes to the same uint256=3500000 URI.
test1-arbitrum-qr-3.5-usdt-2x.2x.mp4
Test 2: Show Details with 3.5 USDT ✅ Details Copy copies only the address; Details Share sends the same text and QR as the QR screen.
  • Details Copy left only the address on the clipboard.
  • Details Share saved the same three lines and a PNG that decodes to the uint256=3500000 URI.
test2-arbitrum-details-3.5-usdt-2x.2x.mp4
Test 3: Receive with no amount ✅ Details Copy, QR Copy and a QR tap copy only the address; the QR keeps the full payment URI.
  • A fresh USDT Receive on Arbitrum One. The QR decodes to ethereum:0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9@42161/transfer?address=0xE960…783e0.
  • Details Copy, QR Copy and a QR tap each left only the address on the clipboard.
  • Share from Details and from the QR saved Network: Arbitrum One and the address with no amount line, plus a PNG that decodes to the same URI.
test3-receive-no-amount-2x.2x.mp4
Test 4: Polygon deposit, then back to Arbitrum ✅ Copies give only the Polygon deposit address; both shares add `Network: Polygon` and `12.75 USDT`; Arbitrum One restores the wallet address.
  • Network Polygon, 12,75, Continue twice. The QR decodes to the Polygon USDT URI for 0x7F1CBAd2f24b05ab78Fa17bc620a57f2F4C42787, without uint256, as bitkit-core builds deposit URIs.
  • QR Copy, a QR tap and Details Copy each left only the deposit address on the clipboard, never the Arbitrum one.
  • Share from both views saved Network: Polygon, the deposit address and 12.75 USDT, and a PNG that decodes to the Polygon URI.
  • Back on Arbitrum One the QR returned to the wallet URI, all three copies gave 0xE960…783e0, and Share sent Network: Arbitrum One with that address and no amount.
test4-polygon-deposit-and-back-2x.2x.mp4
Test 5: Bitcoin receive ✅ Copy, a QR tap and Share use the QR's own Bitcoin URI, and the shared QR decodes to it.
  • Savings Receive: Copy and a QR tap left the QR's bitcoin:bcrt1q… URI on the clipboard.
  • Share saved that URI as text and a PNG that decodes to it.
  • Show Details Copy gave the bare address, and its Share opened the address share with the app icon (the ShareLink path this PR keeps for Bitcoin).
test5-bitcoin-receive-2x.2x.mp4

Not driven: the journeys' actions this PR left unchanged. No device case ran UsdtReceiveSharingTests.swift; CI's Run Tests passed at this head.

Review: full diff, 9 files.

Twin synonymdev/bitkit-android#1558 at aba0c43 matches: the same share text, Copy and a QR tap copy the address, the shared image encodes the payment URI, and the two journey files have identical actions.

@jvsena42 jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approving at 1294b7eed. No findings.

Checked:

  • Copy target: QrArea Copy and a QR tap use copyValue: address (UsdtReceiveView.swift:198), and Details Copy uses pair.address. The address is deposit?.address ?? usdt.address, and the QR URI comes from the same source (:57-58). UsdtWalletManager sets address and receiveUri together on the main actor.
  • Stale state: networkRow clears deposit, amount and draftAmount on a network change. amount is set only after prepareDeposit succeeds, and it is normalized at UsdtReceiveAmountView.swift:37, so the share text says 3.5 USDT, not the raw keypad string. A failed re-prepare after Edit keeps the old deposit and the old amount together.
  • Bitcoin receive: QR.shareImage is the removed generateShareQrImage body with uri passed as a parameter. The three ReceiveQr.swift QrArea callers pass no copyValue, so they still copy the URI. CopyAddressCard at ReceiveQr.swift:579 keeps its ShareLink.
  • The journeys and Docs/USDT-QA.md match the new behaviour and are byte-identical to synonymdev/bitkit-android#1558.

CI is green at this head.

Device gate: 1294b7e — no new run.
Skipped — already driven this round: Arbitrum receive with and without an amount, Show Details Copy and Share, the Polygon deposit and the return to Arbitrum, and Bitcoin receive Copy, QR tap and Share. These are the changed actions of usdt-receive-amount-and-units.xml and usdt-wallet-navigation.xml (iOS 26.5, by ovi-reviewer at 1294b7e, passed: #997 (review)).
Skipped — covered by CI at 1294b7e: unit and integration tests, local e2e (all green).
perf: not relevant; l10n: no UI text changed (the share text reuses usdt__receive_network).

@ovitrif
ovitrif merged commit 8ca0766 into master Oct 17, 2026
18 checks passed
@ovitrif
ovitrif deleted the fix/usdt-receive-sharing branch October 17, 2026 13:47
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.

bug: usdt receive copy puts a payment link on the clipboard instead of the address

4 participants