338 lines
5.5 KiB
Markdown
338 lines
5.5 KiB
Markdown
|
|
# WebSocket API Specification
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
This document specifies the WebSocket API for real-time blockchain data subscriptions, including new blocks, pending transactions, and address activity.
|
||
|
|
|
||
|
|
**Endpoint**: `wss://api.explorer.d-bis.org/ws`
|
||
|
|
|
||
|
|
## Connection Lifecycle
|
||
|
|
|
||
|
|
### Connection
|
||
|
|
|
||
|
|
**URL**: `wss://api.explorer.d-bis.org/ws?chain_id=138`
|
||
|
|
|
||
|
|
**Query Parameters**:
|
||
|
|
- `chain_id` (optional): Default chain ID for subscriptions
|
||
|
|
- `api_key` (optional): API key for authenticated connections
|
||
|
|
|
||
|
|
**Headers**:
|
||
|
|
- `Authorization: Bearer <token>` (optional)
|
||
|
|
|
||
|
|
### Authentication
|
||
|
|
|
||
|
|
**Methods**:
|
||
|
|
1. Query parameter: `?api_key=<key>`
|
||
|
|
2. Header: `Authorization: Bearer <token>`
|
||
|
|
3. Message: Send auth message after connection
|
||
|
|
|
||
|
|
**Auth Message**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "auth",
|
||
|
|
"api_key": "your-api-key"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "auth_success",
|
||
|
|
"user_id": "uuid",
|
||
|
|
"tier": "pro"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Heartbeat
|
||
|
|
|
||
|
|
**Purpose**: Keep connection alive and detect disconnections.
|
||
|
|
|
||
|
|
**Client Ping**: Send every 30 seconds
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "ping"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Server Pong**: Response within 1 second
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "pong",
|
||
|
|
"timestamp": 1640995200
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Timeout**: Connection closed if no pong received within 60 seconds
|
||
|
|
|
||
|
|
## Subscription Model
|
||
|
|
|
||
|
|
### Subscribe to New Blocks
|
||
|
|
|
||
|
|
**Request**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "subscribe",
|
||
|
|
"channel": "blocks",
|
||
|
|
"chain_id": 138,
|
||
|
|
"params": {
|
||
|
|
"include_transactions": false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "subscribed",
|
||
|
|
"subscription_id": "sub_123",
|
||
|
|
"channel": "blocks"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Updates**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "update",
|
||
|
|
"subscription_id": "sub_123",
|
||
|
|
"data": {
|
||
|
|
"number": 12345,
|
||
|
|
"hash": "0x...",
|
||
|
|
"timestamp": "2024-01-01T00:00:00Z",
|
||
|
|
"transaction_count": 100
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Subscribe to Pending Transactions
|
||
|
|
|
||
|
|
**Request**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "subscribe",
|
||
|
|
"channel": "pending_transactions",
|
||
|
|
"chain_id": 138,
|
||
|
|
"params": {
|
||
|
|
"from_address": "0x...", // Optional filter
|
||
|
|
"min_value": "1000000000000000000" // Optional filter
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Updates**: Transaction objects as they enter mempool
|
||
|
|
|
||
|
|
### Subscribe to Address Activity
|
||
|
|
|
||
|
|
**Request**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "subscribe",
|
||
|
|
"channel": "address",
|
||
|
|
"chain_id": 138,
|
||
|
|
"params": {
|
||
|
|
"address": "0x..."
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Updates**: Transactions involving the address
|
||
|
|
|
||
|
|
### Subscribe to Logs/Events
|
||
|
|
|
||
|
|
**Request**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "subscribe",
|
||
|
|
"channel": "logs",
|
||
|
|
"chain_id": 138,
|
||
|
|
"params": {
|
||
|
|
"address": "0x...",
|
||
|
|
"topics": ["0xddf252..."] // Event signatures
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Updates**: Matching log entries
|
||
|
|
|
||
|
|
### Unsubscribe
|
||
|
|
|
||
|
|
**Request**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "unsubscribe",
|
||
|
|
"subscription_id": "sub_123"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "unsubscribed",
|
||
|
|
"subscription_id": "sub_123"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Message Formats
|
||
|
|
|
||
|
|
### Client Messages
|
||
|
|
|
||
|
|
**Subscribe**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "subscribe",
|
||
|
|
"channel": "<channel_name>",
|
||
|
|
"chain_id": 138,
|
||
|
|
"params": { ... }
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Unsubscribe**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "unsubscribe",
|
||
|
|
"subscription_id": "<id>"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Ping**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "ping"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Server Messages
|
||
|
|
|
||
|
|
**Update**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "update",
|
||
|
|
"subscription_id": "<id>",
|
||
|
|
"data": { ... }
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Error**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "error",
|
||
|
|
"code": "invalid_subscription",
|
||
|
|
"message": "Invalid subscription parameters",
|
||
|
|
"subscription_id": "<id>"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Notification**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "notification",
|
||
|
|
"level": "info", // info, warning, error
|
||
|
|
"message": "Subscription limit reached"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Subscription Limits
|
||
|
|
|
||
|
|
**Per Connection**:
|
||
|
|
- Anonymous: 5 subscriptions
|
||
|
|
- Free API Key: 20 subscriptions
|
||
|
|
- Pro API Key: 100 subscriptions
|
||
|
|
- Enterprise: Unlimited
|
||
|
|
|
||
|
|
**Per Chain**:
|
||
|
|
- Limit subscriptions per chain to prevent abuse
|
||
|
|
|
||
|
|
## Reconnection Strategy
|
||
|
|
|
||
|
|
### Automatic Reconnection
|
||
|
|
|
||
|
|
**Strategy**: Exponential backoff
|
||
|
|
|
||
|
|
**Backoff Schedule**:
|
||
|
|
- Initial: 1 second
|
||
|
|
- Max: 60 seconds
|
||
|
|
- Multiplier: 2x
|
||
|
|
|
||
|
|
**Behavior**:
|
||
|
|
- Reconnect automatically
|
||
|
|
- Resubscribe to all active subscriptions
|
||
|
|
- Resume from last received update
|
||
|
|
|
||
|
|
### Manual Reconnection
|
||
|
|
|
||
|
|
**Steps**:
|
||
|
|
1. Close connection gracefully
|
||
|
|
2. Reconnect with same parameters
|
||
|
|
3. Resubscribe to desired channels
|
||
|
|
|
||
|
|
## Rate Limiting
|
||
|
|
|
||
|
|
**Limits**:
|
||
|
|
- Message rate: 10 messages/second per connection
|
||
|
|
- Subscription rate: 5 subscriptions/minute per connection
|
||
|
|
- Update rate: Throttled per subscription type
|
||
|
|
|
||
|
|
**Throttling**: Server may batch or skip updates if client cannot keep up
|
||
|
|
|
||
|
|
## Error Codes
|
||
|
|
|
||
|
|
- `invalid_message`: Malformed message
|
||
|
|
- `invalid_subscription`: Invalid subscription parameters
|
||
|
|
- `subscription_limit`: Too many subscriptions
|
||
|
|
- `rate_limit`: Rate limit exceeded
|
||
|
|
- `unauthorized`: Authentication required
|
||
|
|
- `chain_not_supported`: Chain ID not supported
|
||
|
|
- `internal_error`: Server error
|
||
|
|
|
||
|
|
## Security Considerations
|
||
|
|
|
||
|
|
### Connection Security
|
||
|
|
|
||
|
|
- WSS (WebSocket Secure) required
|
||
|
|
- TLS 1.2+ only
|
||
|
|
- Certificate validation
|
||
|
|
|
||
|
|
### Authentication
|
||
|
|
|
||
|
|
- API key validation
|
||
|
|
- User permission checks
|
||
|
|
- Subscription authorization
|
||
|
|
|
||
|
|
### Message Validation
|
||
|
|
|
||
|
|
- Validate all incoming messages
|
||
|
|
- Sanitize parameters
|
||
|
|
- Reject invalid requests
|
||
|
|
|
||
|
|
## Performance Considerations
|
||
|
|
|
||
|
|
### Message Batching
|
||
|
|
|
||
|
|
**Strategy**: Batch multiple updates into single message when possible
|
||
|
|
|
||
|
|
**Example**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "batch_update",
|
||
|
|
"updates": [
|
||
|
|
{ "subscription_id": "sub_1", "data": {...} },
|
||
|
|
{ "subscription_id": "sub_2", "data": {...} }
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Backpressure
|
||
|
|
|
||
|
|
**Strategy**: Drop updates if client cannot process them
|
||
|
|
|
||
|
|
**Indicators**:
|
||
|
|
- Client buffer full
|
||
|
|
- No ping/pong responses
|
||
|
|
- Slow message processing
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
- REST API: See `rest-api.md`
|
||
|
|
- GraphQL API: See `graphql-api.md`
|
||
|
|
- Mempool Service: See `../mempool/mempool-service.md`
|
||
|
|
|