跳到主要内容

地址转账监听 · 接口详情

交易查询模块

交易查询模块提供对链上交易数据的多维度查询能力,支持按地址查询历史列表、批量查询交易详情,以及跨链聚合查询。

接口列表

方法路径说明
POST/tx/api/v1/transfers/query按地址查询交易列表(游标分页)
POST/tx/api/v1/transfers/multi-chain多链多地址聚合查询
POST/tx/api/v1/transfers/details按交易哈希批量查询详情
GET/tx/api/v1/transfers/detail查询单笔交易详情 V2

地址交易查询

接口路径:POST /tx/api/v1/transfers/query

用途

按单个地址查询其在指定链上的历史交易列表,支持按交易类型、代币过滤,使用游标方式分页。

请求体字段说明

字段类型必填默认值说明
addressstring-待查询的钱包地址
chain_typestring-链类型,不填则跨链查询
chain_idinteger-链 ID
tx_typestring""交易类型过滤,空字符串表示不过滤
tokenstring-代币合约地址,用于过滤特定代币的转账
limitinteger20每次返回的最大记录数,范围 1~100
idinteger-游标 ID,用于分页续查

示例

# 基本查询
curl -X POST "$BASE_URL/tx/api/v1/transfers/query" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"chain_type": "ethereum",
"chain_id": 1,
"address": "0x1234567890abcdef1234567890abcdef12345678",
"limit": 20
}'

# 按代币过滤(查询 USDT 转账)
curl -X POST "$BASE_URL/tx/api/v1/transfers/query" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"chain_type": "ethereum",
"chain_id": 1,
"address": "0x1234...",
"token": "0xdAC17F958D2ee523a2206206994597C13D831ec7"
}'

响应

{
"code": 1,
"msg": "success",
"data": [
{
"chain_type": "ethereum",
"chain_id": 1,
"height": 21000000,
"tx_time": 1745000000,
"tx_hash": "0xabc123...",
"sender": "0x1234...",
"receiver": "0x5678...",
"amount": "1000000000000000000",
"symbol": "ETH",
"decimals": 18,
"tx_status": "success",
"transfer_type": "native",
"token_transfers": [],
"from_details": [],
"to_details": [],
"internal_transactions": []
}
]
}

注意:此接口成功时 code1,消息字段为 msg,与其他接口略有不同。


多地址聚合查询

接口路径:POST /tx/api/v1/transfers/multi-chain

用途

同时查询多条链、多个地址的交易记录,结果聚合后统一返回。

请求体字段说明

字段类型必填默认值说明
addressesarray-多链地址分组列表,至少一项,最多 10 组
addresses[].chain_typestring-链类型
addresses[].chain_idinteger-链 ID
addresses[].addressstring[]-该链下的地址数组,每组最多 20 个地址
limitinteger20返回的最大记录数,范围 1~100
idinteger-游标 ID,用于分页续查

示例

curl -X POST "$BASE_URL/tx/api/v1/transfers/multi-chain" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"addresses": [
{"chain_type": "ethereum", "chain_id": 1, "address": ["0xabc...001", "0xabc...002"]},
{"chain_type": "bsc", "chain_id": 56, "address": ["0xdef...003"]},
{"chain_type": "solana", "chain_id": 1, "address": ["SolanaAddress..."]}
],
"limit": 20
}'

响应

/tx/api/v1/transfers/query 格式相同,data 为聚合后的交易记录数组。


交易详情批量查询

接口路径:POST /tx/api/v1/transfers/details

用途

根据交易哈希批量查询交易详情。

请求体字段说明

字段类型必填说明
chain_typestring链类型
chain_idinteger链 ID
tx_hashstring 或 string[]单个交易哈希或哈希数组

示例

# 查询单笔交易
curl -X POST "$BASE_URL/tx/api/v1/transfers/details" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{"chain_type": "ethereum", "chain_id": 1, "tx_hash": "0xabc123..."}'

# 批量查询多笔交易
curl -X POST "$BASE_URL/tx/api/v1/transfers/details" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{"chain_type": "ethereum", "chain_id": 1, "tx_hash": ["0xabc123...", "0xdef456..."]}'

单笔交易详情查询

接口路径:GET /tx/api/v1/transfers/detail

用途

查询单笔交易的完整详情(V2 版本)。与 /tx/api/v1/transfers/details 的主要区别:

  • 采用 GET 请求,参数通过 Query String 传递
  • 支持 no_cache 参数强制回源:当数据库中无记录时,可按链实时拉取并写入缓存
  • 回源成功后会自动将数据写入数据库缓存
  • 返回的数据结构采用混合字段命名(历史兼容格式,部分字段为 camelCase)

请求参数

参数名位置类型必填说明
chain_typequerystring链类型
chain_idqueryinteger链 ID
tx_hashquerystring交易哈希,支持带或不带 0x 前缀
no_cachequerystringtrue1 时跳过本地缓存直接回源

示例

# 正常查询
curl "$BASE_URL/tx/api/v1/transfers/detail?chain_type=ethereum&chain_id=1&tx_hash=0xabc123..."

# 强制回源查询
curl "$BASE_URL/tx/api/v1/transfers/detail?chain_type=ethereum&chain_id=1&tx_hash=0xabc123...&no_cache=true"

响应(找到交易)

{
"code": 0,
"msg": "success",
"data": {
"chain_type": "ethereum",
"chain_id": 1,
"height": 21000000,
"txTime": 1745000000000,
"txhash": "0xabc123...",
"sender": "0x1234...",
"fee_payer": "0x1234...",
"receiver": "0x5678...",
"transfer_type": "native",
"gasLimit": "21000",
"gasUsed": "21000",
"gasPrice": "20000000000",
"max_fee_per_gas": "30000000000",
"max_priority_fee_per_gas": "1000000000",
"txFee": "420000000000000",
"nonce": "42",
"symbol": "ETH",
"decimals": 18,
"amount": "1000000000000000000",
"txStatus": "success",
"methodId": "",
"methodCall": "",
"l1OriginHash": "",
"fromDetails": [],
"toDetails": [],
"internalTransactionDetails": [],
"tokenTransferDetails": [],
"listenAddress": null,
"is_reorg_resend": false
}
}

响应(交易不存在)

{
"code": 0,
"msg": "success",
"data": null
}

交易数据结构详解

TransactionDetail(列表查询返回格式)

/tx/api/v1/transfers/query/tx/api/v1/transfers/multi-chain/tx/api/v1/transfers/details 接口返回的交易格式。

主体字段:

字段类型说明
chain_typestring归一化后的链类型,小写
chain_idinteger链 ID
heightinteger | null区块高度
tx_timeinteger | null交易时间,秒级 Unix 时间戳
tx_hashstring交易哈希
tx_versioninteger | null交易版本号(Solana 等使用)
senderstring | null发送方地址
fee_payerstring | null手续费支付方地址(Solana 场景)
receiverstring | null接收方地址
transfer_typestring | null交易类型,如 native(原生转账)、token(代币转账)
amountstring | null交易金额,字符串格式避免精度丢失
symbolstring | null主币或代币符号,如 ETHBNB
decimalsinteger | null精度位数,如 18
tx_statusstring | null交易状态:successfailedpending
tx_feestring | null交易手续费
gas_limitstring | nullGas 上限(EVM)
gas_usedstring | null实际消耗 Gas(EVM)
gas_pricestring | nullGas 单价(EVM)
max_fee_per_gasstring | nullEIP-1559 最大 Gas 单价
max_priority_fee_per_gasstring | nullEIP-1559 优先费单价
noncestring | null账户 Nonce(EVM)
method_idstring | null合约调用方法选择器(EVM)
method_callstring | null合约方法名或调用摘要
l1_origin_hashstring | null二层链对应的 L1 原始交易哈希
token_transfersarray代币转账明细列表
from_detailsarray输入地址明细(UTXO 模型)
to_detailsarray输出地址明细(UTXO 模型)
internal_transactionsarray内部交易或 Solana 指令明细

token_transfers(代币转账明细):

字段类型说明
from_addressstring | null代币转出地址
to_addressstring | null代币转入地址
token_contract_addressstring | null代币合约地址
symbolstring | null代币符号
amountstring | null转账数量
decimalsinteger | null代币精度
is_from_contractboolean转出方是否为合约地址
is_to_contractboolean转入方是否为合约地址
from_token_addressstring | null源 token 账户地址(Solana)
to_token_addressstring | null目标 token 账户地址(Solana)
mintstring | nullSolana Mint 地址
program_idstring | nullSolana Program ID

from_details(输入地址明细,UTXO 模型):

字段类型说明
addressstring | null输入地址
amountstring | null输入金额
is_contractboolean是否为合约地址
vin_indexstring | nullUTXO 输入索引
pre_vout_indexstring | null前序交易输出索引
ref_tx_hashstring | null前序引用交易哈希

to_details(输出地址明细,UTXO 模型):

字段类型说明
addressstring | null输出地址
amountstring | null输出金额
is_contractboolean是否为合约地址
vout_indexstring | nullUTXO 输出索引

internal_transactions(内部交易 / Solana 指令):

字段类型说明
from_addressstring | null内部调用发送方
to_addressstring | null内部调用接收方
amountstring | null内部调用金额
tx_statusstring | null内部调用状态
program_idstring | nullSolana Program ID
instr_indexinteger | nullSolana 指令索引
depthinteger | nullSolana 调用深度
instructionstring | nullSolana 指令名称
descriptionstring | null指令说明

V2 接口字段命名差异

/tx/api/v1/transfers/detail 接口返回的格式采用混合命名风格(历史兼容),与列表查询格式有所不同:

V2 格式字段对应列表格式字段主要差异
txhashtx_hash字段名不同
txTimetx_timecamelCase,且为毫秒级时间戳
txStatustx_statuscamelCase
txFeetx_feecamelCase
gasLimitgas_limitcamelCase
gasUsedgas_usedcamelCase
gasPricegas_pricecamelCase
methodIdmethod_idcamelCase
methodCallmethod_callcamelCase
l1OriginHashl1_origin_hashcamelCase
fromDetailsfrom_detailscamelCase
toDetailsto_detailscamelCase
internalTransactionDetailsinternal_transactions字段名不同
tokenTransferDetailstoken_transfers字段名不同

分页说明

交易列表查询使用游标(Cursor)分页而非传统的页码分页:

  1. 首次请求时不传 id 参数,获取最新的 N 条记录
  2. 如果返回记录数量等于 limit,说明可能还有更多数据
  3. 取返回数组中最后一条记录的数据库内部 id 传给下一次请求的 id 参数
  4. 继续请求,直到返回记录数量少于 limit 为止

注意:游标分页不支持跳页,只能顺序向前翻页。


金额处理建议

所有金额字段均以字符串形式返回,以避免大数精度问题。展示时需结合 decimals 字段进行换算:

function formatAmount(amount, decimals) {
if (!amount || decimals === null) return '0';
const bigAmount = BigInt(amount);
const divisor = BigInt(10 ** decimals);
const intPart = bigAmount / divisor;
const fracPart = bigAmount % divisor;
return `${intPart}.${fracPart.toString().padStart(decimals, '0')}`;
}

// 示例:1000000000000000000 (decimals=18) → "1.000000000000000000"
console.log(formatAmount('1000000000000000000', 18));

DEX Pool 最近交易接口

DEX Pool 模块用于维护需要监听的 Pool 地址,并提供最近交易查询。相关订阅和推送仍使用地址管理接口或 WebSocket subscribe。

当链上交易处理成功后,系统会用交易参与地址匹配已启用的 Pool 地址。命中后将完整 TransactionResult 写入该 Pool 对应的 Durable Object FIFO 队列,队列容量默认最多保留最近 100 条。

查询 Pool 最近交易

接口路径:GET /tx/api/v1/dex-pools/{poolAddress}/trades

用途

公开查询指定 Pool 的最近交易记录,不需要额外管理员鉴权。

Query 参数

字段类型必填默认值说明
chainTypestring链类型;兼容 chain_type
chainIdnumber链 ID;兼容 chain_id
limitnumber100返回最近交易条数,范围 1 到 100。

示例

curl "$BASE_URL/tx/api/v1/dex-pools/0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8/trades?chainType=evm&chainId=1&limit=50"

成功响应

{
"code": 0,
"message": "ok",
"data": {
"items": [
{
"chainType": "evm",
"chainId": 1,
"height": 19600000,
"txTime": 1710000000,
"txHash": "0x...",
"sender": "0xsender...",
"feePayer": "0xsender...",
"receiver": "0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8",
"transferType": "Token",
"gasLimit": "21000",
"gasUsed": "21000",
"gasPrice": "1000000000",
"maxFeePerGas": "",
"maxPriorityFeePerGas": "",
"txFee": "21000000000000",
"nonce": "1",
"symbol": "ETH",
"decimals": 18,
"amount": "0",
"txStatus": "success",
"methodId": "0xa9059cbb",
"methodCall": "0x...",
"fromDetails": [],
"toDetails": [],
"internalTransactionDetails": [],
"tokenTransferDetails": [
{
"from": "0xsender...",
"to": "0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8",
"isFromContract": false,
"isToContract": false,
"tokenContractAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"symbol": "USDC",
"amount": "1000000",
"decimals": 6
}
]
}
]
}
}

返回交易字段

data.itemsTransactionResult[],字段命名和 HTTP webhook 推送 body 中的数组元素一致,不使用 WebSocket 推送里的 chain_typetxhashtransfer_type 等字段名。可选字段值为 undefined 时 JSON 中会省略,值为 null 时会保留为 null

主要字段包括:chainTypechainIdheighttxTimetxHashsenderfeePayerreceivertransferTypegasLimitgasUsedgasPricemaxFeePerGasmaxPriorityFeePerGastxFeenoncesymboldecimalsamounttxStatusmethodIdmethodCallfromDetailstoDetailsinternalTransactionDetailstokenTransferDetails


地址管理模块

地址管理模块用于维护每个业务应用的监听地址名单。只有添加到名单中的地址,其链上交易才会被推送到对应应用的 WebSocket 订阅者或 Webhook 回调。

接口列表

方法路径说明
PATCH/tx/api/v1/addressesPatch 模式:同时增删地址
POST/tx/api/v1/addresses批量添加地址
POST/tx/api/v1/addresses/batch-delete批量移除地址
POST/tx/api/v1/addresses/contains查询地址是否存在于名单

公共鉴权说明

所有地址受保护接口都通过 X-API-Key 识别调用方。服务会基于该 Key 完成接口鉴权、业务归属识别和计费统计。

方式说明示例
请求头公共 API KeyX-API-Key: your-api-key

注意:公网接入只需传入 X-API-Key,不需要额外的应用标识请求头或查询参数。


添加监听地址接口

接口路径:POST /tx/api/v1/addresses

用途

向指定应用的监听地址名单中批量添加地址。支持同时为多条链添加地址。

链特殊处理行为

  • 其他非 EVM 链:会尝试将地址同步到平台内部监听组件;同步失败不会阻断本地入库。

请求体字段说明

字段类型必填说明
walletsarray按链分组的地址列表,至少一项
wallets[].chain_typestring链类型,如 ethereumsolanatron
wallets[].addressstring[]该链下的地址数组,至少一个地址

示例

# 添加以太坊地址
curl -X POST "$BASE_URL/tx/api/v1/addresses" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"wallets": [
{
"chain_type": "ethereum",
"address": ["0x1234...", "0xabcd..."]
}
]
}'

# 同时添加多链地址
curl -X POST "$BASE_URL/tx/api/v1/addresses" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"wallets": [
{"chain_type": "ethereum", "address": ["0x1234..."]},
{"chain_type": "tron", "address": ["TJDENsfBJs4RFETt1X1uyT9pBxdnAbFnbm"]},
{"chain_type": "solana", "address": ["SolanaAddress..."]}
]
}'

响应

{
"code": 0,
"message": "ok",
"data": "success"
}

移除监听地址

接口路径:POST /tx/api/v1/addresses/batch-delete

用途

从指定应用的监听地址名单中批量移除地址。移除后,该地址的新交易将不再推送给该应用。

请求体字段说明

/tx/api/v1/addresses 相同:wallets[].chain_type + wallets[].address

示例

curl -X POST "$BASE_URL/tx/api/v1/addresses/batch-delete" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"wallets": [
{"chain_type": "ethereum", "address": ["0x1234..."]}
]
}'

响应

{
"code": 0,
"message": "ok",
"data": "success"
}

地址名单 Patch 更新

接口路径:PATCH /tx/api/v1/addresses

用途

Patch 模式同时对某条链执行地址的增删操作,在一次请求中完成地址名单的部分更新。

请求体字段说明

字段类型必填默认值说明
chain_typestring-链类型,此接口一次只操作一条链
addsstring[][]要加入名单的地址列表
removesstring[][]要移出名单的地址列表

示例

curl -X PATCH "$BASE_URL/tx/api/v1/addresses" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"chain_type": "ethereum",
"adds": ["0xNewAddress001...", "0xNewAddress002..."],
"removes": ["0xOldAddress001..."]
}'

响应

{
"code": 0,
"message": "ok",
"data": "success"
}

地址存在性查询

接口路径:POST /tx/api/v1/addresses/contains

用途

查询某个地址是否已在指定链的地址名单中。

说明:当前版本此接口只验证地址在全局地址表中是否存在,不按 API Key 隔离过滤。

请求体字段说明

字段类型必填说明
chain_typestring链类型
addressstring待查询的地址

示例

curl -X POST "$BASE_URL/tx/api/v1/addresses/contains" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{"chain_type": "ethereum", "address": "0x1234..."}'

响应

{
"code": 0,
"message": "ok",
"data": {
"is_exist": true
}
}

地址管理最佳实践

地址格式规范:

  • EVM 链:使用 0x 开头的 Hex 格式地址,建议使用 EIP-55 checksum 格式
  • Solana:使用 Base58 格式地址
  • Tron:使用 Base58Check 格式(以 T 开头)
  • Bitcoin:使用标准 Bitcoin 地址格式(P2PKH、P2SH、Bech32 等)

地址名单与 WebSocket 订阅的关系:

  • 通过 /tx/api/v1/addresses 添加的地址会被持久化到数据库,应用重启后仍然有效
  • WebSocket 连接建立后,服务会自动监听该应用名单中的所有地址
  • 也可以在 WebSocket 连接建立后,通过 subscribe 命令动态追加监听,但这种方式仅对当前连接有效,断线后不会自动恢复

推荐使用 HTTP 接口管理地址名单,WebSocket 的 subscribe/unsubscribe 命令仅用于临时的细粒度控制。


WebSocket 实时推送

WebSocket 模块提供链上交易的实时推送能力。客户端建立 WebSocket 连接后,服务会在监听地址产生链上交易时立即推送消息。

连接端点:

GET /tx/api/v1/transaction/ws

建立连接

请求说明

WebSocket 握手需要以下请求头:

请求头类型必填说明
Upgradestring固定值 websocket
X-API-Keystring公共 API Key,用于鉴权和计费识别
X-ResendDurationstring历史消息重发时间窗口(秒),默认 180

注意:缺少 X-API-Key 时,连接请求会返回 400 或鉴权失败。

连接示例

# 使用 wscat
wscat -c "wss://api.gelabs.org/tx/api/v1/transaction/ws" \
-H "X-API-Key: your-api-key"

连接成功消息

连接建立后,服务端立即推送:

{
"id": "msg-uuid-001",
"time": 1745000000000,
"type": "connected",
"code": 0,
"data": {
"clientId": "client-abc123",
"appId": "current-business-identity"
},
"msg": "success"
}
字段说明
data.clientId当前连接在服务端的唯一标识,断线重连后会变化
data.appId当前连接绑定的调用方身份

连接失败

HTTP 状态码原因处理建议
400未提供 API Key确认已正确传入 X-API-Key
426Upgrade: websocket 头缺失确认使用 WebSocket 协议连接

消息格式

所有 WebSocket 消息均使用 JSON 格式,遵循以下统一结构:

{
"id": "消息唯一 ID",
"time": 1745000000000,
"type": "消息类型",
"code": 0,
"data": {},
"msg": "success"
}
字段类型说明
idstring消息唯一 ID,由发送方生成
timeinteger消息时间戳,毫秒级 Unix 时间戳
typestring消息类型,决定消息的业务含义
codeinteger业务状态码,0 表示成功,非 0 表示错误
dataobject | null消息业务数据
msgstring文本消息,成功时通常为 success

客户端命令

客户端可以向服务端发送以下命令。每条命令都需要提供唯一的 id 字段,服务端的回执会使用相同的 id 值。

ping(心跳)

发送心跳以保持连接活跃。

发送:

{
"id": "ping-001",
"type": "ping",
"data": {}
}

服务端回执:

{
"id": "ping-001",
"time": 1745000000000,
"type": "pong",
"code": 0,
"data": null,
"msg": "success"
}

subscribe(订阅地址)

订阅指定地址在指定链上的实时交易推送。

说明:通过此命令订阅的地址仅对当前连接有效,连接断开后不会保存。如需持久化地址订阅,请使用地址受保护接口提前将地址加入名单。

发送:

{
"id": "cmd-001",
"type": "subscribe",
"data": {
"address": "0x1234567890abcdef1234567890abcdef12345678",
"chain_type": "ethereum"
}
}

命令参数:

字段类型必填说明
data.addressstring待订阅的地址
data.chain_typestring链类型,服务端会转为小写

成功回执:

{
"id": "cmd-001",
"type": "subscribe",
"code": 0,
"data": {"API Key": "current-business-identity", "address": "0x1234...", "chain_type": "ethereum"},
"msg": "success"
}

错误回执:

{
"id": "cmd-001",
"type": "subscribe",
"code": 400,
"data": null,
"msg": "address and chain_type required"
}

unsubscribe(取消订阅)

取消对指定地址的实时交易订阅。

发送(取消特定链):

{
"id": "cmd-002",
"type": "unsubscribe",
"data": {
"address": "0x1234...",
"chain_type": "ethereum"
}
}

发送(取消所有链,省略 chain_type):

{
"id": "cmd-002",
"type": "unsubscribe",
"data": {
"address": "0x1234..."
}
}

命令参数:

字段类型必填说明
data.addressstring待取消订阅的地址
data.chain_typestring链类型,不填则取消该地址所有链的订阅

成功回执:

{
"id": "cmd-002",
"type": "unsubscribe",
"code": 0,
"data": {"address": "0x1234...", "chainType": "ethereum"},
"msg": "success"
}

取消所有链时,chainTypenull


getTxHash(查询交易详情)

通过 WebSocket 连接查询单笔交易的完整详情。

发送:

{
"id": "cmd-003",
"type": "getTxHash",
"data": {
"chain_type": "ethereum",
"chain_id": 1,
"txHash": "0xabc123..."
}
}

命令参数:

字段类型必填说明
data.chain_typestring链类型
data.chain_idinteger链 ID
data.txHashstring交易哈希
data.messageIdstring实时推送消息的唯一 ID,优先使用此字段

建议:优先使用 messageId(即推送消息的 id 字段值)查询,服务端可更精确地定位记录。

错误回执(交易不存在):

{
"id": "cmd-003",
"type": "getTxHash",
"code": 404,
"data": null,
"msg": "transaction not found"
}

transactionACK(确认已处理交易)

客户端收到 transaction 消息并成功处理后,应发送 ACK 确认。服务端收到 ACK 后会停止对该笔交易的重发逻辑。

重要:如果客户端长时间未发送 ACK,服务端可能在客户端重连后重新推送未确认的交易,以确保消息不丢失。

发送:

{
"id": "ack-001",
"type": "transactionACK",
"data": {
"chain_type": "ethereum",
"chain_id": 1,
"txHash": "0xabc123..."
}
}

成功回执:

{
"id": "ack-001",
"type": "transactionACK",
"code": 0,
"data": {"txHash": "0xabc123..."},
"msg": "success"
}

服务端推送消息

transaction(实时交易推送)

当监听地址产生链上交易时,服务端主动推送:

{
"id": "msg-tx-uuid-001",
"time": 1745000000000,
"type": "transaction",
"code": 0,
"data": {
"chain_type": "ethereum",
"chain_id": 1,
"height": 21000000,
"txTime": 1745000000000,
"txhash": "0xabc123...",
"sender": "0x1234...",
"fee_payer": "0x1234...",
"receiver": "0x5678...",
"transfer_type": "native",
"gasLimit": "21000",
"gasUsed": "21000",
"gasPrice": "20000000000",
"max_fee_per_gas": "30000000000",
"max_priority_fee_per_gas": "1000000000",
"txFee": "420000000000000",
"nonce": "42",
"symbol": "ETH",
"decimals": 18,
"amount": "1000000000000000000",
"txStatus": "success",
"methodId": "",
"methodCall": "",
"fromDetails": [],
"toDetails": [],
"internalTransactionDetails": null,
"tokenTransferDetails": null,
"listenAddress": ["0x1234..."],
"is_reorg_resend": false
},
"msg": "success"
}

交易消息关键字段说明:

字段类型说明
data.listenAddressstring[]命中监听规则的地址列表,一笔交易可能命中多个地址
data.is_reorg_resendboolean是否为链重组后的重发消息true 时需检查本地记录
data.tokenTransferDetailsarray | null代币转账明细列表,ERC-20 转账时包含具体转账信息
data.txTimeinteger交易时间戳,毫秒级

is_reorg_resend 说明:

当值为 true 时,表示此交易因**链重组(Reorg)**被重新推送。建议检查本地是否已存在该 txhash 的记录,并根据需要更新区块高度等信息。

ERC-20 代币转账消息示例:

{
"id": "msg-tx-002",
"type": "transaction",
"code": 0,
"data": {
"chain_type": "ethereum",
"txhash": "0xdef456...",
"transfer_type": "token",
"tokenTransferDetails": [
{
"from": "0x1234...",
"to": "0x5678...",
"isFromContract": false,
"isToContract": false,
"tokenContractAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"symbol": "USDT",
"amount": "1000000000",
"decimals": 6,
"fromTokenAddress": "",
"toTokenAddress": "",
"mint": "",
"programId": ""
}
],
"listenAddress": ["0x1234..."],
"is_reorg_resend": false
},
"msg": "success"
}

HTTP 辅助接口

WebSocket 连接状态查询

接口路径:GET /tx/api/v1/transaction/ws/status

查询指定应用的 WebSocket 连接状态。

curl "$BASE_URL/tx/api/v1/transaction/ws/status" \
-H "X-API-Key: your-api-key"

调用方身份由 X-API-Key 识别;公网接入不需要额外传入应用标识查询参数。

响应:

{
"code": 0,
"message": "ok",
"data": {
"appId": "current-business-identity",
"connectedClients": 2,
"clients": ["client-abc123", "client-def456"],
"details": [
{
"clientId": "client-abc123",
"connectedAt": 1745000000000,
"uptime": 3600,
"pendingTxCount": 0
}
]
}
}
字段类型说明
connectedClientsinteger当前在线客户端数量
details[].uptimeinteger已存活秒数
details[].pendingTxCountinteger尚未收到 ACK 的待确认交易数量

WebSocket 消息重放

接口路径:POST /tx/api/v1/transaction/ws/replay

手动重放一条漏发的交易消息。服务端会:

  1. 将消息幂等写入数据库
  2. 推送给当前在线的 WebSocket 订阅者
  3. 并行触发 Webhook 回调

请求体为一条完整的 WsTransactionMessage 格式消息(与服务端推送的 transaction 消息格式相同)。

响应:

{
"code": 0,
"message": "ok",
"data": {
"processed": true,
"txhash": "0xabc123..."
}
}

错误处理

WebSocket 命令的错误以相同的 JSON 格式通过 WebSocket 消息返回,code 字段为非 0

{
"id": "原始命令的 id",
"type": "命令类型",
"code": 400,
"data": null,
"msg": "错误描述"
}

常见错误汇总:

命令codemsg
subscribe400address and chain_type required
unsubscribe400address required
getTxHash400chain_type, chain_id, txHash required
getTxHash404transaction not found
transactionACK400chain_type and messageId/txHash required

最佳实践

心跳保活

建议每 30 秒发送一次 ping 命令:

setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ id: `ping-${Date.now()}`, type: 'ping', data: {} }));
}
}, 30000);

断线重连

function connect() {
const ws = new WebSocket(WS_URL, { headers: { 'X-API-Key': API_KEY } });
ws.on('close', () => {
console.log('连接断开,5 秒后重连...');
setTimeout(connect, 5000);
});
return ws;
}

ACK 策略

  • 及时 ACK:收到 transaction 消息并完成业务处理后,立即发送 transactionACK
  • 避免漏 ACK:如果业务处理耗时较长,可先 ACK 再异步处理
  • ACK 去重:业务层应以 txhash + chain_type + chain_id 为唯一键做幂等处理

地址订阅策略

方式持久性适用场景
HTTP 地址管理(/tx/api/v1/addresses持久,重启后有效常规业务地址的长期监听
WebSocket subscribe 命令临时,仅当前连接有效临时调试或动态细粒度控制

并发连接

同一个 API Key 对应的业务身份支持多个客户端同时连接,服务端会向所有在线连接广播交易消息。适用于多实例水平扩展或主备切换场景(需业务层做幂等处理)。