# x402 Protocol Reference

## HTTP 402 Payment Flow

The x402 protocol enables HTTP payments using blockchain transactions. Sigwei implements this protocol to monetize API access.

### Standard Payment Flow

1.  **Initial Request**: Client requests PayGate URL without payment

    ```http
    GET /abc123
    ```
2.  **Payment Required**: Server responds with HTTP 402 and payment token

    ```http
    HTTP/1.1 402 Payment Required
    Content-Type: application/json

    {
      "x402": {
        "token": "payment_token_here",
        "amount": "0.01",
        "address": "0x742d35Cc6634C0532925a3b8c2414F4e456C10F4"
      }
    }
    ```
3. **Payment Execution**: Client creates blockchain payment using wallet
4.  **Payment Submission**: Client retries request with payment proof

    ```http
    GET /abc123
    X-Payment: <base64-encoded-payment-data>
    ```
5. **Payment Verification**: Server verifies signature and blockchain transaction
6. **Access Granted**: Client receives proxied response from target URL

### Authentication + Payment Flow

For PayGates with `requireAuth: true`:

1.  **Initial Request**: Client requests without authentication

    ```http
    GET /xyz789
    ```
2.  **Authentication Required**: Server returns 401

    ```http
    HTTP/1.1 401 Unauthorized
    {
      "error": {
        "type": "authentication",
        "code": "AUTH_REQUIRED",
        "message": "This route requires user authentication."
      }
    }
    ```
3.  **Authenticated Request**: Client includes JWT token

    ```http
    GET /xyz789
    Authorization: Bearer <jwt_token>
    ```
4. **Payment Required**: Server returns 402 with payment requirements
5.  **Final Request**: Client includes both auth and payment

    ```http
    GET /xyz789
    Authorization: Bearer <jwt_token>
    X-Payment: <payment_proof>
    ```

## x402 Headers

### Request Headers

```http
X-Payment: <base64-encoded-payment-data>
Authorization: Bearer <jwt_token>  // Optional, for auth-required PayGates
```

### Response Headers

```http
X-Payment-Response: <payment-confirmation-data>  // Optional
X402-Version: 1
Content-Type: application/json
```

## Payment Data Structure

The `X-Payment` header contains base64-encoded JSON with payment information:

```json
{
  "x402Version": 1,
  "scheme": "exact",
  "network": "base-sepolia",
  "payload": {
    "signature": "0x1234567890abcdef...",
    "authorization": {
      "from": "0x742d35cc6634c0532925a3b8c2414f4e456c10f4",
      "to": "0x9876543210fedcba...",
      "value": "1000000",  // Amount in USDC microdollars (1 USDC = 1,000,000)
      "validAfter": "0",
      "validBefore": "1735689600",  // Unix timestamp
      "nonce": "0xabcdef1234567890..."  // 32-byte random nonce
    }
  }
}
```

### Field Descriptions

| Field         | Description                                            |
| ------------- | ------------------------------------------------------ |
| `x402Version` | Protocol version (always 1)                            |
| `scheme`      | Payment scheme (always "exact")                        |
| `network`     | Blockchain network ("base-sepolia" or "base-mainnet")  |
| `signature`   | EIP-712 signature of the authorization                 |
| `from`        | Payer's wallet address                                 |
| `to`          | Payment recipient address (from PayGate configuration) |
| `value`       | Payment amount in USDC microdollars (6 decimals)       |
| `validAfter`  | Earliest valid timestamp (usually "0")                 |
| `validBefore` | Latest valid timestamp                                 |
| `nonce`       | Unique 32-byte identifier to prevent replay attacks    |

## EIP-712 Typed Data Signature

Payments use EIP-712 structured signatures for security:

```json
{
  "domain": {
    "name": "USD Coin",
    "version": "2",
    "chainId": 84532,  // Base Sepolia
    "verifyingContract": "0x036CbD53842c5426634e7929541eC2318f3dCF7e"  // USDC contract
  },
  "types": {
    "TransferWithAuthorization": [
      { "name": "from", "type": "address" },
      { "name": "to", "type": "address" },
      { "name": "value", "type": "uint256" },
      { "name": "validAfter", "type": "uint256" },
      { "name": "validBefore", "type": "uint256" },
      { "name": "nonce", "type": "bytes32" }
    ]
  },
  "primaryType": "TransferWithAuthorization",
  "message": {
    "from": "0x742d35cc6634c0532925a3b8c2414f4e456c10f4",
    "to": "0x9876543210fedcba...",
    "value": "1000000",
    "validAfter": "0",
    "validBefore": "1735689600",
    "nonce": "0xabcdef1234567890..."
  }
}
```

### Network Configurations

**Base Sepolia (Testnet)**

* Chain ID: `84532`
* USDC Contract: `0x036CbD53842c5426634e7929541eC2318f3dCF7e`
* RPC: `https://sepolia.base.org`

**Base Mainnet**

* Chain ID: `8453`
* USDC Contract: `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`
* RPC: `https://mainnet.base.org`

## JavaScript Implementation Example

```javascript
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { baseSepolia } from 'viem/chains';

async function createPayment(paymentRequest, privateKey) {
  const account = privateKeyToAccount(privateKey);
  const walletClient = createWalletClient({
    account,
    chain: baseSepolia,
    transport: http()
  });

  // Generate payment authorization
  const authorization = {
    from: account.address,
    to: paymentRequest.address,
    value: (parseFloat(paymentRequest.amount) * 1e6).toString(), // Convert to microdollars
    validAfter: "0",
    validBefore: Math.floor(Date.now() / 1000) + 3600, // 1 hour validity
    nonce: "0x" + Array.from(crypto.getRandomValues(new Uint8Array(32)))
      .map(b => b.toString(16).padStart(2, '0')).join('')
  };

  // Sign with EIP-712
  const signature = await walletClient.signTypedData({
    domain: {
      name: 'USD Coin',
      version: '2',
      chainId: 84532,
      verifyingContract: '0x036CbD53842c5426634e7929541eC2318f3dCF7e'
    },
    types: {
      TransferWithAuthorization: [
        { name: 'from', type: 'address' },
        { name: 'to', type: 'address' },
        { name: 'value', type: 'uint256' },
        { name: 'validAfter', type: 'uint256' },
        { name: 'validBefore', type: 'uint256' },
        { name: 'nonce', type: 'bytes32' }
      ]
    },
    primaryType: 'TransferWithAuthorization',
    message: authorization
  });

  // Create x402 payment data
  const paymentData = {
    x402Version: 1,
    scheme: "exact",
    network: "base-sepolia",
    payload: {
      signature: signature,
      authorization: authorization
    }
  };

  // Return base64-encoded payment header
  return btoa(JSON.stringify(paymentData));
}

// Usage with HTTP client
const paymentHeader = await createPayment(paymentRequest, "0xYOUR_PRIVATE_KEY");
const response = await fetch('/abc123', {
  headers: {
    'X-Payment': paymentHeader
  }
});
```

## Error Handling

Common payment-related errors:

```json
// Invalid signature
{
  "error": {
    "type": "payment",
    "code": "INVALID_SIGNATURE",
    "message": "Payment signature verification failed"
  }
}

// Insufficient amount
{
  "error": {
    "type": "payment", 
    "code": "INSUFFICIENT_AMOUNT",
    "message": "Payment amount is less than required"
  }
}

// Expired payment
{
  "error": {
    "type": "payment",
    "code": "PAYMENT_EXPIRED",
    "message": "Payment authorization has expired"
  }
}

// Already used nonce
{
  "error": {
    "type": "payment",
    "code": "NONCE_ALREADY_USED",
    "message": "Payment nonce has already been used"
  }
}
```

## Client Libraries

For automatic x402 payment handling, use compatible HTTP clients:

* **JavaScript**: `x402-axios` - Intercepts 402 responses and handles payments automatically
* **Python**: `x402-requests` - Python requests library with x402 support
* **Go**: Manual implementation or x402-compatible HTTP transport
* **cURL**: Manual payment header creation for testing

These libraries abstract away the complexity of payment creation and signature handling, making x402 integration seamless for developers.
