Repository navigation
fix: copy and share USDT receiving addresses - #997
Conversation
[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
SummaryUSDT receive now copies the plain address and shares the network, optional amount, and payment QR from both views.
Reviews (1) · Last reviewed commit: "fix: copy and share usdt receiving addre..." · Reviewed by Greptile |
talosmachina
left a comment
There was a problem hiding this comment.
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:
amountis set todraftAmountonly afterprepareDepositreturns, and bitkit-core'sreceiverejects a response whoseamountdiffers from the request, so the text and theuint256in the deposit URI come from the same value. - Stale amount after switching network:
networkRowclearsamount,draftAmountanddepositwhen the network changes. - Tap on the QR still copies the URI:
QR(content:) { onCopy() }goes throughQrArea.onCopy, which usescopyValue(nowaddress). QR.shareImagebehaves differently from the removedgenerateShareQrImage: same body moved out, only theuricapture became a parameter;QR.swiftalready importsCoreImage.CIFilterBuiltins.- Locale-dependent test expectation: fixed in
1294b7e, the expected network line now comes fromt("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.
There was a problem hiding this comment.
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
0xE960e9111Ce5dd70e4d3aCF37fb91Ed0B8d783e0on the clipboard. - Share saved
Network: Arbitrum One, the address and3.5 USDTon three lines, and a PNG that decodes to the sameuint256=3500000URI.
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=3500000URI.
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 Oneand 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, withoutuint256, 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 and12.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 sentNetwork: Arbitrum Onewith 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
ShareLinkpath 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
left a comment
There was a problem hiding this comment.
Approving at 1294b7eed. No findings.
Checked:
- Copy target:
QrAreaCopy and a QR tap usecopyValue: address(UsdtReceiveView.swift:198), and Details Copy usespair.address. The address isdeposit?.address ?? usdt.address, and the QR URI comes from the same source (:57-58).UsdtWalletManagersetsaddressandreceiveUritogether on the main actor. - Stale state:
networkRowclearsdeposit,amountanddraftAmounton a network change.amountis set only afterprepareDepositsucceeds, and it is normalized atUsdtReceiveAmountView.swift:37, so the share text says3.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.shareImageis the removedgenerateShareQrImagebody withuripassed as a parameter. The threeReceiveQr.swiftQrAreacallers pass nocopyValue, so they still copy the URI.CopyAddressCardatReceiveQr.swift:579keeps itsShareLink. - The journeys and
Docs/USDT-QA.mdmatch 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).
Fixes #995
This PR makes USDT receive copying and sharing work with exchanges and plain address fields.
Description
Out of Scope
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:
The attached QR retains the payment URI and
uint256=3500000.QA Notes
Journeys
usdt-receive-amount-and-units.xml— plain-address copying, exact requested amount, network label and payment QR sharing from both views.usdt-wallet-navigation.xml— the receive QR copies its address while retaining the payment URI for scanning.Manual Tests
Automated Checks
UsdtReceiveSharingTests.swift— verifies exact optional amounts and decodes the shared QR for Arbitrum, Polygon, Bitcoin and Lightning URIs.UsdtReceiveSharingTests.swift,UsdtPaymentLinkTests.swiftandReceiveEditTests.swifton iOS 26.1 — 11 tests passed.