| Crates.io | tndrly |
| lib.rs | tndrly |
| version | 0.3.3 |
| created_at | 2026-01-12 00:39:49.458055+00 |
| updated_at | 2026-01-22 21:40:52.514054+00 |
| description | Unofficial Rust client for the Tenderly API - simulations, virtual testnets, alerts, and more |
| homepage | |
| repository | https://github.com/yldfi/yldfi-rs/tree/main/crates/tndrly |
| max_upload_size | |
| id | 2036778 |
| size | 387,862 |
Unofficial Rust client for the Tenderly API
[dependencies]
tndrly = "0.3"
tokio = { version = "1", features = ["full"] }
use tndrly::Client;
use tndrly::simulation::SimulationRequest;
#[tokio::main]
async fn main() -> Result<(), tndrly::Error> {
// Create client from environment variables
let client = Client::from_env()?;
// Simulate a transaction
let request = SimulationRequest::new(
"0x0000000000000000000000000000000000000000",
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"0x70a08231000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045"
)
.gas(100000)
.save(true);
let result = client.simulation().simulate(&request).await?;
println!("Gas used: {}", result.simulation.gas_used);
println!("Status: {}", if result.simulation.status { "success" } else { "failed" });
Ok(())
}
export TENDERLY_ACCESS_KEY="your-access-key"
export TENDERLY_ACCOUNT="your-account-slug"
export TENDERLY_PROJECT="your-project-slug"
use tndrly::simulation::{SimulationRequest, BundleSimulationRequest};
// Single simulation
let request = SimulationRequest::new(from, to, calldata)
.network_id("1")
.value_wei(1_000_000_000_000_000_000u128)
.gas(100000)
.save(true);
let result = client.simulation().simulate(&request).await?;
// Bundle simulation
let bundle = BundleSimulationRequest::new(vec![tx1, tx2, tx3]);
let results = client.simulation().simulate_bundle(&bundle).await?;
// List saved simulations
let sims = client.simulation().list(0, 10).await?;
// Share a simulation
let url = client.simulation().share("sim-id").await?;
use tndrly::vnets::{CreateVNetRequest, ListVNetsQuery};
// Create a VNet
let request = CreateVNetRequest::new("my-testnet", "My TestNet", 1)
.block_number(18000000)
.sync_state(true);
let vnet = client.vnets().create(&request).await?;
// List VNets
let vnets = client.vnets().list(None).await?;
// Delete VNets (CI cleanup)
client.vnets().delete_many(vec!["id1".into(), "id2".into()]).await?;
Note: The Tenderly Alerts API uses an undocumented request format. Alert creation (
create()) may not work as expected. Read operations (list(),get(),history()) work correctly. See src/alerts/types.rs for details.
use tndrly::alerts::AlertHistoryQuery;
// List existing alerts
let alerts = client.alerts().list().await?;
// Get alert history
let history = client.alerts()
.history(Some(AlertHistoryQuery::new().page(1).per_page(50)))
.await?;
// Get a specific alert
let alert = client.alerts().get("alert-id").await?;
use tndrly::contracts::{AddContractRequest, VerifyContractRequest};
// Add a contract
let contract = client.contracts()
.add(&AddContractRequest::new("1", "0xAddress")
.display_name("My Contract")
.tag("defi"))
.await?;
// Verify source code
let result = client.contracts()
.verify(&VerifyContractRequest::new(
"1",
"0xAddress",
"MyContract",
source_code,
"v0.8.19+commit.7dd6d404",
).optimization(true, 200))
.await?;
use tndrly::actions::{CreateActionRequest, ActionTrigger, TriggerConfig};
// Create an action
let action = client.actions()
.create(&CreateActionRequest::new(
"Notify Slack",
ActionTrigger::Alert,
source_code,
)
.trigger_config(TriggerConfig::alert("alert-id"))
.secret("SLACK_WEBHOOK", webhook_url))
.await?;
// View execution logs
let logs = client.actions().logs(&action.id).await?;
use tndrly::wallets::{AddWalletRequest, UpdateWalletRequest};
// Add a wallet to monitor
let wallet = client.wallets()
.add(&AddWalletRequest::new("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")
.display_name("vitalik.eth")
.tag("whale"))
.await?;
// List all wallets
let wallets = client.wallets().list().await?;
// Update wallet metadata
client.wallets()
.update("0xd8dA...", &UpdateWalletRequest::new()
.display_name("Vitalik Buterin"))
.await?;
// Remove a wallet
client.wallets().remove("0xd8dA...").await?;
MIT