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
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
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 fromscripts/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-118reads onlyreq.apiKey?.ratePerMinwithtimeWindow: '1 minute'. Nothing insrc/referencesratePerDayfor enforcement. A key issued with--per-day 100gets 60/minute, about 86,400 a day.Acceptance criteria
retryAfterpointing at the next day boundary, matching the existing error shapeThe 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
mainbefore you startVerified on 2026-09-24:
npx tsc --noEmitexits 0, andnpx vitest rungives 400 passed, 1 skipped, green across seven consecutive runs.So two open issues are stale and should not scare you off:
@stellar/stellar-sdkvitest mock makes every PR look red") does not reproduce onmain.src/config.ts:245-253memoises eachNetworkConfigin a module-levelMapon first access, so whichever test file imports first freezesprocess.envfor every other file.#113 ("restructure
config.tsinto a per-network map") is already fully implemented atsrc/config.ts:97-315.Ground rules
Required: Before submitting, join the contributor Telegram so your work can be tracked and counted toward the Stellar Wave: https://t.me/+fxHXq8f1SwlkZDBk