how can I fix MetaMask Failed to fetch error? - javascript

I call the contract.methods.ownerOf 2500 times then I got the MetaMask - RPC Error: Failed to fetch. But I call the method about 200 times, then there's no error. how can I fix the error?
(ownerOf is etherscan contract interface)
here's my code.
export async function list() {
const MAX_TOKEN_ID = 2500;
const web3 = new Web3(Web3.givenProvider ||'http://localhost:8080');
const contract = new web3.eth.Contract(ERC721ABI as AbiItem[], CONTRACT);
const list = new Set<number>();
let result: object;
for (let tokenId = 1; tokenId <= MAX_TOKEN_ID; tokenId++) {
const address = await contract.methods.ownerOf(tokenId).call();
list.add(address);
}
result = Array.from(list).map((item) => ({address: item}));
return result;
}
and my error

To make a large number of JSON-RPC requests you need to host your own node or purchase as a node as a service.
RPC requests are not free and someone must pay for them. If you are not paying yourself, then whoever is serving you has all their right to cut you off.

Related

Ethers.js sending a transaction to a smart contract gives 'intrinsic gas too low'

I'm fairly new to blockchain and I'm struggling with sending a transaction to a smart contract - I'm getting intrinsic gas too low error. I've tried searching online for a solution but just couldn't solve it.
From https://stackoverflow.com/a/71261434/20453413 I understand that I need to 'allocate more gas by setting a higher gasLimit', okey, but by how much? Am I calculating gasPrice correctly?
I've deployed my contract to a goerli testnet and I'm using Infura as a provider to the blockchain.
let baseNonce = await provider.getTransactionCount(wallet.getAddress());
const gasPrice = await provider.getGasPrice()
const tx = await someContract.populateTransaction.setFoo('hello');
tx.nonce = baseNonce + 1
tx.value = ethers.utils.parseUnits('0.001', 'ether')
tx.gasPrice = gasPrice
await wallet.signTransaction(tx).then(signedTransaction => {
provider.sendTransaction(signedTransaction).then(transactionResponse => {
console.log("Our transaction response: " + transactionResponse)
})
})
provider.getGasPrice() returns a BigNumber object. Something like this { BigNumber: "21971214174" }
But you need to convert this BigNumber to a string. BigNumber object has a toString() to method. you can check the docs
tx.gasPrice = gasPrice.toString()

.sendSignedTransaction() Not sending Tx

Bit of context; this was working fine on Goerli just a few days a go but the script now works intermittently. At the moment im thinking its down to one of the following:
Node issue - currently using infura and have tried changing it across other public RPCS but didn't work any better
Web3 issue - not sure if something is now outdated
Nonce issue with wallets, not sure if there is something obvious in the code here that is causing my Txs to get stuck and as such never return a receipt
For some reason this was all working fine last night after having not worked all day. Bit stuck as to what i could be doing wrong tbh. The logic is that based on a mempool tx, the sendTx function is invoked with the 'targetAddress' param which contains all the necessary objects to replicate the tx which i am tracking.
Tx.js:
const Web3 = require('web3');
const Tx = require('ethereumjs-tx');
process.removeAllListeners('warning');
require('dotenv').config();
const INFURA_URL_TESTNET = process.env.INFURA_URL_TESTNET;
const web3 = new Web3(INFURA_URL_TESTNET);
const BN = web3.utils.BN;
// Tx details:
const sendTx = async (targetAddress) => {
const address = targetAddress.address;
const ethAmmount = targetAddress.value;
const data = targetAddress.input;
const gasLimit = targetAddress.gas;
//const gasPrice = targetAddress.gasPrice - web3.utils.toWei('1', 'gwei');
const maxFeePerGas = targetAddress.maxFeePerGas //- 1000000;
const maxPriorityFeePerGas = targetAddress.maxPriorityFeePerGas //- 1000000;
const privKey = targetAddress.privKey;
const from = targetAddress.from;
const _txCount = await web3.eth.getTransactionCount(from);
const createTransaction = await web3.eth.accounts.signTransaction(
{ to: address,
from: from,
data: data,
gas: gasLimit,
value: ethAmmount,
nonce: _txCount,
maxFeePerGas: maxFeePerGas,
maxPriorityFeePerGas: maxPriorityFeePerGas,
},
privKey,
);
// Send Tx and Wait for Receipt
const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction);
//const transaction = await web3.eth.getTransaction(createReceipt.transactionHash);
console.log(`Tx successful with hash: ${createReceipt.transactionHash}`);
};
module.exports = {sendTx};
The code stops at the await .sendSignedTx and doesn't return a receipt. As i said, this does work exactly as expected sometimes and i can figure out why sometimes it works and sometimes it doesn't?
Thanks everyone!
Since you are using web3js, you have to handle the event promise chain when calling sendSignedTransaction and log all the payloads. That will tell you the reason for it not being broadcast. Could be a network error, gas issue, maybe nonce .e.t.c.
See https://web3js.readthedocs.io/en/v1.2.11/callbacks-promises-events.html#callbacks-promises-events

Gnosis Transaction Failing On Polygon w/ "Transaction Underpriced" error

I've been trying to get a transaction to execute on Polygon but it's been failing with the following error:
reason: 'processing response error',
code: 'SERVER_ERROR',
body: '{"jsonrpc":"2.0","id":89,"error":{"code":-32000,"message":"transaction underpriced"}}',
This error only occurs on Polygon and it only occurs when using the Gnosis SDK. I've tested it using the Gnosis UI and it executes successfully. I've also tested it using the Gnosis SDK on rinkeby and that works as well.
Here is the code that fails:
const infuraProvider = new ethers.providers.JsonRpcProvider(RPC_PROVIDER);
const wallet = new ethers.Wallet(`0x${PRIVATE_KEY}`, infuraProvider);
const owner1 = wallet.connect(infuraProvider);
const ethAdapterOwner1 = new EthersAdapter({ ethers, signer: owner1 });
const safeSdkInstance = await Safe.create({
ethAdapter: ethAdapterOwner1,
safeAddress: GNOSIS_SAFE_ADDR,
});
const contract = new ethers.Contract(contractJson.address, contractJson.abi, owner1);
const tx = {
to: contract.address,
value: '0',
data: contract.interface.encodeFunctionData('mint', ['[wallet address here]', '[token id here]']),
};
const safeTransaction = await safeSdkInstance.createTransaction(tx);
const executeTxResponse = await safeSdkInstance.executeTransaction(safeTransaction);
Other things I've tried:
Adding a gasPrice - making that gas price incredibly large
Adding a gasLimit
Changing RPC_PROVIDER from an infura provider to a public one
Calling a different function - I tried calling my contracts burn function and it came back with the exact same error
I did notice that even when providing a gasPrice the error I get back says that the transaction provided had a gasPrice of null. But when logging the safeTransaction object it shows a gasPrice is generated by the createTransaction function. So something must be going wrong in the executeTransaction function

Transaction to Uniswap failing on Ropsten TestNet

I am trying to create a transaction on Uniswap programatically, the flow nd code seems to be there, but for whatever reason the transaction fails on Ropsten for "Warning! Error encountered during contract execution [Reverted]". I am using javascript along with Nodejs as my server. Any suggestions on why it is failing? Code below:
const { ethers } = require("ethers");
const walletAddress = "My_own_address";
const wethErc20Address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
const uniErc20Address = "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984";
const uniswapRouterAbi = [
"function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)",
];
async function buyListedTokenWithEth(
amountEthFloat,
uniswapRouterAddress,
provider
) {
const wallet = new ethers.Wallet(Buffer.from(privateKey, "hex"));
const signer = wallet.connect(provider); //provider is Infura https ROPSTEN url
const exchangeContract = new ethers.Contract(
uniswapRouterAddress,
uniswapRouterAbi,
signer
);
const ethAmount = ethers.utils.parseEther("0.1");
const tx = await exchangeContract.swapExactTokensForTokens(
ethAmount,
0,
[wethErc20Address, uniErc20Address],
walletAddress,
createDeadline(), // Math.floor(Date.now() / 1000) + 20
createGasOverrides() // { gasLimit: ethers.utils.hexlify(300000), gasPrice: gasPriceWei }
);
console.log("https://ropsten.etherscan.io/tx/" + tx.hash);
}
The line:
const tx = await exchangeContract.swapExactTokensForTokens(
Should be:
const tx = await exchangeContract.methods.swapExactTokensForTokens(
The error is correct. Your transaction should not be successful.
Go to the uniswap ropsten router address. https://ropsten.etherscan.io/address/0x7a250d5630b4cf539739df2c5dacb4c659f2488d#readContract
There is a function to view WETH address for ropsten.
This is what it returns
0xc778417e063141139fce010982780140aa0cd5ab //Uniswap-router-factory-weth address
instead of
const wethErc20Address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
You are asking the uniswap router to use the WETH address you list instead of the actual WETH address that it uses. Think about it this way. Why would an address with 0 liquidity on uniswap work on Uniswap?
Best to write some function to check liquidity before assuming it exist. No, I will not tell you how to do that.

BCH transaction failed: Missing inputs 25

I am using Bitcoin Cash JS to create a transaction, and my code is as follows:
let BITBOXCli = require('bitbox-cli/lib/bitbox-cli').default;
const explorers = require('bitcore-explorers')
const insight = new explorers.Insight('https://test-bch-insight.bitpay.com')
let BITBOX = new BITBOXCli();
let txb = new BITBOX.TransactionBuilder('testnet');
var To = 'mkiuwbSQQVxMvvbBcYEKUdZgJfURhu3hrW'
var from = 'mvStb7hPtDCL8dmyifPGcYTuToVzf7ajTb';
var bch = require('bitcoincashjs')
var bchLib = require('#owstack/bch-lib')
const buf = new Buffer('b27ab45d3e3d157e8b95f800347974f9991cf13ceb814e1992f40c5e4e6d5253', 'hex')
const privateKey = new bch.PrivateKey(buf, bch.Networks.testnet)
const address = privateKey.toAddress('testnet')
insight.getUnspentUtxos(address.toString(), function (error, utxos) {
if (error) {
console.error(error)
return
}
console.log(utxos)
const utxo = {
txid: utxos[0].txid,
outputIndex: utxos[0].vout,
script: utxos[0].scriptPubKey,
satoshis: utxos[0].satoshis
}
const transaction = new bch.Transaction()
.from(utxo)
.to(To, 50000)
.sign(0, privateKey)
console.log(transaction.toString())
});
Now when I am running this code, I am able to get the raw transaction hash but I am not able to broadcast transaction and message is as follows:
Missing Inputs Error:-25
Any idea about this error?
Or is there any other way to create BCH transaction?
It looks like you're trying to create a simple transaction to send BCH from one address to another. There is now an example for this exact use case in the BITBOX SDK repository:
https://github.com/Bitcoin-com/bitbox-javascript-sdk/blob/master/examples/applications/wallet/send-bch/send-bch.js
There are also other examples there like creating a wallet checking a balance:
https://github.com/Bitcoin-com/bitbox-javascript-sdk/tree/master/examples/applications/wallet
There are even more examples in the Wormhole SDK. (Wormhole SDK is a superset of BITBOX, so it can do anything BITBOX can do):
https://github.com/Bitcoin-com/wormhole-sdk/tree/master/examples

Categories