Repository navigation
fix: correct usdt request and bridge feedback - #948
Conversation
[Medium impact] The PR appears safe to merge; no actionable new issues were found. SummaryCorrects USDT request titles, preparation colors, and bridge feedback.
No actionable new issues were found in the changes since the previous review. Reviews (2) · Last reviewed commit: "docs: clarify payment method review acro..." · Reviewed by Greptile |
talosmachina
left a comment
There was a problem hiding this comment.
No findings. Uses USDT teal (or a neutral accent for a mixed request) while a payment request is being prepared, swaps the raw provider code in deposit details for the localized support note, and puts the readable status beside the technical one in copied diagnostics. Reviewed 5959c7a, full tier.
What I checked, and 4 candidates I ruled out
Read in full: the diff of SendConfirmationView.swift, UsdtDepositHistoryView.swift (the detail view and depositStatusText), UsdtSupportActions.swift, both test files
Call sites traced: accentColor, UsdtDepositDetail.statusText, statusCode, acceptedPaymentEndpointIdentifiers
CI: Run Tests still running at review time; Greptile green. Not built here: iOS does not build on Linux, so Run Tests is the gate for the new testPreparationUsesAcceptedMethodsBeforeWalletSelection.
Ruled out
- Accent precedence: the new
preparingRequestbranch sits abovehwSend.isActive, but the confirm actions are disabled while preparing (.disabled(preparingRequest != nil)), so no hardware or Lightning state can be live behind it. - Mixed-request match:
Set(...) == [usdtArbitrum]is the same USDT-only testSubscriptionsViewalready uses, and the Set form also tolerates a duplicated identifier. - Attention note vs. status:
statusTextcomes fromdepositStatusText, which returnsusdt__deposit_needs_attentionfor every coded or unknown status, so the string comparison shows the note exactly when the status cell says "Needs attention". The code itself is still in the copied diagnostics (Status code:line). - Diagnostics regression: the raw status values stay in parentheses, and the updated tests assert both forms for a transfer and a deposit.
Merge confidence: 4/5, not built here and Run Tests had not finished when I looked.
This comment has been minimized.
This comment has been minimized.
|
Checked J1 on both platforms. The draft editor preserves the entered 10 USD and uses the current BTC/USD rate for each conversion. With controlled rates of 82,380 then 82,445 USD/BTC, both implementations produce 12,139 then 12,130 sats while returning to exactly 10 USD. Repeated switches at an unchanged rate keep the same satoshi amount. The conversion implementations are unchanged from master. The journey expectation was too strict across a rate refresh. Corrected it and the paired README in f2e30b8 and synonymdev/bitkit-android#1506 (05482004d). No pricing behavior changed. Controlled-rate checks, Android amount tests, XML validation and platform formatting/lint checks passed; no new diagnostics. J2–J4 still require the fixtures/funding listed in your report. |
There was a problem hiding this comment.
Suggestion: 👍 Approve
Reaudit: diff 2 files.
No new findings; the rest is in the review.
Twin: synonymdev/bitkit-android#1506 identical at 0548200
QA:
Tests running.
Test J1 failed at 5959c7a.
J2 not tested because the supplied USDT fixture is not provisioned; missing: controlled bridge history and receipt injection.
J3 not tested because it needs prepared bridge transfer and deposit history; missing: a working USDT provider fixture.
J4 not tested because the configured USDT service cannot be resolved and the isolated fixture is not provisioned; missing: USDT quotes and controlled full-balance state.
Replies:
@ben-kaufman: Checked J1 on both platforms. (comment)
@ben-kaufman I confirmed that the original USD amount is retained while the BTC equivalent uses the current rate. This clarifies the earlier J1 concern; the revised journey matches that behavior.
Reviewed by gpt-6.1-sol-medium via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest
|
Re J1: I checked the request routing on both iOS and Android. Both filter the resolved endpoints to the request’s accepted methods. With only USDT accepted, the selection logic chooses USDT even with zero USDT balance. A USD-denominated request that also accepts Bitcoin can initially select Bitcoin when the USDT balance cannot cover it. I couldn’t establish the accepted methods or the exact incoming-request opening step from the recording. Could you include the request’s |
|
@ben-kaufman From the run at 5959c7a:
On that screen USDT was the only funding source offered, which matches your routing check. What failed is the screen itself: it was titled "Bitcoin Betrag" and showed a Bitcoin amount next to the dollar amount for a USDT-only request. So J1 points at the Amount screen's labels for a USDT-only request, not at routing. J1.2x.mp4 |
There was a problem hiding this comment.
Verdict: ✅ All 5 device cases passed at f2e30b8; one LOW outside this change.
QA for f2e30b8:
Tested on two iOS 26.5 simulators (iPhone 17 Pro), regtest, with USDT on the bitkit-docker USDT fixture (local Arbitrum fork with simulated Orchestra and LayerZero).
✅ Test 1: J1 USDT-only request preparation and denomination switches
A 10 USD request accepting only USDT opened on the payer as Preparing with teal icons and a disabled teal swipe, then a locked Amount screen with USDT as the only source; Back closed it without a Bitcoin confirmation, reopening kept $10 and USDT, and on the requester 10 USD came back exactly after every BTC/USD switch (12,143 sats, then 12,145 after a rate refresh), consistent with @ben-kaufman's rate check.
case1-j1-requester-payer-2x.2x.mp4 | ![]() | ![]() |
✅ Test 2: J2 receipt during deposit details
A USDT transfer arriving while deposit details were open showed no sheet over them, celebrated once on return to the USDT wallet, and did not repeat after revisiting deposit details and waiting 105 s on the wallet.
case2-j2-2x.2x.mp4 |
✅ Test 3: J3 readable bridge messages and copied diagnostics
Deposits held with standing_route_unavailable or in provider_review showed Needs attention with the readable support note and no raw code, Copy Details gave Status: Needs attention (held) plus the code line, and an Orchestra transfer in attention copied Status: Bridge needs attention (bridgeNeedsAttention) with its references; both support forms opened prefilled and unsent.
case3-j3-2x.2x.mp4 | ![]() |
✅ Test 4: J4 full-balance USDT send
Sending the whole 25 USDT balance to another owned wallet showed "Unable to pay the transaction fee in USDT. Try a smaller amount." with review closed, and 5 USDT reached review, closed without signing.
case4-j4-2x.2x.mp4 |
✅ Test 5: mixed Bitcoin and USDT request preparation
A USD request accepting Savings and USDT prepared in the neutral grey accent, neither orange nor teal, then opened on Savings with USDT still offered as a funding source.
case5-mixed-requester-payer-2x.2x.mp4 | ![]() |
Findings:
-
LOW: in German, the Amount screen of a USDT-only request is titled "Bitcoin Betrag".
SendAmountViewuseswallet__send_amount, which is "Amount" in English but "Bitcoin Betrag" inde.lproj, while direct USDT Send usesusdt__amount. Routing offered only USDT, and the ₿ line above the dollar amount is the same secondary display direct USDT Send shows, so this is the label behind the earlier J1 report, not a routing defect. This PR does not change that string.case1-j1-payer-de-2x.2x.mp4

|
Thanks, that clarification identified the issue. Fixed in 9d04405: the Paykit USDT amount screen reused The smaller BTC figure stays: it is the wallet-rate equivalent in the shared USDT amount header, not a Bitcoin funding option. The paired journey now checks the title in German and makes that distinction explicit. Android already had the correct title, so #1506 only receives the matching journey clarification. Swift formatting, syntax, translation validation and paired XML checks passed, with no new diagnostics. Independent review found no further issue. The local focused simulator run was blocked before tests by missing cached dependency XCFrameworks, including after attempting cache recovery. Previous-head unit/integration CI passed; updated-head CI is starting. The provider-dependent J2–J4 checks remain blocked by the reported fixture setup. |
|
@ben-kaufman J2, J3 and J4 are no longer blocked: all five cases passed on device at f2e30b8 against the USDT fixture, with recordings in the test results. Its one LOW, the German "Bitcoin Betrag" title, is the label 9d04405 fixes; that review went up seconds after your push, so it predates the fix. |
There was a problem hiding this comment.
Verdict: ✅ Approve: no findings in the delta, and both cases it reaches passed at a08e4c1.
The PR moved to 37749e5 after this run; these results are for a08e4c1.
Findings: none. In 9d04405 the Amount title reads the same app.paykitUsesUsdt flag as the rest of the USDT layout, flips back in selectFundingSource and is cleared by resetSendState, so a Bitcoin send does not inherit the USDT title. The other screens of a Paykit USDT payment use neutral strings.
QA for a08e4c1:
Tested on two iOS 26.5 simulators (iPhone 17 Pro), regtest, with USDT on the bitkit-docker USDT fixture.
Test 1: J1 USDT-only request Amount screen ✅ Titled "Amount" in English and German, reached straight from Preparing.
A 10 USD request accepting only USDT came back to exactly 10 USD after four BTC/USD switches on the requester, at 12,232 sats each time. On the payer it showed Preparing with teal icons and a spinning teal swipe knob, then Amount with USDT the only source, $10 locked (its keypad keys are not tap targets) and ₿ 12,197 as the rate line. In every recorded frame of the three openings, the last Preparing frame is followed directly by Amount: no Bitcoin confirmation, zero BTC or enabled swipe in between. Back closed the sheet to Home, and reopening kept $10 and USDT. With the payer in German the screen read "Amount" and "VERFÜGBAR", the same title direct USDT Send shows in German.
case1-j1-requester-payer-2x.2x.mp4 | ![]() | ![]() |
Test 2: mixed request and plain contact send ✅ Neutral preparing accent; the title follows the selected source.
In German, a 10 USD request accepting Savings and USDT prepared with a grey knob and grey icons, then opened Amount on Sparkonto titled "Bitcoin Betrag" (₿ 12,166). Selecting USDT changed it to "Amount" with the USDT layout ($10), and selecting Sparkonto again restored "Bitcoin Betrag" with ₿ 12,166. A plain Pay to the contact opened on USDT as "Amount", read "Bitcoin Betrag" on Sparkonto and "Amount" again on USDT. Closed without paying.
case2-mixed-and-contact-requester-payer-2x.2x.mp4 | ![]() | ![]() |
Not repeated, passed at f2e30b8 in the test results, whose code no later commit touches:
- J2 receipt during deposit details.
- J3 readable bridge messages and copied diagnostics.
- J4 full-balance USDT send: the fee-collection error it showed still meets the widened journey in a08e4c1.
Covered: the delta f2e30b8..a08e4c1. The wording changes in journeys/README.md, journeys/usdt-payment-links-and-scans.xml and the changelog had no device case. 37749e5, pushed during this run, changes only journeys/paykit-quoted-usdt.xml and is not covered here.
Twin: synonymdev/bitkit-android#1506 has identical journey lines at fec209b. It also replaces the prepared route atomically for the same "Preparing changes directly to Amount" check; iOS meets that check without a code change (Test 1).
piotr-iohk
left a comment
There was a problem hiding this comment.
QA review
Scope: Reviewed the full PR diff against its merge base, at 37749e5.
1 actionable finding — resolve or provide an evidence-backed rebuttal.
USDT-only preparation uses the teal accent, every other accepted-method set stays neutral, and the Amount title follows paykitUsesUsdt, which resetSendState clears. Deposit details show the existing assistance note when the status is Needs attention, and copied transfer and deposit diagnostics keep that readable status beside the technical value. Those presentation contracts match bitkit-android#1506 at b735f400. The new payment-method sentence in paykit-quoted-usdt.xml does not match the iOS payer flow: switching Savings and Spending on confirmation stays there when the quoted BTC amount is unchanged, so Amount does not reopen.
Validation: Run Tests passed at this revision. I inspected the new preparation and support-details assertions and did not execute them locally. Device testing was not performed in this review. Device comments on f2e30b8 and a08e4c1 predate the payment-method sentence added in 37749e5.
Suggested additional test cases
- iOS, regtest, Paykit and USDT enabled. Open a USD request that accepts Savings and USDT while Preparing is still visible. The icons and disabled swipe are neutral grey. On Amount, select USDT and then Savings. The title matches direct USDT Send while USDT is selected, including German, and returns to the Bitcoin amount title on Savings. Close without paying.
Device testing: not performed in this review.
Findings
- [LOW] Reopen Amount after switching Bitcoin rails — inline at
journeys/paykit-quoted-usdt.xml:14.
piotr-iohk
left a comment
There was a problem hiding this comment.
QA review
Scope: Follow-up review of ab313b1 since 37749e5, inheriting the baseline review. This pass checked the payment-method review wording in paykit-quoted-usdt.xml and journeys/README.md against iOS confirmation and Android Amount navigation, and compared that contract with bitkit-android#1506 at b66d83f. Inherited coverage is the Paykit USDT Amount title, the preparing accent, deposit Needs attention copy, and copied transfer and deposit diagnostics.
No new actionable code findings.
The revised step matches both implementations. On iOS, a Savings/Spending switch stays on confirmation when the recomputed payment terms equal the stored terms and remain valid, and returns to Amount when those terms differ or are expired. Android opens Amount for every quoted method change, and Amount's Back control closes the sheet. Both repositories carry the same journey text. That wording records the in-place iOS confirmation update discussed in the earlier Amount-reopen comment.
Validation: source inspection only; no tests were executed in this review. Validate Translations passed at this revision. Run Tests and Run Integration Tests were still running and are not evidence here. Device testing: not performed in this review.
Ready for device testing.
piotr-iohk
left a comment
There was a problem hiding this comment.
Approved based on the code review and verified baseline and follow-up evidence for the PR changes. Historical device evidence does not cover the newer merged-master/rc77 combination; this remains an integration evidence limitation. No outstanding blocking findings in the reviewed scope.
Pull request was closed
|
@ben-kaufman this PR was closed by GitHub, not by anyone deciding to close it. The description of synonymdev/bitkit-android#1506 said To keep it from happening again, could you add this to your agents' PR instructions? |
jvsena42
left a comment
There was a problem hiding this comment.
Code scan at ab313b1: no findings. The production diff is presentation-only. The amount and asset that get debited are unchanged.
Checked:
accentColor(SendConfirmationView.swift:81-90) only tints the summary icon, the details button and the swipe knob. WhilepreparingRequest != nil, details is disabled (l.358), swipe is disabled and loading (l.1085, l.1008),sendContextis nil (l.58) and auto-pay is off (l.232), so nothing can be submitted before review. The amount shown while preparing is stillpreparingRequest.amountin the request's own asset. The paying asset is still chosen on Amount viaselectFundingSource.- USDT-only detection:
acceptedPaymentEndpointIdentifiersis already filtered to supportedMethodIds (PaykitIssuerInterop.swift:13-26). A mixed request whose BTC rails are unsupported on this network collapses to USDT-only and turns teal, which is correct since only USDT is payable there. SendAmountView.swift:137keys the title onapp.paykitUsesUsdt, the same flag that drives the rest of the USDT layout there. It is cleared inresetSendState.- Copied diagnostics only prepend the readable status. No new addresses, keys or tokens.
- Android parity with synonymdev/bitkit-android#1506: same accent rule (
SendConfirmScreen.kt:361-369), same attention note in place of the raw code (UsdtDepositsScreen.kt:483-485), sameStatus: readable (technical)copy. The four journey files and the README subsections are byte-identical to Android master. - No string keys added. The keys now used (
usdt__amount,usdt__deposit_attention) are English-only, so every locale renders English and no locale is longer than English. - Migration: no persisted state touched. Performance: not relevant.
CI: e2e-tests-local - e2e at ab313b1 was cancelled mid-run (The operation was canceled. after the Lightning quickpay specs), not failed by a test. It needs a re-run before merge.
Device gate (partial): ab313b1 — not run yet. The four changed journeys on the iOS simulator against the USDT fixture and the screenshot comparison with the two linked frames are pending. The device result will follow in a second review.
|
Device gate (partial): Setup: Debug build on the iPhone 17 (payer, 25 USDT from the bitkit-docker USDT fixture) and the iPhone 17e (requester), linked as Paykit contacts. Neither wallet has BTC or a channel, so Spending is never offered.
Figma: the USDT-only preparing state matches the USDT teal in both linked frames. Neither frame shows the payer's preparing state or the deposit attention note, so those were compared on colour tokens only. 0 deltas. Seen but outside this PR: on the en_BR comma locale the payable amount renders |
|
Device gate (partial): Run on the payer against the local USDT fixture: six deposits across Polygon, Ethereum, BSC, Base and Tron in held, completed, refunding and refunded states, plus an Orchestra transfer in needs-attention and a USDT0 transfer. J2 — 12 of 14 steps pass
J3 — 12 of 12 steps pass (four sub-checks could not be set up)
Seen but outside this PR's change:
|
|
Thanks Ovi, that was my wording mistake. I saved the rule for future PRs: closing keywords only for the intended issues, |








Closes #949
Twin: synonymdev/bitkit-android#1506
Addresses the iOS equivalents of synonymdev/bitkit-android#1503 and synonymdev/bitkit-android#1504.
This PR corrects USDT request preparation styling and bridge status messages.
Description
Out of Scope
Design
Payment requests · Bridge technical details
Preview
QA Notes
Journeys
paykit-quoted-usdt.xml— USDT-only request preparation stays teal, opens Amount without an intermediate Bitcoin confirmation, and cannot submit before review; denomination switches restore the entered amount, with identical BTC equivalents expected only at an unchanged rate. USDT amount titles match direct Send, including in German; the smaller BTC figure is a wallet-rate equivalent. For the optional funded regtest check, Android reopens Amount after Savings/Spending changes; iOS keeps confirmation open when the exact payment terms remain unchanged and valid. When Amount is reopened, its Back arrow closes the request without revisiting confirmation.usdt-bridge-details.xml— a receipt arriving during deposit details appears once after returning to the wallet.usdt-bridge-support.xml— bridge problems use readable messages; copied diagnostics retain readable and technical status.usdt-payment-links-and-scans.xml— full-balance preparation accepts either actionable fee or balance error without opening review.Manual Tests
N/A
Automated Checks
PaykitPaymentRequestServiceTests.swift— preparing USDT-only and mixed requests use their appropriate accent before wallet selection.UsdtSupportDetailsTests.swift— copied transfer and deposit diagnostics include the readable status beside the technical value.PaykitPaymentActivityTests.swift,UsdtWalletManagerTests.swiftandSendConfirmationViewTests.swiftcoverage — existing payment ownership and deferred receipt behavior remain correct.21 focused simulator tests passed for the initial fixes, including the preparation test. The follow-up amount-title correction passes Swift formatting, syntax, translation and XML checks. Its local focused simulator run was blocked before tests by missing dependency XCFrameworks; CI unit tests, integration tests, build and E2E passed at a08e4c1. The paired journey-only follow-up passes XML parsing and cross-platform parity checks. No funded mainnet payments were needed; the changed journeys remain listed for reviewer device verification.