> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitflare.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Apex 身份验证

> 通过 HTTP 使用 x-api-key 请求头或 api-key 查询参数向 OrbitFlare Apex 进行身份验证， 或通过 QUIC 使用由您的密钥派生的客户端证书。

## 获取 API 密钥

Apex 目前处于测试阶段，仅限受邀用户使用。您的账户启用后，打开 [OrbitFlare 控制台](https://orbitflare.com/dashboard)，进入 **Dashboard > Apex** 创建密钥。每个密钥都属于一个等级，该等级决定您的小费下限和速率限制。

<Warning>
  请像对待密码一样对待密钥。任何持有密钥的人都可以占用您的速率限制来发送交易。但它无法动用您的资金：交易仍然由您自己的密钥对签名。
</Warning>

## HTTP 请求头或查询参数

通过 HTTP 时，密钥随每个请求一起发送。传递密钥有两种方式：

| 方式                      | 示例                                                    | 说明                            |
| ----------------------- | ----------------------------------------------------- | ----------------------------- |
| **`x-api-key` 请求头**（推荐） | `x-api-key: YOUR_API_KEY`                             | 避免密钥出现在 URL、日志和浏览器历史记录中       |
| **`api-key` 查询参数**      | `http://fra.apex.orbitflare.com?api-key=YOUR_API_KEY` | 适用于只接受 URL 的工具，例如 RPC URL 输入框 |

<CodeGroup>
  ```bash Header theme={null}
  curl -s http://fra.apex.orbitflare.com \
    -H "Content-Type: application/json" \
    -H "x-api-key: $APEX_API_KEY" \
    -d '{"jsonrpc":"2.0","id":1,"method":"getTipAccounts","params":[]}'
  ```

  ```bash Query parameter theme={null}
  curl -s "http://fra.apex.orbitflare.com?api-key=$APEX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","id":1,"method":"getTipAccounts","params":[]}'
  ```
</CodeGroup>

这两种方式同样适用于普通 HTTP 路由（`/send`、`/send-bin`、`/send-batch`、`/send-bundle`）。

<Warning>
  与其他 Solana 发送服务一样，HTTP 路由未加密：网络路径上的任何人都可以读取您的 API 密钥和交易。建议优先使用 QUIC（密钥不会离开您的机器），或仅在可信网络中使用 HTTP。如果您怀疑密钥已泄露，请在控制台中轮换密钥。
</Warning>

`getTipAccounts`、`getVersion`、`health` 和 `GET /ping` 无需密钥。所有提交交易的操作都需要密钥。

密钥缺失或无效时，返回 JSON-RPC 错误 `-32001`，在普通路由上则返回 HTTP `401`。参见[错误与速率限制](/cn/apex/errors-and-rate-limits)。

## QUIC 客户端证书

在 QUIC 上不会对每个请求单独进行身份验证，并且**您的 API 密钥永远不会经过网络传输**。流程如下：

1. 您的客户端从 API 密钥派生出一个 ed25519 密钥对。
2. 在 QUIC 握手期间，它在 TLS 客户端证书中出示该公钥。
3. Apex 端点将该公钥映射到您的账户。此后该连接上的每个流都归属于您。

Rust crate [`apex-sender-client`](/cn/apex/rust-client) 会为您完成这一切。对于其他语言，派生方式如下：

```text theme={null}
seed    = HKDF-SHA256(ikm = api_key bytes, salt = "apex-sender", info = "apex-sender-client-cert", L = 32)
keypair = ed25519 keypair from seed
```

将公钥封装进 Solana 的占位 X.509 证书，即验证者用于 TPU QUIC 的同一种格式（`solana-tls-utils` crate 中的 `new_dummy_x509_certificate`）。端点只检查证书中的密钥，其他证书字段会被忽略。

**测试向量：** API 密钥 `test-api-key` 派生出的公钥为 `ANPhYB8kmb2puLauuJKSX5orMk3rVT87gBWWy94F68hU`。

如果握手失败，端点会以应用层错误码关闭连接：

| 关闭码 | 含义                                            |
| --- | --------------------------------------------- |
| `1` | 未出示客户端证书                                      |
| `2` | 证书中的密钥与任何 API 密钥都不匹配                          |
| `3` | 连接数过多：每个 API 密钥最多 128 个连接，每个地址最多 64 个。一个连接就足够 |

### 检查您派生的密钥

控制台会在每个 API 密钥旁显示对应的客户端公钥。如果您的 QUIC 连接被拒绝，请比较这两者。使用 Rust crate：

```rust theme={null}
use apex_sender_client::client_pubkey;

fn main() {
    let api_key = std::env::var("APEX_API_KEY").expect("APEX_API_KEY is required");
    // Prints the certificate key only, never the API key itself.
    println!("{}", client_pubkey(&api_key));
}
```

两者不一致说明密钥复制有误。

## 浏览器

每个 HTTP 响应都带有 `Access-Control-Allow-Origin: *`，并且 `OPTIONS` 预检请求会得到应答，因此您可以从浏览器代码中调用 Apex 端点。

<Warning>
  嵌入在公开网页中的 API 密钥对每位访问者都是可见的。对于公开的前端，请通过您自己的后端发送，或者使用一个您随时准备轮换的密钥。
</Warning>

Apex 端点通过 80 端口上的明文 HTTP 提供服务。通过 HTTPS 加载的页面会受到浏览器混合内容规则的约束，因此请在您计划上线的环境中进行测试。
