6

I want to detect if the user has clicked a button that will make metamask popup asking them to submit, but then rejects the transaction. I have something like the following:

Contract.deployed().then(function (contractInstance) {
        contractInstance.function({ from: web3.eth.accounts[0]}).then(function (error, result) {

            if (!error) {
                console.log('ok')
            } else {
                if (error.message.includes("User denied")) {
                    alert("You rejected the transaction on Metamask!")
                } else {
                    alert(error)
                }
            }

        })
    })

This doesn't work as intended. How should this be done? The error printed if the user rejects the transaction is:

Uncaught (in promise) Error: Error: MetaMask Tx Signature: User denied transaction signature.

So presumably this should be simple by checking if that's the error message.

5 Answers 5

3

I was looking for a solution for this too. I am using truffle and looked up their documentation. http://truffleframework.com/docs/getting_started/contracts

Contract.deployed().then(function(contractInstance){ 
  contractInstance.function({from: web3.eth.accounts[0]}).then(function(result){             
      alert('transaction success')}).catch(function(e){ 
      console.log('error')                                          
})
0
3

I couldn't find an answer for this using Ethers.js, so here is what I did in case others need it. It also includes actions while waiting for the block to be mined and after:

const functionName = async(...parameters)=>{
   let signedContract = new Contract(contractAddress, contractAbi, signer);
   signedContract.method(...parameters)
   .then((tx)=>{
      //action prior to transaction being mined
      provider.waitForTransaction(tx.hash)
      .then(()=>{
         //action after transaction is mined
      })
   })
   .catch(()=>{
   //action to perform when user clicks "reject"
   })
}

I think this might be easier to do with Ethers than Web3.

1

To handle Confirm/Cancel response of user on your contract functions, you can use the transactionHash event & error event from send function.

"transactionHash" returns transactionHash: String: Fired when the transaction hash is available.

"error" returns error: Error: Fired if an error occurs during sending. If the transaction was rejected by the network with a receipt, the receipt will be available as a property on the error object.enter image description here

You can see detail here.

When you click on Confirm button then you can handle this case in the transactionHash event.

When you click on Cancel button then you can handle this case in the error event.

0

I was facing the same problem. Following is my code to connect and sign a transaction using Metamask API:

async function connectMetamask(){
  if (typeof window.ethereum !== 'undefined'
      || (typeof window.web3 !== 'undefined')) {
      const provider = window['ethereum'] || window.web3.currentProvider
  }
  console.log(ethereum.isMetaMask);

  try {
    const accounts = await ethereum.enable();
    console.log("account: " +  accounts[0]);

    ethereum.send({
      method: 'eth_sendTransaction',
      params: [{"from": accounts[0],
      "to": smartContractaddress,
      "gas": "0x2DC6C0", // 30400
      "gasPrice": "0x2540BE400", 
      "value": weitohex, // 2441406250
      "data": inputhex}],
      from: accounts[0],
    },function(err, transactionHash) {
      if (!err){
        console.log(transactionHash); 
        if(transactionHash.result !== undefined){
          document.getElementById('span_metalink').innerText="https://kovan.etherscan.io/tx/"+transactionHash.result;
          document.getElementById('span_metalink').href="https://kovan.etherscan.io/tx/"+transactionHash.result;
          document.getElementById('span_success').innerText = "Transaction Successfully Done!!!";
        }
        else{
          document.getElementById('span_success').innerText = "User denied transaction signature.";
        }
      }
    })

  } catch (error) {
    console.log(error === "User rejected provider access")
  }
}

Hope this will help you.

0

This migbt be the solution you looked for(Tested with Metamask and Ether.js):

....

  }else if(err.code.toString()==='ACTION_REJECTED'){
      //Ignore User rejected
}

....

I Know alittle bit dirty, but works

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.