Error while gas estimation - Signer and signature do not match

Hi,

I am trying to integrate with gasless and getting the below while doing transactions

Code: 417 message: "Error while gas estimation with message cannot estimate gas; transaction may fail or may require manual gas limit (error={"reason":"processing response error","code":"SERVER_ERROR","body":" {"jsonrpc":"2.0","id":1205," error":{"code":3,"message":"execution reverted: Signer and signature do not match/v1/2ac03d4fd9d671e79063 code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.4.0"}

any idea on how to debug?

This is a common error when using Custom approach.
It has to do with EIP712 type hash expected in your smart contract. It should look something like this : EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)

domain type you’re using in the code for the signature should match above type. Domain data has to be in the same order (verify name, chainId etc)

1 Like

@livingrock I am seeing the same error and can confirm that the contract method works as expected without Biconomy and the EIP712 type has matches the signature shared above. It fails if I attempt to use a meta transaction using the custom method or if attempt to call the method on my contract directly. Our contract inherits from BasicMetaTransaction.

contract Broker is BasicMetaTransaction { 
    . . . 
}

Any ideas what to do to address? My usage example appears below:

export const callSubmitCancelOrder = async (contract, contractMethod, contractAddress, contractAbi, userAddress, contractType, price, quantity) => {
    const nonce = await getNonce(userAddress, contract, biconomyProvider);
    const walletProvider = biconomyEthersProvider;

    // EIP712Domain(string name,string version,uint256 chainId, address verifyingContract)
    const domainType = [
        { name: "name", type: "string" },
        { name: "version", type: "string" },
        { name: "chainId", type: "uint256" },
        { name: "verifyingContract", type: "address" }
    ];
    const domainData = {
        name: "Broker",
        version: '1',
        chainId: 137,
        verifyingContract: contractAddress
    };

    const metaTransactionType = [
        { name: "nonce", type: "uint256" },
        { name: "from", type: "address" },
        { name: "functionSignature", type: "bytes" }
    ];

    // get function signature
    const contractInterface = new Interface(contractAbi);
    const functionSignature = contractInterface.encodeFunctionData(contractMethod, [contractType, price, quantity]);

    const message = {
        nonce,
        from: userAddress,
        functionSignature
    };

    const dataToSign = JSON.stringify({
        types: {
            EIP712Domain: domainType,
            MetaTransaction: metaTransactionType
        },
        domain: domainData,
        primaryType: "MetaTransaction",
        message: message
    });
 
    const signature = await signMessage(userAddress, walletProvider, dataToSign);
    const { r, s, v } = getSignatureParameters(signature);

    const recovered = await recoverTypedSignature_v4({
        data: JSON.parse(dataToSign),
        sig: signature,
    });
    const signerCheck = Web3.utils.toChecksumAddress(userAddress) === Web3.utils.toChecksumAddress(recovered); // => true
    console.log('SIGNER CHECK: ', signerCheck);

    // this fails with signature mismatch error
    await contract.executeMetaTransaction(userAddress, functionSignature, r, s, v);

    // This approach fails with 417 error
    await contract[contractMethod](contractType, price, quantity);
};

so the problem is with BasicMetaTransaction I believe. That contract itself doesn’t have EIP712 specs and its meant for traditional personal sign verification.
If you need to go with EIP7127 structured signatures, then metatx-standard/EIP712MetaTransaction.sol at master · bcnmy/metatx-standard · GitHub make this base.

If you stick to current implementation in the contracts, change your code for personal sign like