Repository navigation
feat: refine usdt payment and earn screens - #1494
Conversation
[Medium impact] The changes affect bounded payment and USDT wallet workflows. The PR appears safe to merge, with non-blocking improvements needed for larger-text layouts and subscription interaction tests. FindingsSummaryRefines Earn consent and USDT payment details, adds a clearer deposit-history action, and separates Savings, Spending, and USDT selection.
Intentional presentation changes: Diagram%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Choose payment methods] --> B[Filter by subscription asset]
B --> C[Create subscription draft]
C --> D[Intersect with current receiving methods]
D --> E{Any methods remain?}
E -->|Yes| F[Send proposal with selected methods]
E -->|No| G[Reject creation]
Reviews (1) · Last reviewed commit: "feat: refine usdt payment and earn scree..." · Reviewed by Greptile |
talosmachina
left a comment
There was a problem hiding this comment.
No findings. Splits accepted methods into Savings, Spending and USDT chips for requests and subscriptions, threads the subscription selection into the proposal endpoints, and moves the bridge amounts into expanded details. Reviewed 8bcefb0, full tier.
What I checked, and 6 candidates I ruled out
Read in full: PaykitRequestPricing.kt (subscriptionEndpoints), PaykitPaymentRequestRepo.kt (proposeSubscription, subscriptionProposalEndpoints, acceptedPaymentEndpointIdentifiers), PaykitAcceptedMethods.kt, CreateSubscriptionScreen.kt, CreatePaymentRequestScreen.kt (PaymentRequestDetailsContent), PubkyAuthApprovalSheet.kt and its view model's USDT state, UsdtSendContent.kt, UsdtDepositReceiveScreen.kt, strings.xml hunks
Call sites traced: subscriptionEndpoints (sheet and repo), PaykitPaymentOption.endpoints, every reference to the four removed string keys (none left)
CI: lint, detekt, build-local green. build red on one unit test, PubkyAuthManifestTest > "signup and authorization links resolve only through their enabled aliases"; the same test failed on run 38600594609 of the stacked base branch at c51f3bd, an ancestor of this head, and this diff touches neither the manifest nor that test. e2e-tests-local still running at review time.
Not built here: Android builds of a PR branch are not run on this reviewer; CI is the gate.
Ruled out
- Proposal sends a method the user deselected: the repo intersects the draft selection with the live accepted list (
selected != null && it !in selected), and the new repo test asserts the proposal carries exactly[P2wpkh]. - Empty selection still submits:
acceptedMethods.isNotEmpty()gates Choose Recipient, and an empty intersection throwsRequestUnavailablein the repo. - Stale selection after an asset change on the amount screen:
onContinueclearsrestrictedMethodswhen the asset changes, and the chip path replaces it with the new asset's endpoints. - Required USDT claim cannot be approved once the switch is hidden:
loadUsdtAddresssetsshareUsdtto true whenusdtRequiredand an address loaded, socanAuthorizeholds. - Payment request selection outliving availability:
selectedMethodsnow filters byavailableMethods, so a method that disappears is dropped from the draft. - Bridge cost and estimate no longer on the basic confirmation: matches the stated design (amounts kept in expanded details), so plausibly deliberate.
Merge confidence: 3/5, CI build is red on PubkyAuthManifestTest, which also fails on the base branch and is not tied to this change.
This comment has been minimized.
This comment has been minimized.
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
|
Current head 93da6f0 now passes CI build, all unit tests (including PubkyAuthManifestTest), lint and the E2E build: https://github.com/synonymdev/bitkit-android/actions/runs/38730878107. The earlier manifest-test failure also occurs in ancestor c51f3bd (run 38600594609), with the relevant source and configuration unchanged, so no workaround was added. E2E scenario jobs are still running. The layout and screen-map fixes are posted, and the subscription-test coverage and its limits are explained in the review thread. |
This comment has been minimized.
This comment has been minimized.
piotr-iohk
left a comment
There was a problem hiding this comment.
QA review
Scope: Follow-up review of changes since 93da6f0, including affected callers and prior comments, at 2057b38. Inherited baseline bc-59fb3e88-b55a-461b-b1eb-66a8d94f39eb still covers payment-request and subscription method selection, USDT confirmation details and the quoted swipe amount, deposit history, bridge support, Earn authorization, the funding-source menu, and the earlier journey and test updates.
No new actionable code findings.
This pass covers text-style parameters on buttons, sheet titles, swipe confirmation, and the USDT available balance, plus the new bare-address steps in journeys/usdt-payment-links-and-scans.xml. Those steps match the existing scan, paste, manual-continue, hardware-warning, and enable-resume router. Earlier chip-wrapping and screen-map comments are addressed in the inherited revision: method chips use FlowRow, and the cited node id is gone from the screen map.
CI build passed on this head. This review did not rerun tests or start a device.
Ready for device testing.
Device testing: not performed in this review.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
No HIGH or MEDIUM. Three LOW findings, inline. Reviewed 2057b38. I reviewed this as a funds and consent change: the send confirmation, payment-request and subscription endpoints, and the Earn approval.
Checked and clean:
- Send confirmation. Payment is
quote.amount, Fee ismaximumFee, Max total debit isamount + maximumFee, and Recipient gets isreceivedAmount, with ± only for Orchestra (UsdtSendContent.kt:664-692). Swipe gating is unchanged. Moving the bridge amounts into expanded details is the agreed design and is not raised. - Subscriptions.
acceptedMethodsis recomputed against the live receiving methods on every composition. A cross-asset tap replaces the restriction, and Amount Continue clears it on an asset change. The repo intersects the draft with the live list and the asset, and an empty result throwsRequestUnavailable(PaykitPaymentRequestRepo.kt:896-903). Sheet state is dropped on cancel. Back keeps the selection, as intended. - Payment requests.
selectedMethodsfilters by availability, and Send is disabled on an empty selection. The repo re-intersects with the live list. - Earn consent. The ViewModel is unchanged. A required claim still needs
shareUsdt && usdtAddress != null, andvalidatedUsdtEndpointrejects an endpoint that differs from the one shown. - Bare
0xinput. Android already routes Enter Manually, the scanner and paste throughisUsdtPaymentInput(AppViewModel.kt:6745). The iOS twin's Enter Manually does not, which I raised on synonymdev/bitkit-ios#942. - Figma, all 9 linked frames:
- Earn, USDT-only Earn, basic confirmation, technical details, payment requests, subscriptions, deposit-history entry, funding-source menu and small action buttons were checked for spacing, type, tokens, states and icons. That includes
ic_arrow_*_rightandic_plus_smallagainst the exported frame assets, and the removed-chip 50% opacity with +. - No deltas apart from the two inline LOWs (the expanded-address divider and the screens-map name).
- The middle-ellipsis address matches the Bitcoin review screen and is kept deliberately.
- Earn, USDT-only Earn, basic confirmation, technical details, payment requests, subscriptions, deposit-history entry, funding-source menu and small action buttons were checked for spacing, type, tokens, states and icons. That includes
- Performance. Not performance-relevant: a FlowRow of at most three chips and style changes, with no new polling, waits or locks.
The LOWs do not block approval, which follows the device gate. Each can be fixed here or moved to a follow-up issue, your choice. Please reply on each thread saying which.
Device gate (partial): 2057b38 — not run yet; J1–J7 pending (USDT fixture for J1/J4–J7, two linked wallets for J2/J3). The device result will follow in a second review.
|
Updated with the latest master, including Piotr’s UI-test changes, and resolved the conflicts. Fixed the German USD entry issue: the amount and keypad now use the locale separator while retaining the exact canonical value. A native test enters For the camera report, the zero-camera detail made it reproducible. Fixed in Validation: 4,222 unit tests and 23 focused native UI tests passed; the confirmation tests were rerun after the final divider fix. Compile passed, and the complete lint report has no introduced findings. Also applied the broader Figma typography, spacing and accessibility corrections, and requested another review. The camera fix also passed compile, all 4,222 unit tests, APK build and the full detekt comparison (no introduced findings). Added its hardware-failure checks to |
jvsena42
left a comment
There was a problem hiding this comment.
One more design delta from the Figma pass.
jvsena42
left a comment
There was a problem hiding this comment.
One more Figma delta on Create Subscription.
jvsena42
left a comment
There was a problem hiding this comment.
Device results for 2057b38 (Pixel 9 plus a second emulator as payer, local USDT fixture on an Arbitrum fork).
No new findings. Both open questions were checked against an origin/master build on the same fixture:
- Correction to my partial comment: the Copy toolbar on the bridge address long-press works. Copy / Select all appears on both the PR and master, and Select all → Copy puts the full address on the clipboard. My earlier miss was screenshot timing.
- Celebration not shown after deposit details: if a USDT transfer arrives while deposit details are open, the received celebration never appears after returning to the wallet. Master does the same, so it is out of scope for this PR.
Journeys:
- J1 Earn / receiving details: 1–6 and 8–17 pass. Step 7 could not be forced (the address is derived locally); 18–19 need a funded-wallet restore and were not run.
- J2 quoted USDT requests: 1, 2 and 4–15 pass. The comma-locale steps (3, parts of 8/9/13) and 16 were not run.
- J3 create and propose: all 22 pass. Step 17 is confirmed from the log (
SubscriptionTooLong). - J4 links and scans: 1–12, 14, 16 and 17 pass; a bare
0xvia scanner, Paste and Enter Manually all open USDT send. Hardware-wallet sub-steps were not run. Step 15 shows "Not enough USDT to cover the amount and fees." rather than the journey's wording (unchanged step). - J5 send review / details: all 12 pass.
- J6 bridge details: 3–7 and 9–14 pass; 1–2 not reproduced (a 1-confirmation transfer never showed as pending); 8 is the master issue above.
- J7 bridge support: all pass. Step 9 says "Refund in progress" where the journey says "Refunding".
Figma: 9 frames compared.
- Technical details, address expanded: the gap from Hide Details to the fee note is about 4dp against about 21dp in the frame. At 360dp width, Hide Details falls below the fold, but it can be reached by scrolling. Both are LOW;
1c37a7emay cover the first. - Subscriptions: separate SAVINGS / SPENDING chips against one BITCOIN chip in the frame, as the PR body intends.
- The other six frames match.
l10n: de, pt-BR, el, fr, ru, es and ar at 360dp, no clipping or overflow; Arabic mirrors correctly. The changed USDT/auth keys have no translations yet.
Commits since 2057b38 (86e370c…f43cb25) still need a delta review before approval.
Device gate: 2057b38 — journeys: 7 run, 0 failed (sub-steps not run in J1, J2, J4, J6, J7; journey-wording mismatches in J4 a15, J7 a9); perf: not relevant, no ANR or crash; Figma: 9 screens compared, 3 deltas (LOW); l10n: 3 changed keys plus chip/detail labels checked in de, pt-BR, el, fr, ru, es, ar at 360dp, 0 overflow
jvsena42
left a comment
There was a problem hiding this comment.
Approving at f43cb25.
The device gate passed at 2057b38 (results in my previous review). The commits after it (86e370c, 1c37a7e, 9c75d43, 76e1803, c46da49, f43cb25) got a code-level delta review:
- Submitted-payment transitions (
9c75d43): no double submit (confirm()/send()guards, swipe disabled while busy or completed). Back hides for the whole submitted window. Both hosts dismiss rather than pop once submitted, so a confirmed payment cannot reopen the review. - Auth approval sheet: copy only.
canAuthorizeand the required-claim gating are unchanged. - Scanner (
76e1803): bind waits for permission and a bind failure toasts instead of crashing. The scan result still goes through the sameonScanSuccessrouting. - Floating buttons (
c46da49,f43cb25): bottom padding equals the measured footer height, enabled state and test tags are kept, and the IME case on Create Subscription shrinks the viewport. - All five earlier LOWs are fixed at head.
CI is green at head. One LOW inline: a journey still describes the old deposit button layout.
Device gate: 2057b38 — journeys: 7 run, 0 failed (sub-steps not run in J1, J2, J4, J6, J7; journey-wording mismatches in J4 a15, J7 a9); perf: not relevant, no ANR or crash; Figma: 9 screens compared, 3 deltas (LOW); l10n: 3 changed keys plus chip/detail labels checked in de, pt-BR, el, fr, ru, es, ar at 360dp, 0 overflow. Commits after 2057b38 reviewed in code, not re-run on device.
|
Out of scope for this PR: either already on master or not changed here. Listing them so they aren't lost. None of these block the approval.
|
|
Thanks John. Fixed the two stale journey expectations in 05453b2 and mirrored them on iOS: entering the full balance now expects "Not enough USDT to cover the amount and fees.", and the pending refund expects "Refund in progress". Also made the balance step explicitly use another owned wallet's address after the self-send check. These are documentation-only corrections. XML and cross-platform action parity checks pass, and detekt has no introduced findings. Your Copy correction and the existing master celebration behavior need no changes here. Re-requested review for the commits since your device-tested 2057b38. |
jvsena42
left a comment
There was a problem hiding this comment.
Re-approving at 05453b2. The only change since my approval is 05453b2, which rewords two journey steps to match the app ("Refund in progress", "Not enough USDT to cover the amount and fees."). The LOW at usdt-bridge-support.xml:9 (deposit button layout) is still open.
ovitrif
left a comment
There was a problem hiding this comment.
Approving at 05453b2, code review only (no device runs), after @jvsena42's approval.
Since our review at 1c37a7e: the confirmed-send flash from our LOW is fixed (9c75d43: Submitted stays until success, Back is off once submitted); the scanner now reports a camera that fails to start instead of crashing (76e1803); the subscription and deposit-history changes (c46da49, f43cb25) move layout only, with the same Continue conditions. Nothing new at MEDIUM or above.
The Earn consent wording from our earlier review stays a product call.
jvsena42
left a comment
There was a problem hiding this comment.
Re-approving at ff127b0. The only change since my approval is ff127b0, which updates the deposit-button journey step and the QA doc to the pinned layout. That fixes my LOW on usdt-bridge-support.xml:9.
Closes #1495
This PR refines the USDT payment and Earn screens. Follow-up to merged #1432.
Description
Out of Scope
None.
Design
Home · USDT introduction · Receive fees · Earn · USDT-only Earn · Basic confirmation · Technical details · Payment requests · Subscriptions · Deposit history entry · Funding-source menu · Small action buttons
Subscription methods follow the agreed #1000 discussion: Savings and Spending remain individually selectable, and Bitcoin methods remain mutually exclusive with USDT. Native Android text fields retain their 56 dp minimum (the Figma examples use 52 dp) and expand for larger system text.
Preview
Native captures were checked against these frames and shared in the local review gallery. They use isolated test data and verify presentation and interactions; they do not represent live payments or bridge settlement.
QA Notes
Journeys
share-receiving-details.xml— short Earn copy, optional USDT sharing and disabled behavior.paykit-quoted-usdt.xml— individual receiving methods and selected request options.create-and-propose.xml— subscriptions accept selected Bitcoin methods or USDT; the floating recipient action preserves scrolling, large text and keyboard access.usdt-payment-links-and-scans.xml— plain addresses open USDT with a visible network choice, matching the paired iOS journey.usdt-opt-in.xml— readable enable actions at large text sizes.usdt-send-review-and-details.xml— basic confirmation and expanded technical details.usdt-bridge-details.xml— bridge details and a floating deposit-history action, including scrolling and large text.usdt-bridge-support.xml— compact support actions and refund history.Manual Tests
docs/usdt-qa.md→ Android camera availability: camera failure leaves manual entry and paste usable. A no-camera emulator is required for this hardware fault.Automated Checks
PaymentRequestAmountLocaleTest.kt— German comma input preserves trailing decimals and submits the exact cents.PaykitAcceptedMethodsTest.kt— German method labels remain reachable at 280 dp with 1.5× text scaling.PaykitRequestPricingTest.kt— filters subscription methods by selection, asset and current availability.PaykitPaymentRequestRepoSubscriptionTest.kt— sends only the selected subscription endpoint.CreatePaymentRequestScreenTest.kt— individual request-method selection and removal.CreateSubscriptionScreenTest.kt— selected method controls and unavailable submissions.UsdtPaymentContentTest.kt— expanded bridge details, full-address layout, immediate confirmation, pending-to-success transitions, and return from payment details.UsdtBridgeDetailsTest.kt— refund input remains usable at large text sizes.Local validation: 4,222 unit tests and 19 focused native UI tests passed after rebasing on master, including the new translations. After the submission-transition fix, the full unit suite and all seven payment UI tests passed again. The final build passed. The complete detekt report was inspected against the prior report and current master; no introduced violations remain. Subscription footer checks passed at normal and enlarged text sizes, including Name and Description editing above the keyboard. Native captures cover normal and large text, Home balances, send/receive, fees, completion and Earn. These checks do not exercise live payments or bridge settlement.
Camera failure validation: reproduced the crash on the preceding build with both emulator cameras disabled. The fix preserves manual entry and valid-address paste through to the amount screen, including after reopening the scanner. Permission denial is safe, and granting permission on a camera-enabled emulator starts the live preview. No payment was submitted. Compile, all 4,222 unit tests, APK build and detekt passed; the complete detekt report remains at the same 1,401 existing findings with none introduced.