7

index.js:1 Failed to fetch multicall chunk [{…}] 1 Error: sending a transaction requires a signer (operation="sendTransaction", code=UNSUPPORTED_OPERATION, version=contracts/5.0.2)

Multicall contract address - https://etherscan.io/address/0xeefba1e63905ef1d7acba5a8513c70307c1ce441#writeContract

Works in Uniswap-interface but throws an error in my code, and I don't know what's wrong

tashakori
  • 2,331
  • 1
  • 22
  • 29
Shanu Goyanka
  • 71
  • 1
  • 1
  • 2

3 Answers3

6

You must provide a signer to perform the solidity method.

You can get a signer from your web3 provider.

You can bind a signer to the Contract like so

import Contract from './artifacts/contracts/Contract.sol/Contract.json'
const contractDeployedAddress = "0xblah";

const provider = new ethers.providers.Web3Provider(window.ethereum)
const signer = provider.getSigner();
const contract = new ethers.Contract(contractDeployedAddress, Contract.abi, signer)

await contract.someMethodThatRequiresSigning();
Harry Moreno
  • 10,231
  • 7
  • 64
  • 116
3

I have similar situation which is using @web3-react with reference to the uniswap-interface code.

@web3-react base on the ethers.js, and we must execute the State Changing Methods with signer. I post a sample that I solved.

const { library, account } = useActiveWeb3React();

const contract = getContract(
      CONTRACT_ADDRESS,
      abi,
      library
    );
const signer = contract.connect(library.getSigner());
signer.someStateChangingMethods();

This may help you. https://docs.ethers.io/v5/getting-started/#getting-started--writing

TeaTwo
  • 712
  • 1
  • 5
  • 9
0

To make a multi call, you have to encode functions.

// assuming you created swapRouterContract properly and set params1, params2
// interface.encodeFunctionData available in ether
const encData1 = swapRouterContract.interface.encodeFunctionData(
    "exactInputSingle",
    [params1]
  );

  const encData2 = swapRouterContract.interface.encodeFunctionData(
    "exactInputSingle",
    [params2]
  );

Multicall means we are going to call multiple functions with a single request.

 const calls = [encData1, encData2];
// To send data to the contract, we need to send it in a way that the contract can read it. That is, they need to be encoded.
  // data is transformed into byte
  const encMultiCall = swapRouterContract.interface.encodeFunctionData(
    "multicall",
    [calls]
  );

To send transaction, we need, "to", "from" and "data"

  const txArgs = {
    to: V3SwapRouter,
    from: WALLET_ADDRESS,
    data: encMultiCall,
  };

this transaction has to be sent by a signer. If you send the trasaction via metamask, metamask automatically signs the transaction with the account's private key. But if you sent transaction via code, you have to create a signer

const provider = new ethers.providers.JsonRpcProvider(TEST_URL);
// get the secret of the account 
const wallet = new ethers.Wallet(WALLET_SECRET);
// connect the wallet to the provider
const signer = wallet.connect(provider);

Now you can send the transaction:

const tx = await signer.sendTransaction(txArgs);
console.log("tx", tx);
// wait for the tx processed and added to the blockchain
const receipt = await tx.wait();
console.log(receipt);
Yilmaz
  • 35,338
  • 10
  • 157
  • 202