Sponsored Calls

Sponsored Calls enable you to cover your users’ gas fees, providing a seamless and gasless experience for interacting with your dApp. This is made possible through Gelato’s multi-chain unified gas payment system, 1Balance. Learn more about 1Balance here.

Implementation Steps

1. Import GelatoRelaySDK into your front-end .js project

Import SponsoredCallRequest for Non ERC2771 sponsored calls with GelatoRelay.

import { GelatoRelay, SponsoredCallRequest } from "@gelatonetwork/relay-sdk";
const relay = new GelatoRelay();

or

If you’re using the Viem library in your project, consider importing @gelatonetwork/relay-sdk-viem.

import { GelatoRelay, SponsoredCallRequest } from "@gelatonetwork/relay-sdk-viem";
const relay = new GelatoRelay();

Import CallWithERC2771Request for ERC2771 sponsored calls with GelatoRelay. Learn more about ERC2771 here.

import { GelatoRelay, CallWithERC2771Request } from "@gelatonetwork/relay-sdk-viem";

Once we have imported the GelatoRelay class, when using ERC2771 methods, we must initialize it with the appropriate trustedForwarder. The possible configurations are:

contract: {
    relay1BalanceERC2771: "trustedForwarder for method sponsoredCallERC2771",
    relayERC2771: "trustedForwarder for method callWithSyncFeeERC2771",
    relay1BalanceConcurrentERC2771: "trustedForwarder for method concurrent sponsoredCallERC2771",
    relayConcurrentERC2771:"trustedForwarder for method concurrent callWithSyncFeeERC2771",
    relay1BalanceConcurrentERC2771zkSync: "trustedForwarder for method concurrent sponsoredCallERC2771 on zkSync",
    relay1BalanceERC2771zkSync: "trustedForwarder for method sponsoredCallERC2771 on zkSync",
    relayConcurrentERC2771zkSync: "trustedForwarder for method concurrent callWithSyncFeeERC2771 on zkSync",
    relayERC2771zkSync: "trustedForwarder for method callWithSyncFeeERC2771 on zkSync",
}

We will need to go to the Supported Networks and check the network and the contract addresses to identify the trustedForwarder associated with our method. In the example below, we are using the method sponsoredCallERC2771 on Sepolia, the trustedForwarder associated is 0xd8253782c45a12053594b9deB72d8e8aB2Fca54c. We will initialize GelatoRelay with the following config:

const relay = new GelatoRelay({
    contract: {
        relay1BalanceERC2771:"0xd8253782c45a12053594b9deB72d8e8aB2Fca54c"
    }
});

2. Deploy a smart contract

For non-ERC2771 sponsored calls, no modifications are required in your target contract. Below is an example of a target contract.

contract TargetContract {
    // your logic
    function example() external {
        // your logic
    }
}

For ERC2771 Sponsored Calls

Import ERC2771Context into your target contract and initialize it in the constructor with the appropriate trusted forwarder based on your use case. checkout list of trusted forwarders here.

import {
    ERC2771Context
} from "@gelatonetwork/relay-context/contracts/vendor/ERC2771Context.sol";

contract TargetContract is ERC2771Context {
    // ERC2771Context: setting the immutable trustedForwarder variable
    constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {}
    function example() external{
        // your logic
    }
}

3. Generate a payload for your target contract

// set up target address and function signature abi
const targetContractAddress = "your target contract address";
const abi = ["function example()"];

const [address] = await window.ethereum!.request({
      method: "eth_requestAccounts",
 });

// generate payload using front-end provider such as MetaMask
const client = createWalletClient({
      account: address,
      chain,
      transport: custom(window.ethereum!),
});
const chainId = await client.getChainId();

//encode function data
const data = encodeFunctionData({
    abi: abi,
    functionName: "example",
});

4. Send the payload to Gelato

For sending sponsored calls, you need to have a sponsor API key. Learn how to create a sponsor API key here.

// Populate a relay request
const request: SponsoredCallRequest = {
  chainId: BigInt(chainId),
  target: targetContractAddress,
  data: data as BytesLike,
};
const relayResponse = await relay.sponsoredCall(
    request,
    GELATO_RELAY_API_KEY
);

For ERC2771 Sponsored Calls

// Populate a relay request
const request : CallWithERC2771Request = {
    user: address,
    chainId: BigInt(chainId),
    target: targetContractAddress,
    data: data as BytesLike,
};

const response = await relay.sponsoredCallERC2771(
    request,
    client as any,
    GELATO_RELAY_API_KEY
);

Learn more about implementation of ERC2771 Sponsored Calls here and Non ERC2771 Sponsored Calls here.