Repository navigation
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
7665890 to
e1bc3f4
Compare
e1bc3f4 to
80458b4
Compare
peachbits
left a comment
There was a problem hiding this comment.
Round 2 at f0205e2.
Both round-1 Warnings are fixed:
FiatPluginWebViewrefuses only onevent.isTopFrame === false. The localAnyPlatformLoadRequesttype is needed: with the library's required boolean,no-unnecessary-boolean-literal-compareflags=== falseand its fix turns it back into!event.isTopFrame.- The MoonPay entry is merged into EdgeApp/edge-react-gui#6235's line in
## 4.52.0 (staging).
tsc, eslint on the changed files, and the full jest suite pass locally.
The new Paybis commit handles each path I traced. A refused redirect opens the send scene once, and Back leaves the WebView alone. A redirect that loads anyway on Android opens it once, Back closes the redirect page, and later URL reports are ignored. A completed send closes the widget and opens it again on the same request without the one-time token. There are two Warnings inline: one on where the Paybis change ships, and one on tests.
A UX observation for the task's open question: after Back, Paybis's Pay and Cancel stay disabled, so a user who backed out by mistake can only leave and start a new order. Develop's re-open loaded the same requestId again, which should bring the order back with Pay enabled. Unlike MoonPay, re-opening Paybis does not create a sale, so re-opening on Back may be the better trade for Paybis. That is a product call, and another reason to land Paybis on its own.
Backing out of the send scene popped the webview and opened the MoonPay widget again. MoonPay treats each open as a new sale, so every Back left another sell order waiting for a deposit. Until the pop ran, the webview showed the page behind the payment redirect, which is the QR fallback for links opened outside the app. The ramp webview can now refuse a load before it starts. The MoonPay sell refuses its payment redirect, so the webview stays on MoonPay's page for the order while the send scene is open, and Back returns there. The widget is never opened a second time. If Android loads the redirect page before the refusal arrives, Back closes the webview instead.
Move the sell redirect handling into makeSellPaymentRedirect, a helper both MoonPay and Paybis call, and unit-test it. The helper owns the refusal, the onUrlChange fallback, the first-report guard and closing only a loaded redirect page on Back. Answers the review request for tests. Fixup-for: human
f0205e2 to
8426a1a
Compare
|
Both inline Warnings are addressed: Paybis stays in this PR under Paybis behavior after Back is unchanged in this round. Re-driven on the iOS sim, Back from the send scene returns to the same Transaction details page with the Pay button still busy, as you saw. Whether Paybis should re-open the same |
j0ntz
left a comment
There was a problem hiding this comment.
Self-review (medium) of 5b5fa520b..6c6c0261e: 7 findings, 1 fixed, 5 rejected, 1 a duplicate of the fixed one.
Fixed before review (1)
src/plugins/ramps/paybis/paybisRampPlugin.ts:1401: after a sent transaction the success path popped and re-opened the widget beforeSell_SuccessandsaveTxAction. A throw while re-opening skipped both for a sale that already went out. Develop logged and saved first. Fixed infixup! Keep Paybis sell on its page after Back(the order is now log, save, then re-open).
Rejected in curation (5)
src/plugins/ramps/utils/sellPaymentRedirect.ts:58:closeRedirectPagepops the whole widget scene on Android instead of returning to the order page. Rejected: it pops only after the WebView itself loaded the fallback page, which replaces the order page in the same WebView: no order page is left to return to. This is the "Back pops only the WebView" case from round 2. After a refused redirect it pops nothing, and on the iOS sim Back returns to the same order page for both providers.src/plugins/ramps/utils/sellPaymentRedirect.ts:45:onShouldStartLoaddoes not set the redirect flag. A late URL report after Back then opens the send scene again. Rejected: setting the flag on a refusal would make Back pop the order page on iOS, and tapping Pay again after Back must open the send scene again. The URL report follows the load within milliseconds, while leaving the send scene takes a user tap, andinPaymentcovers that window. The "refusal comes too late" test covers the realistic ordering.src/plugins/ramps/paybis/paybisRampPlugin.ts:1442: a failed or cancelled send no longer re-opens the widget. Rejected: removing that re-open is the task. It flashed the QR page, and for MoonPay it created a new order. The Paybis disabled-buttons trade-off is the open product call from round 2.src/plugins/ramps/paybis/paybisRampPlugin.ts:1400: the success path pops and re-opens differently on iOS and Android. Rejected: in both cases the stack holds one widget WebView (the Android fallback page loads inside it). The pop closes the same scene either way. Develop popped and re-opened the same way.src/plugins/ramps/moonpay/moonpayRampPlugin.ts:1013:urlObjinhandlePaymentRedirectshadows the sell-quoteurlObj. Rejected: the same shadowing exists in develop (the redirect handler'surlObjinside the sell quote's scope). The handler moved here unchanged.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8426a1a. Configure here.
8426a1a to
86aef37
Compare
Report isTopFrame on Android and refuse only main-frame loads Answers the security review finding that a frame inside the MoonPay sell page could open a locked send from its own URL. The react-native-webview patch now passes WebResourceRequest.isForMainFrame() through as isTopFrame, and FiatPluginWebView treats a missing value as a frame, so losing the patch falls back to the main-frame-only URL report. Fixup-for: auto
Backing out of the Paybis sell send scene closed the widget and loaded it again, and the WebView showed the payment redirect page, a QR code meant for outside the app, underneath the send scene. The WebView now refuses the payment redirect and opens the send scene from that callback, so it stays on Paybis's page for the order. Back with nothing sent clears the payment guard and leaves the widget as it is. On Android, where the refusal can come too late, the first URL report of the redirect page opens the send scene instead, and Back closes that page. A completed send still closes the widget and opens it again so it shows the order's status.
Call makeSellPaymentRedirect from the Paybis sell flow, and add approveQuote tests that drive the widget and send scene params: a refused redirect opens send2 once and Back pops nothing; a redirect that loads anyway opens send2 once, Back pops only the WebView and a later report opens nothing; a completed send re-opens the widget without oneTimeToken. Answers the review request for tests. Fixup-for: human
Log the Paybis sale and save its tx action before opening the widget again, as develop does. A throw while re-opening the widget skipped Sell_Success and saveTxAction for a sent transaction (self-review finding). Open nothing when the user leaves the Paybis widget while the payment-details fetch is in flight. The WebView's onClose now marks the widget closed, and the redirect handler checks it after the fetch and in its catch, so a late fetch neither opens the send scene nor pops another scene. Answers the Bugbot finding on the Back race. Fixup-for: auto
86aef37 to
d2df60f
Compare

Description
Second pass on the MoonPay sell Back fix after QA failed EdgeApp/edge-react-gui#6235 on iOS Staging 26101201. Tapping Back on the prefilled send scene still flashed the "Only the Edge application can open this link" QR page, dropped to the sell scene, then jumped forward into the MoonPay webview by itself. The webview it jumped to was a fresh sale on MoonPay's "Review before you sell" page with a new quote, and continuing from it left another sell order waiting for a deposit.
Root cause:
This PR:
FiatPluginWebViewtakes an optionalonShouldStartLoadcallback, wired to the WebView'sonShouldStartLoadWithRequest, which lets a plugin refuse a load before it starts. Only main-frame loads reach the callback: a frame inside the page cannot trigger it. The react-native-webview patch now reportsisTopFrameon Android fromWebResourceRequest.isForMainFrame()(stock 13.15.0 leaves the field out of the blocking callback), and a load with noisTopFramecounts as a frame. No other provider passes it.makeSellPaymentRedirect(src/plugins/ramps/utils/sellPaymentRedirect.ts), owns the refusal, the Android fallback and the first-report guard. MoonPay and Paybis both call it.onUrlChangestill handles the redirect in that case and records that the webview is on the redirect page, and Back then closes the webview so the user lands on the payment-method list.Sell_Successis logged, the transaction details are saved and the completion modal shows.Testing: iOS simulator on the
agenttest account, with a real MoonPay credit/debit sell order of 0.00034 BTC and no local code changes. "Send with Edge" opened the prefilled send scene. Back returned to the same MoonPay order page: a 10 fps screen recording of the tap shows the send scene sliding away to the order page with no QR page, and the app was still on that page 12 seconds later with no new order. "Send with Edge" opened the send scene again for the same order, one confirm slide sent the deposit, and the app showed "Sell Order Complete" over the payment-method list with the sell saved in the wallet's transaction list. Back from the widget before an order exists lands on the payment-method list. After each of the two review fixes the Back path was run again on the simulator with a new unpaid order and no send: "Send with Edge" opened the send scene, Back returned to the same order page, and Back again left the widget for the payment-method list.Android: API 36 emulator, debug build,
agenttest account. MoonPay asks for a sign-in on Android. A local, never-committed injected script therefore sent the MoonPay page to the payment redirect URL for the account's own BTC address; no send was made. In 2 of 3 opens the redirect was refused, the prefilled send scene opened, and Back returned to the same MoonPay page, still there 15 seconds later. The first open after a JS reload answered past the 250 ms limit: the redirect page loaded under the send scene, and Back closed it to the payment-method list with no new MoonPay open. Before the patch reportedisTopFrame, the same frame check skipped every Android load and the redirect page always loaded first.Frame check (Android, cells 37 to 40): the same injected script also pointed frames inside the MoonPay page at the payment redirect URL, by iframe src, by script navigation and by a tap on a link inside a frame. None of them reached
onShouldStartLoadWithRequeston this emulator's WebView 133; the tapped frame showed the web fallback page inside the frame and no send scene opened. A main-frame navigation to the same URL then arrived withisTopFrametrue, was refused, and opened the send scene, and Back returned to the MoonPay page. No send was confirmed.Paybis sell
Paybis sell had the same shape: Back on the prefilled send scene popped the webview and opened the Paybis widget again, and the payment return URL page loaded under the send scene. On the iOS simulator before this change, Back flashed the QR page, then the widget opened again on Paybis's "Waiting for your payment" page for the same order. Paybis re-opens with the same request: no new order was created.
This PR applies the MoonPay approach to Paybis:
onShouldStartLoadrefuses the payment return URL and opens the send scene from that callback. The webview stays on Paybis's page for the order.onUrlChangeis still the Android fallback for a late answer, and only its first report of the return URL opens the send scene. When that page did load, Back closes it.Sell_Successis logged, the transaction details are saved, then the webview closes and opens again on the order's status without the one-time token.Open product question: after Back, Paybis's own Pay, Cancel and in-page back buttons stay disabled behind a spinner, because the page is still waiting on the navigation that was refused. The user leaves with Edge's Back, which returns to the payment-method list. The alternative is to open the widget again on the same
requestIdon Back, which brings the order back with Pay enabled and creates no new order, at the cost of the QR flash and the reload. This PR leaves the webview alone; the alternative is a small change in the Paybis catch.Testing (Paybis): iOS simulator on the
agent2test account with a real Paybis card sell order and no local code changes; no send was confirmed. Pay opened the prefilled send scene with no QR page. Back returned to the same Paybis "Transaction details" page with no new widget open, and Back again left the widget for the payment-method list. On the Android emulator, Paybis's human check fails ("Verification failed") and blocks Continue. A local, never-committed change therefore stubbed the payment details with the account's own BTC address and sent the Paybis page to the payment return URL. The return URL was refused (noonUrlChangereport of it), the send scene opened, Back returned to the same Paybis page, and Back again left the widget for the payment-method list.Unit tests:
sellPaymentRedirect.test.ts(6 tests) covers the helper, and with it MoonPay's redirect logic. A sell suite inpaybisRampPlugin.test.ts(4 tests) captures the webview and send-scene params and calls their callbacks: a refused redirect, a redirect that loads anyway, a refusal that comes after the URL report, and a completed send. Dropping the first-report guard, returningtruefromonShouldStartLoad, or putting develop's pop and re-open back in the catch each fails at least one of them.Re-run on the iOS simulator after the review fixes, with no send confirmed. MoonPay (cells 28 to 30): "Send with Edge" opened the send scene, Back returned to the same order page, and Back again left the widget. Paybis (cells 31 to 34): Pay opened the send scene, Back returned to the same Transaction details page with the Pay button still busy, and Back again left the widget.
The CHANGELOG lines are merged into the 4.52.0 (staging) entry from EdgeApp/edge-react-gui#6235, since neither has shipped.
CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Requirements
If you have made any visual changes to the GUI. Make sure you have:
Test evidence
80458b42026-10-13
2. moonpay order waiting
3. send scene prefilled
4. back frames no qr flash
5. back landed same order 12s later
6. send scene reopened same order
7. sell order complete
8. saved sell tx details
9. back from widget payment list
11. topframe back same order
f0205e22026-10-15
🪓 Local, never-committed stub of the Paybis payment details plus an injected script that sends the Paybis page to the payment return URL (Paybis's human check fails on the Android emulator)
12. 🪓 android send scene from redirect
13. 🪓 android back closes redirect page
14. 🪓 android send scene redirect refused
15. 🪓 android back same moonpay page
16. paybis before send scene
17. paybis before back reveals redirect page
18. paybis before redirect qr page
19. paybis before widget reopens
20. paybis before reopened waiting
21. paybis after pay spinner
22. paybis after send scene
23. paybis after back same paybis page
24. paybis after back again leaves widget
25. 🪓 paybis android send scene
26. 🪓 paybis android back same page
27. 🪓 paybis android back again leaves
d2df60ffixup! Keep Paybis sell on its page after Back
2026-10-17
🪓 Local, never-committed injected script points the MoonPay sell page and frames inside it at the payment return URL (MoonPay asks for sign-in on Android)
28. moonpay send scene
29. moonpay back same order
30. moonpay back again leaves widget
31. paybis pay opens send scene wallet empty
32. paybis send scene
33. paybis back same transaction page
34. paybis back again leaves widget
37. 🪓 android moonpay frame link to payment url
38. 🪓 android frame tap loads in frame no send scene
39. 🪓 android page redirect opens send scene
40. 🪓 android back returns to moonpay page