Type/to search
Built-in Functions
Structures
Built-in Variables and Constants
Conventions
Exchanges
Capability Matrix
Centralized Exchanges
Decentralized Exchanges (DEX)
Prediction Markets
Securities and Futures
On-chain & Custom

Calls Ethereum RPC methods (select eth when configuring the Web3 exchange object).
exchange.IO("api", "tron", ...) calling method is used to call TRON RPC methods (select tron when configuring the Web3 exchange object).

exchange.IO(k, blockChain, rpcMethod)
exchange.IO(k, blockChain, rpcMethod, ...args)

Examples

  • Query the ETH balance in the wallet.

    javascript
    // Convert an on-chain integer amount into a human-readable amount. decimals is the token precision: // 18 for ETH, 6 for USDT/USDC. // Supports both decimal strings and hexadecimal strings prefixed with 0x: RPC methods such as // eth_getBalance return hexadecimal strings prefixed with 0x. function toAmount(raw, decimals) { var t = String(raw).trim() if (t.slice(0, 2).toLowerCase() == "0x") t = BigInt(t).toString() var d = Number(decimals) || 0 if (d == 0) return Number(t) var s = t.length > d ? t : new Array(d - t.length + 2).join("0") + t var frac = s.slice(s.length - d).replace(/0+$/, "") return Number(s.slice(0, s.length - d) + (frac ? "." + frac : "")) } function main() { // "owner" needs to be replaced with the actual wallet address // The position of "latest" is the block parameter, with optional values: 'latest', 'earliest' // or 'pending'. For details, see https://eth.wiki/json-rpc/API#the-default-block-parameter // The return value ethBalance is a hexadecimal string, for example: 0x9b19ce56113070 var ethBalance = exchange.IO("api", "eth", "eth_getBalance", "owner", "latest") // The precision of ETH is 18, i.e. 1 ETH equals 1e18 of the smallest unit var ethDecimal = 18 // On-chain amounts are all integers; converting to a human-readable amount requires shifting // the decimal point according to the precision. The shift is done on the string, // and only the final Number() conversion may round the last digit: 0x9b19ce56113070 // (43656995388076144) prints as 0.043656995388076145, the exact value being // 0.043656995388076144. // For an exact result use exchange.IO("fromUnits", ethBalance, 18), which returns a decimal // string Log(toAmount(ethBalance, ethDecimal)) }
  • For ETH transfers, you can set the {gasPrice: 11, gasLimit: 111, nonce: 111} parameter according to your specific needs. This parameter is passed as the last argument of the exchange.IO() function. Options you do not need can be omitted. Note that a plain transfer without gasPrice is priced at a fixed 100 Gwei with a default gasLimit of 21000, so query the gas price with eth_gasPrice first and pass it in.

    This parameter also supports the data and dryRun fields: data is arbitrary call data (a hexadecimal string starting with 0x), used to directly send the transaction {to, data, value} returned by APIs such as aggregators and Pendle; when data is set, the gas price and gasLimit are estimated by the node in the same way as for a contract call. When dryRun is set to true, the transaction is only signed and not broadcast, and an object containing fields such as hash, raw (the signed transaction), nonce, and gasLimit is returned, which can be used to inspect the transaction content or to send it through another channel. For example: exchange.IO("api", "eth", "send", router, value, {data: calldata, dryRun: true}). Before sending, you can first use exchange.IO("call", router, calldata, {value: value}) to simulate the call. When nonce is not set, the system automatically assigns a nonce and keeps it in sync with the chain, so nonces are not reused when sending transactions consecutively; see exchange.IO("nonce", ...) for details. If a transaction remains unconfirmed on-chain for a long time, you can use exchange.IO("speedUp", ...) to resend it with a higher gas price, or use exchange.IO("cancelTx", ...) to cancel the transaction.

    javascript
    // Human-readable amount -> on-chain integer amount (string). The decimal point is shifted purely // via string operations, without any floating-point arithmetic, // so amounts exceeding 2^53 do not lose precision either. When 17 or more significant digits are // needed, pass amount as a string. function toInnerAmount(amount, decimals) { var t = String(amount), d = Number(decimals) || 0 var m = /^([0-9]*)(?:\.([0-9]*))?[eE]([+-]?[0-9]+)$/.exec(t) if (m) { // Expand scientific notation: 0.0000001 is represented by JavaScript as 1e-7 var digits = (m[1] || "") + (m[2] || ""), point = (m[1] || "").length + parseInt(m[3], 10) t = point <= 0 ? "0." + new Array(1 - point).join("0") + digits : point >= digits.length ? digits + new Array(point - digits.length + 1).join("0") : digits.slice(0, point) + "." + digits.slice(point) } var dot = t.indexOf("."), int = dot < 0 ? t : t.slice(0, dot) var frac = dot < 0 ? "" : t.slice(dot + 1) // Decimal places beyond the precision are truncated directly frac = frac.slice(0, d) while (frac.length < d) frac += "0" return (int + frac).replace(/^0+(?=[0-9])/, "") } function main() { // The precision unit of ETH is 1e18 var ethDecimal = 18 // Transfer amount (human-readable amount), e.g., 0.01 ETH var sendAmount = 0.01 // Convert to the integer amount used on-chain: 0.01 -> "10000000000000000" var amount = toInnerAmount(sendAmount, ethDecimal) // "toAddress" is the ETH wallet address of the transfer recipient and must be filled in // according to the actual situation; amount is the transfer amount exchange.IO("api", "eth", "send", "toAddress", amount) }
  • Query gasPrice.

    javascript
    // The toAmount function is used to convert a hex-encoded value to a decimal value. Passing 0 for // decimals means the decimal point is not shifted function toAmount(raw, decimals) { var t = String(raw).trim() if (t.slice(0, 2).toLowerCase() == "0x") t = BigInt(t).toString() var d = Number(decimals) || 0 if (d == 0) return Number(t) var s = t.length > d ? t : new Array(d - t.length + 2).join("0") + t var frac = s.slice(s.length - d).replace(/0+$/, "") return Number(s.slice(0, s.length - d) + (frac ? "." + frac : "")) } function main() { var gasPrice = exchange.IO("api", "eth", "eth_gasPrice") Log("gasPrice:", toAmount(gasPrice, 0)) // Output: gasPrice: 5000000000 (in wei, i.e. 5 gwei) Log("gasPrice:", toAmount(gasPrice, 9), "gwei") // The precision unit of gwei is 1e9 }
  • Call eth_estimateGas to estimate the Gas required for a transaction.

    javascript
    // The toAmount function is used to convert a hexadecimal-encoded value to a decimal value function toAmount(raw, decimals) { var t = String(raw).trim() if (t.slice(0, 2).toLowerCase() == "0x") t = BigInt(t).toString() var d = Number(decimals) || 0 if (d == 0) return Number(t) var s = t.length > d ? t : new Array(d - t.length + 2).join("0") + t var frac = s.slice(s.length - d).replace(/0+$/, "") return Number(s.slice(0, s.length - d) + (frac ? "." + frac : "")) } function main() { // Encode the call to the approve (authorization) method var data = exchange.IO("encode", "0x111111111117dC0aa78b770fA6A738034120C302", "approve", "0xe592427a0aece92de3edee1f18e0157c05861564", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") Log("data:", data) var gasPrice = exchange.IO("api", "eth", "eth_gasPrice") Log("gasPrice:", toAmount(gasPrice, 0)) var obj = { "from" : "0x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // walletAddress "to" : "0x111111111117dC0aa78b770fA6A738034120C302", "gasPrice" : gasPrice, "value" : "0x0", "data" : "0x" + data, } var gasLimit = exchange.IO("api", "eth", "eth_estimateGas", obj) Log("gasLimit:", toAmount(gasLimit, 0)) // Gas fee = gasLimit * gasPrice. Both are large integers in wei, so multiply them using BigInt // to avoid precision loss, // then convert by 1e18 into a human-readable ETH amount Log("gas fee", toAmount((BigInt(gasLimit) * BigInt(gasPrice)).toString(), 18)) }

Returns

TypeDescription

string / number / bool / object / array / any

Return value of the called RPC method.

Arguments

NameTypeRequiredDescription

k

string

Yes

Function of the exchange.IO() function. When set to api, it indicates that the function is used to extend the call request.

blockChain

string

Yes

Blockchain network called by the exchange.IO() function. When set to eth, it indicates calling RPC methods of the Ethereum network; when set to tron, it indicates calling RPC methods of the TRON network.

rpcMethod

string

Yes

RPC method to be called by the exchange.IO() function.

arg

string / number / bool / object / array / any

No

Parameters of the RPC method to be called.
arg parameters can be multiple, and their type and number depend on the RPC method specified by the rpcMethod parameter.

See Also

Remarks

When the second parameter of the exchange.IO() function is set to eth, you can directly call the RPC methods supported by the Ethereum node server.

Node methods return the node's result as is. When the node returns null (for example eth_getTransactionReceipt for a transaction not yet mined), a null value is returned without an error; when the node returns an error, a null value is returned with the error in GetLastError(), and a contract revert reason is decoded into readable text.

exchange.IO("api", "eth", "send", toAddress, value[, options]) sends native coin from the current wallet; value is an on-chain integer (wei), and the transaction hash is returned. A plain transfer without data is sent as a legacy transaction: without gasPrice it is priced at a fixed 100 Gwei (plus a tiny random amount), and without gasLimit the limit is 21000. That is usually too high on Ethereum mainnet, so query eth_gasPrice first and pass it in. With data the transfer is handled as a contract call: the gas limit is estimated by the node and the gas price is set the same way as for contract write methods (an EIP-1559 transaction on chains that support it; see exchange.IO("api", ...)).

On TRON the second argument is tron and method names are case-insensitive, for example GetNowBlock, GetAccount, GetTransactionInfoByID and TRC20ContractBalance. send takes the recipient address and the TRX amount (in sun, 1 TRX = 1000000 sun) and returns the transaction ID without 0x. Methods that need a signature (transfers, contract triggers and so on) are signed and broadcast automatically. Full-node endpoints that are not built in can be called with the path and request body directly: exchange.IO("api", "tron", "/wallet/endpointName", {body}).