# X402 Facilitator Protocol

## CLI Interface
1. Must be runnable through a CLI command, which can be parsed from 'run.sh'
2. Must output specific logs
3. Must exit with code 0 for success, 1 for failure
4. Must run as a server listening on a specified port

## Protocol Family Support
Facilitators must declare which protocol families they support in their test.config.json:
- **EVM**: Ethereum Virtual Machine compatible networks (Base, Ethereum, etc.)
- **SVM**: Solana Virtual Machine compatible networks (Solana, etc.)
- **Aptos**: Aptos blockchain networks (Mainnet, Testnet, etc.)

## X402 Version Support
Facilitators must declare which x402 protocol versions they support using the `x402Versions` field:
- **x402Versions**: Array of supported x402 protocol versions (e.g., [1, 2])

## Extensions Support
Facilitators must declare which protocol extensions they support using the `extensions` field:
- **extensions**: Array of supported extension names (e.g., ["bazaar"])

## EVM asset transfer method support
Facilitators that support the EVM protocol family must declare which **asset authorization** paths they implement using **`evm.assetTransferMethods`**:
- **eip3009**: EIP-3009 `transferWithAuthorization`
- **permit2**: Uniswap Permit2

Payment **schemes** (exact / upto / batch-settlement) are chosen per server endpoint; the facilitator is matched only on **`assetTransferMethod`**.

If the `evm` field is omitted, the facilitator is assumed to only support `["eip3009"]`.
The test suite uses this to skip scenarios where a server endpoint requires an asset transfer method the facilitator does not support.

Example configuration:
```json
{
  "name": "typescript",
  "type": "facilitator",
  "language": "typescript",
  "protocolFamilies": ["evm", "svm", "aptos"],
  "x402Versions": [2],
  "extensions": ["bazaar"],
  "evm": {
    "assetTransferMethods": ["eip3009", "permit2"]
  },
  "environment": {
    "required": ["PORT", "EVM_PRIVATE_KEY", "EVM_NETWORK"],
    "optional": ["SVM_PRIVATE_KEY", "SVM_NETWORK"]
  }
}
```

Python facilitator example (eip3009 only):
```json
{
  "name": "python",
  "type": "facilitator",
  "language": "python",
  "protocolFamilies": ["evm"],
  "x402Versions": [2],
  "extensions": ["bazaar"],
  "evm": {
    "assetTransferMethods": ["eip3009"]
  },
  "environment": {
    "required": ["PORT", "EVM_PRIVATE_KEY", "SVM_PRIVATE_KEY", "APTOS_PRIVATE_KEY"],
    "optional": ["EVM_NETWORK", "SVM_NETWORK", "APTOS_NETWORK"]
  }
}
```

## Environment Variables / CLI Arguments
The following parameters must be configurable:
- `PORT`: Port to listen on (default: 4022)
- `EVM_PRIVATE_KEY`: Private key for EVM operations
- `SVM_PRIVATE_KEY`: Private key for Solana operations
- `APTOS_PRIVATE_KEY`: Private key for Aptos operations (hex string without 0x prefix)
- `EVM_NETWORK`: EVM network to use (e.g., "eip155:84532" for Base Sepolia)
- `SVM_NETWORK`: Solana network to use (e.g., "solana:devnet")
- `APTOS_NETWORK`: Aptos network to use (e.g., "aptos:2" for Testnet)

## Required Endpoints

### POST /verify
- **Purpose**: Verify a payment against requirements
- **Request Body**:
  ```json
  {
    "x402Version": 2,
    "paymentPayload": {
      "x402Version": 2,
      "scheme": "exact",
      "network": "eip155:84532",
      "payload": { ... },
      "accepted": { ... }
    },
    "paymentRequirements": {
      "scheme": "exact",
      "network": "eip155:84532",
      "asset": "erc20:0x...",
      "amount": "1000000",
      "payTo": "0x...",
      "extra": { ... }
    }
  }
  ```
- **Success Response (200)**:
  ```json
  {
    "isValid": true,
    "payer": "0x..."
  }
  ```
- **Invalid Response (200)**:
  ```json
  {
    "isValid": false,
    "invalidReason": "Invalid signature",
    "payer": "0x..."
  }
  ```

### POST /settle
- **Purpose**: Settle a payment on-chain
- **Request Body**: Same as /verify
- **Success Response (200)**:
  ```json
  {
    "success": true,
    "transaction": "0x...",
    "network": "eip155:84532",
    "payer": "0x..."
  }
  ```
- **Failure Response (200)**:
  ```json
  {
    "success": false,
    "errorReason": "Settlement failed",
    "network": "eip155:84532"
  }
  ```

### GET /supported
- **Purpose**: Get supported payment kinds and extensions
- **Response (200)**:
  ```json
  {
    "kinds": [
      {
        "x402Version": 2,
        "scheme": "exact",
        "network": "eip155:84532",
        "extra": {}
      }
    ],
    "extensions": ["bazaar"]
  }
  ```

### GET /discovery/resources
- **Purpose**: List all discovered resources from bazaar extensions
- **Query Parameters**:
  - `limit` (optional): Maximum number of resources to return (default: 100)
  - `offset` (optional): Offset for pagination (default: 0)
- **Response (200)**:
  ```json
  {
    "x402Version": 1,
    "items": [
      {
        "resource": "https://api.example.com/endpoint",
        "type": "http",
        "x402Version": 2,
        "accepts": [...],
        "discoveryInfo": {...},
        "lastUpdated": "2024-01-01T00:00:00Z",
        "metadata": {}
      }
    ],
    "pagination": {
      "limit": 100,
      "offset": 0,
      "total": 1
    }
  }
  ```

### GET /health
- **Purpose**: Health check endpoint
- **Response (200)**:
  ```json
  {
    "status": "ok"
  }
  ```

### POST /close
- **Purpose**: Gracefully shut down the facilitator
- **Response**: Should terminate the process with exit code 0

## Startup Requirements
- Must log "Facilitator listening" when ready to accept requests
- Must handle graceful shutdown on SIGTERM/SIGINT
- Must validate required environment variables on startup
