Skip to content
Merged
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
17 changes: 0 additions & 17 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,4 @@ HYPEREVM_RPC_URL=
MONAD_RPC_URL=
FOGO_RPC_URL=

# API Key Authentication (disabled by default)
# Set to "true" to require API keys for /build and /permit-params endpoints
# Note: /quote endpoint is exempt from rate limiting but still tracked in metrics
ENABLE_API_KEY=

# Comma-separated list of valid API keys (only used when ENABLE_API_KEY=true)
API_KEYS=

# Rate limiting configuration
# Time window in milliseconds (default: 60000 = 1 minute)
RATE_LIMIT_WINDOW_MS=
# Maximum requests per window per API key (default: 100)
RATE_LIMIT_MAX_REQUESTS=

# For e2e tests
API_KEY=

EXPECTED_SIGNER_ADDRESS=0xe8FDd6f6D10532bd49Cced5502CAa483E232E637
69 changes: 2 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ A RESTful API service that generates unsigned transactions for cross-chain swaps
- **Permit Support**: EIP-2612 permit signatures for gasless token approvals
- **Monochain Swaps**: Single-chain token swaps with DEX aggregation
- **Quote Signature Verification**: Cryptographic verification of all quotes
- **API Key Authentication**: Optional API key requirement with rate limiting
- **Prometheus Metrics**: Built-in metrics endpoint for monitoring

## Supported Chains
Expand Down Expand Up @@ -67,10 +66,6 @@ cp .env.example .env
| `AVALANCHE_RPC_URL` | Avalanche RPC endpoint | Public RPC |
| `BSC_RPC_URL` | BSC RPC endpoint | Public RPC |
| `OPTIMISM_RPC_URL` | Optimism RPC endpoint | Public RPC |
| `ENABLE_API_KEY` | Enable API key authentication | `false` |
| `API_KEYS` | Comma-separated list of valid API keys | - |
| `RATE_LIMIT_WINDOW_MS` | Rate limit time window in ms | `60000` |
| `RATE_LIMIT_MAX_REQUESTS` | Max requests per window per API key | `100` |

## Running the Server

Expand Down Expand Up @@ -138,63 +133,6 @@ Then run:
docker compose up -d
```

## API Key Authentication

The service supports optional API key authentication with per-key rate limiting. By default, authentication is disabled.

### Enabling API Key Authentication

1. Set `ENABLE_API_KEY=true` in your environment
2. Configure valid API keys as a comma-separated list in `API_KEYS`
3. Optionally configure rate limits with `RATE_LIMIT_WINDOW_MS` and `RATE_LIMIT_MAX_REQUESTS`

### Using API Keys

When authentication is enabled, include the `X-API-Key` header in your requests:

```bash
curl -X POST http://localhost:3000/build \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{ ... }'
```

### Rate Limiting

- Rate limiting applies to `/build`, `/permit-params`, and `/hypercore/permit-params` endpoints
- The `/quote` endpoint is exempt from rate limiting (but still tracked in metrics)
- `/health` and `/metrics` endpoints bypass authentication entirely
- Default: 100 requests per minute per API key

### Error Responses

**Missing API Key (when authentication is enabled):**
```json
{
"success": false,
"error": "API key required. Please provide X-API-Key header.",
"code": "UNAUTHORIZED"
}
```

**Invalid API Key:**
```json
{
"success": false,
"error": "Invalid API key",
"code": "UNAUTHORIZED"
}
```

**Rate Limit Exceeded:**
```json
{
"success": false,
"error": "Rate limit exceeded. Please try again later.",
"code": "RATE_LIMITED"
}
```

## API Endpoints

### Health Check
Expand Down Expand Up @@ -249,9 +187,8 @@ GET /metrics
Returns Prometheus-formatted metrics for monitoring. This endpoint is always accessible without authentication.

**Available Metrics:**
- `api_requests_total` - Total API requests by API key, endpoint, method, and status
- `api_requests_total` - Total API requests by endpoint, method, and status
- `api_request_duration_seconds` - Request duration histogram
- `rate_limit_exceeded_total` - Rate limit exceeded events by API key and endpoint
- Default Node.js metrics (CPU, memory, event loop, etc.)

**Example Prometheus scrape config:**
Expand Down Expand Up @@ -788,8 +725,6 @@ All endpoints return consistent error responses:
| `INVALID_SIGNATURE` | Quote signature verification failed |
| `BUILD_FAILED` | Transaction building failed |
| `INTERNAL_ERROR` | Unexpected server error |
| `UNAUTHORIZED` | Missing or invalid API key |
| `RATE_LIMITED` | Rate limit exceeded |

## Architecture

Expand All @@ -804,7 +739,7 @@ src/
│ ├── svm.ts # Solana transaction builder
│ └── sui.ts # Sui transaction builder
├── middleware/
│ └── apiKey.ts # API key auth and rate limiting
│ └── apiKey.ts # Request metrics tracking
└── utils/
├── signature.ts # Quote signature verification
└── hypercore.ts # HyperCore permit utilities
Expand Down
4 changes: 2 additions & 2 deletions bun.lock

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"typescript": "^5.0.0"
},
"dependencies": {
"@mayanfinance/swap-sdk": "^12.2.2",
"@mayanfinance/swap-sdk": "^13.2.0",
"@mysten/sui": "^1.17.0",
"@solana/spl-token": "^0.4.14",
"@solana/web3.js": "^1.98.0",
Expand Down
6 changes: 5 additions & 1 deletion src/builders/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export async function buildEvmTransaction(
}

// Non-gasless: Build transaction calldata
const options = {
usdcPermitSignature,
apiKey: process.env.SWAP_SDK_API_KEY,
}
const txPayload = await getSwapFromEvmTxPayload(
quote,
swapperAddress,
Expand All @@ -70,7 +74,7 @@ export async function buildEvmTransaction(
signerChainId,
payload,
permitParam,
usdcPermitSignature ? { usdcPermitSignature } : undefined
options,
);

// Resolve the 'to' address if it's a promise
Expand Down
4 changes: 3 additions & 1 deletion src/builders/sui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ export async function buildSuiTransaction(
const payload = customPayload ? hexToBuffer(customPayload) : undefined;

// Build composable options
const options: ComposableSuiMoveCallsOptions = {};
const options: ComposableSuiMoveCallsOptions = {
apiKey: process.env.SWAP_SDK_API_KEY,
};

if (usdcPermitSignature) {
options.usdcPermitSignature = usdcPermitSignature;
Expand Down
1 change: 1 addition & 0 deletions src/builders/svm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export async function buildSvmTransaction(
forceSkipCctpInstructions,
separateSwapTx,
skipProxyMayanInstructions,
apiKey: process.env.SWAP_SDK_API_KEY,
}
);

Expand Down
Loading
Loading