6

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)
Kevvv
  • 3,655
  • 10
  • 44
  • 90

1 Answers1

2

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.

Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435
  • I updated the question, but what I'm confused about is, am I getting the private key dynamically from the user to configure the `HDWallet`? Also, should I be using the JSON-RPC method alongside with `HDWallet` because there are some Web3 functionalities like creating a wallet that you have to use without a private key? I believe there is not way to configure `HDWallet` without a private key or mnemonic. – Kevvv Apr 20 '21 at 17:28
  • `dynamically from the user to configure` you don't. You never import user keys to the server-side. If you get private key from the user then effectively you become a hacker and all blockchain security guarantees are lost. – Mikko Ohtamaa Apr 21 '21 at 07:46
  • just to clarify, does this mean signing the transaction always has to be done in the front end and never on the server? The reason I'm asking is I would like to use the web3.js library, but I'm not using Javascript on the front end so I'm unable to do so. – Kevvv Apr 21 '21 at 16:09
  • `just to clarify, does this mean signing the transaction always has to be done in the front end` -> Yes – Mikko Ohtamaa Apr 22 '21 at 10:34
  • Do you guys know if there is a way to do it through a mobile app? – Danny711 Feb 03 '22 at 17:52
  • Here https://ethereum.stackexchange.com/questions/82531/connecting-the-wallet-of-to-your-dapp-and-different-ethereum-wallet-types/82532#82532 – Mikko Ohtamaa Feb 03 '22 at 18:08