eth_sendTransaction - Monad RPC Method
Send a transaction from an unlocked account on Monad. Requires the node to hold the sender's private key — intended for development and testing only.
Creates and sends a new transaction from an unlocked account on Monad. The node signs the transaction server-side using the private key associated with the from address.
Why Monad? Build on the parallel EVM L1 delivering 10,000 TPS with 400ms blocks and sub-cent gas fees with optimistic parallel execution, MonadBFT consensus, $244M Paradigm-led funding, and consumer-grade validator hardware requirements.
Security Warning: Public Dwellir endpoints do not manage unlocked accounts for you. On shared infrastructure,
eth_sendTransactioncommonly returns an unsupported-method response or an account-management error such asunknown account, depending on the client. For production applications, sign transactions client-side and useeth_sendRawTransactioninstead.
When to Use This Method
eth_sendTransaction is useful for high-performance dApp developers, DeFi builders, and teams requiring Ethereum compatibility at scale in development scenarios:
- Local Development — Send transactions quickly on local nodes (Hardhat, Anvil, Ganache) without managing private keys
- Testing Workflows — Rapidly prototype and test contract interactions on dev networks
- Scripted Deployments — Deploy contracts on private or permissioned networks with unlocked accounts
Request Parameters
Address of the sending account (must be unlocked on the node)
Recipient address (omit for contract creation)
Gas limit (default: 90000)
Gas price in wei (legacy transactions)
Maximum total fee per gas (EIP-1559 transactions)
Maximum priority fee per gas (EIP-1559 transactions)
Value to send in wei
Compiled contract code or encoded method call
Response Body
The transaction hash, or zero hash if the transaction is not yet available
Code Examples
# Local dev node only. Public Dwellir endpoints do not expose unlocked-account signing.
curl -X POST http://127.0.0.1:8545 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_sendTransaction",
"params": [{
"from": "0x407d73d8a49eeb85d32cf465507dd71d507100c1",
"to": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"gas": "0x76c0",
"gasPrice": "0x9184e72a000",
"value": "0x9184e72a"
}],
"id": 1
}'// On a local dev node with unlocked accounts (e.g., Hardhat)
const response = await fetch('http://127.0.0.1:8545', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'eth_sendTransaction',
params: [{
from: '0x407d73d8a49eeb85d32cf465507dd71d507100c1',
to: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b',
gas: '0x76c0',
gasPrice: '0x9184e72a000',
value: '0x9184e72a'
}],
id: 1
})
});
const { result: txHash } = await response.json();
console.log('Monad tx hash:', txHash);
// Recommended for production: client-side signing
import { Wallet, JsonRpcProvider, parseEther } from 'ethers';
const provider = new JsonRpcProvider('https://api-monad-mainnet-full.n.dwellir.com/YOUR_API_KEY');
const wallet = new Wallet('YOUR_PRIVATE_KEY', provider);
const tx = await wallet.sendTransaction({
to: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b',
value: parseEther('0.1')
});
console.log('Monad tx hash:', tx.hash);import requests
from web3 import Web3
# Direct RPC call on a LOCAL dev node with unlocked accounts
response = requests.post(
'http://127.0.0.1:8545',
json={
'jsonrpc': '2.0',
'method': 'eth_sendTransaction',
'params': [{
'from': '0x407d73d8a49eeb85d32cf465507dd71d507100c1',
'to': '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b',
'gas': '0x76c0',
'gasPrice': '0x9184e72a000',
'value': '0x9184e72a'
}],
'id': 1
}
)
tx_hash = response.json()['result']
print(f'Monad tx hash: {tx_hash}')
# Recommended for production: client-side signing
w3 = Web3(Web3.HTTPProvider('https://api-monad-mainnet-full.n.dwellir.com/YOUR_API_KEY'))
account = w3.eth.account.from_key('YOUR_PRIVATE_KEY')
tx = {
'to': '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b',
'value': w3.to_wei(0.1, 'ether'),
'gas': 21000,
'gasPrice': w3.eth.gas_price,
'nonce': w3.eth.get_transaction_count(account.address),
'chainId': w3.eth.chain_id
}
signed = account.sign_transaction(tx)
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
print(f'Monad tx hash: {tx_hash.hex()}')package main
import (
"context"
"crypto/ecdsa"
"fmt"
"log"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
)
func main() {
client, err := ethclient.Dial("https://api-monad-mainnet-full.n.dwellir.com/YOUR_API_KEY")
if err != nil {
log.Fatal(err)
}
// Recommended: client-side signing with eth_sendRawTransaction
privateKey, err := crypto.HexToECDSA("YOUR_PRIVATE_KEY_HEX")
if err != nil {
log.Fatal(err)
}
publicKey := privateKey.Public().(*ecdsa.PublicKey)
fromAddress := crypto.PubkeyToAddress(*publicKey)
nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
log.Fatal(err)
}
toAddress := common.HexToAddress("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
log.Fatal(err)
}
tx := types.NewTransaction(nonce, toAddress, big.NewInt(100000000), 21000, gasPrice, nil)
chainID, err := client.ChainID(context.Background())
if err != nil {
log.Fatal(err)
}
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
if err != nil {
log.Fatal(err)
}
err = client.SendTransaction(context.Background(), signedTx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Monad tx hash: %s\n", signedTx.Hash().Hex())
}Common Use Cases
1. Local Development with Hardhat
Send transactions using Hardhat's pre-funded unlocked accounts:
async function devTransfer(provider, from, to, value) {
const txHash = await provider.send('eth_sendTransaction', [{
from,
to,
value: '0x' + value.toString(16),
gas: '0x5208' // 21000
}]);
const receipt = await provider.waitForTransaction(txHash);
console.log(`Transfer confirmed in block ${receipt.blockNumber}`);
return receipt;
}2. Contract Deployment on Dev Network
Deploy contracts without managing private keys locally:
async function deployContract(provider, from, bytecode) {
const txHash = await provider.send('eth_sendTransaction', [{
from,
data: bytecode,
gas: '0x4C4B40' // 5,000,000
}]);
const receipt = await provider.waitForTransaction(txHash);
console.log(`Contract deployed at: ${receipt.contractAddress}`);
return receipt.contractAddress;
}3. Batch Transfers in Testing
Send multiple test transactions on Monad dev networks:
async function batchTransfer(provider, from, recipients) {
const hashes = [];
for (const { to, value } of recipients) {
const hash = await provider.send('eth_sendTransaction', [{
from,
to,
value: '0x' + value.toString(16),
gas: '0x5208'
}]);
hashes.push(hash);
}
return hashes;
}Error Handling
Common errors and solutions:
| Error Code | Description | Solution |
|---|---|---|
| -32000 | Method unavailable or unknown account | Use client-side signing with eth_sendRawTransaction |
| -32000 | Insufficient funds | Ensure from address has enough balance for value + gas |
| -32000 | Nonce too low | A transaction with this nonce was already mined — let the node auto-assign |
| -32601 | Method not found | Method disabled on this node — use client-side signing |
| -32602 | Invalid params | Verify transaction object fields and hex encoding |
Related Methods
eth_sendRawTransaction— Broadcast a pre-signed transaction (recommended for production)eth_signTransaction— Sign without sending (requires unlocked account)eth_estimateGas— Estimate gas cost before sending
eth_signTransaction
Sign a transaction without broadcasting it on Monad. Public shared RPC endpoints commonly return deprecation, unsupported-method, or account-management errors because they do not keep unlocked signers.
eth_call
Execute smart contract calls without creating transactions on Monad. Essential for reading contract state for high-throughput DeFi, latency-sensitive trading, and scalable EVM applications.