Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ jobs:
- name: Build
run: npm run build

- name: Test
run: npm test

- name: Audit production dependencies
run: npm audit --omit=dev --audit-level=high

- name: Validate compose file
run: docker compose config

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:20-slim
FROM node:20-slim@sha256:2cf067cfed83d5ea958367df9f966191a942351a2df77d6f0193e162b5febfc0

ENV HOME=/home/node

Expand Down
51 changes: 34 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
TypeScript reverse proxy for paid HTTP APIs. This version uses the npm
TypeScript x402 SDK packages only:

- `@bankofai/x402-core@1.0.0`
- `@bankofai/x402-evm@1.0.0`
- `@bankofai/x402-tron@1.0.0`
- `@bankofai/x402-core@1.0.1`
- `@bankofai/x402-evm@1.0.1`
- `@bankofai/x402-tron@1.0.1`

Payment requirements are emitted as `scheme=exact`; supported stablecoins add
`extra.assetTransferMethod=permit2`.
Payment requirements support `scheme=exact` and TRON `scheme=exact_gasfree`.
Exact requirements add `extra.assetTransferMethod=permit2`; GasFree requirements
use the TRON GasFree relayer flow without Permit2 metadata.

## Install

Expand All @@ -20,7 +21,7 @@ npm run build
After installing the npm package globally, use the binary directly:

```bash
npm install -g @bankofai/x402-gateway
npm install -g @bankofai/x402-gateway@beta
x402-gateway --help
```

Expand Down Expand Up @@ -65,7 +66,7 @@ curl http://127.0.0.1:4020/__402/health
Paid provider path:

```bash
curl -i http://127.0.0.1:4020/providers/tron-nile-usdt/v1/ping
curl -i http://127.0.0.1:4020/providers/example-price-tron/v1/ping
```

If the endpoint has metering, the gateway returns `402 Payment Required` with a
Expand Down Expand Up @@ -117,7 +118,7 @@ deliberately public test deployment, set `X402_GATEWAY_ADMIN_ALLOW_PUBLIC=true`.
Provider files stay in YAML:

```yaml
name: tron-nile-usdt
name: example-price-tron
forward_url: ${X402_PROVIDER_FORWARD_URL}

routing:
Expand All @@ -128,7 +129,7 @@ routing:
value_from_env: X402_PROVIDER_API_TOKEN

operator:
network: tron-nile
network: tron:0xcd8690dc
currencies:
usd: ["USDT"]
recipient: ${X402_PROVIDER_RECIPIENT_TRON}
Expand All @@ -148,15 +149,17 @@ endpoints:
- price_usd: 0.002
```

`@bankofai/x402-*` 1.0.0 uses `scheme: exact` with
`extra.assetTransferMethod: permit2` in the payment requirement. Older provider
configs that say `exact_permit` are normalized at load time, but new provider
configs should use `protocol: exact` and `asset_transfer_method: permit2`.
`@bankofai/x402-*` 1.0.1 uses `scheme: exact` with
`extra.assetTransferMethod: permit2`, or TRON `scheme: exact_gasfree`. Older
provider configs that say `exact_permit` are normalized to `exact`. For GasFree,
set both `scheme` and `protocol` to `exact_gasfree`; the facilitator must support
GasFree for the selected TRON network and token.

Network aliases accepted:
Non-CAIP TRON aliases are rejected. Provider files must use canonical TRON
CAIP-2 IDs.

EVM convenience aliases accepted:

- `tron-mainnet` -> `tron:mainnet`
- `tron-nile` -> `tron:nile`
- `bsc-mainnet` -> `eip155:56`
- `bsc-testnet` -> `eip155:97`

Expand All @@ -167,6 +170,13 @@ X402_GATEWAY_PROVIDERS_DIR=providers
X402_GATEWAY_HOST=127.0.0.1
PORT=8080
X402_GATEWAY_ADMIN_TOKEN=<admin-token>
X402_GATEWAY_PUBLIC_BASE_URL=https://gateway.example.com
X402_GATEWAY_MAX_BODY_BYTES=1000000
X402_GATEWAY_MAX_RESPONSE_BYTES=10000000
X402_GATEWAY_FACILITATOR_TIMEOUT_MS=10000
X402_GATEWAY_UPSTREAM_TIMEOUT_MS=30000
X402_GATEWAY_MAX_CONCURRENT_REQUESTS=100
X402_GATEWAY_RATE_LIMIT_PER_MINUTE=300
X402_FACILITATOR_URL=https://facilitator-v2.bankofai.io
X402_FACILITATOR_API_KEY=<facilitator-api-key>
X402_PROVIDER_FORWARD_URL=<upstream-base-url>
Expand All @@ -177,6 +187,13 @@ X402_PROVIDER_API_TOKEN=<upstream-token>
Provider YAML may also use `operator.facilitator_api_key_env:
X402_FACILITATOR_API_KEY` so deployments can inject the facilitator API key via
environment variable without storing it in the mounted provider file.
When `facilitator_api_key_env` is configured, that named variable is required;
`check` and `start` fail instead of silently contacting the facilitator without
authentication.

`X402_GATEWAY_PUBLIC_BASE_URL` must be the externally reachable gateway origin.
It makes the challenge `resource.url` absolute, which is required when the
container's internal host or request path is not the public payment URL.

## Docker

Expand All @@ -187,7 +204,7 @@ docker run --rm -p 4020:8080 \
-v "$PWD/providers:/app/providers:ro" \
-e X402_GATEWAY_ADMIN_TOKEN=<admin-token> \
-e X402_FACILITATOR_API_KEY=<facilitator-api-key> \
bankofai/x402-gateway:v20260709182145
<gateway-image>
```

The Docker command binds `0.0.0.0:8080` explicitly; local CLI runs default to
Expand Down
5 changes: 4 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
services:
gateway:
image: ${X402_GATEWAY_IMAGE:-bankofai/x402-gateway:v20260709182145}
image: ${X402_GATEWAY_IMAGE:-bankofai/x402-gateway:test}
pull_policy: always
build:
context: .
dockerfile: Dockerfile
Expand All @@ -12,6 +13,8 @@ services:
environment:
X402_GATEWAY_PROVIDERS_DIR: ${X402_GATEWAY_PROVIDERS_DIR:-/app/providers}
X402_GATEWAY_PUBLIC_BASE_URL: ${X402_GATEWAY_PUBLIC_BASE_URL:-http://host.docker.internal:4020}
X402_GATEWAY_MAX_CONCURRENT_REQUESTS: ${X402_GATEWAY_MAX_CONCURRENT_REQUESTS:-100}
X402_GATEWAY_RATE_LIMIT_PER_MINUTE: ${X402_GATEWAY_RATE_LIMIT_PER_MINUTE:-300}
X402_FACILITATOR_URL: ${X402_FACILITATOR_URL:-https://facilitator.example.com}
X402_FACILITATOR_API_KEY: ${X402_FACILITATOR_API_KEY:-}
X402_PROVIDER_RECIPIENT_TRON: ${X402_PROVIDER_RECIPIENT_TRON:-}
Expand Down
10 changes: 5 additions & 5 deletions examples/provider.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: tron-nile-usdt
name: example-price-tron
title: "TRON Nile USDT Provider"
description: "TRON Nile provider protected by x402 exact Permit2 USDT payment"
category: data
Expand All @@ -8,8 +8,8 @@ forward_url: ${X402_PROVIDER_FORWARD_URL}
openapi_url: ${X402_PROVIDER_OPENAPI_URL}

display:
service_url: ${X402_GATEWAY_PUBLIC_BASE_URL}/providers/tron-nile-usdt
tags: ["tron-nile", "usdt", "x402"]
service_url: ${X402_GATEWAY_PUBLIC_BASE_URL}/providers/example-price-tron
tags: ["nile", "usdt", "x402"]

discovery:
use_case: "Use for validating TRON Nile USDT x402 payments."
Expand All @@ -18,7 +18,7 @@ discovery:
when_to_use:
- "Use when testing x402 exact Permit2 payments on TRON Nile."
request_examples:
- "GET /providers/tron-nile-usdt/v1/ping"
- "GET /providers/example-price-tron/v1/ping"

routing:
type: proxy
Expand All @@ -29,7 +29,7 @@ routing:
value_from_env: X402_PROVIDER_API_TOKEN

operator:
network: tron-nile
network: tron:0xcd8690dc
currencies:
usd: ["USDT"]
recipient: ${X402_PROVIDER_RECIPIENT_TRON}
Expand Down
75 changes: 27 additions & 48 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bankofai/x402-gateway",
"version": "1.0.0",
"version": "1.0.1-beta.7",
"private": false,
"type": "module",
"files": [
Expand All @@ -22,14 +22,17 @@
"node": ">=20"
},
"dependencies": {
"@bankofai/x402-core": "1.0.0",
"@bankofai/x402-evm": "1.0.0",
"@bankofai/x402-tron": "1.0.0",
"@bankofai/x402-core": "1.0.1",
"@bankofai/x402-evm": "1.0.1",
"@bankofai/x402-tron": "1.0.1",
"yaml": "^2.8.2"
},
"devDependencies": {
"@types/node": "^24.10.1",
"tsx": "^4.20.6",
"typescript": "^5.9.3"
},
"overrides": {
"ws": "8.21.0"
}
}
21 changes: 21 additions & 0 deletions providers/local-gasfree/provider.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: local-gasfree
title: Local GasFree E2E Provider
forward_url: http://host.docker.internal:44100
operator:
network: tron:0xcd8690dc
currencies:
usd: ["USDT"]
recipient: TTX1Us19zqsLXhY39PPR7KRUoMa93s3J3i
schemes: [exact, exact_gasfree]
scheme: exact
protocol: exact
asset_transfer_method: permit2
facilitator_url: https://tn-facilitator.bankofai.io
valid_for_seconds: 300
endpoints:
- method: GET
path: /v1/ping
metering:
dimensions:
- tiers:
- price_usd: 0.000001
Loading
Loading