Problem in sending a gasless transaction

My objective is simple I want to send a gasless transaction from one address to another. I am providing the code below.

I am using Openzeppelin Defender relayer to cover the gas prices of the transaction.

const { DefenderRelayProvider,DefenderRelaySigner } = require('@openzeppelin/defender-relay-client/lib/ethers');

const { ethers } = require('ethers');

async function sendGaslessTransaction() {
// Instantiate the DefenderRelayProvider
const credentials = {
apiKey: 'Relayer Api Key',
apiSecret: 'Relayer Api secret'
};

const provider = new DefenderRelayProvider(credentials);


const senderPrivateKey = 'private key';
const beneficiaryAddress = 'Receipent Address'

// Gasless transaction parameters
const transaction = {
to: 'Recipient address',  
value: ethers.utils.parseEther("0.0005"),
gasLimit: 21000
};

const wallet = new ethers.Wallet(senderPrivateKey);

const signedTransaction = await wallet.signTransaction(transaction);

console.log("signed transaction",signedTransaction)

const relayerSignedTransaction = {
    to: beneficiaryAddress.toLowerCase(),
    value: ethers.utils.parseEther("0.0005").toHexString(), // Amount to transfer in wei
    gasLimit: 30000,
    data: signedTransaction
  };

// Instantiate the DefenderRelaySigner

const signer = new DefenderRelaySigner(credentials, provider, { speed: 'fast' });

// Populate the transaction with additional details
const populatedTransaction = await signer.populateTransaction(relayerSignedTransaction);

// Send the gasless transaction to the relayer for execution and gas fee payment 
try {
const response = await signer.sendTransaction(populatedTransaction);
console.log('Transaction hash:', response.transactionHash);

} catch (error) {
console.error('Error sending gasless transaction:', error);
}
}

sendGaslessTransaction();

In a gasless transaction, funds are transferred from AddressA to AddressB and the relayer pays the gas fees of this transaction. The same is my objective but in the code provided the funds are transferring from the relayer account to AddressB instead it should transfer from AddressA and the relayer should only cover the gas price.

The problem I think is in the Defender Relayer Signer class it is using the relayer to sign and send the transaction and ignoring the wallet generated using the private key of address A.

Additionally, I have seen that many tutorials and resources are using smart contracts for this purpose but I want to execute the transaction without implementing any smart contract

Thanks

Hello @Syed_Rabeet,

This seems to be more Defender support than Upgrades, so I reclassified your question to the Defender category.

Before anyone else takes the issue, I think it would be helpful to know if you get this code from some reference. The way the transaction is being constructed does not seem to be right. Particularly this:

const wallet = new ethers.Wallet(senderPrivateKey);

const signedTransaction = await wallet.signTransaction(transaction);

console.log("signed transaction",signedTransaction)

const relayerSignedTransaction = {
    to: beneficiaryAddress.toLowerCase(),
    value: ethers.utils.parseEther("0.0005").toHexString(), // Amount to transfer in wei
    gasLimit: 30000,
    data: signedTransaction
  };

You don't need to append a signed transaction as the data argument of another transaction. Also, note that is required a smart contract following the ERC2771 (or any other forwarding mechanism). The relayer is just an account that can be programmed to relay signed requests by following a smart contract logic.

Perhaps you may want to take a look to our ERC2771Forwarder and ERC2771Context implementations. Also consider these haven't been released as of today but we're targeting a release soon.