Skip to content

Latest commit

 

History

History
136 lines (95 loc) · 6.3 KB

File metadata and controls

136 lines (95 loc) · 6.3 KB

API Guide

The API layer in Velo provides a lightweight service interface for agent-assisted and application-driven flows.

Runtime

The API is implemented with Fastify and is intended to expose payment-aware routes for cash-related requests.

Routes

Method Path Price (USDC) Description
GET /health Free Health check
GET /api/v1/openapi.json Free OpenAPI 3.1 specification
GET /api/v1/services Free Service catalog
GET /api/v1/cash/agents 0.001 Provider discovery
POST /api/v1/cash/request 0.01 Create a cash request
GET /api/v1/cash/request/:id Free Poll request status
POST /api/v1/cash/request/:id/release Free Release escrow (hand-off)
POST /api/v1/cash/request/:id/refund Free Refund escrow (after timeout)
GET /api/v1/reputation/:address 0.0005 On-chain reputation lookup
GET /api/v1/admin/status Admin auth System status & store metrics

Rate Limiting

All API endpoints are rate-limited per IP address to prevent abuse. The following limits are enforced:

Endpoint Limit Reason
GET /health 100 req / 1 min Infrastructure health check
GET /api/v1/openapi.json 60 req / 1 min Free specification endpoint
GET /api/v1/services 60 req / 1 min Free catalog endpoint
GET /api/v1/cash/agents 30 req / 1 min Paid discovery; limit abuse
POST /api/v1/cash/request 20 req / 1 min Paid escrow lock (costly)
GET /api/v1/cash/request/:id 60 req / 1 min Free polling
POST /api/v1/cash/request/:id/release 20 req / 1 min Free state transition
POST /api/v1/cash/request/:id/refund 10 req / 1 min Free refund (after timeout)
GET /api/v1/reputation/:address 30 req / 1 min Paid reputation lookup
GET /api/v1/admin/status 20 req / 1 min Admin status (requires API key)

When a client exceeds the limit, the API responds with 429 Too Many Requests and a Retry-After header indicating the number of seconds to wait before retrying.

Admin Authentication

Admin-only endpoints (e.g., GET /api/v1/admin/status) are protected by a shared API key.

Setup:

  1. Generate a secure key:
    openssl rand -hex 32
    
  2. Set it in your environment or .env file:
    ADMIN_API_KEY=<your-generated-key>
    
  3. Restart the API server.

Usage:

Include the key as a Bearer token in the Authorization header:

Authorization: Bearer <admin-api-key>

If the key is missing or invalid, the API responds with 401 Unauthorized or 403 Forbidden.

Refund Webhook

When a refund is processed via POST /api/v1/cash/request/:id/refund, the API can notify a Slack or Discord channel via a webhook URL.

Setup:

  1. Create an incoming webhook in your Slack workspace or Discord server.
  2. Set the URL in your environment or .env file:
    REFUND_WEBHOOK_URL=https://hooks.slack.com/services/.../.../...
    
  3. Restart the API server.

The webhook payload includes the trade ID, amount in USDC, buyer address, and seller address. The format auto-detects whether the URL points to Discord or Slack. Leave the variable empty (or unset) to disable webhook notifications entirely.

Payment Gate

The current implementation uses an x402-style challenge mechanism. When a valid payment header is not present, the API returns a challenge payload rather than allowing unrestricted access.

Configuration

The API reads environment variables from the local environment or .env file. The most important values include the port, merchant address, and network configuration.

Fee Sponsorship for Users Without XLM

The API supports fee-bump transactions to sponsor transaction fees for users who don't hold XLM. This allows users to interact with the escrow contract without needing to maintain an XLM balance for transaction fees.

How It Works

When a fee sponsor is configured, the API wraps user transactions in Stellar fee-bump transactions. The sponsor account pays the transaction fees while the user's account executes the contract operations. This is particularly useful for:

  • New users who haven't acquired XLM yet
  • Mobile-first experiences where onboarding complexity should be minimized
  • Agent-mediated flows where the end user may not have a funded wallet

Configuration

Set the SPONSOR_SECRET_KEY environment variable in apps/api/.env:

SPONSOR_SECRET_KEY=S...YOUR_SPONSOR_SECRET_KEY

The sponsor account must:

  • Have sufficient XLM balance to cover transaction fees
  • Be funded on the target network (testnet or mainnet)
  • Be properly secured (this is a signing key)

Behavior

  • When SPONSOR_SECRET_KEY is set: The API automatically wraps transactions in fee-bump transactions for both custodial and non-custodial flows
  • When SPONSOR_SECRET_KEY is unset: Users must pay their own transaction fees (standard behavior)
  • Works on both testnet and mainnet: Unlike the custodial BUYER_SECRET_KEY, fee sponsorship is not restricted to testnet

Fee Calculation

The fee-bump transaction fee is calculated as:

bump_fee = inner_transaction_fee + BASE_FEE

This ensures the sponsor pays both the inner transaction's resource fees and the fee-bump operation overhead.

Security Considerations

  • The sponsor account holds XLM and can sign transactions, so it must be properly secured
  • Consider using a dedicated sponsor account with limited XLM balance to limit exposure
  • Monitor sponsor account balance and transaction history for unusual activity
  • On mainnet, implement proper key management practices (HSM, key rotation, etc.)