Simulate an EVM transaction against a forked chain state using Tenderly, and verify that the resulting asset changes match stated intent. Intended to be invoked by other skills as a pre-execution safety gate.
This skill should be invoked before any onchain transaction is sent when:
data hex string from a swap router)If this skill is not installed, calling skills should warn the user that pre-execution verification is unavailable and ask for explicit confirmation before proceeding.
One environment variable is required:
export TENDERLY_NODE_ACCESS_KEY="your-key-here"
Obtain a key from Tenderly — the free tier supports approximately 62,500 simulations per month (400 TUs per simulation, 25M TU/month free).
The Tenderly gateway uses a per-chain subdomain. Route to the correct endpoint based on the transaction's chainId. The access key is passed as a header — do not embed it in the URL:
| Chain | chainId | Endpoint |
|---|---|---|
| --- | --- | --- |
| Base | 8453 | https://base.gateway.tenderly.co |
| Ethereum | 1 | https://mainnet.gateway.tenderly.co |
| Optimism | 10 | https://optimism.gateway.tenderly.co |
| Arbitrum One | 42161 | https://arbitrum.gateway.tenderly.co |
| Polygon | 137 | https://polygon.gateway.tenderly.co |
If the chainId is not in this list, skip verification, warn the user that the chain is unsupported, and require explicit confirmation before proceeding.
> Add new entries as additional chains become supported.
The calling skill provides a transaction payload with the following fields:
| Field | Type | Notes |
|---|---|---|
| --- | --- | --- |
from | address | The wallet sending the transaction |
to | address | The contract being called |
data | hex string | Encoded calldata |
value | hex string | Native token value (e.g. "0x0") |
chainId | integer | Used to select the correct Tenderly endpoint |
For cross-chain swaps, chainId refers to the source chain — the chain where the transaction is sent. Verify the outbound leg only.
TENDERLY_URL="https://base.gateway.tenderly.co"
curl -sS -X POST "$TENDERLY_URL" \
-H "Content-Type: application/json" \
-H "X-Access-Key: $TENDERLY_NODE_ACCESS_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tenderly_simulateTransaction",
"params": [
{
"from": "0xYourWalletAddress",
"to": "0xContractAddress",
"data": "0xCalldata",
"value": "0x0"
},
"latest"
]
}'
| Field | Description |
|---|---|
| --- | --- |
result.assetChanges | ERC-20 token transfers: token address, from, to, amount |
result.balanceChanges | Native token (ETH) balance changes per address |
After Tenderly simulation, check the following before approving execution:
If any check fails, stop and surface the discrepancy clearly. Do not proceed to execution without explicit user confirmation.
"Verifying transaction on Base via Tenderly..."
"Verification complete. Asset changes:"
" → Send 5 USDC from 0xYour... to 0xRouter..."
" ← Receive 0.00242 WETH at 0xYour..."
"All checks passed. Proceeding to execution."
If a check fails:
"Verification flagged an issue:"
" Output token destination is 0xUnexpected... — expected 0xYour..."
"Do not proceed until this is resolved. Aborting."
| Condition | Action |
|---|---|
| --- | --- |
TENDERLY_NODE_ACCESS_KEY not set | Warn that verification is unavailable; require explicit user confirmation before proceeding |
chainId not in supported list | Warn that chain is unsupported for verification; require explicit user confirmation |
| Tenderly returns an error | Surface the error message; treat as verification failure and require confirmation |
| Rate limit hit (HTTP 429) | Warn the user; do not retry automatically; require confirmation to proceed without verification |
| Verification passes all checks | Return control to the calling skill to proceed with execution |
| Verification fails a check | Halt; surface the specific discrepancy; do not execute |
共 1 个版本