Feature request - Relay support for signTransaction

I want to be able to sign a transaction using my Defender Relay account and send the transaction privately to a mining pool using a service like Taichi https://taichi.network/#rpc
That is, I don't want the transaction to go into the mempool so it can be sandwich attacked.

The defender relay client does not implement the signTransaction function on the signer.
Error: DefenderRelaySigner#signTransaction: method not yet supported
If it did, I could sign the transaction and then easily send the signed tx via Taichi.

I tried to work around this by encoding the transaction myself and signing using signMessage but that doesn't work as signMessage takes a hash of the message. To sign and Ethereum transaction, the digest is the keccak256 of the RLP encoded transaction, not the hash.

2 Likes

Hey @naddison36! Thanks for the request. Do you see any other use cases for signTransaction besides sending it via taichi? If not, what do you think about adding a private flag to a relayer (or an individual transaction), which would cause it to be routed via taichi or flashbots?

A private flag would be great for Taichi. Taichi has a REST API to get the status of a private tx so does Relay abstract that away from the user? It'd be nice from a user perspective, but it starts bloating what Relay does.

I think adding full support for flashbots will be tricky so easiest to just give signTransaction support. Developers can then use the Flashbots API. eg bundling transactions which can include existing transactions in the mempool.

1 Like

FYI, I have recently used Flashbots helping someone recover staked tokens from a wallet that had been hacked. Whenever they sent ETH to the account it'd be swept so they couldn't withdraw their staked tokens and move to a safe account.

To recover I bundled three transactions that

  1. sent ETH to the hacked account
  2. withdraw the staked token
  3. transferred it to the new wallet

If Relay supported signTransaction I could have used a Relay account for the first transaction. I can't use Relay for the second two as that has to be signed by the hacked wallet.

1 Like

Got it, thanks for the explanation! And congrats on the token rescue!

1 Like

SparkPool have announced they are ending their Taichi Network service along with Gas Now on 15th of October, 2021.

Ethermine is now offering an alternative for private transactions
https://ethermine.org/private-rpc

Flashbots is doing something similar. We'll have to do some research about the available options, but for the time being, it seems like implementing signTx is indeed the easiest way to begin with as you suggested.

Yes, I saw Flashbots Protect RPC. Good to see there's now a number of options for private transactions.

Relay supporting signTx would be fantastic.

Thanks

Any progress on Relay supporting signTransaction?

1 Like

Hey @naddison36, not at the moment. We want to be particularly careful with this, since allowing transactions to be sent outside the regular relayer flow can potentially lead to clogged relayers. We'll keep you posted when we start working on this.

1 Like

Hey there,

I've been playing with a hardhat plugin to enable external transaction signers into a hardhat project, I believe it is a good use case for signTransaction.

Currently I can sign the txs using Google KMS, and send the txs through a regular network provider. It would be great to have that enabled for OZ Defender Signer as well, but I noticed the DefenderSignerProvider.signTransaction is not supported.

      const txSignature = await this.defenderRelaySigner.signTransaction(unsignedTx);
      const signedRawTx = serializeTransaction(unsignedTx, txSignature);

      return this._wrappedProvider.request({
        method: "eth_sendRawTransaction",
        params: [signedRawTx],
      });

It returns:

Error: DefenderRelaySigner#signTransaction: method not yet supported

I also tested that with the signMessage, but as @naddison36 noted it uses only the hash of the message and not the keccak256(RLP).

Thanks

Hey @fforbeck, the reason for not allowing signTransaction (ie signing a tx without broadcasting it) is that Relayers handle nonce management internally. If you signed a tx but failed to broadcast it, the relayer's nonce would be off. So we need to be particularly careful on how we handle this.

That said, I'm curious about why you need signTransaction support on the hardhat plugin. Given that you are signing the tx to send it immediately afterwards, why not just send it via the Relayer as well?

Hey @spalladino ! That makes sense. Thanks for clarifying.

The idea is to enable external signer providers in the hardhat plugin, e.g: google kms, aws kms, etc, and using that signer config regardless of the network provider.

Now that you mentioned the nonce management, yeah, I also think it is a good idea to send the tx directly to the relayer. The reason why I didn't try that before was because I noticed the hardhat provider config expects an implementation of EIP1193Provider, and apparently it needs some sort of wrapper class for the DefenderRelayProvider to manage the calls/events, which is a bit more complex than the signer wrapper. I will probably try that at some point, but it just requires a deeper integration.

1 Like

Perhaps you can use the existing relayer integration with web3 or ethers.js, and get an EIP1193 provider out of that? I haven't checked the hardhat code, but maybe going through one of these libraries does the trick!