feat(intents): batch lookup, list-filter enum validation, token rejection & manual sweep trigger (#269, #270, #275, #276) - #349
Open
priscaenoch wants to merge 1 commit into
Conversation
… manual sweep trigger Implements four Stellar Wave issues: stellar-vortex-protocol#269 — Safe manual sweep trigger - IntentsSweeperService.sweep() now returns a SweepResult summary. - New IntentsSweeperService.triggerManualSweep(source) runs exactly one sweep cycle and logs the invocation loudly (source, timestamp, result). - main.ts installs a SIGUSR2 handler that invokes it — operator-only (needs shell access), no HTTP surface. Replaces the REPL break-glass procedure in docs/runbooks/on-call.md. stellar-vortex-protocol#270 — Enum validation for ListIntentsDto.state / chain - intents.types.ts exports INTENT_STATES (mirrors SUPPORTED_CHAINS); IntentState is now derived from it. - ListIntentsDto.state uses @isin(INTENT_STATES); chain uses @isin(SUPPORTED_CHAINS). Both stay @IsOptional(). Swagger enum: annotations added. - ?state=bogus / ?chain=bogus now return 400 with validation details instead of a silently-empty result set. stellar-vortex-protocol#275 — Batch intent-status lookup - New POST /api/v1/intents/batch accepting { intentIds: string[] } (capped at 100 via @ArrayMaxSize). Returns the record for each found ID; missing IDs omitted. - IntentsService.getMany() reuses get() per ID (de-duplicated); Prisma adapter should implement this as a single WHERE intent_id IN (...) query. stellar-vortex-protocol#276 — Reject unrecognised destination/source tokens - TokensService.resolveSrcTokenOrThrow / resolveDstTokenOrThrow throw a BadRequestException when the token is not in the registry. - IntentsController.create() uses them, so an unknown srcTokenAddress or dstTokenContract now returns 400 instead of creating an intent with priceUSD undefined. quote() applies the same check when a token identifier is supplied. - CHANGELOG.md notes the behaviour tightening. Tests: new tokens.service, getMany and manual-trigger unit specs; e2e coverage for the batch endpoint, enum-filter 400s and unknown-token 400s. Also restores two lines dropped by earlier merge conflicts that block compilation of the files touched here: the INTENTS_REPOSITORY import in intents.service.ts and `isActive: true` in SolversService.reactivate().
|
@priscaenoch 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! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements four Stellar Wave issues in the intents surface:
SIGUSR2) replacing the REPL break-glass procedureListIntentsDto.state/chain(@IsIn), returning a real400instead of a silently-empty resultPOST /api/v1/intents/batchstatus-lookup endpointpriceUSDCloses #269
Closes #270
Closes #275
Closes #276
Issue links:
ListIntentsDto.state/chain#270Changes
#269 — Manual sweep trigger
IntentsSweeperService.sweep()now returns aSweepResult({ expiredCount, slashedCount, durationMs }).IntentsSweeperService.triggerManualSweep(source)runs exactly one sweep cycle and logs the invocation loudly (MANUAL SWEEP TRIGGERED/… COMPLETE/… FAILEDwith source + timestamp + result) so it stands out in an incident timeline.main.tsinstalls aSIGUSR2handler that calls it. Operator-only: it needs shell access to the host (kill -USR2 <pid>), has no HTTP surface, and is unreachable by any API client.docs/runbooks/on-call.md→ "Manual sweep trigger (emergency)" rewritten with the real procedure (the "attach a Node.js REPL" text is gone).#270 — Enum validation for list filters
intents.types.tsexportsINTENT_STATES(mirrorsSUPPORTED_CHAINS);IntentStateis now derived from it — single source of truth.ListIntentsDto.state→@IsIn(INTENT_STATES),chain→@IsIn(SUPPORTED_CHAINS), both still@IsOptional().@ApiPropertyOptional({ enum })added so/docsshows the real allowed values.GET /api/v1/intents?state=bogus/?chain=notachainnow return400with validation details.useris unchanged (free-form address, per the issue).#275 — Batch intent-status lookup
POST /api/v1/intents/batch— body{ intentIds: string[] }, capped at 100 via@ArrayMaxSize. Returns{ intents, count }; IDs with no match are omitted (not individually 404'd).POSTbecause the ID list can exceed a query-string.IntentsService.getMany(ids)reusesget()per ID and de-duplicates. A code comment notes issue feat: rebuild backend on NestJS, drop Express #1's Prisma adapter should implement this as a singleWHERE intent_id IN (...)query.#276 — Reject unrecognised tokens
TokensService.resolveSrcTokenOrThrow/resolveDstTokenOrThrowwrap the existingresolve*helpers and throwBadRequestExceptionwhen the token is not in the registry.IntentsController.create()uses them → an unknownsrcTokenAddress(on a known chain) ordstTokenContractnow returns a clean400instead of creating an intent withpriceUSD: undefined.quote()applies the same check when a token contract/address is supplied (symbol-only quotes still work, so existing quote fixtures are unaffected).CHANGELOG.mddocuments the behaviour tightening (previously-accepted malformed requests now rejected).Merge-corruption restored (required for the touched files to compile)
Two lines dropped by earlier merge-conflict resolutions on
main, restored because they block compilation of files this PR edits:src/intents/intents.service.ts— re-addedimport { INTENTS_REPOSITORY, IIntentsRepository } from "./intents.repository";(added by42a8c89, lost in merge1ef46dd).src/solvers/solvers.service.ts—reactivate(){ ...solver, isActive }→{ ...solver, isActive: true }, matching every sibling method in the file.Testing / validation
Unit tests (run and pass):
src/tokens/tokens.service.spec.ts—resolveSrcTokenOrThrow/resolveDstTokenOrThrow(found → returns, unknown/empty →BadRequestException).src/intents/intents-batch-lookup.spec.ts—getMany: all found / some missing / empty input / de-dupes.src/intents/intents-sweeper.manual-trigger.spec.ts— runs exactly one sweep, logs loudly with source, propagates + logs failure.E2E tests added (in
test/validation-negative-paths.e2e-spec.tsandtest/intents.e2e-spec.ts): batch endpoint shape + array-cap400;?state=bogus/?chain=bogus→400; unknowndstTokenContract/srcTokenAddress→400; the old "unknown srcToken still succeeds" fixture updated to assert the new400.Lint:
npm run lint— 0 errors (pre-existing warnings only).mainis currently red before this branch —npm run typecheck/npm test/npm run test:e2efail onmainata305ab0due to merge-conflict corruption from concurrently-merged PRs, in files this PR does not own and was instructed not to modify:src/intents/intents.controller.ts—list()/quote()lostasync,Throttleimport dropped (9tscerrors).src/stats/stats.service.ts— references renamed methodbuildProtocolStats.src/intents/intents.service.spec.ts,intents-sweeper.service.spec.ts,intents.gateway.spec.ts— out of sync with the currentIntentsServiceconstructor.test/__mocks__/@stellar/stellar-sdk.ts/test/utils/create-test-app.ts— missing exports/imports, blocking the whole e2e suite.This PR reduces the
tscerror count (fixes 4, introduces 0) and repairs thesolvers.serviceunit suite. The remaining failures need a separate reconciliation PR from the owners of those files.🤖 Generated with Claude Code