curl --request POST \
--url https://api.range.org/v2/simulate/evm \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"network": "eth",
"transaction": {
"from": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"value": "0x0",
"data": "0xa9059cbb…",
"gas": "0x5208",
"gas_price": "0x3b9aca00",
"max_fee_per_gas": "0x3b9aca00",
"max_priority_fee_per_gas": "0x3b9aca00",
"nonce": "0x1"
},
"state_overrides": {
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045": {
"balance": "0xde0b6b3a7640000"
}
}
}
'import requests
url = "https://api.range.org/v2/simulate/evm"
payload = {
"network": "eth",
"transaction": {
"from": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"value": "0x0",
"data": "0xa9059cbb…",
"gas": "0x5208",
"gas_price": "0x3b9aca00",
"max_fee_per_gas": "0x3b9aca00",
"max_priority_fee_per_gas": "0x3b9aca00",
"nonce": "0x1"
},
"state_overrides": { "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045": { "balance": "0xde0b6b3a7640000" } }
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
network: 'eth',
transaction: {
from: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
to: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
value: '0x0',
data: '0xa9059cbb…',
gas: '0x5208',
gas_price: '0x3b9aca00',
max_fee_per_gas: '0x3b9aca00',
max_priority_fee_per_gas: '0x3b9aca00',
nonce: '0x1'
},
state_overrides: {'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045': {balance: '0xde0b6b3a7640000'}}
})
};
fetch('https://api.range.org/v2/simulate/evm', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.range.org/v2/simulate/evm",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'network' => 'eth',
'transaction' => [
'from' => '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
'to' => '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
'value' => '0x0',
'data' => '0xa9059cbb…',
'gas' => '0x5208',
'gas_price' => '0x3b9aca00',
'max_fee_per_gas' => '0x3b9aca00',
'max_priority_fee_per_gas' => '0x3b9aca00',
'nonce' => '0x1'
],
'state_overrides' => [
'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045' => [
'balance' => '0xde0b6b3a7640000'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.range.org/v2/simulate/evm"
payload := strings.NewReader("{\n \"network\": \"eth\",\n \"transaction\": {\n \"from\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n \"to\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"value\": \"0x0\",\n \"data\": \"0xa9059cbb…\",\n \"gas\": \"0x5208\",\n \"gas_price\": \"0x3b9aca00\",\n \"max_fee_per_gas\": \"0x3b9aca00\",\n \"max_priority_fee_per_gas\": \"0x3b9aca00\",\n \"nonce\": \"0x1\"\n },\n \"state_overrides\": {\n \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\": {\n \"balance\": \"0xde0b6b3a7640000\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.range.org/v2/simulate/evm")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"network\": \"eth\",\n \"transaction\": {\n \"from\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n \"to\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"value\": \"0x0\",\n \"data\": \"0xa9059cbb…\",\n \"gas\": \"0x5208\",\n \"gas_price\": \"0x3b9aca00\",\n \"max_fee_per_gas\": \"0x3b9aca00\",\n \"max_priority_fee_per_gas\": \"0x3b9aca00\",\n \"nonce\": \"0x1\"\n },\n \"state_overrides\": {\n \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\": {\n \"balance\": \"0xde0b6b3a7640000\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/simulate/evm")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"network\": \"eth\",\n \"transaction\": {\n \"from\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n \"to\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"value\": \"0x0\",\n \"data\": \"0xa9059cbb…\",\n \"gas\": \"0x5208\",\n \"gas_price\": \"0x3b9aca00\",\n \"max_fee_per_gas\": \"0x3b9aca00\",\n \"max_priority_fee_per_gas\": \"0x3b9aca00\",\n \"nonce\": \"0x1\"\n },\n \"state_overrides\": {\n \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\": {\n \"balance\": \"0xde0b6b3a7640000\"\n }\n }\n}"
response = http.request(request)
puts response.read_bodySimulate an EVM Transaction
Simulate an unsigned EVM transaction, including a Safe execTransaction before any signatures exist, to inspect balance changes, transfers, and approvals.
curl --request POST \
--url https://api.range.org/v2/simulate/evm \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"network": "eth",
"transaction": {
"from": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"value": "0x0",
"data": "0xa9059cbb…",
"gas": "0x5208",
"gas_price": "0x3b9aca00",
"max_fee_per_gas": "0x3b9aca00",
"max_priority_fee_per_gas": "0x3b9aca00",
"nonce": "0x1"
},
"state_overrides": {
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045": {
"balance": "0xde0b6b3a7640000"
}
}
}
'import requests
url = "https://api.range.org/v2/simulate/evm"
payload = {
"network": "eth",
"transaction": {
"from": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"value": "0x0",
"data": "0xa9059cbb…",
"gas": "0x5208",
"gas_price": "0x3b9aca00",
"max_fee_per_gas": "0x3b9aca00",
"max_priority_fee_per_gas": "0x3b9aca00",
"nonce": "0x1"
},
"state_overrides": { "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045": { "balance": "0xde0b6b3a7640000" } }
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
network: 'eth',
transaction: {
from: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
to: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
value: '0x0',
data: '0xa9059cbb…',
gas: '0x5208',
gas_price: '0x3b9aca00',
max_fee_per_gas: '0x3b9aca00',
max_priority_fee_per_gas: '0x3b9aca00',
nonce: '0x1'
},
state_overrides: {'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045': {balance: '0xde0b6b3a7640000'}}
})
};
fetch('https://api.range.org/v2/simulate/evm', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.range.org/v2/simulate/evm",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'network' => 'eth',
'transaction' => [
'from' => '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
'to' => '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
'value' => '0x0',
'data' => '0xa9059cbb…',
'gas' => '0x5208',
'gas_price' => '0x3b9aca00',
'max_fee_per_gas' => '0x3b9aca00',
'max_priority_fee_per_gas' => '0x3b9aca00',
'nonce' => '0x1'
],
'state_overrides' => [
'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045' => [
'balance' => '0xde0b6b3a7640000'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.range.org/v2/simulate/evm"
payload := strings.NewReader("{\n \"network\": \"eth\",\n \"transaction\": {\n \"from\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n \"to\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"value\": \"0x0\",\n \"data\": \"0xa9059cbb…\",\n \"gas\": \"0x5208\",\n \"gas_price\": \"0x3b9aca00\",\n \"max_fee_per_gas\": \"0x3b9aca00\",\n \"max_priority_fee_per_gas\": \"0x3b9aca00\",\n \"nonce\": \"0x1\"\n },\n \"state_overrides\": {\n \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\": {\n \"balance\": \"0xde0b6b3a7640000\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.range.org/v2/simulate/evm")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"network\": \"eth\",\n \"transaction\": {\n \"from\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n \"to\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"value\": \"0x0\",\n \"data\": \"0xa9059cbb…\",\n \"gas\": \"0x5208\",\n \"gas_price\": \"0x3b9aca00\",\n \"max_fee_per_gas\": \"0x3b9aca00\",\n \"max_priority_fee_per_gas\": \"0x3b9aca00\",\n \"nonce\": \"0x1\"\n },\n \"state_overrides\": {\n \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\": {\n \"balance\": \"0xde0b6b3a7640000\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/simulate/evm")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"network\": \"eth\",\n \"transaction\": {\n \"from\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n \"to\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"value\": \"0x0\",\n \"data\": \"0xa9059cbb…\",\n \"gas\": \"0x5208\",\n \"gas_price\": \"0x3b9aca00\",\n \"max_fee_per_gas\": \"0x3b9aca00\",\n \"max_priority_fee_per_gas\": \"0x3b9aca00\",\n \"nonce\": \"0x1\"\n },\n \"state_overrides\": {\n \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\": {\n \"balance\": \"0xde0b6b3a7640000\"\n }\n }\n}"
response = http.request(request)
puts response.read_bodyAuthorizations
Authorization method required to allow user to access the api endpoints.
Body
eth, arb1, base, oeth, pol, bnb, avax "eth"
Show child attributes
Show child attributes
Per-address state overrides applied before the simulation, keyed by address. Forwarded to the node as-is.
{ "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045": { "balance": "0xde0b6b3a7640000" } }
Response
"eth"
success, reverted Show child attributes
Show child attributes
"0x5208"
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Every address the simulation touched, ordered by screening priority rather than by where it appeared in the transaction. The parties to the transaction come first, then the Safe and the contracts a batch pointed at, then the contracts that were merely called. Position means nothing beyond that, so it should not be read as the order in which effects happened.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Present only when the calldata decoded as a Safe execTransaction and the Safe answered. For every other transaction this field is absent altogether, rather than null or an empty object.
Show child attributes
Show child attributes
One object per MultiSend entry, in payload order. Null whenever safe.batch_state is not decoded, and absent alongside safe. The arrays above carry applied effects only, so on a failed batch they are empty while each entry still reports what it attempted.
Show child attributes
Show child attributes
Was this page helpful?