Gasless transactions and account abstraction

Supercool's relayer can sponsor gasless transactions so that you can remove friction for your users and let them interact with your dapp or wallet without paying gas. Sponsorship is instant and per-transaction (ie no need for a user to pay and then refund them).
Supercool’s relayer is compatible with:
  • ERC-4337 wallets and UserOps - this standard allows for any arbitrary transaction to be made gasless, but requires that users have special ERC-4337 accounts
  • ERC-2771 with EIP-712 signatures - these standards allow gasless transactions from any wallet, but may or may not work with target contracts (marketplaces, NFTs, etc.) based on the dapp or token contract’s code

ERC-4337 account abstraction wallets

Supercool integrates with ERC-4337 wallet implementations and runs a bundler/paymaster that can sponsor transactions and perform transaction bundling. The smart contract wallet (SCW) can wrap any externally owned account (EOA), such as a Metamask wallet or an email-based wallet (Privy, Magic, Web3Auth, etcetera).
In this case, the end user flow would look like:
  1. 1.
    User signs into their EOA
  2. 2.
    Supercool’s relayer either connects to the user’s ERC-4337 smart contract wallet or creates the users smart contract wallet for the user, gaslessly
  3. 3.
    User signs UserOp signatures in the dapp and submits them to the relayer, who then executes the transaction. The user pays no gas
Our Javascript/Typescript SDK can make this process as simple as calling some functions. See the Account Abstraction (ERC-4337) bundlers and paymasters tech guide for an example.

ERC-2771 and EIP-712

ERC-2771 and EIP-712 do not require special smart contract wallets, but the dapp or token smart contracts must behave a little differently than for standard transactions. Most importantly is that the transaction’s msg.sender will not be the end-user’s wallet, and will instead be the relayer. If the dapp or token smart contracts implement ERC-2771 or some other means for understanding the end-user’s address, then the implementation is compatible.
The flow is similar to above:
  1. 1.
    User signs in to their EOA
  2. 2.
    User signs an EIP-712 signature and sends this to the relayer, which executes the transaction on chain and pays gas for the user
This flow can also be handled by our Javascript/Typescript SDK. See the Meta-transactions and gas sponsorship tech guide for an example.

Sponsorship eligibility conditions

Supercool lets you conditionally sponsor gas for your users based on eligibility checks. These checks query view or pure Solidity functions before submitting the transaction to the relayer. You specify the eligibility checks when you make a transaction relay request.
You can read more in Conditional gas sponsorship, but here's a quick example eligibility check that sponsors gas for a DAO vote if the voter holds enough tokens in the DAO:
import {supercool} from '@supercoolxyz/relayer-client'
import {ethers} from 'ethers'
// replace this with whatever function creates your EOA (Metamask, etc.) signer
const eoaSigner = getEOASigner()
const provider = new supercool.RelayerProvider({apiKey: ..., apiSecret: ...})
const signer = supercool.GaslessForwarderSigner.fromEOASigner(
provider, eoaSigner
)
const contract = new ethers.Contract(contractAddress, abi, signer)
const inter = new ethers.Interface(abi)
const eligibilityChecks = [
new supercool.EligibilityCheck({
chain: 'ethereum',
address: '0xabc123',
functionFragment: inter.getFunction('checkEligibility')
// If the return value is a boolean, `true` means the vote is
// eligible for sponsorship.
// If the return value is not a boolean, you can provide a
// "resultCheck". For example, this checks that an integer
// return value is > 5.
resultCheck: new supercool.EligibilityResultCheck(
supercool.EligibilityResultCheck.GREATER_THAN,
5
)
})
inter.encodeFunctionData(
inter.getFunction('checkEligibility'),
[val1, val2]
)
]
// Submit the vote transaction gaslessly if the user passes eligibility checks.
// Otherwise, ask the user to pay for gas.
await contract.castVote(proposalId, voteValue, {
eligibility: eligibilityChecks
})
Note that the @supercoolxyz/relayer-client package is not published yet, but you can reach out to us at [email protected] for early access.