Reputation: 3515
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
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