feat: add x402 machine accounting API#30
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 52 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds a machine quarter-report API protected by typed-data signatures, delegation checks, nonce replay protection, and rate limiting. It also adds X402 payment configuration, a discovery endpoint, report-slice shaping, and the supporting database schema and environment settings. ChangesMachine API — auth, rate limiting, report slices, X402 payment
Estimated code review effort🎯 5 (Critical) | ⏱️ ~100 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR lays the groundwork for a paid “machine API” to access published accounting report data by introducing x402 paywall integration, EVM delegation-based request authentication, replay protection via nonces, and per-agent/delegator rate limiting—along with the necessary DB schema and environment configuration.
Changes:
- Adds a new paid API endpoint (
/api/machine/reports/quarters/{quarterId}) protected by x402, EIP-712 signatures, and delegation registry checks. - Introduces DB-backed rate limiting and nonce consumption tables/migrations to support throttling and replay-attack resistance.
- Expands environment configuration and adds x402 + supporting crypto/validation dependencies.
Reviewed changes
Copilot reviewed 14 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/machine-api/x402.ts | Builds x402 server/config for the accounting paywall integration. |
| src/lib/machine-api/report-slices.ts | Defines machine-report “slice” identifiers and response shaping for each slice. |
| src/lib/machine-api/registry.ts | Adds delegation registry contract read to resolve delegator for an agent address. |
| src/lib/machine-api/rate-limit.ts | Implements DB-backed rate limiting for the machine API. |
| src/lib/machine-api/nonces.ts | Implements DB-backed nonce consumption to prevent replay. |
| src/lib/machine-api/auth.ts | Adds EIP-712 request verification + delegation + membership checks. |
| src/lib/auth/permissions.ts | Extends DAO share permission checks to support configurable RPC/chain. |
| src/db/schema.ts | Adds Drizzle schema for machine API rate limits and request nonces tables. |
| src/app/api/machine/reports/quarters/[id]/route.ts | New machine API endpoint with auth + rate limiting + report slice output, wrapped in x402 payment. |
| src/app/.well-known/agents.json/route.ts | Adds discovery metadata describing the machine API capabilities and signing/payment details. |
| drizzle/0019_magenta_deathbird.sql | Migration creating machine_api_rate_limits and machine_api_request_nonces tables + indexes/FK. |
| drizzle/meta/0019_snapshot.json | Drizzle schema snapshot for migration 0019. |
| drizzle/meta/_journal.json | Registers migration 0019 in the Drizzle journal. |
| .env.example | Documents new env vars for x402, delegation registry, and DAO share chain/RPC overrides. |
| package.json | Adds x402 packages as dependencies. |
| pnpm-lock.yaml | Locks new dependencies and updates platform-specific package metadata. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 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 `@src/app/.well-known/agents.json/route.ts`:
- Around line 7-13: The discovery payload from getRegistryDiscovery is currently
allowing a null registry address, which later becomes a published EIP-712 domain
with verifyingContract set to null. Update the agents.json route so
getRegistryDiscovery only returns registry details when both chainId and address
are valid, and otherwise omits the capability or marks it unavailable; ensure
the signature domain construction in the published response uses the same strict
validation as getDelegationRegistryConfig and never exposes a null
verifyingContract.
In `@src/app/api/machine/reports/quarters/`[id]/route.ts:
- Around line 45-47: The error handling in the route handler is returning the
raw internal exception message from errorResponse, which can expose sensitive
implementation details. Update the [id] route’s error path so the handler
returns a stable, generic public 500 message instead of error.message, and keep
the detailed Error object for internal logging in the same try/catch flow. Use
the existing route handler and errorResponse call site as the location to adjust
the response behavior.
In `@src/lib/auth/permissions.ts`:
- Around line 71-85: The permission client setup in createPublicClient currently
allows DAO_SHARE_RPC_URL to override the transport while still defaulting to
gnosis when DAO_SHARE_CHAIN_ID is missing, which creates a mismatched network
configuration. Update the logic in src/lib/auth/permissions.ts so
DAO_SHARE_RPC_URL and DAO_SHARE_CHAIN_ID are required together, or otherwise
ignore the DAO_SHARE_RPC_URL path when the chain id is absent; use the existing
createPublicClient and hasDaoShares flow as the target for the change. Ensure
the function fails fast with a clear error when only one of the two env vars is
set, so the auth check in src/lib/machine-api/auth.ts always reads against the
intended chain.
In `@src/lib/machine-api/auth.ts`:
- Around line 108-133: The signature handling in auth.ts is only checking
presence via requireString and then casting before verifyTypedData, so malformed
signatures can escape as generic server errors. Add a signature-specific
validation step near the nonce/signature parsing in the auth verification flow,
or catch viem parse errors around verifyTypedData and translate them into
MachineApiAuthError so bad signatures fail as auth errors instead of 500s.
In `@src/lib/machine-api/rate-limit.ts`:
- Around line 23-39: The rate-limit upsert in machine-api/rate-limit.ts mixes
the app clock with the database clock by deriving resetAt from Date.now() while
comparing against Postgres now(), which can skew the window. Update the logic in
the rate-limit insert/update path (the execute/sql block in the rate-limit
function) so reset_at is computed entirely in SQL using the database clock, and
reuse that same DB-derived timestamp in both the insert and conflict-update
branches.
In `@src/lib/machine-api/x402.ts`:
- Around line 44-56: getPublicAccountingX402Config currently publishes fallback
chainId/network/payTo values that can disagree with the stricter validation used
by createAccountingX402Server, so update it to use the same strict
X402_ACCOUNTING_* validation or return no payment config unless all required
values are valid. Keep the existing getPublicAccountingX402Config symbol, and
make sure the emitted facilitatorUrl, network, chainId, and payTo fields only
reflect a complete, valid configuration rather than silently substituting 84532
or null.
🪄 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
Run ID: 9171899d-1c28-4c50-a93d-f2e6d165a0cb
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (15)
.env.exampledrizzle/0019_magenta_deathbird.sqldrizzle/meta/0019_snapshot.jsondrizzle/meta/_journal.jsonpackage.jsonsrc/app/.well-known/agents.json/route.tssrc/app/api/machine/reports/quarters/[id]/route.tssrc/db/schema.tssrc/lib/auth/permissions.tssrc/lib/machine-api/auth.tssrc/lib/machine-api/nonces.tssrc/lib/machine-api/rate-limit.tssrc/lib/machine-api/registry.tssrc/lib/machine-api/report-slices.tssrc/lib/machine-api/x402.ts
There was a problem hiding this comment.
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 `@src/lib/machine-api/report-slices.ts`:
- Around line 38-49: The helper pair `toNumber()` and `sumUsd()` currently turns
any malformed non-empty `usdAmount` into 0, which hides bad ledger data and
produces incorrect totals. Update `toNumber()` to reject unparsable values by
throwing an error (or move validation earlier before `sumUsd()` is called) so
invalid exports fail loudly instead of being treated as zero. Keep the behavior
for missing values explicit, but ensure `QuarterReportData["ledgerRows"]` with
bad `usdAmount` values cannot silently flow through `sumUsd()` and the report
generation path.
🪄 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
Run ID: 78508d62-37a9-4996-9f95-db916cbf110e
📒 Files selected for processing (9)
src/app/.well-known/agents.json/route.tssrc/app/api/machine/reports/quarters/[id]/route.tssrc/lib/auth/permissions.tssrc/lib/machine-api/auth.tssrc/lib/machine-api/nonces.tssrc/lib/machine-api/rate-limit.tssrc/lib/machine-api/registry.tssrc/lib/machine-api/report-slices.tssrc/lib/machine-api/x402.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- src/lib/machine-api/nonces.ts
- src/lib/machine-api/registry.ts
- src/lib/auth/permissions.ts
- src/lib/machine-api/auth.ts
- src/app/api/machine/reports/quarters/[id]/route.ts
This pull request introduces database schema changes to support machine API rate limiting and request nonce tracking, updates environment configuration options for x402 and delegation registry integration, and adds several new dependencies to the project. These changes lay the groundwork for improved API security, flexibility in blockchain integration, and support for new x402 features.
Database schema updates:
machine_api_rate_limitsandmachine_api_request_noncesto track API usage and prevent replay attacks, including relevant indexes and foreign key constraints.0019_magenta_deathbird.Configuration and integration enhancements:
.env.examplefor x402 accounting, delegation registry, and chain configuration, enabling more flexible deployment and integration with external services.Dependency management:
@x402/core,@x402/evm, and@x402/nextpackages to support x402 and EVM integration. [1] [2] [3]@signinwithethereum/siwe,ajv,jose,tweetnacl,require-from-string, and others. [1] [2] [3] [4] [5] [6] [7]Build and platform support:
libcconstraints for various platform-specific packages inpnpm-lock.yaml, improving compatibility across different Linux environments. [1] [2] [3] [4] [5]Let me know if you want more details on any specific change or how these updates might affect your development workflow!
Summary by CodeRabbit