How to use OpenZeppelin defender relayers

Hello, I am trying to use Open Zeppelin's defender relayer and web3 js to sponsor USDC gasless tx for users in my app.

The issue is I keep getting an error that says something like: Error: Cannot transfer from the provider sender without actually stating the real cause of the error.

Enviorment: NestJs

Code:

import { DefenderRelayProvider } from '@openzeppelin/defender-sdk-relay-signer-client/lib/web3';

import Web3 from 'web3';

export async function createAvaxSignedTransaction(
    senderWallet: string,
    recipientAddress: string,
    amount: number,
    env: "prod" | "test",
) {
    try {
        const credentials = {
            apiKey: process.env.DEFENDER_API_KEY,
            apiSecret: process.env.DEFENDER_API_SECRET
        };

        if (!credentials.apiKey || !credentials.apiSecret) {
            throw new Error("Defender API credentials not set");
        }

        console.log("Instatiating defender....")

        const provider = new DefenderRelayProvider({
            apiKey: credentials.apiKey,
            apiSecret: credentials.apiSecret,
            authConfig: {
                useCredentialsCaching: true,
                type: 'relay'
            }
        }, { speed: 'fast' });

        const web3 = new Web3(provider);

        const usdcContractAddress = getUsdcAvaxContractAddress(env);

        const usdcContract = new web3.eth.Contract(usdcABI, usdcContractAddress);

        // Approve the Defender Relayer to spend USDC on behalf of the sender
        console.log(`Approving Defender Relayer to spend ${amount} USDC on behalf of ${senderWallet}...`);
        const approveTx = await usdcContract.methods.approve(senderWallet, amount).send({ from: senderWallet, gas: '100000' });
        console.log(`Approval transaction sent:`, approveTx.transactionHash);

        // Send USDC transfer transaction
        console.log(`Sending ${amount} USDC from ${senderWallet} to ${recipientAddress} using Defender Relayer...`);
        const transferTx = await usdcContract.methods.transfer(recipientAddress, amount).send({ from: senderWallet, gas: '100000' });
        console.log(`Transaction sent:`, transferTx.transactionHash);
        return transferTx.transactionHash;
    } catch (error) {
        console.error("An error occurred while creating the signed transaction:", error);
        throw error;
    }
}

Let me know if you need any more information helping me out. Thanks.

Hi, welcome to the community! :wave:

Have you checked the defender docs: https://docs.openzeppelin.com/defender/module/relayers#using-web3.js

Yes. I have. But it does not solve my problem.