How to make users pay for transactions with tokens

Hello. So I implemented meta transactions with the help of Relayer and Autotask and @spalladino :slight_smile: Everything works fine and loving it!

However I have one problem. Since I'm paying for the gas now, I want users to pay for tx using a specific ERC20 token. I know how to transfer the token from the user to whatever account I want but then the transfer is another transaction which requires the user to sign. This will make users sign transactions twice (one for the orginal tx and one for the ERC20 payment).

I'm looking for a way to make the user sign only once. Any ideas please?

@spalladino please any ideas?

Hey @isoteriksoftware! The usual flow for having your users pay you in erc20 for relaying their txs is having a Forwarder that, in addition to verifying the user's signature and forwarding the call, also executes a transferFrom on an erc20 to take some of the user's funds and move them to whoever is paying for the gas (aka tx.origin).

Note that, for this to work, you'll first need your user to grant an erc20 approval to your forwarder, so it can call transferFrom. This initial tx does require the user to pay for gas, since it needs to come from the user's address, unless you are working with a token that supports ERC20Permit or a similar method (such as DAI or USDC).

Hope this helps!

1 Like

Hey @spalladino
How would the relayer convert the ERC20 tokens to native tokens(ETH, MATIC etc)? Is there a fee conversion module in built? As I don't have the private key of the relayer I can't manually transfer or swap the ERC20 tokens.

Hey @Yashasvi_Chaudhary,

We don't have any conversion module built-in, especially because the relayer's gasPrice might not be the same across time if we resubmit a transaction due to slow processing. So, in order to convert ERC20 to native tokens, you need an exchange rate and a gasPrice to charge your users.

I think the best approach for this is to set up a gasPriceCap policy and use an oracle to define how many tokens you would get from the user's account.

Hope it helps!

Thanks for the reply!
One thing I am unable to understand is if the case is that the relayer gets paid in the same transaction. For example I use Gnosis's execTransaction function which has a handlePayment feature of paying the relayer in the same transaction.

Now the ERC20 tokens would reside in the relayer's account once the transaction is complete. How do I convert those ERC20 tokens to ETH or Matic so that the relayer is self sufficient and I don't have to keep topping it up. How do I attach a ERC20 token to native token conversion script. The hurdle I feel is not having the private key, I get that exposing private key is a security concern so can this flow be done without exposing private key?

1 Like

Using the execTransaction function will do the job of repaying to your Relayer, so I'll assume there's a single chain setup, and you only want to convert the ERC20 tokens to the native token on the same chain.

How do I convert those ERC20 tokens to ETH or Matic so that the relayer is self sufficient and I don't have to keep topping it up

For this case, you may set up a sentinel to monitor the payments you receive, and then connect an Autotask as a notification to fire whenever the sentinel detects a deposit/payment. The Autotask can have all of the conversion logic, and you can use our defender-relay-client's ethersjs wrapper.

How do I attach a ERC20 token to native token conversion script?

This is what an Autotask can do, and it automatically injects the relayer API keys so you don't need the private key but you can still use it.

I get that exposing private key is a security concern so can this flow be done without exposing private key?

Is a 100% doable:

  • If you don't like to use Autotask but still want to create a script to use it, you can leverage the defender-relay-client and it's ethersjs/web3 wrapper to use it as if it were a normal ethersjs/web3 client with a private key
  • You can also use the ethersjs/web3 wrapper on Autotask and get the API Keys injected automatically so you don't manage sensitive information
  • If your concern is the security of the API Keys, you can delete them and regenerate them every now and then without loosing the private key

If you're planning to do a multichain setup for some reason, there are some extra steps but I guess you'll figure it out once setting up a single-chain environment

Thanks @ernestognw
All is clear now!

1 Like