MinimalForwarder: signature does not match request

I've skimmed through other similar topics but couldn't figure out a solution.

I'm getting the error 'MinimalForwarder': signature does not match request. This happens when I send my transaction without verifying signature.

It's worth noting that when I use

// const signature = await signer._signTypedData(TypedData.domain, types, request);

ethers.utils.verifyTypedData returns correct address, however the valid check(verify) returns false.

On the contrary if I use

const signature = await signer.provider.send('eth_signTypedData_v4',
                    [address, JSON.stringify(toSign)]);

ethers.utils.verifyTypedData returns wrong address and valid returns true.

Can someone point to me where I'm messing up?

                const EIP712DomainType = [
                    { name: 'name', type: 'string' },
                    { name: 'version', type: 'string' },
                    { name: 'chainId', type: 'uint256' },
                    { name: 'verifyingContract', type: 'address' }
                ]

                const ForwardRequestType = [
                    { name: 'from', type: 'address' },
                    { name: 'to', type: 'address' },
                    { name: 'value', type: 'uint256' },
                    { name: 'gas', type: 'uint256' },
                    { name: 'nonce', type: 'uint256' },
                    { name: 'data', type: 'bytes' }
                ]

                const types = { ForwardRequestType };
                const provider= new ethers.providers.Web3Provider(window.ethereum)
                // Forwarder Contract
                const forwarderContract = new ethers.Contract(forwarder, Forwarder.ForwarderAbi, 
                 provider);
                // gets nonce and chainID
                const nonce = await forwarderContract.getNonce(address).then(nonce => nonce.toString());
                const chainId = await forwarderContract.provider.getNetwork().then(n => n.chainId);

                // Encode meta-tx request
                const boxesInterface = new ethers.utils.Interface(PayFactory.abi);
                const data = boxesInterface.encodeFunctionData('RedeemPayment', [code]);

                const request = {
                    from: address, // current user address
                    to: contractAddress, 
                    value: 0,
                    gas: 1e6,
                    nonce,
                    data
                };

                const TypedData = {
                    domain: {
                        name: 'MinimalForwarder',
                        version: '0.0.1',
                        chainId: chainId,
                        verifyingContract: forwarder,
                    },
                    primaryType: 'ForwardRequest',
                    types: {
                        EIP712Domain: EIP712DomainType,
                        ForwardRequest: ForwardRequestType
                    },
                    message: {
                        request
                    }
                };
                const toSign = { ...TypedData, message: request };

                const signature = await signer._signTypedData(TypedData.domain, types, request);

                const valid = await forwarderContract.verify(request, signature);

                console.log("valid:", valid)

                let recovered = await ethers.utils.verifyTypedData(TypedData.domain, types, request, signature);

                console.log("recoveredAddress:", recovered)
                if (recovered == address) {
                    console.log('verified TypedData ');
                //  Call server endpoint.            
  }
                else {
                    console.log("Wrong recovered Addy")
                }

UPDATE:

When I use:

const signature = await signer.provider.send('eth_signTypedData_v4',
                    [address, JSON.stringify(toSign)]);

The valid check(verify) method returns true and the recovered address incorrect. I tried sending the transaction and got this error instead:
Although one or more Error Occurred [**execution reverted** ] Contract Execution Completed.

Here is the tx on Mumbai.

Same error as here

Update:

Although one or more Error Occurred [ execution reverted ] Contract Execution Completed

This error means the forwarder executed the call, however the target contract function that I was calling was reverting because I had a revert statement which was triggered accidentally ;).

Hey @Ibrahim96,

Sorry for the late response, now I see you figured it out, but please let me know if you need any other support request around this.

Best!

Just to add some insights to this thread, when you see this message:

Although one or more Error Occurred [ execution reverted ] Contract Execution Completed

It means that the signature verification at the Forwarder level succeeded and the smart contract that you are trying to call is being executed. I suggest to go directly to that smart contract and call the function directly (without a meta-tx) to see exactly what is the problem with that contract.

Once you sort that error out, then the meta-tx via the Forwarder should work with no issues.