Send current exchange-rate requests without a device timestamp - #6155
Merged
Conversation
j0ntz
approved these changes
Aug 14, 2026
The rates loop stamped "current" pairs with the device clock (new Date()). On a device whose clock runs fast that isoDate is a future date, and the rates server returns no rate for future dates. Every current rate came back null, so the cache stored current: 0 and fiat balances rendered as $0.00 even though crypto balances were correct. Confirmed against rates3/rates4.edge.app: past / now / +1m resolve, while +2m and beyond return null. The reporting device was ~2 min ahead of server time (its log uploads show the device UTC ahead of the server date header), so its current requests landed right on the server's future cutoff. Omit isoDate for current pairs so the server timestamps them with its own clock; historical pairs keep their explicit date. Verified the server returns the latest rate when isoDate is absent.
peachbits
force-pushed
the
matthew/rates-current-clock-skew
branch
from
August 15, 2026 03:03
4f1705a to
1c64ca1
Compare
peachbits
enabled auto-merge
August 15, 2026 03:09
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.
CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Requirements
No visual changes to the GUI — this touches the exchange-rate request logic only — so the device-testing checklist below does not apply.
Description
Symptom: wallets render correct crypto balances but
$0.00fiat — the same signature as the Cardano report in the ticket.Verbose exchange-rate logging from an affected device (
4.50.2, Android) shows every current rate returning no rate while historical rates resolve:The 16 no-rate pairs are exactly the current-timestamp ones; the cache then stores
current: 0, so fiat = amount × 0 =$0.00.Root cause:
convertToRatesParamsstamped "current" pairs with the device clock (new Date()). The rates server returns no rate for a timestamp more than ~2 minutes in the future, and this device's clock runs ~2 minutes fast (its log uploads show the device UTC ahead of the serverdateheader), so every current request landed right on the server's future cutoff.Replaying the device's verbatim request against
rates3/rates4.edge.app/v3/ratesconfirmed it: past / now / +1m resolve; +2m and beyond return null. WithisoDateomitted, the server uses its own clock and returns the latest rate.Fix: omit
isoDatefor current pairs so the server timestamps them; historical pairs keep their explicit date. Immune to device clock skew, with no behavior change when the clock is correct. Adds aconvertToRatesParamsregression test (current → noisoDate; historical → date preserved).Verified:
tsc,eslint, and theExchangeRateActionsjest suite (6/6) pass.Note
Medium Risk
Changes how all current rate queries are built for the rates server; incorrect behavior would affect fiat display app-wide, but the change is narrow and covered by a targeted test.
Overview
Fixes wallets showing correct crypto balances but $0.00 fiat when the device clock is slightly fast. Current rate pairs used to get
isoDatefromnew Date()inconvertToRatesParams; the rates server rejects timestamps too far in the future and returns no rate, so the cache storedcurrent: 0.convertToRatesParamsnow leavesisoDateundefined for pairs with no historical date (crypto and fiat), so the server timestamps with its own clock. Pairs with an explicitisoDatestill send that date for historical lookups.Also exports
convertToRatesParamsfor tests and adds a regression test that current pairs omitisoDateon the wire while historical pairs keep it. CHANGELOG updated.Reviewed by Cursor Bugbot for commit 1c64ca1. Bugbot is set up for automated code reviews on this repo. Configure here.