diff --git a/docs/reference/api/discovery.md b/docs/reference/api/discovery.md index 4bfec26..852a949 100644 --- a/docs/reference/api/discovery.md +++ b/docs/reference/api/discovery.md @@ -1,8 +1,8 @@ # API reference — discovery and bazaar -The bazaar is the public directory of sellers registered with this facilitator. Agents use it to find paywalled resources; humans use the analytics endpoints to understand traffic. +The bazaar is the public directory of sellers registered with this Facilitator. Agents use it to find paywalled resources; humans use the analytics endpoints to understand traffic. -All endpoints under this group share a rate limit of **200 requests per minute per IP**. +Rate limits vary by endpoint: `GET /bazaar` (100/min), the `/bazaar/*` analytics endpoints (200/min each), `GET /discovery/resources` (no limit). See the [rate limits table](./overview.md#rate-limits). ## `GET /discovery/resources` diff --git a/docs/reference/api/overview.md b/docs/reference/api/overview.md index 79beff4..ceb1bdc 100644 --- a/docs/reference/api/overview.md +++ b/docs/reference/api/overview.md @@ -66,16 +66,19 @@ See the [error codes reference](../error-codes.md) for the canonical list. Rate limits are applied per IP address (read from `X-Forwarded-For` if present, else the connection IP). Limits are enforced by Redis keys with a rolling window. -| Endpoint | Limit | -| ----------------------------------- | --------------- | -| `POST /register` | 3 per hour | -| `POST /verify` | 1000 per minute | -| `POST /settle` | 500 per minute | -| `GET /discover` | 100 per minute | -| `GET /onramp` | 30 per minute | -| `GET /merchants/:id/mpp/config` | 100 per minute | -| `* /merchants/:id/mpp/charge` | 500 per minute | -| `/bazaar/*`, `/discovery/resources` | 200 per minute | +| Endpoint | Limit | +| -------------------------------------------------------------------------------------------------- | --------------- | +| `POST /register` | 3 per hour | +| `POST /verify` | 1000 per minute | +| `POST /settle` | 500 per minute | +| `GET /discover` | 100 per minute | +| `GET /onramp` | 30 per minute | +| `GET /merchants/:id/mpp/config` | 100 per minute | +| `* /merchants/:id/mpp/charge` | 500 per minute | +| `GET /bazaar` | 100 per minute | +| `GET /bazaar/stats` · `/routes` · `/resources` · `/sellers` · `/transactions` · `/cost-comparison` | 200 per minute | + +Every other endpoint — including `GET /supported`, `GET /.well-known/x402.json`, `GET /bridge/fees`, `GET /bridge/status/:id`, `GET /discovery/resources`, `GET /health`, and the `/.well-known/agent-skills/*` tree — is currently unrate-limited. When you exceed a limit you receive `429 Too Many Requests` with `error: "RATE_LIMIT"`. diff --git a/docs/reference/api/sellers.md b/docs/reference/api/sellers.md index dcb04b2..c414fbd 100644 --- a/docs/reference/api/sellers.md +++ b/docs/reference/api/sellers.md @@ -27,11 +27,11 @@ Register a seller wallet and receive a `merchantId` plus the Facilitator's recei ### Errors -| Status | `error` | Cause | -| ------ | ------------------------- | ---------------------------------------- | -| `400` | validation | Missing or invalid `wallet` / `network`. | -| `404` | `UnsupportedNetworkError` | `network` is not enabled on this relay. | -| `429` | `RATE_LIMIT` | Too many registrations from this IP. | +| Status | `error` | Cause | +| ------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `400` | validation | Missing or invalid `wallet` / `network`. | +| `400` | `UNSUPPORTED_NETWORK` | `network` is not enabled on this relay. Response `details` include `supportedNetworks` and an `example` payload to retry. | +| `429` | `RATE_LIMIT` | Too many registrations from this IP. | ### Example diff --git a/docs/reference/api/settlements.md b/docs/reference/api/settlements.md index 84c82ba..ab6bdb6 100644 --- a/docs/reference/api/settlements.md +++ b/docs/reference/api/settlements.md @@ -134,7 +134,7 @@ Shape depends on the workflow type. Quote the fee breakdown for a given route and amount. This is the authoritative source for gas allowances — the static schedule in [fees](../fees.md) is for reference only. -**Rate limit:** 200 requests per minute per IP. +**No rate limit.** ### Query parameters @@ -162,7 +162,6 @@ Quote the fee breakdown for a given route and amount. This is the authoritative | ------ | ---------------------- | --------------------------------- | | `400` | validation | Missing `from` / `to` / `amount`. | | `404` | `ROUTE_NOT_CONFIGURED` | No gas schedule for this pair. | -| `429` | `RATE_LIMIT` | | ### Example diff --git a/docs/reference/cli-scripts.md b/docs/reference/cli-scripts.md index 958eb00..57d8902 100644 --- a/docs/reference/cli-scripts.md +++ b/docs/reference/cli-scripts.md @@ -19,26 +19,31 @@ Run from the repo root. Run from `packages/relay`. -| Command | Purpose | -| --------------------- | ---------------------------------------------------------------------- | -| `bun run dev` | Start the HTTP server with hot reload. | -| `bun run start` | Start without watch (production-style). | -| `bun run build` | Type-check and compile. | -| `bun run db:generate` | Generate a new Drizzle migration from schema changes. | -| `bun run db:push` | Push the current schema to the database without migrations (dev only). | -| `bun run db:migrate` | Apply pending migrations. | -| `bun run test` | Run the relay test suite. | +| Command | Purpose | +| --------------------------- | ---------------------------------------------------------------------- | +| `bun run dev` | Start the HTTP server with hot reload. | +| `bun run build` | Bundle for production (`bun build` → `dist/`). | +| `bun run test` | Run the relay test suite. | +| `bun run lint` | ESLint on `src/`. | +| `bun run db:generate` | Generate a new Drizzle migration from schema changes. | +| `bun run db:push` | Push the current schema to the database without migrations (dev only). | +| `bun run db:migrate` | Apply pending migrations. | +| `bun run db:seed-dashboard` | Seed demo data for the bazaar dashboard. | + +To run the relay in production without watch, execute the built bundle directly: `bun dist/index.js` after `bun run build`. ## Worker scripts Run from `packages/worker`. -| Command | Purpose | -| --------------- | ------------------------------------------------------------------------------- | -| `bun run dev` | Start the worker, polling both `fast-settlement` and `cross-settlement` queues. | -| `bun run start` | Start without watch. | -| `bun run build` | Type-check and compile. | -| `bun run test` | Run the worker test suite (uses Temporal's test environment). | +| Command | Purpose | +| --------------- | --------------------------------------------------------------- | +| `bun run dev` | Start the worker via `tsx watch --env-file=.env src/worker.ts`. | +| `bun run build` | Compile TypeScript with `tsc`. | +| `bun run test` | Run the worker test suite (uses Temporal's test environment). | +| `bun run lint` | ESLint on `src/`. | + +To run the worker in production, execute the compiled output directly: `node dist/worker.js` after `bun run build`. ## Shared scripts diff --git a/docs/reference/error-codes.md b/docs/reference/error-codes.md index 786f1f6..b39e850 100644 --- a/docs/reference/error-codes.md +++ b/docs/reference/error-codes.md @@ -12,18 +12,17 @@ Every error returned by the relay uses the same JSON envelope: ## Canonical codes -| `error` | HTTP | Cause | Raised by | -| ---------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -| `SELLER_NOT_FOUND` | `404` | Unknown `merchantId`. | `/discover`, `/settle`, `/merchants/:id/mpp/config`, `/merchants/:id/mpp/charge`, `/bazaar/transactions?merchantId=…` | -| `INVALID_PAYMENT` | `400` | Payment validation failed (missing `merchantId`, zero amount, `payTo` mismatch, invalid signature, amount over per-tx limit). | `/verify`, `/settle` | -| `REPLAY_DETECTED` | `409` | Signature / nonce already settled. | `/settle` | -| `CIRCUIT_BREAKER` | `503` | Per-tx limit, daily volume limit, or global pause is active. | `/settle` | -| `RATE_LIMIT` | `429` | Per-IP rate limit exceeded on this endpoint. | All rate-limited endpoints | -| `ROUTE_NOT_CONFIGURED` | `404` | No gas allowance schedule for the `from` / `to` pair. | `/bridge/fees`, `/bazaar/cost-comparison` | -| `ERROR` | varies (defaults 500) | Custom operational error raised by a route handler. | Any | -| `INTERNAL_ERROR` | `500` | Unhandled exception. | Any — check logs / traces. | - -There is no `UnsupportedNetworkError` in the canonical list because it is raised during registration only; it surfaces with HTTP `404` and the same envelope. +| `error` | HTTP | Cause | Raised by | +| ---------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `SELLER_NOT_FOUND` | `404` | Unknown `merchantId`. | `/discover`, `/settle`, `/merchants/:id/mpp/config`, `/merchants/:id/mpp/charge`, `/bazaar/transactions?merchantId=…` | +| `INVALID_PAYMENT` | `400` | Payment validation failed (missing `merchantId`, zero amount, `payTo` mismatch, invalid signature, amount over per-tx limit). | `/verify`, `/settle` | +| `UNSUPPORTED_NETWORK` | `400` | Registration requested a CAIP-2 not enabled on this relay. Response `details` include `supportedNetworks` and an `example` payload. | `/register` | +| `REPLAY_DETECTED` | `409` | Signature / nonce already settled. | `/settle` | +| `CIRCUIT_BREAKER` | `503` | Per-tx limit, daily volume limit, or global pause is active. | `/settle` | +| `RATE_LIMIT` | `429` | Per-IP rate limit exceeded on this endpoint. | All rate-limited endpoints | +| `ROUTE_NOT_CONFIGURED` | `404` | No gas allowance schedule for the `from` / `to` pair. | `/bridge/fees`, `/bazaar/cost-comparison` | +| `ERROR` | varies (defaults 500) | Custom operational error raised by a route handler. | Any | +| `INTERNAL_ERROR` | `500` | Unhandled exception. | Any — check logs / traces. | ## Validation failures