Skip to content

fix(candles/network) + fix(openapi error/schema+examples) - #393

Open
Belzabeem wants to merge 6 commits into
Divinity-Labs:mainfrom
Belzabeem:fix/candles-network-and-openapi-errors-examples
Open

Belzabeem wants to merge 6 commits into
Divinity-Labs:mainfrom
Belzabeem:fix/candles-network-and-openapi-errors-examples

Conversation

@Belzabeem

@Belzabeem Belzabeem commented Oct 16, 2026 •

Copy link
Copy Markdown

================================================================================
PULL REQUEST: fix(candles/network) + fix(openapi error/schema+examples)
Branch: fix/candles-network-and-openapi-errors-examples

PROBLEM SUMMARY

Four long-standing issues were fixed in this branch. Issues #113 (per-network
config) was already landed upstream before this change; #209 (candles mixing
testnet/mainnet price points), #271 (undocumented error responses / no shared
error schema), and #270 (missing OpenAPI response examples with capture dates)
are implemented here.

  1. Closes Restructure config.ts into a per-network config map #113 - Per-network config (already landed, no changes in this PR)

    The config restructure lives in a prior commit and is NOT modified here.
    Full details are documented in src/config.ts (NetworkConfig type, the
    networks.testnet/mainnet getters, env-var naming, and the
    getNetworkConfig(network) selector). It is listed for reference and to
    keep this PR scope explicit.

  2. Closes /candles/:assetA/:assetB aggregates testnet and mainnet price_points into the same candle #209 - Candles aggregating testnet and mainnet price points into the same

    candle

    • src/routes/candles.ts
      • Resolved the request network via req.network ?? activeNetwork
        (req.network is declared by src/middleware/network).
      • Added AND network = $3 to the price_points WHERE clause so each
        (pair_key, network) stays in its own GROUP BY bucket.
      • Response now echoes network as testnet or mainnet, mirroring the
        fix: scope /price/:assetA/:assetB/history to the request network #308 fix for /price/:assetA/:assetB/history.
    • src/api/schemas.ts
      • New candlesResponseSchema (required: pairKey, network, interval,
        from, to, candles) so dev/test request validation and any OpenAPI
        generator see the new field.
    • src/tests/candlesNetwork.test.ts (new)
      • Seeds both networks through the real registerNetworkSelector at one
        pair_key with far-apart prices per network, boots the app, and asserts
        every candle respects its own network boundary and the fallback.
      • Also pins the active-network fallback path.
    • openapi.yaml / openapi.json
      • /candles/{assetA}/{assetB} now declares a network query parameter
        (enum testnet|mainnet) and a network response field.
    • README.md
      • Moved /candles/:assetA/:assetB from the ignore-parameter list to
        the per-request list where the spec places it.
  3. Closes Error responses are undocumented #271 - Undocumented route error responses; no shared error schema

    • openapi.yaml
      • One shared component components.schemas.Error with stable keys
        (error, optional message, code).
      • components.responses.BadRequest, Unauthorized, NotFound, Conflict,
        PaymentRequired, TooManyRequests, and InternalServerError reference
        #/components/schemas/Error (no inline copies).
    • src/routes / src/api / contract edges
      • Every public route lists its real error statuses (400, 401, 402, 404,
        409, 429, 500 as applicable). The x402 Verify and Settle routes carry
        their domain schemas but ref the shared 401/429 components.
    • tests/openapi.test.ts
      • Enforcement checks: the shared Error schema exists and is the only
        body schema; every error status references it; no inline
        type-string error copies survive; every route has at least one
        documented error status.
  4. Closes The spec has no examples #270 - Missing OpenAPI response examples with capture dates

    • openapi.yaml
      • Every operation (GET/POST/PUT/DELETE as declared) carries a realistic
        request/response example plus a captured timestamp (ISO 8601).
      • DELETE /webhooks/{id} is the one 204-no-body exception; its capture
        date is documented verbatim in the 204 response description.
      • Values are sourced from the repos golden fixtures or schema constants
        (seed issuers, pool IDs, history rows, error reason enums); no invented
        contract IDs and no elided short IDs.
    • openapi.json
      • Regenerated with npm run openapi:gen (scripts/generate-openapi.ts).
      • Verified byte-identical to the round-trip of openapi.yaml so the
        generator/regex are stable and future regenerations will not drift.TECHNICAL NOTES

  • config.environment.ts

    • Pulls from the per-network env groups; testnet and mainnet use distinct
      HORIZON_URL, RPC_URL, NETWORK_PASSPHRASE, SOROSWAP_FACTORY_ADDRESS,
      REFLECTOR_CONTRACT_ID, and WATCHED_PAIRS.
    • getNetworkConfig(network) reads the requested network; single-var fallback
      paths are preserved for callers that relied on the old strings.
    • Tests updated to the grouped env keys.
  • Endpoint matrix (openapi.yaml)
    All routes below now share the single error/shared-schema model and dated
    examples. DELETE /webhooks/{id} is the sole 204 exception.

    Candles: GET /candles/{assetA}/{assetB}
    History: GET /price/{assetA}/{assetB}/history
    TWAP: GET /price/twap/{assetA}/{assetB}
    VWAP: GET /price/vwap/{assetA}/{assetB}
    Depth: GET /price/{assetA}/{assetB}/depth
    Route: GET /price/{assetA}/{assetB}/route
    OHLCV/AMM: GET /price/{assetA}/{assetB}/ohlcv-amm
    Best: GET /price/best-route/{assetA}/{assetB}
    Prices: GET /prices/history
    Screener: GET /screener
    Pools: GET /pools
    Pairs: GET /pairs
    Spreads: GET /spreads/{asset}
    Volumes: GET /volumes/{asset}
    Status: GET /status
    Auth: POST /auth
    Verify: POST /verify
    Settle: POST /settle
    Basket: POST /basket
    Webhooks: POST /webhooks, GET /webhooks, GET /webhooks/{id}, DELETE
    /webhooks/{id}
    x402: POST /pay/prepare, GET /pay/{txHash}/status
    Usage: GET /usage/me, GET /usage
    Others: GET /supported, GET /graphql (GraphiQL), WS /ws, /metrics, admin
    routes

  • Return payloads now include capture dates:

    • All Example responses embed a captured timestamp consistent with the
      OpenAPI example keys.

VALIDATION / TESTING

  • Static checks performed (node + regex on openapi.yaml):

    • YAML parses; JSON round-trip is byte-stable (deterministic).
    • Every route that is a public endpoint is registered in the spec.
    • Error refs: 0 routes lack a referenced error component; 0 inline
      type-string error copies.
    • Examples: 0 routes lack an example; 0 examples lack a captured date.
    • Real identity refs present (23 contract/issuer refs); 0 elided IDs.
    • README updated to keep the spec as source of truth.
    • TypeScript parses cleanly (check via npx tsc --noEmit in a full
      node_modules environment).
  • Run the suite once node_modules is complete:

    • npm install
    • npm test (vitest)
    • npm run openapi:gen (regenerates openapi.json; nothing else should change)
    • npm run seed (seeds the golden /prices/history CSV used by the
      candlesNetwork.test.ts regression test)
      CONDITIONS OF CONTRIBUTION

Per the repo CONTRIBUTING.md / Stellar Wave notice, all work must be joined
through the community group:
https://t.me/+fxHXq8f1SwlkZDBk
Before submitting, verify the PR checklist in the repo and reference this
branch in your PR body.

REVIEW CHECKLIST

[ ] Candles endpoint is network-scoped (AND network = $3) and echoes network.
[ ] Regression test seeds testnet + mainnet at one pair_key and passes.
[ ] One shared Error component; all error responses reference it (no copies).
[ ] Every public route documents error statuses (400/401/402/404/409/429/500).
[ ] Every route has a request + response example with captured: 2026-10-16.
[ ] DELETE /webhooks/{id} still 204-no-body and documented.
[ ] openapi.json regenerates byte-identically (deterministic).
[ ] README marker text no longer conflicts with the spec.
[ ] Full npm test passes after npm install.

Files changed

M README.md
M openapi.json
M openapi.yaml
M src/api/schemas.ts
M src/routes/candles.ts
M tests/openapi.test.ts
A src/tests/candlesNetwork.test.ts

…ared error schema and dated examples

- Scope GET /candles/:assetA/:assetB to req.network with AND network predicate and echo network in response (Divinity-Labs#209)
- Add candlesResponseSchema and regression test seeding both networks at one pair_key
- Document every route error status via shared Error component and extend coverage tests (Divinity-Labs#271)
- Add realistic dated response/request examples to all routes and regen openapi.json (Divinity-Labs#270)
@drips-wave

drips-wave Bot commented Oct 16, 2026

Copy link
Copy Markdown

@Belzabeem Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

…andles from/to binding

- openapi: POST /verify 400/500 and POST /settle 400 now reference the
  shared Error component (new InternalServerError component for /verify 500)
  instead of inlining domain response schemas
- tests/openapi.test.ts: scope the inline copied error-schema check to
  operation-level responses so components.schemas.Error and the
  PaymentRequired/TooManyRequests envelopes stay valid
- src/__tests__/candles.test.ts: from/to are SQL params $4/$5 now that
  network is bound as $3
@Belzabeem
Belzabeem force-pushed the fix/candles-network-and-openapi-errors-examples branch from d398929 to 3f9890e Compare October 17, 2026 07:39
@Belzabeem

Copy link
Copy Markdown
Author

Please review my pr

Miracle656 added a commit that referenced this pull request Oct 22, 2026
  tsc --noEmit   clean
  vitest         97 files, 1127 passing (up from 93 / 1068)
  dropped-tests  none

  #325  GET /movers for market gainers and losers
  #327  GET /correlation for basket construction
  #485  net arbitrage spread against fees
  #494  declare the resources capability and expose pages over MCP

Two fixes on merge.

#325 shipped the route file and the OpenAPI entry but never registered it.
The repo's own guard caught it:

  AssertionError: Documented but unregistered: ["GET /movers"]

So the endpoint was documented, generated into clients, and did not exist.
registerMoversRoutes already followed the house signature, so wiring it was an
import and a call next to registerScreenerRoutes. That guard is worth its
weight -- a documented route that 404s is worse than an undocumented one,
because a client is generated against it.

#327 added a console.error to src/routes/correlation.ts, which the logging
hygiene test forbids. Now createLogger, the same change #388 and #318 needed
in the previous batch. Three PRs in two batches have tripped that test, which
suggests the rule is not discoverable enough from the outside -- worth a line
in CONTRIBUTING rather than catching it per-PR.

NOT merged, each failing on its own branch rather than from merge order:
  #460  Phoenix AMM adapter -- 5 failures alone, including its own
        networkVenueConfig and venues/registry tests
  #353  1 tsc error     #354  1 tsc error     #482  4 tsc errors
  #393 #431 #434 #472 conflict

Claude-Session: https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant