eth_sendRawTransaction - Moonbase RPC Method
Submit signed transactions to Moonbase Alpha. Essential for broadcasting transactions for EVM dApp testing, XCM integration validation, and pre-mainnet deployment verification.
Submits a pre-signed transaction for broadcast to Moonbase Alpha.
Why Moonbase? Build on the Moonbeam testnet for risk-free EVM dApp development and deployment testing with free testnet tokens, full EVM compatibility, XCM testing capabilities, and identical feature set to Moonbeam mainnet.
When to Use This Method
The eth_sendRawTransaction method serves these key scenarios for Moonbeam developers, dApp testers, and teams validating cross-chain integrations:
- Submit pre-signed transactions - Broadcast transactions that were signed offline or in a secure enclave, keeping private keys away from the RPC endpoint
- Broadcast from offline signers - Air-gapped devices and hardware wallets first sign, then use this method to push the signed payload to Moonbase
- Resubmit stuck transactions - Replace pending transactions with the same nonce and a higher gas price when the original is not being included in blocks
- Deploy contracts programmatically - Submit contract creation transactions containing compiled bytecode and constructor arguments
Common Use Cases
1. Sign and Send an ETH Transfer
Build, sign, and broadcast a native ETH transfer with proper nonce management. The nonce must be retrieved from the node immediately before signing to avoid conflicts with pending transactions.
import { JsonRpcProvider, Wallet, parseEther, Transaction } from 'ethers';
const provider = new JsonRpcProvider('https://api-moonbase-alpha.n.dwellir.com/YOUR_API_KEY');
const wallet = new Wallet('PRIVATE_KEY', provider);
async function sendNativeTransfer(to, amountInEth) {
const tx = await wallet.sendTransaction({
to: to,
value: parseEther(amountInEth)
});
console.log('Transaction submitted:', tx.hash);
const receipt = await tx.wait();
console.log(`Confirmed in block ${receipt.blockNumber}, gas used: ${receipt.gasUsed}`);
return receipt;
}
const receipt = await sendNativeTransfer('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', '0.01');2. Resubmit a Stuck Transaction
If a pending transaction is not being confirmed due to low gas, submit a replacement with the same nonce and a higher gas price. The replacement must use an increased fee to be accepted by the Moonbase mempool.
import { JsonRpcProvider, Wallet, parseEther } from 'ethers';
const provider = new JsonRpcProvider('https://api-moonbase-alpha.n.dwellir.com/YOUR_API_KEY');
const wallet = new Wallet('PRIVATE_KEY', provider);
async function speedUpTransaction(originalTxHash, gasMultiplier = 1.5) {
const pendingTx = await provider.getTransaction(originalTxHash);
if (!pendingTx) throw new Error('Transaction not found');
const feeData = await provider.getFeeData();
const replacementTx = {
to: pendingTx.to,
value: pendingTx.value,
data: pendingTx.data,
nonce: pendingTx.nonce,
maxFeePerGas: feeData.maxFeePerGas * BigInt(Math.floor(gasMultiplier * 100)) / 100n,
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas * BigInt(Math.floor(gasMultiplier * 100)) / 100n,
gasLimit: pendingTx.gasLimit
};
const tx = await wallet.sendTransaction(replacementTx);
console.log('Replacement transaction:', tx.hash);
return tx;
}
const newTx = await speedUpTransaction('0x...');3. Deploy a Compiled Contract
Submit a contract deployment transaction containing the compiled bytecode. The to field is omitted for contract creation transactions; the contract address is deterministically derived from the sender address and nonce.
import { JsonRpcProvider, Wallet, ContractFactory } from 'ethers';
const provider = new JsonRpcProvider('https://api-moonbase-alpha.n.dwellir.com/YOUR_API_KEY');
const wallet = new Wallet('PRIVATE_KEY', provider);
const contractAbi = ['constructor(string memory name, uint256 supply)'];
const contractBytecode = '0x608060...';
async function deployContract(constructorArgs) {
const factory = new ContractFactory(contractAbi, contractBytecode, wallet);
const contract = await factory.deploy(...constructorArgs);
console.log('Deployment tx:', contract.deploymentTransaction().hash);
await contract.waitForDeployment();
console.log('Contract deployed at:', await contract.getAddress());
return contract;
}
const contract = await deployContract(['MyToken', 1000000]);Best Practices
- Always sign transactions client-side: never send private keys to any RPC endpoint, including https://api-moonbase-alpha.n.dwellir.com/YOUR_API_KEY
- Track nonces carefully to avoid gaps or conflicts: retrieve the pending nonce from
eth_getTransactionCountwith"pending"tag before each signing - The return value is a transaction hash: use
eth_getTransactionReceiptto poll for confirmation status - Handle replacement transactions correctly: the replacement must use the same nonce with a higher gas price
- Use
eth_estimateGasto set an appropriate gas limit before signing and sending
Code Examples
Error Handling
| Error Code | Message | Description |
|---|---|---|
| -32000 | Nonce too low | Transaction nonce already used |
| -32000 | Insufficient funds | Account has insufficient balance |
| -32000 | Gas too low | Gas limit insufficient |
| -32000 | Replacement underpriced | Gas price too low for replacement |
Related Methods
eth_estimateGas- Estimate gas requiredeth_gasPrice- Get current gas priceeth_getTransactionReceipt- Get transaction result
eth_accounts
Returns a list of addresses owned by the client on Moonbase Alpha. Typically returns an empty array on public RPC endpoints.
eth_getTransactionByHash
Retrieve transaction details by hash on Moonbase Alpha. Essential for Moonbeam developers, dApp testers, and teams validating cross-chain integrations tracking transactions on the Moonbeam testnet for risk-free EVM dApp development and deployment testing.