Skip to content

fix: type /quote 'amount' as string to preserve u64 precision#94

Open
serejke wants to merge 2 commits into
jup-ag:mainfrom
serejke:fix/quote-amount-u64-string
Open

fix: type /quote 'amount' as string to preserve u64 precision#94
serejke wants to merge 2 commits into
jup-ag:mainfrom
serejke:fix/quote-amount-u64-string

Conversation

@serejke
Copy link
Copy Markdown

@serejke serejke commented May 29, 2026

The bug

The /quote amount query parameter is a u64 in atomic units ("raw amount before decimals"), but it is declared type: integer, format: uint64. openapi-generator maps every type: integer to a TypeScript number (it ignores format), and a JS number is an IEEE-754 double — exact only up to Number.MAX_SAFE_INTEGER = 2^53−1 = 9_007_199_254_740_991. A u64 ranges up to 18_446_744_073_709_551_615, so any quote whose atomic input exceeds 2^53−1 silently loses precision before it ever reaches the wire. This is reachable at realistic values — e.g. holding >~9M whole tokens of any 9-decimal SPL token, or BONK-class high-supply tokens.

Proof

Number(9007199254740993n)        // → 9007199254740992   ❌ off by one, silently
(9007199254740993n).toString()   // → "9007199254740993" ✅ exact

Consistency

The response side already does the right thing: inAmount, outAmount, otherAmountThreshold, and PlatformFee.amount are all type: string. This PR aligns the request side with that existing convention.

The fix

  • swagger.yaml: AmountParameter schema type: integer / format: uint64type: string (with a comment explaining why).
  • Regenerated the typescript-fetch client with the pinned openapi-generator 7.3.0 (openapitools.json) via npm run openapi-gen. The only generated change is QuoteGetRequest.amount: numberstring.

Prior art

This is the same idea as #23 ("change amount type to string"), which was closed unmerged in Feb 2024. That attempt predated the v6→v1 API restructure and hand-edited the old generated DefaultApi.ts + bumped the version; this PR instead fixes it at the source (swagger.yaml) and regenerates, so the spec and client stay in sync. The bug is still present in main today (amount: number).

⚠️ Breaking change

Callers currently passing a JS number will need to pass a string. That is the point: any number above 2^53−1 was already silently wrong. Strings ≤ 2^53−1 and numeric-string inputs round-trip identically over the query string, so the fix is transparent for small amounts and correct for large ones. This likely warrants a major version bump — deferring to maintainer preference.

serejke added 2 commits May 29, 2026 18:07
The amount query parameter is a u64 in atomic units (raw amount before
decimals), but was declared type: integer, format: uint64. openapi-generator
maps every type: integer to a TS number (an IEEE-754 double), which is exact
only up to 2^53-1. u64 amounts can reach ~1.84e19, so any quote whose atomic
input exceeds 2^53-1 silently loses precision before hitting the wire.

Type it as string, matching the response-side amounts (inAmount, outAmount,
otherAmountThreshold) which are already strings for the same reason.
QuoteGetRequest.amount: number -> string. Generated with the pinned
openapi-generator 7.3.0 (openapitools.json) via npm run openapi-gen.
@serejke serejke force-pushed the fix/quote-amount-u64-string branch from d313343 to 048b3ba Compare May 29, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant