Docs

eth_sendRawTransaction - Gnosis RPC Method

Submit signed transactions to Gnosis. Essential for broadcasting transactions for prediction markets (largest by market cap), Safe wallet infrastructure, CoW Protocol DEX, and Gnosis Pay card integration.

Submits a pre-signed transaction for broadcast to Gnosis.

Why Gnosis? Build on the prediction market pioneer with $260M+ TVL and xDAI stablecoin-based gas fees with stablecoin gas fees for predictable costs, Shutter MEV protection, 150K+ Safe wallets, and Circles decentralized UBI protocol.

When to Use This Method

The eth_sendRawTransaction method serves these key scenarios for prediction market builders, DAO tooling developers, and teams building MEV-protected applications:

  • 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 Gnosis
  • 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.

JavaScript
import { JsonRpcProvider, Wallet, parseEther, Transaction } from 'ethers';

const provider = new JsonRpcProvider('https://api-gnosis-mainnet.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('0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', '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 Gnosis mempool.

JavaScript
import { JsonRpcProvider, Wallet, parseEther } from 'ethers';

const provider = new JsonRpcProvider('https://api-gnosis-mainnet.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.

JavaScript
import { JsonRpcProvider, Wallet, ContractFactory } from 'ethers';

const provider = new JsonRpcProvider('https://api-gnosis-mainnet.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-gnosis-mainnet.n.dwellir.com/YOUR_API_KEY
  • Track nonces carefully to avoid gaps or conflicts: retrieve the pending nonce from eth_getTransactionCount with "pending" tag before each signing
  • The return value is a transaction hash: use eth_getTransactionReceipt to poll for confirmation status
  • Handle replacement transactions correctly: the replacement must use the same nonce with a higher gas price
  • Use eth_estimateGas to set an appropriate gas limit before signing and sending

Code Examples

Error Handling

Error CodeMessageDescription
-32000Nonce too lowTransaction nonce already used
-32000Insufficient fundsAccount has insufficient balance
-32000Gas too lowGas limit insufficient
-32000Replacement underpricedGas price too low for replacement