OceanAltOceanAlt

開發者 · 免費 API

給你的 Agent / 系統裝上付款前風險檢查

同一套我們自己在用的地址風險判斷,開放成免費 API:免註冊、支持跨域(CORS)、返回可核驗證據。直接嵌進你的系統或 AI Agent 的結算前流程——付款前先問一句「這個對手方安不安全」。

免註冊 · 免費

直接調用,無需 API key(每分鐘 60 次,每月 2,000 次,按來源 IP 計量)。

留個郵箱:每月 5,000 次高速

自助拿一把密鑰,請求頭帶 Authorization: Bearer:每分鐘 180 次。用完只降速到每分鐘 60 次,接口不會停。

註冊表 Agent:每月 50,000 次

已在註冊表登記過 Agent 的,直接用它的憑證(x-agent-id + x-agent-secret):每分鐘 300 次,額度按主體聚合。不用再申請第二把鑰匙。

支持跨域 CORS

瀏覽器 / agent / 服務端都能直接請求。

給證據,不只給分

命中哪個名單、鏈上路徑,都能點開核驗。

想提額度? 留個郵箱自助拿一把密鑰 → 密鑰只在郵件裡出現一次,我們這邊只存哈希值。

機器可讀規範

OpenAPI 3.1 —— 讓 Agent 自動發現參數和返回結構,不用讀人話去猜。

/openapi.json

輸出語言

人讀字段默認英文,加 lang=zh 給中文。另返回 signal_keys(與語言無關的信號鍵),Agent 請按它做判斷,別去解析人話。

GET / POST/api/decide

付款前調一次(決策)

你的 agent 正要付一筆——先問一句能不能付。返回機器可執行決策 allow / review / decline + 可核證據 + retry 語義;allow/review 還帶一張可核驗的結算憑證(綁到你的結算上)。免費、無需 key。付費帶結算版見 /api/x402/decision。

參數

  • to 必填將要付款的收款地址:0x 以太坊系 / T 波場 TRON
  • amountUsdc 可選金額(USDC,選填,僅記錄)
  • purpose 可選用途備註(選填)
  • network 可選0x 地址所在 EVM 鏈(同 /api/risk)
  • task 可選付款意圖:這筆錢是為了什麼(選填;帶了任一意圖字段就多做一層意圖檢查,空的會被要求補充)
  • reasoning 可選付款意圖:為什麼付給這個收款方(選填)
  • maxAmountUsdc 可選調用方聲明的單筆上限(USDC,選填);實付超過即 decline

示例

curl "https://oceanalt.com/api/decide?to=0x8589427373D6D84E98730D7795D8f6f8731FDA16"

返回

{
  "decision": "decline",         // allow | review | decline
  "allow": false,                // one-line gate: if (!allow) halt()
  "address": "0x8589...FDA16",
  "verdict": "risky",
  "risk": 100,
  "evidence": [ { "label": "hit mixer list", "detail": "Tornado Cash", "url": "..." } ],
  "retry_hint": "Do not retry; use a different payee.",
  "disclaimer": "OceanAlt has denied this service request. ...",   // on decline
  "intelligence": { "sources": [ /* OceanAlt AML + external adapter status */ ] },
  "tier": "free",
  "upgrade": "POST /api/x402/decision — same decision, plus settles on x402."
  // on allow/review: also "settlement": { "attestation_id", "verify_url", ... }
}
GET / POST/api/payee/decide

收款方也要過閘(收款方三態決策)

另一半:付款 Agent 結算前先問收款方接不接這筆錢。返回 accept / decline / hold_request_info / not_ready + 原因碼 + requested_fields + 證據 + 簽名。全部是規則:收款方就緒度來自注冊表四級階梯,付款方地址反向篩查,金額區間 / 用途 / KYA 要求來自收款方自己設的策略。免費、無需 key。

參數

  • payee 必填註冊表裡的收款方 sid(見 /registry.json)
  • payer.address 可選付款方地址(會反向做 AML 篩查)
  • payer.agentId 可選付款 Agent 的 KYA 標識(收款方要求 KYA 時必填)
  • amountUsdc 可選金額(收款方設了區間時必填)
  • purpose 可選用途(收款方設了用途白名單時必填)

示例

curl -X POST "https://oceanalt.com/api/payee/decide" -H "content-type: application/json" -d '{"payee":"oceanalt-200lab-premium","payer":{"address":"0x8589427373D6D84E98730D7795D8f6f8731FDA16"},"amountUsdc":5,"purpose":"api-call"}'

返回

{
  "status": "decline",           // accept | decline | hold_request_info | not_ready
  "final": true,
  "reasons": [ "PAYER_SANCTIONED" ],
  "requested_fields": [],        // only on hold_request_info
  "decision_id": "pd_…",
  "expires_at": null,            // 48h on hold_request_info
  "payee_ref": { "sid": "…", "rating_status": "verified", "open_disputes": 0, "policy": { "min_usdc": null, "max_usdc": null, "require_kya": false, "purposes": [] } },
  "evidence": [ { "kind": "registry", "ref": "…/registry.json#sid", "complete_through": "…" }, { "kind": "screening", "ref": "…/api/risk?addr=…", "complete_through": "…" } ],
  "signature": { "token": "…", "verify_url": "…/api/attestation/verify?token=…" },
  "next": "Do not settle. Re-paying does not change this result."
}
GET/api/risk

單地址查詢

付款前查一個收款地址:是否命中制裁 / 混幣器 / 我方風險名單,或鏈上高危信號?返回判定 + 可核驗證據。

參數

  • addr 必填要查的地址:0x 以太坊系 / T 波場 TRON / Solana base58
  • network 可選0x 地址所在 EVM 鏈:ethereum(默認)/ base / bsc / polygon / arbitrum / optimism / avalanche

示例

curl "https://oceanalt.com/api/risk?addr=0x8589427373D6D84E98730D7795D8f6f8731FDA16&network=ethereum"

返回

{
  "address": "0x8589...FDA16",
  "verdict": "risky",           // risky | caution | clear
  "risk": 100,                   // 0-100
  "blocked": true,              // does the gateway block it?
  "signals": ["mixer contract"],
  "evidence": [                  // click-through, verifiable
    { "label": "hit mixer list", "detail": "Tornado Cash",
      "url": "https://etherscan.io/address/0x8589..." }
  ],
  "advice": "Decline. ...",
  "standard": "https://oceanalt.com/en/rap"
}
POST/api/risk/batch

批量查詢

一次查一串地址(自動去重,最多 25 個)。適合 OTC 收款臺 / 系統批處理。結果按 高危 → 謹慎 → 清白 排序。

參數

  • addresses 必填地址數組(JSON body),最多 25 個

示例

curl -X POST "https://oceanalt.com/api/risk/batch" \
  -H "content-type: application/json" \
  -d '{"addresses":["0x8589...","TWd4...","T..."]}'

返回

{
  "summary": { "total": 3, "risky": 1, "caution": 0, "invalid": 1 },
  "results": [
    { "address": "0x8589...", "verdict": "risky", "risk": 100,
      "blocked": true,  "top": "mixer contract" },
    { "address": "TWd4...",    "verdict": "clear", "risk": 3,
      "blocked": false, "top": "has prior activity" }
  ]
}
GET/api/risk/flow

資金流分析(波場 + EVM)

波場 USDT 地址:上下游對手方(按金額 top 8)、第一筆 U 來源、被 Tether 凍結的對手方標記、跨鏈橋識別。EVM(ethereum/base/polygon/arbitrum/optimism,傳 network)給 USDT/USDC 上下游 + 橋識別。

參數

  • addr 必填波場 TRON 地址(T 開頭)或 0x EVM 地址
  • network 可選0x 地址所在 EVM 鏈(ethereum 默認 / base / polygon / arbitrum / optimism);波場無需填

示例

curl "https://oceanalt.com/api/risk/flow?addr=TWd4WrZ9wn84f5x1hZhL4DHvk738ns5jwb"

返回

{
  "chain": "tron",
  "total": 10000,
  "inbound":  [ { "address": "T...", "tag": "Binance-Hot",
                  "count": 17, "usdt": 2890000, "risky": false } ],
  "outbound": [ { "address": "T...", "tag": "OKX Hot",
                  "count": 25, "usdt": 3370000, "risky": false } ],
  "firstInflow": { "from": "T...", "usdt": 500, "date": "2024-06-01" },
  "riskyParties": 0
}

冪等鍵:安全地重試付款

網絡中斷時,你的 Agent 不知道付款請求到底執行了沒有。給 POST /api/pay 的付款調用(以及 rotate)帶上 Idempotency-Key 請求頭,重試時保持同一個 key、同一個 nonce、同樣的請求體:24 小時內我們原樣返回第一次的響應,不會重複執行,也不會把這次重試記成重放攻擊。語義參照 IETF 草案 draft-ietf-httpapi-idempotency-key-header。

curl -X POST "https://oceanalt.com/api/pay" \
  -H "content-type: application/json" \
  -H "x-agent-secret: $OCEANALT_AGENT_SECRET" \
  -H "Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9324" \
  -d '{"agentId":"my-agent","amountUsdc":1,"to":"0x…","purpose":"api-credits","nonce":"b3f1c2…"}'
  • Idempotent-Replayed: true同 key、同請求體、同憑證的重試:原樣返回第一次的狀態碼和響應體。
  • 422 idempotency_key_reused同一個 key 用在了不同的請求體上(比如重試時換了 nonce)。沒有執行。
  • 409 idempotency_request_in_progress第一次請求還在處理中。這是併發,不是重放攻擊,不記威脅。等 retry-after 秒後原樣重發。
  • 400 idempotency_key_invalidkey 需為 1–255 個可打印 ASCII 字符,建議用 UUID。

回放必須出示與第一次相同的 x-agent-secret —— 只知道 key 的人拿不到你的響應。不帶這個頭的調用,行為與以前完全一樣。要發起一筆新的付款,請換新的 key 和新的 nonce。

Webhook 簽名與驗簽

在控制台(/keys)配置了 webhook 的,你的 Agent 付款被攔下時,我們會 POST 一段 JSON 到你的地址。每條消息都按 Standard Webhooks 規範簽名,你的系統可以確認它真的來自 OceanAlt、沒有被改過、不是舊消息重放。

  • webhook-id消息唯一編號;同一條消息重試時不變,請按它去重。
  • webhook-timestamp發送時間(Unix 秒)。與你的當前時間相差超過 5 分鐘就拒絕。
  • webhook-signaturev1,<base64>:對「webhook-id.webhook-timestamp.原始請求體」做 HMAC-SHA256,密鑰是 whsec_ 之後那段 base64 解碼出的字節。輪換密鑰後 24 小時內會帶兩個簽名(空格分隔),任一匹配即可。

Node 驗簽示例(零依賴,這段代碼在我們的自測裡原樣跑過):

import { createHmac, timingSafeEqual } from "node:crypto";

// secret:  the whsec_… value shown once in the console
// rawBody: the request body exactly as received (do NOT JSON.parse and re-stringify it)
export function verifyOceanAltWebhook(secret, headers, rawBody, toleranceSec = 300) {
  const id = headers["webhook-id"];
  const ts = headers["webhook-timestamp"];
  const sigs = headers["webhook-signature"];
  if (!id || !ts || !sigs) return false;
  if (Math.abs(Date.now() / 1000 - Number(ts)) > toleranceSec) return false; // stale or replayed

  const key = Buffer.from(secret.slice("whsec_".length), "base64");
  const expected = createHmac("sha256", key).update(id + "." + ts + "." + rawBody).digest();

  // during a rotation there are two space-separated signatures; accept if either matches
  return sigs.split(" ").some((entry) => {
    const [version, b64] = entry.split(",");
    const got = Buffer.from(b64 || "", "base64");
    return version === "v1" && got.length === expected.length && timingSafeEqual(got, expected);
  });
}

// Express example:
// app.post("/hooks/oceanalt", express.raw({ type: "application/json" }), (req, res) => {
//   const raw = req.body.toString("utf8");
//   if (!verifyOceanAltWebhook(process.env.OCEANALT_WEBHOOK_SECRET, req.headers, raw)) return res.sendStatus(401);
//   const event = JSON.parse(raw); // then deduplicate on req.headers["webhook-id"]
//   res.sendStatus(204);
// });

也可以用任意 Standard Webhooks 庫驗簽(standardwebhooks.com),把控制台給你的 whsec_ 密鑰傳進去即可。

簽名密鑰在控制台生成,只顯示一次,可隨時輪換。收件方要在約 5 秒內回 2xx;沒送到的會在 1 分鐘、5 分鐘、30 分鐘、2 小時後自動重試,最多共 5 次,不跟隨重定向。每次嘗試的狀態碼、耗時和錯誤摘要都在控制台的「最近投遞」裡,保留 30 天。

給密鑰上三道鎖:能力範圍、IP 白名單、過期時間

密鑰默認什麼都不限,你已經在用的密鑰不受影響。持有者可以自己加上限制 —— 它們決定這把密鑰萬一洩露,對方能拿它做多少事。

能力範圍(scope):這把密鑰能調哪些接口

  • screen_address查地址:單個收款地址篩查(?on= 時點查詢不讀密鑰,不受影響)GET /api/risk
  • screen_endpoint查付款網址:這個端點是不是已知釣魚站GET /api/endpoint
  • decide付款前判決:allow / review / decline(含可選的付款意圖檢查)GET /api/decide · POST /api/decide
  • payee_decide收款方決策:接不接這筆錢POST /api/payee/decide
  • batch_screen批量篩查:一次最多 25 個地址(付費的 POST /api/x402/batch 按付款認,不讀密鑰)POST /api/risk/batch
  • trace_funds資金流追蹤:多跳沾染追蹤與上下游對手方分析(同一份上游資金數據的兩種看法,合成一組)GET /api/risk/trace · GET /api/risk/flow
  • evidence_bundle證據包:一個地址的 Ed25519 簽名證據包GET /api/evidence/bundle
  • intent_check盲簽比對:這段 calldata 真正會執行什麼,與你聲稱要付的那筆對不對得上POST /api/intent/check
  • baseline_lookup控制基線查詢:結算前查對手方自證過哪些控制項GET /api/baseline/lookup

上面沒列出來的接口不讀密鑰,按來源 IP 限流:x402 付費端點(按付款認,本來就不需要密鑰)、時點查詢 GET /api/risk?on=,以及網關、履約、註冊表那幾個接口。MCP 端點 POST /api/mcp 是可選的:不帶密鑰照常全部可用;帶了密鑰,工具調用按密鑰限流,持有者設的能力範圍和 IP 白名單按工具生效,判決可進決策日誌(這是我們自己發的密鑰,不是 MCP 規範裡的 OAuth 授權)。另外,這三道鎖管的是「這把密鑰能做什麼」,不是「能做多少」:2026-09-16 新納入的六個接口仍按來源 IP 限流、仍不計入任何人的月額度 —— 不帶密鑰調它們,和以前一模一樣。Agent 憑證(x-agent-id + x-agent-secret)是另一套,不受這些限制影響。決策日誌默認關閉,持有者自己打開後才記錄,可用 GET /api/access-keys/decisions 導出(JSON 或 CSV,整份簽名)。

  • 403 key_scope_denied這次調的接口不在這把密鑰的範圍裡。返回裡寫明是哪個範圍、這把密鑰允許哪些。
  • 403 key_ip_denied請求不是從白名單裡的地址發出的。最多 20 條,可寫單個地址或網段(CIDR,例如 198.51.100.0/24);IPv4 與 IPv6 分開算。我們認的是連接真正來自哪裡,請求頭裡自稱的 X-Forwarded-For 不算數。
  • 200 access.key_rejected = expired過了持有者設的過期時間。和被停用是同一個待遇:調用仍然按匿名檔服務,但明確告訴你密鑰沒被認 —— 不會悶聲降級讓你去自己代碼裡找 bug。

讀設置 / 改設置(用密鑰本身認證)

curl "https://oceanalt.com/api/access-keys/settings" -H "authorization: Bearer $OCEANALT_API_KEY"

curl -X POST "https://oceanalt.com/api/access-keys/settings" \
  -H "authorization: Bearer $OCEANALT_API_KEY" \
  -H "content-type: application/json" \
  -d '{"scopes":["screen_address","decide"],"ip_allowlist":["198.51.100.0/24"],"expires_at":"2027-01-01T00:00:00Z"}'

收窄(少給能力組、把白名單收緊、把過期時間提前)憑密鑰就能立即生效;放寬(多給能力組、放開或刪掉白名單、延後或取消過期)要點一封發到該密鑰登記郵箱的確認信 —— 否則偷到密鑰的人第一件事就是把限制刪掉,這三道鎖等於沒上。一次請求裡只要有一項是放寬,整次改動都等確認。沒帶的字段保持原樣。

在網頁上設置 →

判定含義

  • risky命中制裁 / 混幣器 / 我方風險名單,或鏈上高危 → 建議拒付。
  • caution存在風險信號 → 只在授權額度內謹慎處理。
  • clear篩查完成,未見風險信號。注意:沒查到信號 ≠ 一定安全。
  • uncertain篩查沒能完成(上游數據這一刻拿不到)。沒有風險分。請稍後重試,絕不能當成 clear 處理。

支持的網絡

7 條 EVM 鏈 + 波場 TRON + Solana。制裁 / 混幣器 / 詐騙名單判定與鏈無關(全網通用);鏈上信號與穩定幣(USDT/USDC)發行方凍結按對應鏈實時查、可點開核驗。

  • ethereum · base · bsc · polygon · arbitrum · optimism · avalanche
  • tron (USDT-TRC20 凍結 / 深度追蹤 / 資金流) · solana (制裁名單)

x402 付費高階(按次付費 · 免註冊免 key)

更重的分析走 x402:HTTP 402 → 籤一次 USDC 授權 → 200。facilitator 代驗簽、代付 gas、不託管你的資金。用 oceanalt-aml SDK 一行搞定,或任意 x402 客戶端。

  • POST /api/x402/decision完整網關合規判決(allow/review/decline)+ 證據 · $0.30
  • GET /api/x402/trace?addr=T…波場多跳沾染追蹤(≤3 跳) · $0.20
  • POST /api/x402/batch批量篩查(≤25) · $0.10

機器可讀清單(免費 vs 付費 / 網絡 / facilitator / 定價):/api/x402

x402 是什麼 + 瀏覽器裡實測合規預檢:/zh/x402

SDK 與 MCP(裝進你的 Agent)

① 編程 SDK(Node / 瀏覽器 / Deno / Bun,免費路徑零依賴):

npm i oceanalt-aml

import { OceanAltAML } from "oceanalt-aml";
const aml = new OceanAltAML();
const r = await aml.screen("0x…", { network: "optimism" });        // free
const d = await aml.decision({ to: "0x…", amountUsdc: 25 },        // paid (x402)
  { privateKey: process.env.PAYER_KEY });

② MCP server(讓 Claude / 任意 MCP 客戶端原生調用):

{
  "mcpServers": {
    "oceanalt-aml": {
      "command": "npx", "args": ["-y", "oceanalt-aml-mcp"],
      "env": { "OCEANALT_PAYER_KEY": "0x…" }
    }
  }
}

免費工具:screen_address、recent_flagged;付費工具:compliance_decision、deep_trace、batch_screen(需 OCEANALT_PAYER_KEY)。

合理使用:免費供個人與集成測試。大流量 / 商用請聯繫我們。本接口給風險信號,不構成投資 / 交易建議。

x402 生態可調用(免費):我們把 AML 聲明為 x402 資源、price=0,Agent 無需付費、無需 key 直接調用。機器可讀清單:/api/x402

→ 先在網頁裡試試查地址 · 完整合規網關(11 道閘) · RAP 標準