跳至主要内容

地址轉帳監聽 · 介面詳情

交易查詢模組

交易查詢模組提供對鏈上交易資料的多維度查詢能力,支援按地址查詢歷史列表、批量查詢交易詳情,以及跨鏈聚合查詢。

介面列表

方法路徑說明
POST/tx/api/v1/transfers/search按地址查詢交易列表(游標分頁)
POST/tx/api/v1/transfers/multi-chain多鏈多地址聚合查詢
POST/tx/api/v1/transactions/batch-get按交易雜湊批量查詢詳情
GET/tx/api/v1/transactions/{tx_hash}查詢單筆交易詳情 V2

地址交易查詢

介面路徑:POST /tx/api/v1/transfers/search

用途

按單個地址查詢其在指定鏈上的歷史交易列表,支援按交易類型、代幣過濾,使用游標方式分頁。

請求體欄位說明

欄位類型必填預設值說明
addressstring-待查詢的錢包地址
chain_typestring-鏈類型,不填則跨鏈查詢
chain_idinteger-鏈 ID
tx_typestring""交易類型過濾,空字串表示不過濾
tokenstring-代幣合約地址,用於過濾特定代幣的轉帳
limitinteger20每次返回的最大記錄數,範圍 1~100
idinteger-游標 ID,用於分頁續查

範例

# 基本查詢
curl -X POST "$BASE_URL/tx/api/v1/transfers/search" \
-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/search" \
-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/search 格式相同,data 為聚合後的交易記錄陣列。


交易詳情批量查詢

介面路徑:POST /tx/api/v1/transactions/batch-get

用途

根據交易雜湊批量查詢交易詳情。

請求體欄位說明

欄位類型必填說明
chain_typestring鏈類型
chain_idinteger鏈 ID
tx_hashstring 或 string[]單個交易雜湊或雜湊陣列

範例

# 查詢單筆交易
curl -X POST "$BASE_URL/tx/api/v1/transactions/batch-get" \
-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/transactions/batch-get" \
-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/transactions/{tx_hash}

用途

查詢單筆交易的完整詳情(V2 版本)。與 /tx/api/v1/transactions/batch-get 的主要區別:

  • 採用 GET 請求,參數透過 Query String 傳遞
  • 支援 no_cache 參數強制回源:當資料庫中無記錄時,可按鏈即時拉取並寫入快取
  • 回源成功後會自動將資料寫入資料庫快取
  • 返回的資料結構採用混合欄位命名(歷史相容格式,部分欄位為 camelCase)

請求參數

參數名位置類型必填說明
chain_typequerystring鏈類型
chain_idqueryinteger鏈 ID
tx_hashpathstring交易雜湊,支援帶或不帶 0x 前綴
no_cachequerystringtrue1 時跳過本地快取直接回源

範例

# 正常查詢
curl "$BASE_URL/tx/api/v1/transactions/0xabc123...?chain_type=ethereum&chain_id=1"

# 強制回源查詢
curl "$BASE_URL/tx/api/v1/transactions/0xabc123...?chain_type=ethereum&chain_id=1&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/search/tx/api/v1/transfers/multi-chain/tx/api/v1/transactions/batch-get 介面返回的交易格式。

主體欄位:

欄位類型說明
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/transactions/{tx_hash} 介面返回的格式採用混合命名風格(歷史相容),與列表查詢格式有所不同:

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 命令僅用於臨時的細粒度控制。


Webhook 回呼推送

Webhook 模組用於把監聽地址命中的鏈上交易主動推送到接入方提供的 HTTP 回呼地址。它適合服務端到服務端整合:接入方無需保持 WebSocket 長連線,只需提供一個可公網存取的 HTTPS 介面並配置到目前應用。

推送配置介面

方法路徑說明
GET/tx/api/v1/app/config查詢目前應用的推送配置
POST/tx/api/v1/app/config建立或替換目前應用的推送配置
PUT/tx/api/v1/app/config局部更新目前應用的推送配置
DELETE/tx/api/v1/app/config刪除目前應用的推送配置
GET/tx/api/v1/app/webhook/retry/status查詢 Webhook 持久化重試狀態
POST/tx/api/v1/app/webhook/retry手動觸發一次 Webhook 立即重試

所有配置介面均透過 X-API-Key 識別目前應用:

curl "$BASE_URL/tx/api/v1/app/config" \
-H "X-API-Key: your-api-key"

配置欄位

欄位類型必填說明
enable_wsboolean是否啟用 WebSocket 推送
enable_webhookboolean是否啟用 Webhook 推送
webhook_urlstring | null接入方回呼地址,必須是合法 URL;傳 null 表示清空
webhook_secretstring | null共享金鑰。服務端推送時會原樣放入請求頭 Sign
ws_ack_resend_interval_secondsintegerWebSocket ACK 重發間隔,單位秒
is_activeboolean是否啟用目前應用配置,僅 PUT 支援

注意GET /tx/api/v1/app/config 不會返回 webhook_secret。如果需要輪換金鑰,請透過 POSTPUT 重新設定。

開啟 Webhook

curl -X PUT "$BASE_URL/tx/api/v1/app/config" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"enable_webhook": true,
"webhook_url": "https://example.com/tx-history/webhook",
"webhook_secret": "replace-with-shared-secret"
}'

成功回應:

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

查詢配置回應範例:

{
"code": 0,
"message": "ok",
"data": {
"app_id": "current-business-identity",
"enable_ws": true,
"enable_webhook": true,
"webhook_url": "https://example.com/tx-history/webhook",
"ws_ack_resend_interval_seconds": 60,
"webhook_delivery_status": "active",
"webhook_retrying_since": null,
"webhook_last_failed_transaction_id": null,
"webhook_last_failure_reason": null,
"is_active": true,
"created_at": "2026-05-21T06:00:00.000Z",
"updated_at": "2026-05-21T06:10:00.000Z"
}
}

Webhook 投遞狀態欄位

欄位類型說明
webhook_delivery_statusstringWebhook 投遞狀態:active 正常推送,retrying 正在持久化重試,disabled 已因連續失敗自動關閉
webhook_retrying_sinceinteger | null進入重試狀態的秒級 Unix 時間戳
webhook_last_failed_transaction_idinteger | null超過 36 小時仍失敗時記錄的內部交易 ID
webhook_last_failure_reasonstring | null最近一次或最終失敗原因

關閉或清空 Webhook

curl -X PUT "$BASE_URL/tx/api/v1/app/config" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"enable_webhook": false,
"webhook_url": null
}'

回呼請求格式

當監聽地址命中新交易,且目前應用滿足 enable_webhook=truewebhook_url 已配置、is_active=true 時,服務端會向 webhook_url 傳送請求。

POST https://example.com/tx-history/webhook
Content-Type: application/json
Sign: replace-with-shared-secret
說明
請求方法固定為 POST
Content-Type固定為 application/json
Sign配置的 webhook_secret;未配置時為空字串
請求體TransactionResult[],即交易物件陣列
回應要求建議在業務接收成功後返回任意 2xx 狀態碼;回應體不做格式要求

說明:目前版本的 Sign 是共享金鑰透傳,不是 HMAC 摘要簽名。接入方應使用常量時間比較驗證該值,並只接受 HTTPS 回呼。

Webhook 持久化重試

當 Webhook 首次推送失敗時,服務會將本批交易寫入持久化重試佇列,並把目前應用標記為 webhook_delivery_status=retrying。處於重試狀態時,後續命中的交易不會繼續直接請求訂閱方服務,而是全部進入佇列。

重試由獨立排程器執行,間隔從 1s 開始漸進增長,最長到 36h。每次重試會從資料庫讀取待推送交易詳情,並按最多 100 筆交易組成一個 TransactionResult[] 批量 POST 到 webhook_url。只要訂閱方返回任意 2xx 狀態碼,本批即視為投遞成功。

如果某批訊息從首次失敗起超過 36h 仍無法成功投遞,服務會自動將 enable_webhook 更新為 false,並在應用配置中記錄失敗交易 ID 與最後失敗原因。訂閱方修復服務後,需要重新開啟 Webhook。

查詢重試狀態

介面路徑:GET /tx/api/v1/app/webhook/retry/status

curl "$BASE_URL/tx/api/v1/app/webhook/retry/status" \
-H "X-API-Key: your-api-key"

回應範例:

{
"code": 0,
"message": "ok",
"data": {
"app_id": "current-business-identity",
"enable_webhook": true,
"webhook_delivery_status": "retrying",
"webhook_retrying_since": 1779680000,
"webhook_last_failed_transaction_id": null,
"webhook_last_failure_reason": "Webhook HTTP 503: service unavailable",
"pending": 42,
"next_retry_at": 1779680060
}
}

手動觸發重試

介面路徑:POST /tx/api/v1/app/webhook/retry

訂閱方服務恢復後,可手動觸發一次立即重試,加快積壓訊息投遞:

curl -X POST "$BASE_URL/tx/api/v1/app/webhook/retry" \
-H "X-API-Key: your-api-key"

回應範例:

{
"code": 0,
"message": "ok",
"data": {
"code": 0,
"message": "ok",
"data": {
"attempted": 42,
"delivered": 42,
"failed": 0,
"finalFailed": false,
"nextRetryAt": null,
"pending": 0
}
}
}

回呼 Body 範例

Webhook 請求體沒有外層 codemessagedata 包裝,直接是交易陣列。同一次回呼可能包含一筆或多筆交易。

[
{
"chainType": "evm",
"chainId": 1,
"height": 21000000,
"txTime": 1745000000000,
"txHash": "0xabc123...",
"sender": "0x1234...",
"feePayer": "0x1234...",
"receiver": "0x5678...",
"transferType": "NativeCoin",
"gasLimit": "21000",
"gasUsed": "21000",
"gasPrice": "20000000000",
"maxFeePerGas": "30000000000",
"maxPriorityFeePerGas": "1000000000",
"txFee": "420000000000000",
"nonce": "42",
"symbol": "ETH",
"decimals": 18,
"amount": "1000000000000000000",
"txStatus": "success",
"methodId": "",
"methodCall": "",
"fromDetails": [],
"toDetails": [],
"internalTransactionDetails": [],
"tokenTransferDetails": []
}
]

ERC-20 / Token 轉帳範例:

[
{
"chainType": "evm",
"chainId": 1,
"height": 21000001,
"txTime": 1745000005000,
"txHash": "0xdef456...",
"sender": "0x1234...",
"feePayer": "0x1234...",
"receiver": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"transferType": "Token",
"gasLimit": "65000",
"gasUsed": "52000",
"gasPrice": "20000000000",
"maxFeePerGas": "30000000000",
"maxPriorityFeePerGas": "1000000000",
"txFee": "1040000000000000",
"nonce": "43",
"symbol": "ETH",
"decimals": 18,
"amount": "0",
"txStatus": "success",
"methodId": "0xa9059cbb",
"methodCall": "transfer(address,uint256)",
"fromDetails": [],
"toDetails": [],
"internalTransactionDetails": [],
"tokenTransferDetails": [
{
"from": "0x1234...",
"to": "0x5678...",
"isFromContract": false,
"isToContract": false,
"tokenContractAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"symbol": "USDT",
"amount": "1000000000",
"decimals": 6
}
]
}
]

Webhook 交易欄位

Webhook body 中的陣列元素為 TransactionResult,欄位採用 camelCase 命名,和 DEX Pool 最近交易介面data.items 元素一致,不使用 WebSocket 推送中的 chain_typetxhashtransfer_type 等欄位名。

欄位類型說明
chainTypestring鏈類型。內部規範值通常為 evmsvmtvmutxo
chainIdinteger鏈 ID
heightinteger區塊高度
txTimeinteger交易時間戳;通常為毫秒級 Unix 時間戳
txHashstring交易雜湊
senderstring傳送方地址
feePayerstring手續費支付方地址,部分鏈可能省略
receiverstring接收方地址或合約地址
transferTypestring交易類型,如 NativeCoinToken、合約呼叫等
gasLimitstringGas 上限
gasUsedstring實際消耗 Gas
gasPricestringGas 單價
maxFeePerGasstringEIP-1559 最大 Gas 單價
maxPriorityFeePerGasstringEIP-1559 優先費單價
txFeestring交易手續費
noncestring帳戶 Nonce
symbolstring主幣符號
decimalsinteger主幣精度
amountstring主交易金額,字串格式避免精度遺失
txStatusstring交易狀態,如 successfailedpending
bizStatusstring | null業務處理狀態,可能不存在
bizStatusReasonstring | null業務狀態說明,可能不存在
methodIdstring合約方法選擇器
methodCallstring合約方法名或呼叫摘要
txVersioninteger交易版本號,部分鏈可能存在
l1OriginHashstring二層鏈對應的 L1 原始交易雜湊,部分鏈可能存在
fromDetailsarrayUTXO 輸入地址明細
toDetailsarrayUTXO 輸出地址明細
internalTransactionDetailsarray內部交易或 Solana 指令明細
tokenTransferDetailsarray代幣轉帳明細

tokenTransferDetails

欄位類型說明
fromstring代幣轉出地址
tostring代幣轉入地址
isFromContractboolean轉出方是否為合約地址
isToContractboolean轉入方是否為合約地址
tokenContractAddressstring代幣合約地址
symbolstring代幣符號
amountstring轉帳數量,字串格式
decimalsinteger代幣精度
fromTokenAddressstring來源 token 帳戶地址,Solana 場景可能存在
toTokenAddressstring目標 token 帳戶地址,Solana 場景可能存在
mintstringSolana Mint 地址,可能存在
programIdstringSolana Program ID,可能存在

fromDetails / toDetails

欄位類型說明
addressstring輸入或輸出地址
amountstring金額,字串格式
isContractboolean是否為合約地址
vinIndexstringUTXO 輸入索引,fromDetails 中可能存在
preVoutIndexstring前序交易輸出索引,fromDetails 中可能存在
txHashstring前序引用交易雜湊,fromDetails 中可能存在
voutIndexstringUTXO 輸出索引,toDetails 中可能存在

internalTransactionDetails

欄位類型說明
fromstring內部呼叫傳送方
tostring內部呼叫接收方
amountstring內部呼叫金額
txStatusstring內部呼叫狀態
mintstringSolana Mint 地址,可能存在
ownerstringSolana Owner 地址,可能存在
programIdstringSolana Program ID,可能存在
isFromContractboolean傳送方是否為合約地址
isToContractboolean接收方是否為合約地址
instrIndexintegerSolana 外層指令索引
depthintegerSolana 呼叫深度
instructionstringSolana 指令名
descriptionstring指令說明

接入方處理建議

  • 鑑權:驗證請求頭 Sign 是否等於配置的 webhook_secret,未通過時返回 401403
  • 冪等:以 chainType + chainId + txHash 作為主冪等鍵;如果一筆交易內有多條代幣明細,可結合 tokenContractAddress + from + to + amount 做業務明細去重。
  • 快速回應:建議先持久化原始 body 或寫入佇列,再非同步執行業務處理,避免回呼介面耗時過長。
  • 金額處理:所有金額欄位均為字串,應結合對應 decimals 換算展示金額,避免使用 JavaScript number 直接承載大整數。
  • 異常重試:服務端提供 Webhook 持久化重試,單批最多 100 筆交易,最長重試視窗 36 小時;接入方仍應以 chainType + chainId + txHash 做冪等處理,並保留歷史查詢補償能力。

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 對應的業務身分支援多個客戶端同時連線,服務端會向所有在線連線廣播交易訊息。適用於多實例水平擴展或主備切換場景(需業務層做冪等處理)。