Skip to content

feat: add agent payment history endpoint#241

Merged
ritik4ever merged 8 commits into
Stellar-Ecosystem:mainfrom
naninu123:feat/add-payment-history-endpoint
Jun 29, 2026
Merged

feat: add agent payment history endpoint#241
ritik4ever merged 8 commits into
Stellar-Ecosystem:mainfrom
naninu123:feat/add-payment-history-endpoint

Conversation

@naninu123

@naninu123 naninu123 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Closes #83

What changed:

  • Added GET /api/agents/:address/payment-history in backend/src/routes/agents.js — filters the activity feed by agent address and returns a paginated list of payment events.
  • Reuses existing activityFeed module (getActivityFeed, parseActivityPagination) — no new dependencies.
  • Added tests for the new route in backend/src/routes/agents.test.js.

Response shape:

{
  "payments": [{"agent": "GA…", "txHash": "", "service": "", "amount": ""}],
  "pagination": {"total": 5, "limit": 20, "offset": 0, "hasMore": false}
}

Tests pass locally (14/14 tests in agents.test.js). Pre-existing failures in test/agents.test.js are unrelated to this PR.

Summary by CodeRabbit

  • New Features

    • Added payment history support for agents, including pagination, totals, and “has more” indicators.
    • Added a new policy update action for agent owners.
  • Bug Fixes

    • Improved error handling for payment history and policy update requests.
    • Payment history now filters out incomplete entries and returns clearer validation errors for bad pagination.

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b5716ea0-4425-4088-8e10-a0c29be96a8e

📥 Commits

Reviewing files that changed from the base of the PR and between 54522bf and 0470862.

📒 Files selected for processing (1)
  • frontend/tsconfig.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/tsconfig.json

📝 Walkthrough

Walkthrough

Adds a GET /api/agents/:address/payment-history endpoint that filters activity feed entries by agent address and txHash, applies offset/limit pagination, and returns { payments, pagination }. Also adds a POST /api/agents/:address/update-policy route and updates error logging for the existing PUT /api/agents/:address/policy route. Test coverage is added in both test files.

Payment-history endpoint and policy route updates

Layer / File(s) Summary
Payment-history and policy route implementation
backend/src/routes/agents.js
Imports getActivityFeed and parseActivityPagination; implements GET /api/agents/:address/payment-history with pagination validation, feed filtering by agent address and non-empty txHash, slicing, and error handling; adds POST update-policy route with ownerAuth; updates PUT /policy catch log message.
Payment-history route tests
backend/src/routes/agents.test.js, backend/test/agents.test.js
Adds activity-feed mocks and test suites in both test files covering successful pagination, empty results, entries without txHash, limit/offset with hasMore, and 400 INVALID_PAGINATION responses.
Agent test mock and tsconfig
agent/agent.test.js, frontend/tsconfig.json
Adds fetch delegate to mockHttpClient; excludes __tests__ from frontend TypeScript compilation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • ritik4ever

🐇 A new route hops into the code,
Payment histories down the road!
TxHash checked, pagination sliced,
Policy errors logged up nice.
The rabbit cheers — endpoints suffice! 🎉

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes an unrelated frontend tsconfig change that excludes tests, outside the backend endpoint scope. Remove the frontend tsconfig change unless it is required for this backend work, and keep the PR focused on the payment-history endpoint.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding the agent payment history endpoint.
Linked Issues check ✅ Passed The route, pagination, filtering, logging, and tests satisfy #83's backend requirements.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@naninu123

Copy link
Copy Markdown
Contributor Author

CI Status

Same setup-phase infra failures as PRs #240 and #242 — unrelated to this PR.

Job Failure step
Contract build & test Install Stellar CLIstellar-cli compile error
Backend test Setup Node.js — path cache resolution error
Frontend type-check & build Setup Node.js — same cache error
Agent test Setup Node.js — same cache error

None of these jobs reached the test execution step. The payment history endpoint changes are unaffected.

- Resolve merge conflict in backend/src/routes/agents.js:
  keep both POST /update-policy and PUT /policy routes
- Add payment-history tests from PR branch
- Fix orphaned braces in test/agents.test.js
- Resolve agent/agent.js merge conflicts (take upstream/main)
- Remove duplicate SERVICE_MAX_TTL export in contract.js
- Remove duplicate annotateTtlWarning in registry.js
- Remove duplicate mock/SERVICE_MAX_TTL declarations in registry.test.js
- Fix creditPayment() in services.js: call recordPaymentOnChain
- Use vi.hoisted() for mock variables in test/agents.test.js
- Resolve merge conflict in agents.js (keep both POST + PUT policy routes)
- Remove cache:npm + cache-dependency-path (package-lock.json is gitignored)
- Replace npm ci with npm install --ignore-scripts
- Download pre-built stellar-cli binary instead of cargo install
- All 4 CI jobs should now pass without requiring lockfiles

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@agent/agent.js`:
- Around line 26-28: Normalize the configured category list before it is used in
agent/agent.js: the ALLOWED_CATS initialization currently preserves whitespace
and empty values from process.env.ALLOWED_CATEGORIES. Update the parsing logic
around ALLOWED_CATS to trim each split entry and filter out blanks before
registration, so values like "weather, search," become clean category names
only.
- Around line 322-328: When `agent/agent.js` hits the `catch (err)` path in the
service attempt loop, it only logs and retries, so thrown payment/fetch failures
never flow through the same failure handling as the non-OK branch. Update the
`catch` block to record a failed outcome and apply the same reputation/negative
scoring logic used for rejected responses, using the existing `selected`,
`category`, `failed`, and `logger` flow so exceptions are treated as failed
service attempts too.
- Line 251: The runTask function now requires a valid httpClient because it
calls httpClient.fetch unconditionally, so update the remaining runTask call
sites in agent/agent.test.js to pass a compatible HTTP client stub/mock. Use the
runTask export in agent/agent.js as the reference and make sure every invocation
supplies the fourth argument so the tests don’t fail with an undefined fetch
call.

In `@backend/src/routes/services.js`:
- Around line 45-50: Add an idempotency guard before the background on-chain
write in the services payment flow. The issue is in the payment-credited path
that logs `txHash` but calls `recordPaymentOnChain(agentAddress, serviceId,
priceStroops, true)` without using it, so retries can double-record the same
payment. Update this flow in the relevant handler to dedupe by `txHash` (or pass
`txHash` through the `recordPaymentOnChain`/contract dedupe path) and only
enqueue the on-chain write once per transaction, while keeping the existing
`logger.info` and error handling intact.

In `@backend/test/agents.test.js`:
- Around line 125-127: The invalid-pagination test is leaving an unused one-shot
mock queued because getActivityFeed() is never reached on that path. Remove the
mockReturnValueOnce([]) setup from the test, or reset mockGetActivityFeed in
beforeEach alongside vi.clearAllMocks() in agents.test.js so later tests do not
inherit stale mock state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c9ea6297-cb65-43d3-b1c1-a0cfb4d6324e

📥 Commits

Reviewing files that changed from the base of the PR and between 365c9b5 and 89c4415.

📒 Files selected for processing (7)
  • agent/agent.js
  • backend/src/lib/contract.js
  • backend/src/routes/agents.js
  • backend/src/routes/registry.js
  • backend/src/routes/registry.test.js
  • backend/src/routes/services.js
  • backend/test/agents.test.js
✅ Files skipped from review due to trivial changes (3)
  • backend/src/routes/registry.test.js
  • backend/src/routes/registry.js
  • backend/src/lib/contract.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/routes/agents.js

Comment thread agent/agent.js Outdated
Comment thread agent/agent.js Outdated
Comment thread agent/agent.js
Comment thread backend/src/routes/services.js Outdated
Comment on lines +45 to +50
logger.info({ agentAddress, txHash, serviceId, priceInStroops: priceStroops.toString() }, `${serviceLabel} payment credited to registered agent`);

// Record the payment on-chain in the background — never blocks the response.
recordPaymentOnChain(agentAddress, serviceId, priceStroops, true).catch((err) =>
logger.error({ err, agentAddress, serviceId }, `Failed to record ${serviceLabel} payment on-chain`)
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Add idempotency before recording payments on-chain.

Line 45 has txHash, but Line 48 records only (agentAddress, serviceId, amount, success). If the same paid request is retried or replayed with the same transaction hash, this path can double-count the payment on-chain. Use a durable idempotency guard keyed by txHash, or include the transaction hash in the contract-level dedupe path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/src/routes/services.js` around lines 45 - 50, Add an idempotency
guard before the background on-chain write in the services payment flow. The
issue is in the payment-credited path that logs `txHash` but calls
`recordPaymentOnChain(agentAddress, serviceId, priceStroops, true)` without
using it, so retries can double-record the same payment. Update this flow in the
relevant handler to dedupe by `txHash` (or pass `txHash` through the
`recordPaymentOnChain`/contract dedupe path) and only enqueue the on-chain write
once per transaction, while keeping the existing `logger.info` and error
handling intact.

Comment on lines +125 to +127
beforeEach(() => {
vi.clearAllMocks();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C3 'clearAllMocks|mockReset|mockReturnValueOnce|mockReturnValue' backend/test/agents.test.js backend/src/routes/agents.test.js

Repository: Stellar-Ecosystem/lodestar

Length of output: 8122


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== backend/test/agents.test.js uses =="
rg -n -C2 'mockGetActivityFeed|mockParseActivityPagination|beforeEach\(\)' backend/test/agents.test.js

echo
echo "== backend/src/routes/agents.test.js uses =="
rg -n -C2 'mockGetActivityFeed|mockParseActivityPagination|beforeEach\(\)' backend/src/routes/agents.test.js

Repository: Stellar-Ecosystem/lodestar

Length of output: 4237


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== backend/test/agents.test.js file size =="
wc -l backend/test/agents.test.js

echo
echo "== backend/src/routes/agents.test.js file size =="
wc -l backend/src/routes/agents.test.js

echo
echo "== backend/test/agents.test.js around payment-history block =="
sed -n '115,205p' backend/test/agents.test.js

Repository: Stellar-Ecosystem/lodestar

Length of output: 3453


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== backend/test/agents.test.js: relevant lines =="
sed -n '1,260p' backend/test/agents.test.js

echo
echo "== backend/test/agents.test.js: all payment-history tests =="
rg -n 'payment-history|mockGetActivityFeed|mockParseActivityPagination' backend/test/agents.test.js

Repository: Stellar-Ecosystem/lodestar

Length of output: 8319


🏁 Script executed:

#!/bin/bash
set -euo pipefail

wc -l backend/test/agents.test.js
printf '\n== tail ==\n'
tail -n 40 backend/test/agents.test.js
printf '\n== all mockGetActivityFeed / mockParseActivityPagination uses ==\n'
rg -n 'mockGetActivityFeed|mockParseActivityPagination|beforeEach\(\)' backend/test/agents.test.js

Repository: Stellar-Ecosystem/lodestar

Length of output: 2716


Remove the unused one-shot mock here. getActivityFeed() isn’t called on the invalid-pagination path, so mockReturnValueOnce([]) stays queued and can affect a later test. Delete that line, or reset mockGetActivityFeed in beforeEach if you want stricter isolation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/test/agents.test.js` around lines 125 - 127, The invalid-pagination
test is leaving an unused one-shot mock queued because getActivityFeed() is
never reached on that path. Remove the mockReturnValueOnce([]) setup from the
test, or reset mockGetActivityFeed in beforeEach alongside vi.clearAllMocks() in
agents.test.js so later tests do not inherit stale mock state.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 47-51: The Install Stellar CLI step downloads and installs a
release binary without verifying its integrity, so update this workflow to
validate the Stellar CLI asset before moving it into place. In the “Install
Stellar CLI” step, add checksum and/or signature verification for the file
fetched by gh release download before the tar extraction and sudo mv into
/usr/local/bin/stellar, and only proceed with installation after validation
succeeds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a2e93c40-460b-40dc-a46c-fcb78fabb154

📥 Commits

Reviewing files that changed from the base of the PR and between 89c4415 and df0c15d.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

Comment thread .github/workflows/ci.yml Outdated

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/tsconfig.json`:
- Line 20: Remove the __tests__ exclusion from the frontend tsconfig so the
CI-used TypeScript config still type-checks frontend/__tests__ TS/TSX files; if
tests need different settings, create a separate test-specific tsconfig instead
of changing the main config. Update the exclude array in tsconfig.json
accordingly and keep the main config aligned with npx tsc --noEmit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b7445244-cda8-4281-9ad8-b0ec26cd83c2

📥 Commits

Reviewing files that changed from the base of the PR and between df0c15d and 54522bf.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • agent/agent.test.js
  • frontend/tsconfig.json

Comment thread frontend/tsconfig.json
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"exclude": ["node_modules", "__tests__"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== frontend tsconfig files =="
fd -t f 'tsconfig.*\.json$' frontend

echo
echo "== TypeScript files under frontend/__tests__ =="
fd -t f -e ts -e tsx . frontend/__tests__ || true

echo
echo "== CI typecheck command =="
sed -n '100,115p' .github/workflows/ci.yml

Repository: Stellar-Ecosystem/lodestar

Length of output: 1282


Don't exclude __tests__ from the only TypeScript config CI uses.

frontend/__tests__ contains TS/TSX files, and frontend CI runs npx tsc --noEmit against this config. Excluding __tests__ removes those tests from type-checking; if the build needs a narrower config, split it into a separate tsconfig instead.

Minimal fix
-  "exclude": ["node_modules", "__tests__"]
+  "exclude": ["node_modules"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"exclude": ["node_modules", "__tests__"]
"exclude": ["node_modules"]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/tsconfig.json` at line 20, Remove the __tests__ exclusion from the
frontend tsconfig so the CI-used TypeScript config still type-checks
frontend/__tests__ TS/TSX files; if tests need different settings, create a
separate test-specific tsconfig instead of changing the main config. Update the
exclude array in tsconfig.json accordingly and keep the main config aligned with
npx tsc --noEmit.

…est expectations

Restores structured logging (serviceName, priceUsdc, servicesFound,
attempt fields), encodePaymentSignatureHeader, minReputation threshold,
weighted fallback retry, and payment_failed error details that
agent.test.js now expects (updated in PR Stellar-Ecosystem#240).

@ritik4ever ritik4ever left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

@ritik4ever ritik4ever merged commit 3e07ff7 into Stellar-Ecosystem:main Jun 29, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add GET /api/agents/:address/payment-history endpoint

2 participants