Skip to content

Money is a Float throughout the GraphQL schema #371

Open

Description

@Miracle656

Background

price: Float!
sdexPrice: Float!
ammPrice: Float!
vwap: Float!
volume: Float!

GraphQL's Float is an IEEE 754 double. Prices are stored as
Decimal(36, 18) in schema.prisma and are already cast ::float in 18 places
in the SQL — this schema is the last step of that chain, and it makes the loss
permanent and caller-visible.

For an asset priced around 0.18 this rarely matters. For a long-tail asset
priced at 0.000000000000001234, or a volume in the billions, doubles start
eating digits — and the whole purpose of this API is being the number other
systems trust.

What to build

This is a design change, so propose it before building it.

  • A custom Decimal scalar serialising as a string, preserving the stored
    precision end to end.
  • Decide what happens to existing clients: adding a new field alongside the
    Float and deprecating the old one is the usual path, and it is a breaking
    change either way, so the migration needs stating.
  • Audit where the ::float casts happen — fixing the schema while the SQL still
    rounds achieves nothing.
  • A test with a value that genuinely cannot survive a double round-trip.

Acceptance criteria

  • Monetary values can be requested at full stored precision
  • The precision survives the whole path, SQL included
  • Existing clients have a documented migration
  • A test asserts a value that a double would round is returned exactly
  • The trade-off and the migration are written down

Drips Wave · Complexity: Advanced · 200 points


Repo: Divinity-Labs/Lens. Node + TypeScript, Fastify, mercurius for
GraphQL at POST /graphql, Prisma on Postgres, Redis, Prometheus.

Run the tests: npm test. The tests are vitest, not jest. Running jest
here reports "66 suites, 0 tests" and means nothing. A single file is
npx vitest run src/__tests__/graphqlSubscription.test.ts.

Load test (prices) is already failing on main and has been for some
time. It is not your PR. Everything else should be green.

Read src/__tests__/graphqlSubscription.test.ts before you start. It is the
house pattern for testing this surface and it is good — it drives a real
subscription through a real server and asserts on what a client receives.

This service prices real assets on Stellar mainnet. A wrong number is worse
than a missing one, because the caller cannot tell.

Never elide an address, a contract id or a key in code, comments or test
fixtures. A previous batch shortened a contract id in an issue and five
contributors invented plausible-looking ids to fill the gap. Write it in full or
not at all.


Required: Before submitting, join the contributor Telegram so your work can be tracked and counted toward the Stellar Wave: https://t.me/+fxHXq8f1SwlkZDBk

Activity

  1. Jossy-ossy commented on Oct 16, 2026

    @Jossy-ossy
    Contributor

    @Jossy-ossy has applied to work on this issue as part of the Stellar Wave Program's 10th wave.

    I would like to work on this issue because I am passionate about making a positive difference in society. I believe that every problem deserves attention and practical solutions. I am willing to learn, contribute my ideas, work with others, and dedicate my time to finding meaningful ways to address this issue. I see this opportunity as a chance to develop my skills while contributing to positive change.

    ℹ️ Repo Maintainers: To accept this application, review their application or assign @Jossy-ossy to this issue.

  2. drips-wave commented on Oct 16, 2026

    @drips-wave

    Congratulations, @Jossy-ossy! 🎉 Your application was accepted by the repo's maintainers, and the issue is due on October 22, 2026.

    🧑‍💻 @Jossy-ossy: Please resolve the issue such that the repo's maintainers have enough time to review your contribution before the due date. You'll earn Points for completing the issue on-time, which will make you eligible for a share of the Stellar Wave Program's reward pool.

    Warning

    When opening a PR, please link it to this issue to ensure it gets tracked accurately. Points are awarded when this issue is marked as completed by the maintainer.

    🤠 Repo maintainers: Please keep an eye on the contributor's progress and review their work before the due date. You can manage this issue, including adjusting its complexity and points, here.

    🌊 Happy Wave 🌊

  3. Jossy-ossy commented on Oct 16, 2026

    @Jossy-ossy
    Contributor

    Proposed approach before implementation:

    • Preserve the current GraphQL Float fields for compatibility and add parallel Exact fields using a Decimal scalar that serializes only as a decimal string.
    • Keep PostgreSQL numeric results as strings in the exact path. Remove the float casts from price and volume queries, and keep numeric-to-Number conversion only in the legacy Float resolvers.
    • Carry exact decimals through the aggregate resolver as well as history and candle queries; exact fields must not be derived from legacy Float values.
    • Document that clients should migrate to the exact fields now, deprecate Float fields, and remove them only in a later breaking API release.
    • Add an integration regression using a value such as 0.000000000000001234 and assert the exact string is returned end to end.

    This keeps existing clients working while establishing a lossless path for new clients. Please let me know if you want a different field naming or migration policy before I build it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions