fix(grid-wallet-prod): activity list reflects the real ledger, not the UI#745
Conversation
…e UI Money moved but the activity list didn't. Three causes, all real: - Inbound rows only ever came from the arrival webhook, which never reaches localhost without a tunnel. Every completion site now calls refreshLedger (balance AND GET /transactions together), so rows come from Grid. - Grid records an inbound pull as a DEBIT (it debits the external source), so keying the row off `direction` labelled arriving money "Money sent". transactionToRow now derives direction from which side the wallet is on and falls back to direction/type when the wallet id isn't known. - Funding arrives in two legs (fiat credit, then conversion), so fetchActivity lists only the legs that touch the wallet — the leg the balance moved on. The push stand-in produced no row at all, because it funded the PLATFORM's USD account and on-ramped from it: that lands spendable balance, but the transaction belongs to the platform and never appears in GET /transactions?customerId=... (measured: 0 of 20 rows). It's now a REALTIME_FUNDING quote settled with POST /sandbox/send — the same settlement a pushed wire gets, and the customer's own transaction. Verified in the sandbox: COMPLETED, wallet as destination, spendable balance. That drops the platform on-ramp helpers entirely, and with them two endpoints from the proxy allowlist (the proxy injects the platform's own credentials, so a narrower allowlist is a real reduction in reach). Also in this pass: - Outbound is ledger-driven too: a pending row goes in on confirm and settles from the transaction's terminal status, so a failed quote no longer leaves a phantom "Withdrawn from balance" row. - Webhook cards show a static Payload label instead of a Response tab (there is no response to show), vertically centred in the tab group. - Panel filter chips for Requests vs Webhooks; action cards are never filtered. - After USD arrives, quote+execute USD internal -> USDB automatically. - External accounts dedupe on routing+account number (or IBAN). Collapses nothing today — the demo randomizes digits per add — but stops true repeats. - accountLabel() shows handles whole and masks only numbers (no more "•••• @upi"). - detectAddressNetworks() + tests: groundwork for pasting from the real clipboard outside sandbox. Not wired to the UI yet.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
Contributor
Author
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Money moved but the activity list didn't. Three causes, all real:
refreshLedger(balance andGET /transactionstogether), so rows come from Grid rather than from the UI.DEBIT(it debits the external source), so keying the row offdirectionlabelled arriving money "Money sent".transactionToRownow derives direction from which side the wallet is on, falling back todirection/typewhen the wallet id isn't known.fetchActivitylists only the legs that touch the wallet — the leg the balance moved on.The push stand-in produced no row at all, for a different reason: it funded the platform's USD account and on-ramped from it. That lands spendable balance, but the transaction belongs to the platform and never appears in
GET /transactions?customerId=…— measured 0 of 20 rows in the customer's list. It's now aREALTIME_FUNDINGquote settled withPOST /sandbox/send: the same settlement a pushed wire gets, and the customer's own transaction.Fidelity note: a real wire to those deposit instructions lands USD in the fiat account and the sweep converts it (two legs); the stand-in settles straight into the wallet (one). Both produce a customer transaction and a row.
That removed the platform on-ramp helpers entirely, and with them
GET /platform/internal-accountsandPOST /sandbox/internal-accounts/{id}/fundfrom the proxy allowlist. The proxy injects the platform's own client credentials, so a narrower allowlist is a real reduction in what a compromised browser session can reach.Also in this pass
Payloadlabel instead of a Response tab (there is no response to show), vertically centred in the tab group.accountLabel()shows handles whole and masks only numbers (no more•••• @upi).detectAddressNetworks()+ 15 tests — groundwork for pasting from the real clipboard outside sandbox. Deliberately not wired to the UI yet; the ambiguous-EVM case still needs a chain prompt.Verification
Sandbox-probed before wiring, then end-to-end in a browser:
REALTIME_FUNDING+/sandbox/send→COMPLETED, listed with the wallet as destination, spendable (not book-only) balance.Money added · Added to balance · Just now · +$25.00.+$100.00inbound now reads as added, not sent.INVALID_INPUT: Sending currency 'EUR' is not configured), so the stand-in deposits USD and the action card says so rather than implying euros arrived.tsc --noEmitclean.Known, not addressed here
The push flow is hard to reach: on "Select bank" the 13 saved accounts fill the screen, and the country picker that leads to deposit instructions sits behind the small + in the top-right. Fixing it means either capping the saved list or giving the instructions path its own row on the source step — both visible design changes, so they're left for a follow-up.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Pjqydq34z8DBK1kBrioXK2