-
Notifications
You must be signed in to change notification settings - Fork 97
Add GET /api/streams/:id/claimable #485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -694,6 +694,61 @@ export const swaggerDocument = { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "/api/streams/{id}/claimable": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| get: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| summary: "Get real-time claimable amount", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: "Retrieves the current real-time claimable amount for a stream using Soroban contract simulation. Returns 0 if paused, canceled, or before the cliff.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parameters: [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: "id", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| in: "path", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: "The unique ID of the stream.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| schema: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: "string", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| responses: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "200": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: "Real-time claimable amount and query context.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "application/json": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| schema: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: "object", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| properties: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| streamId: { type: "string", example: "1" }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| claimableAmount: { type: "number", example: 450.123456 }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assetCode: { type: "string", example: "USDC" }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| at: { type: "integer", description: "Ledger timestamp at which query was simulated", example: 1716812160 }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+713
to
+728
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Verify the claimable endpoint response structure
# Search for the claimable endpoint handler implementation
rg -nP -A 10 "get.*['\"/]api/streams/:id/claimable" --type=ts
# Also check for response construction patterns
rg -nP -C 3 "streamId.*claimableAmount.*assetCode" --type=tsRepository: ritik4ever/stellar-stream Length of output: 731 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Show the full claimable handler block (approx) around the route definition
sed -n '420,520p' backend/src/index.ts
# Narrow search for how the response is sent within the claimable handler
rg -n "claimableLimiter|/api/streams/:id/claimable|claimable" backend/src/index.ts | head -n 50
# Find where the handler sends the 200 JSON (res.json / res.send / helper calls)
rg -n "app\.get\(\"/api/streams/:id/claimable\"|res\.json\(|res\.send\(|sendSuccess|sendApiSuccess" backend/src/index.ts -nRepository: ritik4ever/stellar-stream Length of output: 4438 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Inspect the swagger schema around the referenced lines
sed -n '690,760p' backend/src/swagger.ts
# Locate and inspect the helper functions that produce `at` and `claimableAmount`
rg -n "function getLatestLedgerTime|getLatestLedgerTime\s*=" backend/src -S
rg -n "function getOnChainClaimableAmount|getOnChainClaimableAmount\s*=" backend/src -SRepository: ritik4ever/stellar-stream Length of output: 2491 🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '380,520p' backend/src/services/streamStore.tsRepository: ritik4ever/stellar-stream Length of output: 4326 Update claimable swagger contract: structure matches implementation; add required fields The Option 2: Add required fields schema: {
type: "object",
+ required: ["streamId", "claimableAmount", "assetCode", "at"],
properties: {
streamId: { type: "string", example: "1" },
claimableAmount: { type: "number", example: 450.123456 },
assetCode: { type: "string", example: "USDC" },
at: { type: "integer", description: "Ledger timestamp at which query was simulated", example: 1716812160 },
},
},📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "404": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: "Stream not found.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "application/json": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| schema: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $ref: "#/components/schemas/Error", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "500": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: "Failed to simulate claimable amount.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "application/json": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| schema: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $ref: "#/components/schemas/Error", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "/api/recipients/{accountId}/streams": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| get: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| summary: "Get recipient streams", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: ritik4ever/stellar-stream
Length of output: 5960
🏁 Script executed:
Repository: ritik4ever/stellar-stream
Length of output: 112
🏁 Script executed:
Repository: ritik4ever/stellar-stream
Length of output: 13170
🏁 Script executed:
Repository: ritik4ever/stellar-stream
Length of output: 51
Fix flaky
/api/streams/:id/claimablerate-limit test caused by shared limiter state.claimableLimiteris created once inbackend/src/index.tsand attached as middleware for/api/streams/:id/claimable; the test only doesvi.clearAllMocks(), which won’t reset the limiter’s in-memory bucket.GET /api/streams/:id/claimableblock already hit the endpoint, consuming quota—so the expectation that the first 30 looped requests are always200(and the 31st is always429) can fail.vi.resetModules()or expose a way to clear the limiter store), or adjust assertions to account for already-consumed quota.🤖 Prompt for AI Agents