通知渠道

使用通知渠道来获取关于不同 Defender 模块的事件通知,比如 Monitor 触发器,工作流或者 Relayer 交易生命周期事件。

支持的渠道

来自 Defender

设置

前往 Settings → Notification Channels 部分,选择并配置你喜欢的渠道。

在 Defender 中创建通知渠道

使用

通知渠道可以被链接到任何 Defender 模块,以获取事件通知。

在 Defender 模块中使用通知渠道

此外,还可以自定义通知模板,查看方法

附加配置

Webhook 密钥

作为一项额外的安全措施,Defender 实现了基于哈希的消息认证码 (HMAC),通过添加 Defender-SignatureDefender-Timestamp 请求头到发送到 webhook 端点的通知中。因此,接收通知的端点可以验证请求的真实性。

每个 webhook 通知都有一个与之关联的密钥,可以在 Settings → Notification Channnels → Webhook details 下访问。

Defender-Signature 使用 SHA256 algorithmwebhook secret 来签名 payload 和时间戳。

只有账户中的管理员用户才有权限查看 webhook 密钥。

签名验证

使用 Defender SDK

签名的真实性可以使用 Defender SDK 中的 verifySignature 实用函数来验证。

function webhookHandler(req, res) {
  const signature = req.headers['Defender-Signature'];
  const timestamp = req.headers['Defender-Timestamp'];

  const defender = new Defender({
    apiKey: process.env.API_KEY,
    apiSecret: process.env.API_SECRET,
  });

  const result = client.notificationChannel.verifySignature({
    body: req.body,
    signature,
    timestamp,
    secret: process.env.WEBHOOK_SECRET,
    validityInMs: 1000 * 60 * 10, // 10 mins
  });

  if (!result.valid) throw new Error(result.error);

  // your handler code
}
手动验证

签名是使用 HMAC 与 SHA256 算法生成的,因此可以使用正确的 Webhook Secret 在任何编程语言中进行验证。

Python 示例
该代码示例在 Python 3.12 中测试。对于不同的版本,代码可能略有不同。
from datetime import datetime, timedelta, UTC
import hmac
import hashlib

def verify_signature(body_object: dict, timestamp: str, signature: str secret: str) -> bool:
    # Parse the timestamp
    try:
        timestamp_dt = datetime.fromisoformat(timestamp)
    except ValueError:
        return False  # Invalid timestamp format

    # Get the current time and calculate the time difference
    current_time = datetime.now(UTC)
    time_difference = current_time - timestamp_dt

    # Check if the time difference is within the allowed range (10 minutes)
    if time_difference > timedelta(minutes=10):
        return False

    # Merge timestamp with body_object
    payload_to_verify = {**body_object, 'timestamp': timestamp}
    payload_to_verify_str = json.dumps(payload_to_verify, separators=(',', ':'))

    # Create a new HMAC object using the secret and the SHA256 hash algorithm
    hmac_obj = hmac.new(secret.encode(), payload_to_verify_str.encode(), hashlib.sha256)

    # Generate signature
    generated_signature = hmac_obj.hexdigest()

    # Compare the generated signature with the provided signature
    return hmac.compare_digest(generated_signature, signature)