How to use Relayer to broadcast signed transaction?

Can Defender Relayer broadcast a signed transaction (in string format)?

:computer: Environment

Relayer

:memo:Details

I'm implementing an API that allows clients to send a transaction payload, and our server would sign the Tx with an EOA wallet and broadcast the tx on chain. In this case, I already have a signed Tx string, how can I broadcast the signed Tx with Defender Relayer?

I was looking at https://docs.openzeppelin.com/defender/relay#sending-transactions, the example code was

import { Relayer } from 'defender-relay-client';
const relayer = new Relayer({apiKey: YOUR_API_KEY, apiSecret: YOUR_API_SECRET});

const tx = await relayer.sendTransaction({
  to, value, data, gasLimit, speed: 'fast'
});

It can send the transaction it doesn't include the signing procedure. I'm using a wallet vendor to sign the tx and I don't have the wallet private key; In this case, how can I use Relayer to broadcast an already signed transaction? If Defender Relayer is not the best way to do it, any suggestions?

I also looked into the metaTx guide https://docs.openzeppelin.com/defender/guide-metatx but not entirely sure how that works with the Defender Relayer. If using a forwarder, my understanding is I need to make the following changes:

  1. original contract extends ERC2771Context
  2. create a forwarder following the example of MinimalForwarder
  3. I don't think Autotask since it's not event based

I don't have wallet private key, and everything is handled in the backend, I don't have access to wallet provider or signer. The transaction is signed and broadcasted on my server in one API call, so I feel that I don't really need to verify the signature, or use forwarder. how do I plug the signTx string into the whole MetaTx procedure?

:1234: Code to reproduce

Note this is a custodial wallet and everything is handled through APIs.

  1. Client request (tx payload) => MyServerAPI.sendTransaction(tx payload)
  2. where sendTransaction includes two steps:
    a. MyServer => WalletVendorAPI.signTransaction => signedTx => MyServer
    b. MyServer.broadcastSignedTransaction(signedTx)

The wallet balance is 0, how can I cover the gas fee for MyServer.broadcastSignedTransaction?