Skip to content

ratePerDay is stored, returned, advertised — and never enforced #175

Description

@Miracle656

Background

The per-key daily quota exists everywhere except where it would do something. It is a column with a default of 10000, settable via POST /admin/keys (src/api/admin.ts:59,71), returned in the admin response, settable from scripts/issue-api-key.ts, and loaded into the request context (src/api/auth.ts:14,51).

Then the rate limiter at src/index.ts:115-118 reads only req.apiKey?.ratePerMin with timeWindow: '1 minute'. Nothing in src/ references ratePerDay for enforcement. A key issued with --per-day 100 gets 60/minute, about 86,400 a day.

Acceptance criteria

  • A daily counter is enforced per API key and survives a process restart
  • Exceeding it returns 429 with a retryAfter pointing at the next day boundary, matching the existing error shape
  • The per-minute limit keeps working unchanged
  • Tests: under limit passes, over limit 429s, counter resets at the boundary
  • Redis being unavailable does not silently disable the quota — decide fail-open or fail-closed and document it

Drips Wave · Complexity: Intermediate · 150 points


The shape of the problem

Lens aggregates SDEX trades and AMM pool prices into VWAP, OHLCV and best-route data. It is in good shape on the surface — 47 test files, 401 passing tests, a clean typecheck, changesets, OpenAPI publishing, Prometheus metrics.

Underneath it is two codebases wearing one coat. Everything written since the dual-network work (#113–#118) is network-aware. Everything written before it silently pools testnet and mainnet: exactly one of roughly twenty data-reading modules filters by network. Several issues below are that seam.

State of main before you start

Verified on 2026-09-24: npx tsc --noEmit exits 0, and npx vitest run gives 400 passed, 1 skipped, green across seven consecutive runs.

So two open issues are stale and should not scare you off:

#113 ("restructure config.ts into a per-network map") is already fully implemented at src/config.ts:97-315.

Ground rules

  • Every PR needs a test that fails before the change and passes after, unless the issue says otherwise.
  • A price with the wrong units, the wrong network or the wrong timestamp is worse than no price. Prefer refusing to answer over answering confidently.
  • Don't widen a Prometheus label to something unbounded. Pairs and networks are fine; issuers and pool ids are not.
  • Don't reformat a file you're changing.


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

Activity

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

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions