# Pacifica Connector Implementation Guide

> 面向 `packages/connectors/pacifica`，统一 REST / WebSocket 接口签名、限流与错误处理实现，支撑 M1.6 Placement Throttling、Incremental Grid 等工作流。

---

## 1. 组件总览

| 模块 | 文件 | 说明 |
|------|------|------|
| REST Adapter | `packages/connectors/pacifica/src/adapter.ts` | 下单、撤单、批量撤单、账户/仓位查询 |
| WS Order Gateway | `packages/connectors/pacifica/src/wsOrderGateway.ts` | WebSocket RPC 下单、撤单、订阅 fills/orders |
| Signing | `packages/connectors/pacifica/src/signing.ts` | Ed25519 签名、header 生成、时钟偏移校验 |
| Rate Limiter | `packages/connectors/pacifica/src/rateLimiter.ts`（待实现） | 令牌桶（REST / WS 共享）；支持突发与排队 |
| Adapter Registry | `packages/connectors/pacifica/src/adapterRegistry.ts` | 多账户（maker/hedger/...）注册与生命周期管理 |

---

## 2. REST API 调用示例

### 2.1 创建订单（POST `/api/v1/orders`）

```ts
const payload = {
  symbol: "BTC",
  side: "buy",
  price: "12345.6",
  amount: "0.01",
  tif: "GTC",
  post_only: true,
  reduce_only: false,
  client_order_id: "grid-BTC--3-1696766400000-0"
};

const { headers, body } = signRequest({
  method: "POST",
  path: "/api/v1/orders",
  payload,
  apiKey: account.apiKey,
  secret: account.secret
});

const res = await fetch(`${baseUrl}/orders`, {
  method: "POST",
  headers,
  body: JSON.stringify(payload),
  signal: abortController.signal
});
```

- **签名要点**  
  - `timestamp = Date.now()`；`expiry_window = 5000ms`（可配置）。  
  - 签名字段：`{ method, path, queryString, body, timestamp, expiry_window }`。  
  - Header:  
    ```
    X-Pacific-Key: <apiKey>
    X-Pacific-Timestamp: <timestamp>
    X-Pacific-Expiry-Window: <expiry_window>
    X-Pacific-Signature: <hex/base64 signature>
    ```

### 2.2 撤单（DELETE `/api/v1/orders/{order_id}`）

```ts
const path = `/api/v1/orders/${orderId}`;
const { headers } = signRequest({ method: "DELETE", path, apiKey, secret });
await fetch(`${baseUrl}${path}`, { method: "DELETE", headers });
```

### 2.3 按 ClientId 撤单（DELETE `/api/v1/orders/by_client_id/{client_id}`）

同上，`path = /api/v1/orders/by_client_id/${clientId}`。  
注意 `clientId` 需 URI encode。

### 2.4 批量撤单（POST `/api/v1/orders/cancel_batch`）

```ts
const payload = { symbol: "BTC", order_ids: ["..."], client_order_ids: ["..."] };
const { headers, body } = signRequest({ method: "POST", path: "/api/v1/orders/cancel_batch", payload, apiKey, secret });
await fetch(`${baseUrl}/orders/cancel_batch`, { method: "POST", headers, body });
```

> **返回体统一处理**：解析 JSON；若 `error.code` 存在则抛出 `ConnectorError`，包含 `code` / `message` / `status`。

---

## 3. WebSocket 订单网关

### 3.1 建连与认证

```ts
const ws = new PacificaWebSocket({
  url: wsUrl,
  apiKey,
  secret,
  heartbeatIntervalMs: 30_000,
  reconnectBackoff: [1000, 2000, 5000, 10000]
});

await ws.connect();          // 建立 socket
await ws.waitForOpen();      // 等待 OPEN
await ws.authenticate();     // 发送 auth 消息，携带签名与时间戳
```

认证 payload 与 REST 类似：  
`{ type: "auth", account: apiKey, timestamp, expiry_window, signature }`

### 3.2 RPC 模式

WebSocket 使用 request/response（JSON-RPC 风格）：

```ts
const payload = {
  symbol: "BTC",
  side: "bid",                 // bid/ask
  price: "12345.6",
  amount: "0.01",
  tif: "GTC",
  client_order_id: "grid-BTC--3-1696766400000-0"
};
const res = await ws.sendRpc("create_order", payload, timeoutMs);
```

- **请求体**：与 REST 一致，字段名改为 `snake_case`（参考 Pacifica 官方文档）。  
- **响应**：如果成功，返回 `{ order_id: "..." }`；失败则包含 `error` 字段。  
- **错误处理**：  
  - `error.code = "post_only_cross"` → 调整价格重试；  
  - `error.code = "rate_limit_exceeded"` → 进入排队/回退。  
- `timeoutMs` 默认 15 秒，可按 Workstream 2 需求调整。

### 3.3 事件订阅

```ts
ws.subscribeAuthenticated(`orders.${apiKey}`);
ws.subscribeAuthenticated(`fills.${apiKey}`);
ws.on("message", handlePrivateMessage);
```

`handlePrivateMessage` 负责解析 channel、路由到 runner 的 `routeOrder` / `routeFill`。

### 3.4 断线与重连

- 心跳：客户端每 30 秒发送一次 `{ type: "ping" }`，收到 `{ type: "pong" }` 即认为连接有效。  
- 重连策略：指数退避（1s→2s→5s→10s），超过 5 次失败触发告警。  
- 重连后需重新 `authenticate`，并补发订阅。  
- 未完成的 RPC 需在重连后回调失败，交由上层重试。

---

## 4. Rate Limiter（令牌桶）

### 4.1 需求

- REST：每账户每 endpoint 需控制突发请求数，避免 429；默认 `burst = 10`、`refill = 10/秒`。  
- WS：Placement Throttling 2.0 需要可配置的令牌桶，支持 `burst`、`refillMs`、`maxQueueDepth`。

### 4.2 接口

```ts
interface RateLimiter {
  acquire(tokens?: number): Promise<void>;     // 获取令牌，若不足则等待
  tryAcquire(tokens?: number): boolean;        // 无等待的尝试
  pending(): number;                           // 当前排队任务数
}
```

- 实现放置在 `packages/connectors/pacifica/src/rateLimiter.ts`，供 REST/WS 共享。  
- 需暴露 metrics（待定）：`connector_rate_limiter_tokens`, `connector_rate_limiter_queue`.

### 4.3 集成点

- REST Adapter：在每个请求前调用 `rateLimiter.acquire()`；超时则抛出 `RateLimitError`。  
- WS Gateway：发送 RPC 前 acquire；Placement Throttling 2.0 会用批次调度采集数据。  
- 配置：  
  ```yaml
  execution:
    rest_rate_limiter:
      burst: 10
      refill_per_sec: 8
    ws_rate_limiter:
      burst: 6
      refill_per_sec: 5
      max_queue_depth: 50
  ```

---

## 5. 错误处理与重试

| 错误类型 | 行为 | 备注 |
|----------|------|------|
| 429 / `rate_limit_exceeded` | 指数退避重试（100ms → 200ms → ...，最多 5 次） | 超过次数后抛给上层触发降级 |
| 5xx / 网络错误 | 同上，若连续失败 3 次 → 触发告警 | |
| `post_only_cross` | 调整价格（spread + cushion）重试一次 | 超过次数则上抛 |
| 订单不存在 | 视为成功（撤单幂等） | |
| 签名错误 / 401 | 立即触发 Kill-Switch | 需检查时间同步 |

---

## 6. 指标与日志

- `connector_rest_latency_ms{method, path, status}`：REST RTT  
- `connector_ws_rpc_latency_ms{method, status}`：WS RPC RTT  
- `connector_rate_limit_retries_total{method}`：限流重试次数  
- `connector_ws_reconnects_total`：重连次数  
- Pino 日志字段：`component: 'PacificaConnector'`, `action: 'rest_request' | 'ws_rpc' | 'ws_reconnect'`

---

## 7. 测试清单

1. **签名单元测试**：`signing.ts` 生成的 header 与官方示例一致；过期签名被拒。  
2. **REST 集成测试**：Mock Pacifica API，对创建/撤单/批量撤单/错误码逐一验证。  
3. **WS 集成测试**：模拟 RPC 成功、post-only、限流、超时；验证重连逻辑与排队状态。  
4. **Rate Limiter 压测**：在 1s 内提交 50 个请求，确认突发被平滑、队列不溢出。  
5. **日志/指标**：保证上述 metric/log 在测试环境可以采集。

---

## 8. 未决事项

- 官方 API 若新增 `modify_order`，可直接替换 `cancel+place` 模式；否则需在 Workstream 1 中谨慎实现原子性。  
- 若 Pacifica 提供批量 create/cancel 接口，可追加专用适配器以减少 RTT。  
- 真实限流参数（burst/refill）需与官方确认并写入 README/CONFIG_REFERENCE。
