Search code examples
ethereumsolidityweb3js

eth_sendTransaction does not exist/is not available


I'm currently using ERC721PresetMinterPauserAutoId for a smart contract and the Web3.js library in the Node.js backend server. When I try to call the mint function using this Web3 API:

 var myContract = new web3.eth.Contract(ERC721PresetMinterPauserAutoIdABI, ERC721PresetMinterPauserAutoIdContractAddress, {
    from: from, 
    gasPrice: gasPrice
  });

  let result;
  try {
    result = await myContract.methods.mint(receipientAddress).send();
    res.status(201).send(result)
  } catch (error) {
    res.status(201).send(error)
  }

I get the following error:

Returned error: The method eth_sendTransaction does not exist/is not available

I'm communicating to the Rinkeby blockchain through the Infura gateway and according to this post, Infura supports only eth_sendRawTransaction, not eth_sendTransaction.

I was able to successfully send Ether using a signed transaction:

  const gasPrice = await web3.eth.getGasPrice()
  const txCount = await web3.eth.getTransactionCount(from, 'pending')
  var rawTx = {
      nonce: txCount,
      gasPrice:"0x" + gasPrice,
      gasLimit: '0x200000',
      to: to,
      value: "0x1000000000000000",
      data: "0x",
      chainId: 4
  };

  var privateKey = new Buffer.from(pk, "hex")
  var tx = new Tx(rawTx, {"chain": "rinkeby"});
  tx.sign(privateKey);

  var serializedTx = tx.serialize();
  const signedTx = await web3.eth.sendSignedTransaction("0x" + serializedTx.toString("hex"));

However, I'm unable to call the mint method on the smart contract using the raw transaction. I've tried:

await myContract.methods.mint(receipientAddress).sendSignedTransaction("0x" + serializedTx.toString("hex"));

or

await myContract.methods.mint(receipientAddress).sendRawTransaction("0x" + serializedTx.toString("hex"));

But, I still get the error message eth_sendTransaction does not exist/is not available.

Update

I tried using signing the transaction using a Truffle's library on the advise of @MikkoOhtamaa:

const HDWalletProvider = require("@truffle/hdwallet-provider");
const privateKeys = process.env.PRIVATE_KEYS || ""
const walletAPIUrl = `https://rinkeby.infura.io/v3/${process.env.INFURA_API_KEY}`
const provider = new HDWalletProvider(
  privateKeys.split(','),
  walletAPIUrl
);
const web3 = new Web3API(provider)

Solution

  • Install a Web3.js middleware layer that signs transactions locally, instead of sending a JSON-RPC method to Infura.

    One of the solutions is Truffle HDWallet.