Mr. Engineer
Mr. Engineer

Reputation: 3515

USDT executeMetaTransaction on Polygon - Gasless transaction

I'm working on USDT executeMetaTransaction so that user can perform gasless transaction.

But I'm getting Signer and signature do not match error. Following is how I sign the transaction :

const userWallet = new ethers.Wallet(PRIVATE_KEY, provider);
const nonce = await usdtContract.getNonce(userWallet.address);

const domain = {
      name: '(PoS) Tether USD',
      version: '1',
      chainId: 137,  // Polygon chain ID
      verifyingContract: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F"   };

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

  const message = {
      nonce: nonce,
      from: userWallet.address,
      functionSignature: functionSignature   };

const signature = await userWallet.signTypedData(domain, types, message);   
const { r, s, v } = ethers.Signature.from(signature);

For the functionSignature I'm encoding transfer function of USDT :

const recipientTransfer = usdtContract.interface.encodeFunctionData("transfer", [recipientAddress, amountAfterFee]);

Any idea what's wrong with it?

Upvotes: 0

Views: 102

Answers (1)

Adeel Nawaz
Adeel Nawaz

Reputation: 416

I will suggest to use eth-sig-util for user signature and in domain type use salt .

const domainType = [
    { name: "name", type: "string" },
    { name: "version", type: "string" },
    { name: "verifyingContract", type: "address" },
    { name: "salt", type: "bytes32" }
];

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

const domainData = {
    name: "(PoS) Tether USD",
    version: "1",
    verifyingContract: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
    salt: "0x0000000000000000000000000000000000000000000000000000000000000089",
};

   const transferFunctionAbi = ["function transfer(address to, uint amount)"];
  const interfaceTransferFunction = new ethers.utils.Interface(transferFunctionAbi);
  const functionSignature = interfaceTransferFunction.encodeFunctionData("transfer", [ to, amountUSDT ]);

    const msgParams = {
        types: {
            EIP712Domain: domainType,
            MetaTransaction: metaTransactionType
        },
        domain: domainData,
        primaryType: "MetaTransaction",
        message: {
            nonce: nonce.toNumber(),
            from: from,
            functionSignature: functionSignature
        }
  };

    const privateKey = Buffer.from(privateKeyUser, "hex")
    const sig = sigUtil.signTypedData_v4(
        privateKey,
        {data: msgParams}
  );

Upvotes: 1

Related Questions