Skip to main content
POST
/
evm
ots_getInternalOperations
curl --request POST \
  --url https://hyperliquid-mainnet.core.chainstack.com/4f8d8f4040bdacd1577bff8058438274/evm \
  --header 'Content-Type: application/json' \
  --data '
{
  "jsonrpc": "2.0",
  "method": "ots_getInternalOperations",
  "params": [
    "0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381"
  ],
  "id": 1
}
'
import requests

url = "https://hyperliquid-mainnet.core.chainstack.com/4f8d8f4040bdacd1577bff8058438274/evm"

payload = {
"jsonrpc": "2.0",
"method": "ots_getInternalOperations",
"params": ["0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381"],
"id": 1
}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
jsonrpc: '2.0',
method: 'ots_getInternalOperations',
params: ['0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381'],
id: 1
})
};

fetch('https://hyperliquid-mainnet.core.chainstack.com/4f8d8f4040bdacd1577bff8058438274/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://hyperliquid-mainnet.core.chainstack.com/4f8d8f4040bdacd1577bff8058438274/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([
'jsonrpc' => '2.0',
'method' => 'ots_getInternalOperations',
'params' => [
'0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381'
],
'id' => 1
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);

$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://hyperliquid-mainnet.core.chainstack.com/4f8d8f4040bdacd1577bff8058438274/evm"

payload := strings.NewReader("{\n \"jsonrpc\": \"2.0\",\n \"method\": \"ots_getInternalOperations\",\n \"params\": [\n \"0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381\"\n ],\n \"id\": 1\n}")

req, _ := http.NewRequest("POST", url, payload)

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://hyperliquid-mainnet.core.chainstack.com/4f8d8f4040bdacd1577bff8058438274/evm")
.header("Content-Type", "application/json")
.body("{\n \"jsonrpc\": \"2.0\",\n \"method\": \"ots_getInternalOperations\",\n \"params\": [\n \"0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381\"\n ],\n \"id\": 1\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://hyperliquid-mainnet.core.chainstack.com/4f8d8f4040bdacd1577bff8058438274/evm")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"ots_getInternalOperations\",\n \"params\": [\n \"0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381\"\n ],\n \"id\": 1\n}"

response = http.request(request)
puts response.read_body
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": [
    {
      "type": 0,
      "from": "0x5555555555555555555555555555555555555555",
      "to": "0x6666666666666666666666666666666666666666",
      "value": "0xde0b6b3a7640000"
    }
  ]
}
This method is available on Chainstack. Not all Hyperliquid methods are available on Chainstack, as the open-source node implementation does not support them yet — see Hyperliquid methods for the full availability breakdown.
The ots_getInternalOperations JSON-RPC method retrieves all internal ETH transfers and operations that occurred within a transaction on the Hyperliquid EVM blockchain. This Otterscan-specific method reveals value transfers that happen inside smart contract execution, which are not visible in standard transaction receipts.
Get your own node endpoint todayStart for free and get your app to production levels immediately. No credit card required.You can sign up with your GitHub, X, Google, or Microsoft account.

Parameters

  1. transaction hash (string, required): The hash of the transaction to analyze

Response

The method returns an array of internal operation objects representing all value transfers within the transaction.

Response structure

Each internal operation contains:
  • type — the operation type (0: transfer, 1: self-destruct, 2: create, 3: create2)
  • from — the address sending the value
  • to — the address receiving the value
  • value — the amount of ETH transferred in wei (hex)

Usage example

curl -X POST https://hyperliquid-mainnet.core.chainstack.com/4f8d8f4040bdacd1577bff8058438274/evm \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "ots_getInternalOperations",
    "params": ["0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381"],
    "id": 1
  }'
from web3 import Web3

w3 = Web3(Web3.HTTPProvider("YOUR_CHAINSTACK_ENDPOINT"))

tx_hash = "0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381"

# ots_getInternalOperations is an Otterscan method, so call it via the raw JSON-RPC provider
response = w3.provider.make_request("ots_getInternalOperations", [tx_hash])
print(response["result"])
import { JsonRpcProvider } from "ethers";

const provider = new JsonRpcProvider("YOUR_CHAINSTACK_ENDPOINT");

const txHash =
  "0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381";

// ots_getInternalOperations is an Otterscan method, so send a raw JSON-RPC request
const operations = await provider.send("ots_getInternalOperations", [txHash]);
console.log(operations);
import { createPublicClient, http } from "viem";

const client = createPublicClient({
  transport: http("YOUR_CHAINSTACK_ENDPOINT"),
});

const txHash =
  "0xf94f3d2ed5b59aefb6a0e566af8e86552014d84f6ed2f38a1366dedffe723381";

// ots_getInternalOperations is an Otterscan method, so use the raw request method
const operations = await client.request({
  method: "ots_getInternalOperations" as any,
  params: [txHash] as any,
});
console.log(operations);
Use your own endpoint in your code. The code examples use a placeholder Chainstack endpoint (YOUR_CHAINSTACK_ENDPOINT) — replace it with your own Hyperliquid node endpoint from the Chainstack console. The curl above uses a shared public endpoint for quick checks only; do not use it in production.

Example response

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": [
    {
      "type": 0,
      "from": "0x5555555555555555555555555555555555555555",
      "to": "0x6666666666666666666666666666666666666666",
      "value": "0xde0b6b3a7640000"
    },
    {
      "type": 0,
      "from": "0x6666666666666666666666666666666666666666",
      "to": "0x7777777777777777777777777777777777777777",
      "value": "0x6f05b59d3b20000"
    }
  ]
}

Operation types

The type field indicates the operation:
  • 0 — Regular ETH transfer
  • 1 — Self-destruct (contract deletion with balance transfer)
  • 2 — Contract creation via CREATE opcode
  • 3 — Contract creation via CREATE2 opcode

Use cases

The ots_getInternalOperations method is essential for:
  • Value flow analysis: Track how ETH moves through complex contract interactions
  • DeFi debugging: Understand token swaps and liquidity operations
  • Security auditing: Detect unexpected value transfers in contracts
  • Payment splitting: Analyze how contracts distribute payments
  • Fee tracking: Monitor protocol fees and revenue sharing
  • MEV analysis: Study arbitrage and sandwich attack patterns
  • Wallet tracking: Follow funds through mixer and privacy protocols
  • Tax reporting: Identify all value transfers for accounting
  • Contract verification: Ensure contracts handle ETH as expected
  • Forensic analysis: Investigate exploits and fund movements
This method is particularly valuable for understanding complex DeFi transactions where multiple contracts interact and transfer value in ways not visible through standard transaction data.

Body

application/json
jsonrpc
enum<string>
default:2.0
required

JSON-RPC version

Available options:
2.0
method
enum<string>
default:ots_getInternalOperations
required

The RPC method name

Available options:
ots_getInternalOperations
params
array
required

Parameters: [transaction hash]

id
integer
default:1
required

Request identifier

Response

200 - application/json

Successful response with internal operations

jsonrpc
string

JSON-RPC version

id
integer

Request identifier

result
array

Array of internal operations

Last modified on July 7, 2026