Skip to content

feat(keys,creator): add TWAP, graduated curve config, trade simulation and deprecation endpoints - #1007

Merged
Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
TS-mfon:feat/issues-866-869-870-872-consolidated
Oct 1, 2026
Merged

Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
TS-mfon:feat/issues-866-869-870-872-consolidated

Conversation

@TS-mfon

@TS-mfon TS-mfon commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Closes #866
Closes #869
Closes #870
Closes #872

Consolidates the four creator-key endpoints onto a single branch rebased on latest main. Opened as one PR deliberately: all four touch src/modules/keys/keys.routes.ts, and #869/#872 both touch src/modules/creator/creator.routes.ts plus prisma/schema/{activity,creator}.prisma, so as separate PRs they conflict with each other on merge. This supersedes #889, #890, #891 and #892.


#866 — TWAP endpoint

GET /api/v1/keys/:keyId/twap?window=1h|24h|7d

Returns twapPrice, spotPrice, windowLedgers, snapshotCount; twapPrice is null when fewer than two snapshots fall in the window. 60s Redis TTL, invalidated from the trade indexer and on every price-snapshot write.

Note on overlap with #978: main already has GET /:keyId/price/twap (windows 1h|4h|24h, returns twap/deltaPct/stale) from #978 (which resolved issue 963). That is a different endpoint contract from the one #866 specifies. Rather than overwrite it, #866's implementation lives in a new src/modules/keys/key-twap-window.service.ts and the existing key-twap.service.ts is untouched. If you'd rather have one endpoint than two, say so and I'll collapse them.

#869 — Graduated curve configuration

POST /api/v1/creator/:keyId/curve (creator-only) and GET /api/v1/keys/:keyId/curve-config (public).

Max 5 milestones, supplyThreshold positive and strictly ascending, exponent an integer in 1..5.

#870 — Trade simulation

GET /api/v1/keys/:keyId/simulate?quantity=N&side=buy|sell

Closed-form integral evaluation (O(1), no discrete step loop), comma-separated batch quantities, batch ceiling of 20 and per-entry ceiling of 1,000,000, and a 422 when a sell exceeds circulating supply. 15s Redis TTL.

#872 — Key deprecation and buyback

POST /api/v1/creator/:keyId/deprecate (creator-only)

Requires buybackPricePerKey to be a positive integer, verifies the creator's XLM balance covers circulatingSupply * buybackPricePerKey (400 INSUFFICIENT_BALANCE otherwise), sets status = 'Deprecated' and tradingPaused = true, records KEY_DEPRECATED, and queues holder notifications.


Review feedback carried over from #890

  • Migration directory (high). The migration is at prisma/schema/migrations/20260930000000_add_graduated_curve_and_key_status/, not prisma/migrations/. package.json points Prisma at ./prisma/schema, so the previous location would not have been picked up by prisma migrate deploy.
  • Non-finite rejection (medium). Milestone validation rejects non-finite values, so 1e400 (parsed as Infinity) is refused rather than reaching the gateway.

Still open from the #889/#890 reviews

  • Contract view calls. curveGateway.configureGraduatedCurve and the TWAP get_twap path still log rather than submitting to Soroban, so both are effectively DB-backed. Wiring them to a real contract client is a larger change than these four endpoints; happy to do it here or in a follow-up, your call.

Schema

  • ActivityType: adds GRADUATED_CURVE_CONFIGURED, KEY_DEPRECATED.
  • CreatorProfile: adds curveMilestones (Json?), baseExponent (Int, default 1), status (String, default "Active").

Verification

npx prisma generate --schema ./prisma/schema   # ok
npx tsc --noEmit                               # 0 errors
npx jest src/modules/creator/__tests__/creator-curve.test.ts \
         src/modules/creator/__tests__/creator-deprecate.test.ts \
         src/modules/keys/__tests__/key-simulate.test.ts \
         src/modules/keys/__tests__/key-twap-window.test.ts
# Test Suites: 4 passed, 4 total   Tests: 25 passed, 25 total

…n and deprecation endpoints

Closes accesslayerorg#866
Closes accesslayerorg#869
Closes accesslayerorg#870
Closes accesslayerorg#872

Consolidates the four endpoints onto one branch rebased on latest main,
so they land together instead of conflicting in keys.routes.ts,
creator.routes.ts and the prisma schema.

accesslayerorg#866 - GET /api/v1/keys/:keyId/twap?window=1h|24h|7d
  Served from a new key-twap-window.service.ts so it does not clobber
  the GET /:keyId/price/twap service added by accesslayerorg#978 (1h/4h/24h). Returns
  twapPrice, spotPrice, windowLedgers and snapshotCount, with twapPrice
  null below two snapshots. 60s Redis TTL, invalidated from the trade
  indexer and on every price-snapshot write including the first.

accesslayerorg#869 - POST /api/v1/creator/:keyId/curve, GET /api/v1/keys/:keyId/curve-config
  Creator-only milestone config, max 5 milestones, strictly ascending
  positive thresholds, integer exponents 1..5.

accesslayerorg#870 - GET /api/v1/keys/:keyId/simulate?quantity=N&side=buy|sell
  Closed-form integral preview with batch quantities, batch and quantity
  ceilings, and rejection when a sell exceeds circulating supply.

accesslayerorg#872 - POST /api/v1/creator/:keyId/deprecate
  Creator-only buyback wind-down with solvency check, status transition,
  trading pause and queued holder notifications.

Schema: adds GRADUATED_CURVE_CONFIGURED and KEY_DEPRECATED activity
types, and curveMilestones, baseExponent and status on CreatorProfile.
The migration lives in prisma/schema/migrations, which is the directory
package.json points Prisma at, rather than prisma/migrations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 1, 2026 12:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

Labels

None yet

Projects

None yet

3 participants