Skip to main content

选择传输方式

所有传输方式都采用相同的小费规则、相同的验证和相同的路由。传输方式只改变字节到达 Apex 端点的方式。 交易大小限制在各处都相同:legacy 和 v0 交易最大 1232 字节,交易 v1 最大 4096 字节。

构建已签名并带小费的交易

本页的示例在每种语言中共用一个辅助模块。它构建一笔带有计算预算和小费的 memo 交易,对其签名,并且可以确认签名。直接运行它会以 base64 形式输出一笔已签名交易,cURL 示例使用的就是这个输出。 首先设置环境变量:
对于 cURL 示例,请在每次发送前签名一笔新的交易:
交易只在其 blockhash 有效期间有效,大约 60 到 90 秒,因此请在发送前一刻签名。

JSON-RPC sendTransaction

向 Apex 端点的根路径发送 POST。这是标准的 Solana sendTransaction 格式,因此现有代码只需替换 URL 并添加 API 密钥即可迁移。
响应:
Apex 不会进行模拟或预检。skipPreflightpreflightCommitment 不起作用。如果您需要模拟,请在发送前先在您的常规 RPC 上调用 simulateTransaction

普通 HTTP 路由

这些路由与 JSON-RPC 位于同一主机和端口上,并省去了 JSON-RPC 封装。 在二进制路由上,选项以查询标志的形式传递:?mev_protect=1&max_retries=N 错误为带有 HTTP 状态码的 JSON:{"error": "<label>", "message": "..."}。参见错误与速率限制

POST /send

POST /send-bin

开销最低的 HTTP 路径:传入时无需 base64,也无需 JSON。请求体就是序列化后的交易,逐字节一致。

POST /send-batch

在一次请求中发送最多 16 笔相互独立的交易。请求体是一个帧序列:
每笔交易单独进行准入判定。批量不具备原子性:部分帧可能被接受,而其他帧被拒绝。如需要么全部成功、要么全部不执行,请使用捆绑包
只要请求本身有效,响应始终是 HTTP 200,每帧一个结果,按帧的顺序排列:

GET /ping

返回 pong。无需 API 密钥。用它在需要之前打开并预热 HTTP 连接,以及让空闲连接保持存活。参见最佳实践

CORS

每个 HTTP 响应都带有 Access-Control-Allow-Origin: *,并且 OPTIONS 预检请求会得到应答,因此上述所有路由都可以在浏览器代码中使用。在将密钥下发到前端之前,请参见浏览器注意事项

QUIC

QUIC 是最快的接入方式。您与 Apex 端点保持一个持久连接,通过由您的 API 密钥派生的客户端证书完成一次身份验证,并为每笔交易打开一个流。在预热的连接上,一次发送就是打开一个流并写入一次,只占用客户端几微秒的时间。 流分为两种:

Rust

apex-sender-client crate 实现了整个传输层:证书、保活、0-RTT 恢复和重连。该程序在两种流上各发送一笔交易。它使用与快速入门相同的 Cargo.toml

准入码

双向流会返回以下之一: 对该数据包而言,拒绝是最终结果。在响应到达之前发生的传输错误可以安全重试,因为端点按签名去重。

在其他语言中使用 QUIC

您可以使用任何支持客户端证书的 QUIC 库,在任意语言中实现该传输层。 连接
  • QUIC (RFC 9000),使用 TLS 1.3 和 ALPN solana-tpu
  • 服务器证书是自签名的占位证书。不要验证它。
  • 客户端必须出示由您的 API 密钥派生的证书
  • 每个 Apex 端点保持一个打开的连接。定期发送 QUIC PING(Rust 客户端每秒 ping 一次)。端点的空闲超时为 30 秒。已启用 0-RTT。
交易数据包 打开一个流,恰好写入一个数据包,然后结束该流:
这正是对 { wire_transaction: Vec<u8>, mev_protect: bool, max_retry: Option<u16> } 使用 bincode 默认的定长整数小端序选项进行编码的结果。整个数据包最大不得超过 4160 字节。 准入帧(仅限双向流)
在 Rust 中,wire::encode_packetwire::decode_admission 是这两种帧的参考实现。