docs(spec): note that exchangeRate is fee-exclusive - #888
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
✱ Stainless preview builds for gridThis PR will update the cli go kotlin openapi php python ruby typescript Edit this comment to update them. They will appear in their respective SDK's changelogs. ✅ grid-typescript studio · code · diff
✅ grid-openapi studio · code · diff
✅ grid-ruby studio · code · diff
✅ grid-kotlin studio · code · diff
✅ grid-go studio · code · diff
✅ grid-python studio · code · diff
✅ grid-php studio · code · diff
✅ grid-cli studio · code · diff
This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push. |
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
Greptile SummaryThe PR clarifies that exchange rates exclude fees across exchange-rate, quote, and transaction schemas, then propagates those descriptions into the assembled OpenAPI specifications. However, the new quote and transaction arithmetic conflicts with existing published examples.
Confidence Score: 4/5The exchange-rate arithmetic should be reconciled with the published quote and transaction examples before merging so clients are not given contradictory calculation guidance. The changed quote formula prescribes fee subtraction followed by division, while existing quote and transaction examples consistently obtain receiving amounts by multiplying by the documented rate. Files Needing Attention: openapi/components/schemas/quotes/Quote.yaml and openapi/components/schemas/transactions/Transaction.yaml
|
| Filename | Overview |
|---|---|
| openapi/components/schemas/exchange_rates/ExchangeRate.yaml | Clarifies fee-exclusive exchange-rate semantics; the intentional exchange-rate example arithmetic was not flagged. |
| openapi/components/schemas/quotes/Quote.yaml | Adds an explicit fee-adjusted division formula that conflicts with multiple published quote examples using multiplication. |
| openapi/components/schemas/transactions/Transaction.yaml | Adds fee-exclusive wording and rejects multiplication, conflicting with existing transaction examples that use the inverse rate convention. |
| openapi.yaml | Propagates the three schema-description changes into the assembled public contract, including the inconsistent quote and transaction guidance. |
| mintlify/openapi.yaml | Propagates the same descriptions into the documentation contract, exposing the inconsistent arithmetic to documentation consumers. |
Prompt To Fix All With AI
### Issue 1
openapi/components/schemas/quotes/Quote.yaml:83-88
**Exchange-rate formula contradicts examples**
When an integrator derives `totalReceivingAmount` from a quote, the new formula computes `(10000 - 10) / 0.92 ≈ 10858.7`, while the published example returns `9200` using `10000 × 0.92`. This contradictory rate direction causes clients following the description to calculate and display a different receiving amount from the API response; the same inconsistency affects the new transaction wording.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "docs(spec): note that exchangeRate is fe..." | Re-trigger Greptile
|
Thanks — there is a real contradiction here, but it is not in the new wording. The The rate direction is inverted in that example. Examples with precise rates confirm the documented direction and the fee-exclusive formula:
The two that match to eight significant figures are unambiguous: a round number like return float(Decimal(sending_amount - fees) / Decimal(receiving_amount))On the Not fixing the example in this PR. Correcting |
743b1b4 to
bf7a375
Compare
|
Correcting my previous comment: chasing this further showed my What I got wrong. I wrote the formula in minor units, The implementation in Decimal(sending_amount - total_fees)
* Decimal(10**receiving_currency.decimals)
/ (Decimal(receiving_amount) * Decimal(10**sending_currency.decimals))So the rate is a ratio of major units. The descriptions now say "in major units" and describe the fee ordering in words rather than giving a minor-unit formula that is only conditionally true. Three examples now confirm it, including the cross-decimal one:
On the original flag. The contradiction you identified is real, and the fee-exclusive claim still holds. The I audited every quote example in the repo: 16 of 18 fail the documented relationship, nearly all by publishing the rate inverted. Only Good catch. The formula would have shipped wrong for cross-decimal corridors. |
bf7a375 to
248ef1f
Compare
248ef1f to
31d9cbe
Compare
31d9cbe to
1c51d00
Compare
1c51d00 to
1199872
Compare

Summary
Documents that
exchangeRateis fee-exclusive, on all three schemas that expose it:Quote,Transaction, andExchangeRate.The previous description was
Number of sending currency units per receiving currency unit.That is silent on where fees sit relative to the rate, so an integrator converting a sending amount at the quoted rate computes a receiving amount that is too high by the fee.Verification
The rate is computed in
grid/objects/quote.py:Fees are deducted before the conversion. Checked against the published examples whose rates are precise enough to be unambiguous:
quote-system.mdxUSD→EURcurrencies-and-rails.mdxUSD→MXNquote-system.mdxUSD→BTCWording
Each description is written for the fields available on its own object:
QuotenamesfeesIncludedandtotalSendingAmountdirectly.Transactionstates the property without naming fields. The object carries no fee field to reference.ExchangeRatepoints at the siblingfeesobject.Each states the fee ordering and stops there, leaving the arithmetic to the reader.
Test plan
make buildrebundledopenapi.yamlandmintlify/openapi.yaml. The bundle diff is exactly the three description lines.@redocly/cli@1.34.5 lint openapi.yaml: valid.spectral lint --fail-severity=error: 0 errors. Remaining warnings and infos are pre-existing across the spec.Follow-ups, not addressed here
Two pre-existing issues surfaced while verifying this change. Both are worth fixing, and neither belongs in a description-only PR.
1. The rate's unit basis is undocumented. The amount fields are in the smallest unit of their currency, but the rate is not: each side is scaled by its currency's
decimalsfirst. For USD→BTC, dividing the wire integers (99500 cents / 828835 sats) gives0.12004802, off by 10^6 from the published120048.01920768; scaling each side first (995.00 / 0.00828835) reproduces it exactly. Same-decimal corridors hide this, so it only bites on pairs like USD→BTC. Wording that explains this clearly, without leaning on "major/minor unit" (terms absent from this spec) or on named denominations (BTC's smallest unit is the satoshi), needs its own pass.2. Most quote examples in the repo contradict this field. 16 of the 18 quote examples do not satisfy the documented relationship between
exchangeRate, the amounts, and the fee. Most publish the rate inverted, receiving-per-sending rather than sending-per-receiving.openapi/paths/quotes/quotes.yamlshowsexchangeRate: 0.92for a USD→EUR send where sending-per-receiving is about 1.087, so10000 x 0.92 = 9200reconciles only because the rate direction and the operation are both flipped and the errors cancel. Onlyquote-system.mdxandcurrencies-and-rails.mdxare correct today.A reader who checks this description against a nearby example will find they disagree, so fixing the examples is the higher-value follow-up.
🤖 Generated with Claude Code