Skip to content

Plan: TokenAmount type for Spark-token amounts (int128)#699

Closed
peterrojs wants to merge 1 commit into
mainfrom
07-17-token-amount-int128
Closed

Plan: TokenAmount type for Spark-token amounts (int128)#699
peterrojs wants to merge 1 commit into
mainfrom
07-17-token-amount-int128

Conversation

@peterrojs

Copy link
Copy Markdown

Claim this PR

Summary

  • Spark-token amounts (USDB in Embedded Wallets, USDB card settlements, delegated-key spending limits) are uint128 end-to-end in the Spark protocol, but the Grid OpenAPI spec narrows every amount to format: int64. The narrowing sits exactly at this repo's boundary — sparkcore stores/carries uint128, and downstream (webdev/grid-api vendored client, observatory) faithfully consumes the int64.
  • This is the canonical spec change: introduce a TokenAmount scalar (string-encoded uint128) and a matching TokenCurrencyAmount object; use them only on fields that carry Spark-token amounts. Fiat-only fields stay int64.
  • Chain: this PR → webdev regen + sparkcore consumers → observatory backend + frontend.

Approach

Surgical, typed migration:

  • New common/TokenAmount.yaml: type: string, pattern: '^[0-9]+$', documented decoder guidance (parse as bigint / int / BigInteger / Decimal; never as JS number).
  • New common/TokenCurrencyAmount.yaml: mirrors CurrencyAmount but with TokenAmount.
  • Fields that are strictly Spark-token in v1 (card summaries, DelegatedKeySpendingLimit.maxPerTransaction) switch directly to TokenAmount.
  • Polymorphic fields where the same value can be fiat or Spark token (InternalAccount.balance, Quote.*Amount, ExchangeRate.*Amount, Transaction.sent/received/fees, RateDetails.*Fee*, AgentTransferDetails.amount, TransferIn/OutRequest.amount) switch to oneOf: [CurrencyAmount, TokenCurrencyAmount] or scalar oneOf: [{int64}, TokenAmount].
  • Version bumped info.version 2025-10-132026-07-17 and a matching servers.url — existing pinned clients keep the old int64 shape until they migrate.

Alternatives considered and rejected (details in plan file): uniform string across every amount (too broad, breaks all fiat clients); sibling fiatAmount / tokenAmount fields (bigger diff for no schema clarity gain); keep int64 + maximum (silent overflow already caused a real production incident — see the treasury snapshot memory).

Peter confirmed on Slack that (a) the ongoing team int64→int128 audit does not cover this spec, and (b) the OpenAPI CurrencyAmount is fair game (only the GraphQL CurrencyAmount { value: Long! } in sparkcore is off-limits).

Changes: 22 items across openapi/components/schemas/

  • common/TokenAmount.yaml (new)
  • common/TokenCurrencyAmount.yaml (new)
  • customers/InternalAccount.yamlbalance, totalBalance → oneOf
  • quotes/Quote.yamltotalSendingAmount, totalReceivingAmount, feesIncluded → oneOf
  • quotes/QuoteRequest.yamllockedCurrencyAmount → oneOf
  • exchange_rates/ExchangeRate.yaml — sending/min/max/receivingAmount → oneOf
  • exchange_rates/ExchangeRateFees.yamlfixed, total → oneOf
  • transactions/IncomingTransaction.yamlreceivedAmount, fees → oneOf
  • transactions/OutgoingTransaction.yamlsentAmount, receivedAmount, fees → oneOf
  • transactions/IncomingRateDetails.yamlgridApiFixedFee, gridApiVariableFeeAmount → oneOf (+ fixes stray type: number, format: int64)
  • transactions/OutgoingRateDetails.yamlcounterpartyFixedFee, gridApiFixedFee, gridApiVariableFeeAmount → oneOf (+ same fix)
  • cards/CardPullSummary.yaml, CardRefundSummary.yaml, CardSettlementSummary.yamltotalAmountdirect TokenAmount (USDB v1)
  • cards/CardTransaction.yamlauthorizedAmount, settledAmount, refundedAmount → oneOf
  • auth/DelegatedKeySpendingLimit.yamlmaxPerTransactiondirect TokenAmount (USDB v1)
  • agents/AgentTransferDetails.yamlamount → oneOf
  • transfers/TransferInRequest.yaml, TransferOutRequest.yamlamount → oneOf
  • sandbox/SandboxFundRequest.yaml, SandboxSendRequest.yaml, SandboxUmaReceiveRequest.yaml — amount fields → oneOf
  • config/PlatformCurrencyConfig.yaml, invitations/UmaInvitation*.yaml, receiver/CurrencyPreference.yaml — per-file audit during implementation
  • openapi/openapi.yaml + openapi.yaml bundle — register new schemas; bump info.version + servers.url; regenerate bundle via make build
  • One narrative migration doc in mintlify/ covering the TokenAmount encoding + JS-number pitfall

Full plan (code sketches for every field, verification checklist, risks): docs/plans/2026-07-17-token-amount-int128.md in this PR's diff.

Reply with a comment (e.g. LGTM) to approve — emoji reactions don't notify me here.

Requested by @peterrojs

Original PR: #698

akanter commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

This stack of pull requests is managed by Graphite. Learn more about stacking.

@peterrojs peterrojs closed this Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants