跳转到主要内容
本指南介绍如何将 ChainStream KYT/KYA 合规能力集成到您的应用中,包括 CEX 充提风控、钱包风险提示、批量筛查等完整场景。

前置准备

API 基础信息

配置项
Base URLhttps://api.chainstream.io/
Auth Domaindex.asia.auth.chainstream.io
Audiencehttps://api.dex.chainstream.io

KYT 相关 Scopes

Scope说明
kyt.readKYT API 读取权限(查询交易风险)
kyt.writeKYT API 写入权限(注册交易分析)

生成 Access Token

import { AuthenticationClient } from 'auth0';

const auth0Client = new AuthenticationClient({
  domain: 'dex.asia.auth.chainstream.io',
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret'
});

// 获取 KYT 完整权限的 Token
const response = await auth0Client.oauth.clientCredentialsGrant({
  audience: 'https://api.dex.chainstream.io',
  scope: 'kyt.read kyt.write'
});

const accessToken = response.data.access_token;

API 调用

所有请求需在 Header 中携带 Token:
const response = await fetch('https://api.chainstream.io/v1/kyt/transfer', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ /* request body */ })
});

CEX 充值风控

交易所充值场景是 KYT 最核心的应用场景,需要在资金入账前完成风险判断。

业务流程

接入步骤

1

初始化客户端

import { AuthenticationClient } from 'auth0';

// 生成 Token(建议缓存,过期前刷新)
async function getAccessToken() {
  const auth0Client = new AuthenticationClient({
    domain: 'dex.asia.auth.chainstream.io',
    clientId: process.env.CHAINSTREAM_CLIENT_ID,
    clientSecret: process.env.CHAINSTREAM_CLIENT_SECRET
  });

  const { data } = await auth0Client.oauth.clientCredentialsGrant({
    audience: 'https://api.dex.chainstream.io',
    scope: 'kyt.read kyt.write'
  });

  return data.access_token;
}
2

交易检测

监听用户充值地址的入账交易:
async function onDepositDetected(tx) {
  const deposit = {
    network: 'ethereum',           // 网络:bitcoin, ethereum, Solana
    asset: tx.asset,               // 资产类型:ETH, SOL 等
    transferReference: tx.hash,    // 交易哈希
    direction: 'received'          // 方向:sent 或 received
  };
  
  // 调用 KYT 分析
  const result = await registerTransfer(deposit);
  
  // 获取风险评估
  const risk = await getTransferSummary(result.externalId);
  
  // 执行决策
  await executeDecision(tx, risk);
}
3

注册交易

调用 KYT API 注册交易:
async function registerTransfer(deposit) {
  const response = await fetch('https://api.chainstream.io/v1/kyt/transfer', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      network: deposit.network,
      asset: deposit.asset,
      transferReference: deposit.transferReference,
      direction: deposit.direction
    })
  });
  
  return await response.json();
}
4

获取风险评估

查询交易的风险摘要:
async function getTransferSummary(transferId) {
  const response = await fetch(
    `https://api.chainstream.io/v1/kyt/transfers/${transferId}/summary`,
    {
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    }
  );
  
  return await response.json();
}
5

自动决策

根据风险等级执行相应操作:
async function executeDecision(tx, risk) {
  const riskLevel = risk.rating; // SEVERE, HIGH, MEDIUM, LOW
  
  switch (riskLevel) {
    case 'SEVERE':
      await freezeDeposit(tx);
      await createSARReport(tx, risk);
      await notifyCompliance(tx, risk);
      break;
      
    case 'HIGH':
      await holdDeposit(tx, { hours: 24 });
      await createManualReview(tx, risk);
      break;
      
    case 'MEDIUM':
      await creditDeposit(tx);
      await flagForMonitoring(tx, risk);
      break;
      
    case 'LOW':
      await creditDeposit(tx);
      break;
  }
  
  // 记录审计日志
  await auditLog.record({
    action: 'DEPOSIT_RISK_DECISION',
    txHash: tx.hash,
    riskLevel,
    timestamp: new Date()
  });
}

完整流程详解

合规集成的端到端流程涵盖:检测 → 注册 → 轮询 → 风险判定 → 放行/冻结

1. 检测阶段

触发源说明延迟
链上监听监控充值地址区块确认时间
用户提交提现申请即时
定时扫描补漏机制可配置

2. 注册阶段

POST https://api.chainstream.io/v1/kyt/transfer
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "network": "ethereum",
  "asset": "ETH",
  "transferReference": "0x1234567890abcdef...",
  "direction": "received"
}
响应:
{
  "externalId": "123e4567-e89b-12d3-a456-426614174000",
  "asset": "ETH",
  "network": "ethereum",
  "transferReference": "0x1234567890abcdef...",
  "direction": "received",
  "updatedAt": "2024-01-15T10:30:00.000Z"
}

3. 查询阶段

async function pollForResult(transferId, maxAttempts = 10) {
  for (let i = 0; i < maxAttempts; i++) {
    const response = await fetch(
      `https://api.chainstream.io/v1/kyt/transfers/${transferId}/summary`,
      {
        headers: { 'Authorization': `Bearer ${accessToken}` }
      }
    );
    const data = await response.json();
    
    if (data.rating) {
      return data;
    }
    
    await new Promise(r => setTimeout(r, 3000)); // 3秒间隔
  }
  
  throw new Error('Analysis timeout');
}

4. 判定阶段

风险判定规则配置:
risk_rules:
  severe:
    action: FREEZE
    auto_execute: true
    notify:
      - compliance@company.com
      - security@company.com
    
  high:
    action: MANUAL_REVIEW
    auto_execute: false
    hold_period: 24h
    escalation: 4h
    
  medium:
    action: FLAG
    auto_execute: true
    monitoring_period: 30d
    
  low:
    action: PASS
    auto_execute: true

5. 执行阶段

操作触发条件后续流程
放行LOW 风险正常入账/放款
标记MEDIUM 风险入账但持续监控
暂扣HIGH 风险进入人工审核队列
冻结SEVERE 风险冻结 + 合规报告

完整服务实现

import { AuthenticationClient } from 'auth0';

class ComplianceService {
  constructor() {
    this.accessToken = null;
    this.tokenExpiry = null;
  }

  // 获取或刷新 Token
  async getAccessToken() {
    if (this.accessToken && this.tokenExpiry > Date.now()) {
      return this.accessToken;
    }

    const auth0Client = new AuthenticationClient({
      domain: 'dex.asia.auth.chainstream.io',
      clientId: process.env.CHAINSTREAM_CLIENT_ID,
      clientSecret: process.env.CHAINSTREAM_CLIENT_SECRET
    });

    const { data } = await auth0Client.oauth.clientCredentialsGrant({
      audience: 'https://api.dex.chainstream.io',
      scope: 'kyt.read kyt.write'
    });

    this.accessToken = data.access_token;
    // Token 通常 24 小时有效,提前 1 小时刷新
    this.tokenExpiry = Date.now() + (23 * 60 * 60 * 1000);
    
    return this.accessToken;
  }

  // 充值合规检查
  async checkDeposit(deposit) {
    const token = await this.getAccessToken();
    
    // 1. 注册交易
    const registerResponse = await fetch('https://api.chainstream.io/v1/kyt/transfer', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        network: deposit.network,
        asset: deposit.asset,
        transferReference: deposit.txHash,
        direction: 'received'
      })
    });
    const registered = await registerResponse.json();

    // 2. 等待并获取风险评估
    const risk = await this.waitForAnalysis(token, registered.externalId);
    
    // 3. 生成决策
    const decision = this.makeDecision(risk);
    
    // 4. 记录审计
    await this.auditLog(deposit, risk, decision);
    
    return decision;
  }

  async waitForAnalysis(token, transferId, maxAttempts = 10) {
    for (let i = 0; i < maxAttempts; i++) {
      const response = await fetch(
        `https://api.chainstream.io/v1/kyt/transfers/${transferId}/summary`,
        { headers: { 'Authorization': `Bearer ${token}` } }
      );
      const result = await response.json();
      
      if (result.rating) {
        return result;
      }
      await new Promise(r => setTimeout(r, 3000));
    }
    throw new Error('Analysis timeout');
  }

  makeDecision(risk) {
    const decisions = {
      'SEVERE': {
        action: 'FREEZE',
        requireSAR: true,
        notify: ['compliance@company.com', 'security@company.com']
      },
      'HIGH': {
        action: 'HOLD',
        requireReview: true,
        holdHours: 24
      },
      'MEDIUM': {
        action: 'PASS',
        flagMonitoring: true
      },
      'LOW': {
        action: 'PASS'
      }
    };
    return decisions[risk.rating] || decisions['LOW'];
  }

  async auditLog(deposit, risk, decision) {
    console.log({
      timestamp: new Date().toISOString(),
      type: 'COMPLIANCE_CHECK',
      deposit,
      risk,
      decision
    });
  }
}

// 使用示例
const compliance = new ComplianceService();

app.post('/deposit/process', async (req, res) => {
  const deposit = req.body;
  const decision = await compliance.checkDeposit(deposit);
  res.json(decision);
});

CEX 提现风控

提现场景需要在用户发起提现时,检查目标地址的风险。

业务流程

实现示例

async function handleWithdrawal(request) {
  const { toAddress } = request;
  const token = await complianceService.getAccessToken();
  
  // 1. 注册地址
  const registerResponse = await fetch('https://api.chainstream.io/v1/kyt/address', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ address: toAddress })
  });
  await registerResponse.json();
  
  // 2. 获取地址风险
  const riskResponse = await fetch(
    `https://api.chainstream.io/v1/kyt/addresses/${toAddress}/risk`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  );
  const addressRisk = await riskResponse.json();
  
  // 3. 风险处理
  switch (addressRisk.rating) {
    case 'SEVERE':
      return {
        status: 'REJECTED',
        reason: 'Target address is associated with known criminal activity',
        riskLevel: 'SEVERE'
      };
      
    case 'HIGH':
      return {
        status: 'PENDING_CONFIRMATION',
        warning: 'This address has been flagged as high risk',
        riskDetails: addressRisk,
        requiresConfirmation: true
      };
      
    default:
      return {
        status: 'APPROVED',
        riskLevel: addressRisk.rating
      };
  }
}

// Express 路由示例
app.post('/withdraw/request', async (req, res) => {
  const result = await handleWithdrawal(req.body);
  res.json(result);
});

钱包风险提示

钱包应用中,在用户发起转账前提供风险提示。

用户体验流程

前后端集成

前端不应直接暴露 clientSecret,应通过后端 API 代理调用 ChainStream。
// 地址输入变化时触发
async function onAddressChange(address) {
  if (!isValidAddress(address)) return;
  
  setLoading(true);
  
  try {
    // 调用后端代理 API
    const response = await fetch('/api/risk/check-address', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ address })
    });
    const risk = await response.json();
    
    setRiskInfo({
      level: risk.rating,
      labels: risk.labels,
      warnings: risk.warnings
    });
  } finally {
    setLoading(false);
  }
}

批量地址筛查

企业场景下的存量地址合规筛查。

应用场景

  • 定期合规审计
  • 新监管要求落地
  • 并购尽调
  • 风险排查

批量筛查实现

async function batchScreenAddresses(addresses) {
  const token = await complianceService.getAccessToken();
  const results = [];
  
  for (const address of addresses) {
    try {
      // 注册地址
      await fetch('https://api.chainstream.io/v1/kyt/address', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ address })
      });
      
      // 获取风险
      const riskResponse = await fetch(
        `https://api.chainstream.io/v1/kyt/addresses/${address}/risk`,
        { headers: { 'Authorization': `Bearer ${token}` } }
      );
      const risk = await riskResponse.json();
      
      results.push({
        address,
        rating: risk.rating,
        riskScore: risk.riskScore
      });
    } catch (error) {
      results.push({
        address,
        error: error.message
      });
    }
  }
  
  // 处理高风险地址
  const highRiskAddresses = results.filter(
    r => r.rating === 'SEVERE' || r.rating === 'HIGH'
  );
  
  return { all: results, highRisk: highRiskAddresses };
}

最佳实践

阈值设置建议

根据业务类型调整风险阈值:
业务类型SEVERE 处理HIGH 处理MEDIUM 处理
持牌 CEX自动冻结人工审核标记监控
钱包应用强警告警告提示
DeFi 协议拒绝交互警告正常
OTC 平台拒绝交易额外 KYC正常

审计日志要求

确保记录完整的审计轨迹:
{
  "eventId": "evt_123456",
  "timestamp": "2024-01-15T10:30:00Z",
  "eventType": "RISK_DECISION",
  "subject": {
    "transferId": "123e4567-e89b-12d3-a456-426614174000",
    "txHash": "0x...",
    "userId": "user_789"
  },
  "riskAssessment": {
    "rating": "HIGH",
    "riskScore": 72
  },
  "decision": {
    "action": "HOLD",
    "decidedBy": "SYSTEM",
    "reason": "Auto-hold per risk policy"
  },
  "metadata": {
    "policyVersion": "1.2.0",
    "engineVersion": "2024.01"
  }
}

下一步