Skip to content

Permissionless-Software-Foundation/psf-bch-api-base

Repository files navigation

psf-bch-api-base

License js-standard-style

This project is a fork of psf-bch-api with one major change: paid access now uses the x402 protocol on the Base ecosystem, with pricing in USDC, instead of x402-bch on BCH.

The API surface remains focused on BCH infrastructure (BCH full node, Fulcrum, and SLP indexer), but monetization and payment verification are handled through x402-compatible middleware and facilitator endpoints.

What Changed In This Fork

  • Switched from x402-bch middleware to x402-express.
  • Added Base/EVM payment support (@x402/evm) and x402-axios client example.
  • Pricing is configured in X402_PRICE_USDC (USDC amount), not BCH satoshis.
  • x402 network is configured using CAIP-2 format (for example eip155:8453 for Base mainnet and eip155:84532 for Base Sepolia).
  • Facilitator auth headers are generated using Coinbase CDP JWT auth (FACILITATOR_KEY_ID and FACILITATOR_SECRET_KEY) when using CDP endpoints.

Architecture

The server is a Node.js + Express REST API following a Clean Architecture style, and it still depends on:

  • BCH full node JSON-RPC
  • Fulcrum API
  • SLP indexer API

The access-control layer now supports:

  • open access (no auth, no payment)
  • bearer-token auth
  • x402 paid access on Base + USDC
  • optional bearer bypass for trusted clients when x402 is enabled

Quick Start

  1. Install dependencies:
npm install
  1. Create a local env file:
cp .env-example .env
  1. Edit .env for your infrastructure and access-control mode.

  2. Start the server:

npm start

By default, the API runs on http://localhost:5942 and controllers are mounted under /v6.

Environment Variables

All configuration is loaded from environment variables (typically from .env).

Core Server and BCH Infrastructure

  • PORT (default: 5942)
  • NODE_ENV (default: development)
  • API_PREFIX (default: /v6)
  • LOG_LEVEL (default: info)
  • RPC_BASEURL (default: http://127.0.0.1:8332)
  • RPC_USERNAME
  • RPC_PASSWORD
  • RPC_TIMEOUT_MS (default: 15000)
  • RPC_REQUEST_ID_PREFIX (default: psf-bch-api)
  • FULCRUM_API
  • FULCRUM_TIMEOUT_MS (default: 15000)
  • SLP_INDEXER_API
  • SLP_INDEXER_TIMEOUT_MS (default: 15000)
  • REST_URL or LOCAL_RESTURL (default fallback: http://127.0.0.1:5942/v6/)
  • IPFS_GATEWAY (default: p2wdb-gateway-678.fullstack.cash)
  • SERVER_KEEPALIVE_TIMEOUT_MS (default: 3000)
  • SERVER_HEADERS_TIMEOUT_MS (default: 65000)
  • SERVER_REQUEST_TIMEOUT_MS (default: 120000)

x402 + Base + USDC Settings

  • X402_ENABLED (default: true)
  • SERVER_BASE_ADDRESS (EVM address receiving x402 settlements)
  • X402_PRICE_USDC (USDC charged per request)
  • x402_NETWORK (CAIP-2 chain ID; e.g. eip155:8453 or eip155:84532)
  • x402_FACILITATOR_URL (default: https://api.cdp.coinbase.com/platform/v2/x402)
  • FACILITATOR_KEY_ID (required for CDP facilitator auth)
  • FACILITATOR_SECRET_KEY (required for CDP facilitator auth)

Optional Bearer Auth

  • USE_BASIC_AUTH (default: false)
  • BASIC_AUTH_TOKEN

Access Control Modes

Behavior is controlled by X402_ENABLED and USE_BASIC_AUTH.

1) Open Access

X402_ENABLED=false
USE_BASIC_AUTH=false

No payment and no auth checks.

2) Bearer Auth Only

X402_ENABLED=false
USE_BASIC_AUTH=true
BASIC_AUTH_TOKEN=my-secret-token

Requests (except / and /health) must send:

Authorization: Bearer my-secret-token

3) x402 Payments on Base (USDC)

X402_ENABLED=true
USE_BASIC_AUTH=false
SERVER_BASE_ADDRESS=0xYourBaseAddress
X402_PRICE_USDC=0.1
x402_NETWORK=eip155:8453
x402_FACILITATOR_URL=https://api.cdp.coinbase.com/platform/v2/x402
FACILITATOR_KEY_ID=your_key_id
FACILITATOR_SECRET_KEY=your_secret

Protected endpoints return 402 Payment Required when no valid payment is attached. x402-capable clients can pay and retry automatically.

4) x402 + Bearer Bypass

When X402_ENABLED=true, the server also exposes machine-discovery endpoints:

  • /.well-known/x402 - x402-bch v2 payment discovery manifest
  • /openapi.json - OpenAPI 3 projection generated from apiDoc annotations
  • /swagger.json - Swagger 2.0 compatibility projection
  • /llms.txt - LLM-oriented markdown index of service metadata
  • /.well-known/agent.json - draft agent manifest describing API actions

When X402_ENABLED=false, these discovery endpoints return 404.

Combined: x402 + Bearer Token

You can enable both at the same time:

X402_ENABLED=true
USE_BASIC_AUTH=true
BASIC_AUTH_TOKEN=my-secret-token

Bearer-authenticated requests bypass payment; all others must pay via x402.

Client Example: Axios + x402

Use examples/01-x402-axios-client.js to test the payment flow end-to-end.

What it does:

  1. Calls a protected endpoint without payment and expects 402.
  2. Repeats the call using x402-axios + an EVM wallet and expects success.

Run it with an EVM private key:

PRIVATE_KEY=0x... node examples/01-x402-axios-client.js

The script is configured for Base mainnet by default (viem/chains base). You can switch it to Base Sepolia by using the commented testnet import in the file.

Coinbase CDP Credentials

When using Coinbase's hosted facilitator (https://api.cdp.coinbase.com/platform/v2/x402), you must provide:

  • FACILITATOR_KEY_ID
  • FACILITATOR_SECRET_KEY

These are CDP Secret API Key credentials from the Coinbase Developer Platform API Keys dashboard and are used to generate JWT auth headers for /verify and /settle.

Development

Common commands:

npm start
npm test
npm run test:integration
npm run docs

X402_ENABLED=false USE_BASIC_AUTH=false


5. Start the server:

`npm start`

The server will start on port `5942` by default (or whatever you set in `PORT`). API documentation is available at `http://localhost:5942/`.

### Generating API Docs

The API reference documentation is generated by [apiDoc](https://apidocjs.com/) from inline annotations in the source code. To regenerate:

`npm run docs`

The output is written to the `docs/` directory and served by the running server at its root URL.

To regenerate API docs plus discovery artifacts (`openapi.json`, `swagger.json`, `llms.txt`, and `agent.json` payload source):

`npm run docs:all`

This runs apiDoc first, then generates `docs/discovery-artifacts.json` from the same annotation source.

A live version can be found at [bch.fullstack.cash](https://bch.fullstack.cash/).

## Production (Docker)

A Docker setup is provided in the `production/docker/` directory for production deployments. The target OS is Ubuntu Linux.

1. Install [Docker and Docker Compose](https://docs.docker.com/engine/install/ubuntu/).

2. Navigate to the Docker directory:

`cd production/docker`

3. Create and configure the `.env` file. An example is provided:

`cp .env-example .env`

Edit `.env` to match your production infrastructure. Note that inside a Docker container, `localhost` refers to the container itself. Use `172.17.0.1` (the default Docker bridge gateway) to reach services running on the host machine:

RPC_BASEURL=http://172.17.0.1:8332 FULCRUM_API=http://172.17.0.1:3001/v1 SLP_INDEXER_API=http://172.17.0.1:5010


Set `APIDOC_URL` to the public base URL for your deployment (for example `https://api.example.com` or your subdomain). The container entrypoint applies this value to `apidoc.json` and the `apidoc` section of `package.json`, then runs `npm run docs` before starting the server so generated HTML matches each instance. The compose file mounts `./.env` to `/home/safeuser/psf-bch-api/.env` so it matches `dotenv.config()` in the app.

4. Build the Docker image:

`docker-compose build --no-cache`

5. Start the container:

`docker-compose up -d`

The container maps host port `5942` to container port `5942`. The `.env` file is mounted into the container as a volume, so you can update configuration without rebuilding.

To view logs:

`docker logs -f psf-bch-api`

To stop the container:

`docker-compose down`

A helper script `cleanup-images.sh` is provided to remove dangling Docker images after rebuilds.

## Testing

The project includes both unit tests and integration tests. Tests use [Mocha](https://mochajs.org/) as the test runner, [Chai](https://www.chaijs.com/) for assertions, and [Sinon](https://sinonjs.org/) for mocking. Code coverage is provided by [c8](https://github.com/bcoe/c8).

### Unit Tests

Unit tests are located in `test/unit/` and cover adapters, controllers, and use cases. They do not require any running infrastructure. To run:

`npm test`

This will first lint the code with [Standard](https://standardjs.com/), then execute all unit tests with code coverage.

To generate an HTML coverage report:

`npm run coverage`

The report is written to the `coverage/` directory.

### Integration Tests

Integration tests are located in `test/integration/` and require the back end infrastructure (full node, Fulcrum, SLP indexer) to be running. To run:

`npm run test:integration`

Integration tests have a 25-second timeout per test to accommodate network calls.

## Configuration Reference

All configuration values are read from environment variables (via the `.env` file). The complete list:

- `PORT` - Server listen port. Default: `5942`
- `NODE_ENV` - Environment (`development` or `production`). Default: `development`
- `API_PREFIX` - URL prefix for all REST endpoints. Default: `/v6`
- `LOG_LEVEL` - Winston logging level. Default: `info`
- `RPC_BASEURL` - Full node JSON-RPC URL. Default: `http://127.0.0.1:8332`
- `RPC_USERNAME` - Full node RPC username.
- `RPC_PASSWORD` - Full node RPC password.
- `RPC_TIMEOUT_MS` - Full node RPC request timeout in ms. Default: `15000`
- `FULCRUM_API` - Fulcrum indexer REST API URL.
- `FULCRUM_TIMEOUT_MS` - Fulcrum API request timeout in ms. Default: `15000`
- `SLP_INDEXER_API` - SLP Token Indexer REST API URL.
- `SLP_INDEXER_TIMEOUT_MS` - SLP Indexer API request timeout in ms. Default: `15000`
- `LOCAL_RESTURL` - Internal REST URL for wallet operations. Default: `http://127.0.0.1:5942/v6/`
- `IPFS_GATEWAY` - IPFS gateway hostname. Default: `p2wdb-gateway-678.fullstack.cash`
- `X402_ENABLED` - Enable x402-bch payment middleware. Default: `true`
- `SERVER_BCH_ADDRESS` - BCH address for x402 payments. Default: `bitcoincash:qqsrke9lh257tqen99dkyy2emh4uty0vky9y0z0lsr`
- `FACILITATOR_URL` - x402-bch facilitator service URL. Default: `http://localhost:4345/facilitator`
- `X402_PRICE_SAT` - Satoshis charged per API call via x402. Default: `200`
- `USE_BASIC_AUTH` - Enable Bearer token authentication. Default: `false`
- `BASIC_AUTH_TOKEN` - Expected Bearer token value.

## License

[MIT](./LICENSE.md)

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages