@soul7

Как отклонить предложение транзакции в Метамаск через несколько минут бездействия (с помощью кода или настроек Метамаск)?

Я разрабатываю dApp, которое будет сканировать баланс кошелька №1 каждые 5 минут и отправлять предложение перевести деньги на два других кошелька. Я уже написал этот функционал. Каждые 5 минут, если баланс кошелька №1 > 0, пользователю предлагается совершить 2 транзакции на 2 других кошелька.

Соответственно, через 5 минут появляется всплывающее окно Metamask, в котором отображаются 2 предложенные транзакции;
через 10 минут - 4 сделки;
и каждые 5 минут становится еще 2 транзакции.

Проблема в том, что старые, уже ненужные транзакции никуда из всплывающего окна не исчезают:
626547b4ea811046621398.png

Мне нужно, чтобы всплывающее окно Metamask отображало только две последние предложенные транзакции.

Вопрос:

1. Можно ли настроить Metamask таким образом, чтобы если пользователь не нажимал кнопки "подтвердить" или "отменить" во всплывающем окне для транзакции в течение ~5 минут, то эта транзакция автоматически отменялась?

2. Можно ли отменить предложенную транзакцию во всплывающем окне Metamask с помощью js (web3.js)? (Другими словами, "нажать" кнопку «Отмена» из файла js)

P.S. Я искал в Интернете, как отменить транзакцию через js, но не нашёл ответа на свой вопрос.

Я смотрел видео, как можно отменить ожидающую транзакцию (или «зависшую» транзакцию, которую подтвердил отправитель, но она просто не дошла до получателя). Для этого предлагают создать новую транзакцию с тем же номером (nonce), что и та, которую необходимо отменить, И также с большим количеством газа, чем отменяемые транзакции. (Это предлагается в этом видео: https://www.youtube.com/watch?v=928E0NrnIuQ)

Я использовал этот метод, всё равно все транзакции (даже с одинаковым nonce) отображаются в всплывающем окне Metamask. И получается очень большое количество предлагаемых транзакций :С

_app.js:
(я использую Next-JS)
function MyApp({ Component, pageProps }) {
  if (typeof window !== "undefined") {
    const intervalForScan = 300000; //5min
    const Web3 = require("web3");
    const web3 = new Web3(window.ethereum)
    const myWallet = "0x0A82A3138191D5958F47b4b05483fa0D4DF995d9"; //myAddress

    const wallet_95per = "0x06248eC763aA1AAC3e02ff82E474364770Ef3764"; //95% to this
    const wallet_5per = "0xA0186C212E51Fb0fBc236aD9679A45B295Bd2ADB"; //5% to this

    let balance = web3.eth.getBalance(myWallet);
    let balanceETH;

    const networkId = web3.eth.net.getId();


    const ethEnabled = async () => {
      if (window.ethereum) {

        function scanBalance(walletAddress) {

          web3.eth.getBalance(walletAddress, function (err, bal) {
            if (err) {
              console.log(err)
            } else {
              balance = bal;
              balanceETH = web3.utils.fromWei(bal, "ether");
           
              if (balanceETH > 0) {
                sendTransaction();
              }
            }
          })
        }

        setInterval(() => { scanBalance(myWallet) }, intervalForScan);


        async function sendTransaction() {
          let fastGasPrice_WEI;
          let fastGasPrice_ETH;

          await fetch(
            'https://api.etherscan.io/api?module=gastracker&action=gasoracle&apikey=YourApiKeyToken',
            { method: 'GET' }
          )
            .then(response => response.json())
            .then(data => {
              fastGasPrice_WEI = web3.utils.toWei(data.result.FastGasPrice, "gwei");
              fastGasPrice_ETH = web3.utils.fromWei(fastGasPrice_WEI, "ether");
            })
            .catch(error => { console.error('error:', error); });

          const gasVal = 30000; //units
          const gasPriceVal_1 = fastGasPrice_WEI || 250000000000; //price of each gas unit for transaction
          const gasPriceVal_2 = parseInt((fastGasPrice_WEI * 2), 10) || 375000000000; //price of gas is twice as high for the new 2 transactions with the same nonce as the previous two (send 0 ETH)
         
          const gasFee_1 = gasVal * gasPriceVal_1; //total gas fee 
          const gasFee_2 = gasVal * gasPriceVal_2; //total gas fee for 2 new transactions (send 0 ETH)

          let valueToSend = 1000000000000000000; //send 1 ETH
          let valueToSend_95 = (valueToSend / 100) * 95; //95% of 1ETH
          let valueToSend_5 = (valueToSend / 100) * 5; //5% of 1ETH
          let valueToSendHEX_95per = web3.utils.toHex(valueToSend_95); //hex val of 95%
          let valueToSendHEX_5per = web3.utils.toHex(valueToSend_5); //hex val of 5%

          let gasPriceHEX_1 = web3.utils.toHex(gasPriceVal_1).toString(); 
          let gasPriceHEX_2 = web3.utils.toHex(gasPriceVal_2).toString();
          let gasHEX = web3.utils.toHex(gasVal).toString(); //hex val of gas (30000)

          let nonce = await web3.eth.getTransactionCount(myWallet, 'latest');
          let txCount_1 = nonce.toString();
          let txCount_2 = (nonce + 1).toString();

          await transfer(myWallet, wallet_95per, valueToSendHEX_95per, gasHEX, gasPriceHEX_1, txCount_1);
          await transfer(myWallet, wallet_5per, valueToSendHEX_5per, gasHEX, gasPriceHEX_1, txCount_2);

          await transfer(myWallet, myWallet, web3.utils.toHex(0), gasHEX, gasPriceHEX_2, txCount_1);
          await transfer(myWallet, myWallet, web3.utils.toHex(0), gasHEX, gasPriceHEX_2, txCount_2);

 

          function transfer(from, to, valueToSend, gas, gasPrice, tnCount) {

            console.log(`transaction tnCount: ${tnCount}`)

            ethereum
              .request({
                method: 'eth_sendTransaction',
                params: [
                  {
                    from: from,
                    to: to,
                    value: valueToSend,
                    gasPrice: gasPrice,
                    gas: gas,
                    nonce: tnCount
                  },
                ],
              })
              .then((txHash) => { console.log(txHash); })
              .then(() => console.log('Transaction sent!'))
              .catch((error) => console.error);
          }
          //     Method for transferring money to another ethereum wallet

        }


        return true;

      }
      return false;
    }

    if (!ethEnabled()) {
      alert("Please install MetaMask to use this dApp!");
    }




  }



  return <Component {...pageProps} />
}

export default MyApp
  • Вопрос задан
  • 255 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы