Alerting API 参考
简介
Tenderly 的 Alert API 允许您创建简单和复杂的 Alerts。 简单告警由一条规则组成,例如method_call 会在事务调用您的 public 或 external 方法时触发。复杂告警可包含多个条件,只有当所有条件都满足时才会触发。例如,同时包含 method_call 和 state_change 的告警,会在事务调用指定方法并更新指定存储槽时触发。
使用 API 定义 Alert 时,您需要指定以下内容:
- 投递渠道(delivery channels):当告警规则触发时,会通知这些渠道。详见 Delivery Channels。
- 表达式(expressions)数组:当数组中每个表达式所代表的所有条件都被满足时,告警将被触发。
您只能通过 Dashboard 创建投递渠道,但可以使用 API 获取它们。
身份验证
在创建告警之前,您需要设置身份验证并标识您的项目:- JavaScript
- Shell
- Python
const TENDERLY_API_KEY = 'your_api_key';
const PROJECT_SLUG = 'your_project_slug';
const ACCOUNT_ID = 'me'; // Use 'me' or your specific account ID
// Base configuration for axios
const baseConfig = {
baseURL: 'https://api.tenderly.co/api/v1',
headers: {
'X-Access-Key': TENDERLY_API_KEY,
'Content-Type': 'application/json'
}
};
export TENDERLY_API_KEY="your_api_key"
export PROJECT_SLUG="your_project_slug"
export ACCOUNT_ID="me" # Use 'me' or your specific account ID
import requests
TENDERLY_API_KEY = 'your_api_key'
PROJECT_SLUG = 'your_project_slug'
ACCOUNT_ID = 'me' # Use 'me' or your specific account ID
# Base configuration for requests
base_url = 'https://api.tenderly.co/api/v1'
headers = {
'X-Access-Key': TENDERLY_API_KEY,
'Content-Type': 'application/json'
}
表达式类型
您可以使用不同的表达式类型来指定 Alerts 的触发规则。| 表达式类型 | 监控对象 | 主要用途 | 必填参数 | 可选参数 |
|---|---|---|---|---|
method_call | 合约中特定函数的调用(适用于直接或内部事务) | 跟踪重要函数何时被调用 | - line_number:函数定义所在行;call_position:调用位置(“first”、“last”、“any”) | 无 |
whitelisted_caller_addresses | 来自特定地址的调用 | 基于白名单的访问控制 | - addresses:Ethereum 地址数组 | 无 |
blacklisted_caller_addresses | 来自被拉黑地址的调用 | 基于黑名单的访问控制 | - addresses:Ethereum 地址数组 | 无 |
contract_address | 特定合约的交互 | 跟踪与某合约的所有交互 | - address:合约地址 | - transaction_type:“direct”、“source” 或 “internal” |
network | 特定网络上的事件 | 多链监控 | - network_id:网络/链 ID | 无 |
tag | 具有特定标签的合约 | 基于分组的监控 | - tag:标签字符串 | - transaction_type:“direct”、“source” 或 “internal” |
tx_status | 事务成功/失败 | 跟踪失败的事务 | 无 | - transaction_success:布尔值 |
function_params | 函数参数值 | 跟踪特定函数的输入 | - address:合约地址;function_line_number:函数定义行;parameter_conditions:条件数组 | - 参数特定的选项 |
tx_value | 事务金额 | 跟踪大额转账 | - transaction_value:金额(wei);operator:比较运算符 | 无 |
emitted_log | 合约事件 | 跟踪特定事件 | - address:合约地址;event_name:事件名称;event_id:事件签名 | - match_any:布尔值;decode_events:布尔值;parameter_conditions:条件数组 |
state_change | 合约状态变化 | 跟踪存储变更 | - address:合约地址;parameter_conditions:条件数组 | - 比较选项(阈值、百分比) |
view_function | 只读函数结果 | 跟踪计算得到的值 | - address:合约地址;input:ABI 编码的函数数据;network_id:网络 ID | - parameter_condition:值比较 |
eth_balance | ETH 余额变化 | 跟踪余额阈值 | - address:合约地址;threshold:余额(wei);operator:比较运算符 | 无 |
erc20_transfer_matcher | ERC20 转账一致性 | 校验转账机制 | - address:代币地址;log_name:事件名称;balances:状态变量名 | 无 |
tx_error | 事务错误 | 跟踪意外失败 | 无 | - addresses_to_ignore:地址数组 |
tx_internal_error | 内部事务错误 | 跟踪内部调用失败 | 无 | - addresses_to_match:地址数组 |
no_action | 无活动 | 跟踪合约休眠 | - check_after_seconds:时间阈值 | - no_log:日志条件;no_transaction:事务条件 |
sandwich_transaction | 三明治攻击 | 跟踪 MEV 活动 | - address:合约地址 | - transaction_type:“direct”、“source” 或 “internal” |
说明
- 比较运算符(
operator)的有效取值:>、>=、<、<=、==、!=、contains、notContains - 参数类型(
parameter_type)包括:uint、int、bool、address、string、byte - 所有地址必须是有效的 Ethereum 地址(以
0x开头,40 个十六进制字符) - Wei 值应作为字符串传入以处理大数
- 网络 ID 应与目标区块链一致(例如 Ethereum 主网为 “1”)
简单表达式示例
以下示例展示如何设置简单表达式规则。1. 方法调用监控
使用场景:监控智能合约中的特定函数调用。- JavaScript
- Shell
- Python
const methodCallAlert = {
name: "Critical Function Call Alert",
description: "Monitors calls to critical functions",
enabled: true,
expressions: [{
type: "method_call",
expression: {
line_number: 123, // Line where function is defined
call_position: "any" // "first", "last", or "any"
}
},
{
"type": "contract_address",
"expression": {
"address": "0xe592427a0aece92de3edee1f18e0157c05861564"
}
}
],
delivery_channels: [{
id: "your_channel_id",
enabled: true
}]
};
await axios.post(
`/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
methodCallAlert,
baseConfig
);
curl -X POST "https://api.tenderly.co/api/v1/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert" \
--header "Content-Type: application/json" \
--header "X-Access-Key: ${TENDERLY_API_KEY}" \
--data-raw '{
"name": "Critical Function Call Alert",
"description": "Monitors calls to critical functions",
"enabled": true,
"expressions": [
{
"type": "method_call",
"expression": {
"line_number": 123,
"call_position": "any"
}
},
{
"type": "contract_address",
"expression": {
"address": "0xe592427a0aece92de3edee1f18e0157c05861564"
}
}
],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": true
}]
}'
method_call_alert = {
"name": "Critical Function Call Alert",
"description": "Monitors calls to critical functions",
"enabled": True,
"expressions": [{
"type": "method_call",
"expression": {
"line_number": 123,
"call_position": "any"
}
},
{
"type": "contract_address",
"expression": {
"address": "0xe592427a0aece92de3edee1f18e0157c05861564"
}
}],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": True
}]
}
response = requests.post(
f"{base_url}/account/{ACCOUNT_ID}/project/{PROJECT_SLUG}/alert",
headers=headers,
json=method_call_alert
)
2. 状态变化监控
使用场景:监控合约状态变量的变化,特别适用于跟踪关键参数,例如暂停状态或余额阈值。- JavaScript
- Shell
- Python
const stateChangeAlert = {
name: "Critical State Change Alert",
description: "Monitors important state changes",
enabled: true,
expressions: [{
type: "state_change",
expression: {
address: "0x1234....",
parameter_conditions: [
{
parameter_name: "pause",
parameter_type: "bool",
compare_change: true
},
{
parameter_name: "totalSupply",
parameter_type: "uint",
compare_percentage: true,
comparison_value: "5",
operator: ">="
}
]
}
}],
delivery_channels: [{
id: "your_channel_id",
enabled: true
}]
};
await axios.post(
`/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
stateChangeAlert,
baseConfig
);
curl -X POST "https://api.tenderly.co/api/v1/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert" \
--header "Content-Type: application/json" \
--header "X-Access-Key: ${TENDERLY_API_KEY}" \
--data-raw '{
"name": "Critical State Change Alert",
"description": "Monitors important state changes",
"enabled": true,
"expressions": [{
"type": "state_change",
"expression": {
"address": "0x1234....",
"parameter_conditions": [
{
"parameter_name": "pause",
"parameter_type": "bool",
"compare_change": true
},
{
"parameter_name": "totalSupply",
"parameter_type": "uint",
"compare_percentage": true,
"comparison_value": "5",
"operator": ">="
}
]
}
}],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": true
}]
}'
state_change_alert = {
"name": "Critical State Change Alert",
"description": "Monitors important state changes",
"enabled": True,
"expressions": [{
"type": "state_change",
"expression": {
"address": "0x1234....",
"parameter_conditions": [
{
"parameter_name": "pause",
"parameter_type": "bool",
"compare_change": True
},
{
"parameter_name": "totalSupply",
"parameter_type": "uint",
"compare_percentage": True,
"comparison_value": "5",
"operator": ">="
}
]
}
}],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": True
}]
}
response = requests.post(
f"{base_url}/account/{ACCOUNT_ID}/project/{PROJECT_SLUG}/alert",
headers=headers,
json=state_change_alert
)
3. 事件监控
使用场景:监控您的合约发出的特定事件,并支持参数过滤。- JavaScript
- Shell
- Python
const eventAlert = {
name: "Large Transfer Event Alert",
description: "Monitors large transfer events",
enabled: true,
expressions: [{
type: "emitted_log",
expression: {
address: "0x1234....",
event_name: "Transfer",
event_id: "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80",
parameter_conditions: [
{
parameter_name: "amount",
parameter_type: "uint",
operator: ">=",
comparison_value: "1000000000000000000" // 1 ETH
}
],
decode_events: true
}
}],
delivery_channels: [{
id: "your_channel_id",
enabled: true
}]
};
await axios.post(
`/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
eventAlert,
baseConfig
);
curl -X POST "https://api.tenderly.co/api/v1/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert" \
--header "Content-Type: application/json" \
--header "X-Access-Key: ${TENDERLY_API_KEY}" \
--data-raw '{
"name": "Large Transfer Event Alert",
"description": "Monitors large transfer events",
"enabled": true,
"expressions": [{
"type": "emitted_log",
"expression": {
"address": "0x1234....",
"event_name": "Transfer",
"event_id": "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80",
"parameter_conditions": [
{
"parameter_name": "amount",
"parameter_type": "uint",
"operator": ">=",
"comparison_value": "1000000000000000000"
}
],
"decode_events": true
}
}],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": true
}]
}'
event_alert = {
"name": "Large Transfer Event Alert",
"description": "Monitors large transfer events",
"enabled": True,
"expressions": [{
"type": "emitted_log",
"expression": {
"address": "0x1234....",
"event_name": "Transfer",
"event_id": "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80",
"parameter_conditions": [
{
"parameter_name": "amount",
"parameter_type": "uint",
"operator": ">=",
"comparison_value": "1000000000000000000"
}
],
"decode_events": True
}
}],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": True
}]
}
response = requests.post(
f"{base_url}/account/{ACCOUNT_ID}/project/{PROJECT_SLUG}/alert",
headers=headers,
json=event_alert
)
4. 原生 ETH 余额监控
使用场景:当某个地址的原生 ETH 余额低于阈值时告警,例如必须保持有充足资金的中继器或运营钱包。将告警范围限定到某个网络和地址,然后将原生余额与阈值(以 wei 表示)进行比较。- JavaScript
- Shell
- Python
const balanceAlert = {
name: "Low ETH balance alert",
description: "Alerts when the native ETH balance falls below 0.1 ETH",
enabled: true,
expressions: [
// Scope to a specific network
{
type: "network",
expression: {
network_id: "1" // Ethereum mainnet
}
},
// Scope to the watched address
{
type: "contract_address",
expression: {
address: "0x3b8c2f1a9d7e4605c8a1b2d3e4f5061728394a5b"
}
},
// Trigger when the native balance drops below the threshold
{
type: "eth_balance",
expression: {
address: "0x3b8c2f1a9d7e4605c8a1b2d3e4f5061728394a5b",
threshold: "100000000000000000", // 0.1 ETH in wei
operator: "<"
}
}
],
delivery_channels: [{
id: "your_channel_id",
enabled: true
}]
};
await axios.post(
`/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
balanceAlert,
baseConfig
);
curl -X POST "https://api.tenderly.co/api/v1/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert" \
--header "Content-Type: application/json" \
--header "X-Access-Key: ${TENDERLY_API_KEY}" \
--data-raw '{
"name": "Low ETH balance alert",
"description": "Alerts when the native ETH balance falls below 0.1 ETH",
"enabled": true,
"expressions": [
{
"type": "network",
"expression": {
"network_id": "1"
}
},
{
"type": "contract_address",
"expression": {
"address": "0x3b8c2f1a9d7e4605c8a1b2d3e4f5061728394a5b"
}
},
{
"type": "eth_balance",
"expression": {
"address": "0x3b8c2f1a9d7e4605c8a1b2d3e4f5061728394a5b",
"threshold": "100000000000000000",
"operator": "<"
}
}
],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": true
}]
}'
balance_alert = {
"name": "Low ETH balance alert",
"description": "Alerts when the native ETH balance falls below 0.1 ETH",
"enabled": True,
"expressions": [
{
"type": "network",
"expression": {
"network_id": "1"
}
},
{
"type": "contract_address",
"expression": {
"address": "0x3b8c2f1a9d7e4605c8a1b2d3e4f5061728394a5b"
}
},
{
"type": "eth_balance",
"expression": {
"address": "0x3b8c2f1a9d7e4605c8a1b2d3e4f5061728394a5b",
"threshold": "100000000000000000",
"operator": "<"
}
}
],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": True
}]
}
response = requests.post(
f"{base_url}/account/{ACCOUNT_ID}/project/{PROJECT_SLUG}/alert",
headers=headers,
json=balance_alert
)
复杂告警示例
以下示例展示复杂的表达式规则。只有当expressions 数组中的每个表达式都被满足时,告警才会触发。
1. 安全监控系统
使用场景:结合多个条件的全面安全监控:- 监控管理员函数调用
- 跟踪大额转账
- 监视黑名单地址
- 对关键参数的状态变化进行告警
- JavaScript
- Shell
- Python
const securityAlert = {
name: "Security Monitoring System",
description: "Comprehensive security monitoring for contract",
enabled: true,
expressions: [
{
"type": "contract_address",
"expression": {
"address": "0xe592427a0aece92de3edee1f18e0157c05861564"
}
},
// Admin function monitoring
{
type: "method_call",
expression: {
line_number: 123,
call_position: "any"
}
},
// Blacklist checking
{
type: "blacklisted_caller_addresses",
expression: {
addresses: [
"0xblacklisted1...",
"0xblacklisted2..."
]
}
},
// Large value transfers
{
type: "tx_value",
expression: {
transaction_value: "100000000000000000000", // 100 ETH
operator: ">"
}
},
// Critical state changes
{
type: "state_change",
expression: {
address: "0x1234....",
parameter_conditions: [
{
parameter_name: "pause",
parameter_type: "bool",
compare_change: true
},
{
parameter_name: "owner",
parameter_type: "address",
compare_change: true
}
]
}
}
],
delivery_channels: [{
id: "your_channel_id",
enabled: true
}]
};
await axios.post(
`/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
securityAlert,
baseConfig
);
curl -X POST "https://api.tenderly.co/api/v1/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert" \
--header "Content-Type: application/json" \
--header "X-Access-Key: ${TENDERLY_API_KEY}" \
--data-raw '{
"name": "Security Monitoring System",
"description": "Comprehensive security monitoring for contract",
"enabled": true,
"expressions": [
{
"type": "contract_address",
"expression": {
"address": "0xe592427a0aece92de3edee1f18e0157c05861564"
}
},
{
"type": "method_call",
"expression": {
"line_number": 123,
"call_position": "any"
}
},
{
"type": "blacklisted_caller_addresses",
"expression": {
"addresses": [
"0xblacklisted1...",
"0xblacklisted2..."
]
}
},
{
"type": "tx_value",
"expression": {
"transaction_value": "100000000000000000000",
"operator": ">"
}
},
{
"type": "state_change",
"expression": {
"address": "0x1234....",
"parameter_conditions": [
{
"parameter_name": "pause",
"parameter_type": "bool",
"compare_change": true
},
{
"parameter_name": "owner",
"parameter_type": "address",
"compare_change": true
}
]
}
}
],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": true
}]
}'
security_alert = {
"name": "Security Monitoring System",
"description": "Comprehensive security monitoring for contract",
"enabled": True,
"expressions": [
{
"type": "contract_address",
"expression": {
"address": "0xe592427a0aece92de3edee1f18e0157c05861564"
}
},
{
"type": "method_call",
"expression": {
"line_number": 123,
"call_position": "any"
}
},
{
"type": "blacklisted_caller_addresses",
"expression": {
"addresses": [
"0xblacklisted1...",
"0xblacklisted2..."
]
}
},
{
"type": "tx_value",
"expression": {
"transaction_value": "100000000000000000000",
"operator": ">"
}
},
{
"type": "state_change",
"expression": {
"address": "0x1234....",
"parameter_conditions": [
{
"parameter_name": "pause",
"parameter_type": "bool",
"compare_change": True
},
{
"parameter_name": "owner",
"parameter_type": "address",
"compare_change": True
}
]
}
}
],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": True
}]
}
response = requests.post(
f"{base_url}/account/{ACCOUNT_ID}/project/{PROJECT_SLUG}/alert",
headers=headers,
json=security_alert
)
2. DeFi 协议监控
使用场景:监控 DeFi 协议的以下情况:- 大额交易/兑换
- 显著的价格影响
- 流动性变化
- 失败的事务
- 三明治攻击
- JavaScript
- Shell
- Python
const defiMonitor = {
name: "DeFi Protocol Monitor",
description: "Comprehensive DeFi protocol monitoring system",
enabled: true,
expressions: [
// Monitor large swaps via events
{
type: "emitted_log",
expression: {
address: "0xpool_address",
event_name: "Swap",
event_id: "0x...", // Swap event signature
parameter_conditions: [
{
parameter_name: "amountOut",
parameter_type: "uint",
operator: ">=",
comparison_value: "1000000000000000000000" // 1000 tokens
}
],
decode_events: true
}
},
// Monitor liquidity changes
{
type: "state_change",
expression: {
address: "0xpool_address",
parameter_conditions: [
{
parameter_name: "reserve0",
parameter_type: "uint",
compare_percentage: true,
comparison_value: "10",
operator: ">="
},
{
parameter_name: "reserve1",
parameter_type: "uint",
compare_percentage: true,
comparison_value: "10",
operator: ">="
}
]
}
},
// Monitor for sandwich attacks
{
type: "sandwich_transaction",
expression: {
address: "0xpool_address",
transaction_type: "direct"
}
},
// Monitor failed transactions
{
type: "tx_error",
expression: {
addresses_to_ignore: [] // Monitor all addresses
}
}
],
delivery_channels: [{
id: "your_channel_id",
enabled: true
}]
};
await axios.post(
`/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
defiMonitor,
baseConfig
);
curl -X POST "https://api.tenderly.co/api/v1/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert" \
--header "Content-Type: application/json" \
--header "X-Access-Key: ${TENDERLY_API_KEY}" \
--data-raw '{
"name": "DeFi Protocol Monitor",
"description": "Comprehensive DeFi protocol monitoring system",
"enabled": true,
"expressions": [
{
"type": "emitted_log",
"expression": {
"address": "0xpool_address",
"event_name": "Swap",
"event_id": "0x...",
"parameter_conditions": [
{
"parameter_name": "amountOut",
"parameter_type": "uint",
"operator": ">=",
"comparison_value": "1000000000000000000000"
}
],
"decode_events": true
}
},
{
"type": "state_change",
"expression": {
"address": "0xpool_address",
"parameter_conditions": [
{
"parameter_name": "reserve0",
"parameter_type": "uint",
"compare_percentage": true,
"comparison_value": "10",
"operator": ">="
},
{
"parameter_name": "reserve1",
"parameter_type": "uint",
"compare_percentage": true,
"comparison_value": "10",
"operator": ">="
}
]
}
},
{
"type": "sandwich_transaction",
"expression": {
"address": "0xpool_address",
"transaction_type": "direct"
}
},
{
"type": "tx_error",
"expression": {
"addresses_to_ignore": []
}
}
],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": true
}]
}'
defi_monitor = {
"name": "DeFi Protocol Monitor",
"description": "Comprehensive DeFi protocol monitoring system",
"enabled": True,
"expressions": [
{
"type": "emitted_log",
"expression": {
"address": "0xpool_address",
"event_name": "Swap",
"event_id": "0x...",
"parameter_conditions": [
{
"parameter_name": "amountOut",
"parameter_type": "uint",
"operator": ">=",
"comparison_value": "1000000000000000000000"
}
],
"decode_events": True
}
},
{
"type": "state_change",
"expression": {
"address": "0xpool_address",
"parameter_conditions": [
{
"parameter_name": "reserve0",
"parameter_type": "uint",
"compare_percentage": True,
"comparison_value": "10",
"operator": ">="
},
{
"parameter_name": "reserve1",
"parameter_type": "uint",
"compare_percentage": True,
"comparison_value": "10",
"operator": ">="
}
]
}
},
{
"type": "sandwich_transaction",
"expression": {
"address": "0xpool_address",
"transaction_type": "direct"
}
},
{
"type": "tx_error",
"expression": {
"addresses_to_ignore": []
}
}
],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": True
}]
}
response = requests.post(
f"{base_url}/account/{ACCOUNT_ID}/project/{PROJECT_SLUG}/alert",
headers=headers,
json=defi_monitor
)
3. 带非活动告警的 ERC20 代币监控
使用场景:全面的代币监控,包括:- 转账监控
- 余额检查
- 状态一致性检查
- 非活动监控
- JavaScript
- Shell
- Python
const tokenMonitor = {
name: "ERC20 Token Monitor",
description: "Comprehensive ERC20 token monitoring with inactivity alerts",
enabled: true,
expressions: [
// Monitor Transfer event consistency
{
type: "erc20_transfer_matcher",
expression: {
address: "0xtoken_address",
log_name: "Transfer",
balances: "balances"
}
},
// Monitor large transfers
{
type: "emitted_log",
expression: {
address: "0xtoken_address",
event_name: "Transfer",
event_id: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
parameter_conditions: [
{
parameter_name: "value",
parameter_type: "uint",
operator: ">=",
comparison_value: "1000000000000000000000" // 1000 tokens
}
]
}
},
// Monitor total supply changes
{
type: "state_change",
expression: {
address: "0xtoken_address",
parameter_conditions: [
{
parameter_name: "totalSupply",
parameter_type: "uint",
compare_percentage: true,
comparison_value: "1",
operator: ">="
}
]
}
},
// Monitor for inactivity
{
type: "no_action",
expression: {
no_log: {
address: "0xtoken_address",
event_name: "Transfer",
event_id: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
},
check_after_seconds: 86400 // 24 hours
}
}
],
delivery_channels: [{
id: "your_channel_id",
enabled: true
}]
};
await axios.post(
`/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
tokenMonitor,
baseConfig
);
curl -X POST "https://api.tenderly.co/api/v1/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert" \
--header "Content-Type: application/json" \
--header "X-Access-Key: ${TENDERLY_API_KEY}" \
--data-raw '{
"name": "ERC20 Token Monitor",
"description": "Comprehensive ERC20 token monitoring with inactivity alerts",
"enabled": true,
"expressions": [
{
"type": "erc20_transfer_matcher",
"expression": {
"address": "0xtoken_address",
"log_name": "Transfer",
"balances": "balances"
}
},
{
"type": "emitted_log",
"expression": {
"address": "0xtoken_address",
"event_name": "Transfer",
"event_id": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"parameter_conditions": [
{
"parameter_name": "value",
"parameter_type": "uint",
"operator": ">=",
"comparison_value": "1000000000000000000000"
}
]
}
},
{
"type": "state_change",
"expression": {
"address": "0xtoken_address",
"parameter_conditions": [
{
"parameter_name": "totalSupply",
"parameter_type": "uint",
"compare_percentage": true,
"comparison_value": "1",
"operator": ">="
}
]
}
},
{
"type": "no_action",
"expression": {
"no_log": {
"address": "0xtoken_address",
"event_name": "Transfer",
"event_id": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
},
"check_after_seconds": 86400
}
}
],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": true
}]
}'
token_monitor = {
"name": "ERC20 Token Monitor",
"description": "Comprehensive ERC20 token monitoring with inactivity alerts",
"enabled": True,
"expressions": [
{
"type": "erc20_transfer_matcher",
"expression": {
"address": "0xtoken_address",
"log_name": "Transfer",
"balances": "balances"
}
},
{
"type": "emitted_log",
"expression": {
"address": "0xtoken_address",
"event_name": "Transfer",
"event_id": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"parameter_conditions": [
{
"parameter_name": "value",
"parameter_type": "uint",
"operator": ">=",
"comparison_value": "1000000000000000000000"
}
]
}
},
{
"type": "state_change",
"expression": {
"address": "0xtoken_address",
"parameter_conditions": [
{
"parameter_name": "totalSupply",
"parameter_type": "uint",
"compare_percentage": True,
"comparison_value": "1",
"operator": ">="
}
]
}
},
{
"type": "no_action",
"expression": {
"no_log": {
"address": "0xtoken_address",
"event_name": "Transfer",
"event_id": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
},
"check_after_seconds": 86400
}
}
],
"delivery_channels": [{
"id": "your_channel_id",
"enabled": True
}]
}
response = requests.post(
f"{base_url}/account/{ACCOUNT_ID}/project/{PROJECT_SLUG}/alert",
headers=headers,
json=token_monitor
)