Gelato Relay
- 1.
- 2.Have a Safe configured with threshold equal to 1, where only 1 signature is needed to execute transactions.
- 3.
yarn add ethers @safe-global/relay-kit @safe-global/protocol-kit @safe-global/safe-core-sdk-types
Currently, the Relay Kit is only compatible with the Gelato relay. There are 2 different ways to use the Gelato relay:
- 1.
- 2.
Gelato 1Balance allows you to execute transactions using a prepaid deposit. This can be used to sponsor transactions to other Safes or even to use a deposit on Polygon to pay the fees for a wallet on another chain.
For the 1Balance quickstart tutorial, you will use the Gelato relayer to pay for the gas fees on BNB Chain using the Polygon USDC you've deposited into your Gelato 1Balance account.
For this tutorial you will need a Safe with a threshold of 1 deployed on BNB Chain. You can create one using Safe{Wallet} or the Protocol Kit.
- 1.
- 3.
- 5.
While using Gelato, you can specify that you only want the relay to allow transactions from specific smart contracts. If one of those smart contracts is a Safe smart contract, you will need to either verify the contract on a block explorer or get the ABI of the contract implementation (not the ABI of the smart contract address). This is because the Safe smart contracts use the Proxy Pattern, so the implementation logic for your smart contract exists on a different address.
import { ethers } from 'ethers'
import { GelatoRelayPack } from '@safe-global/relay-kit'
import Safe, { EthersAdapter, getSafeContract } from '@safe-global/protocol-kit'
import { MetaTransactionData, MetaTransactionOptions, OperationType } from '@safe-global/safe-core-sdk-types'
Modify the variables to customize to match your desired transaction settings.
// https://chainlist.org
const RPC_URL='https://endpoints.omniatech.io/v1/bsc/mainnet/public'
const provider = new ethers.providers.JsonRpcProvider(RPC_URL)
const signer = new ethers.Wallet(process.env.OWNER_1_PRIVATE_KEY!, provider)
const safeAddress = '0x...' // Safe from which the transaction will be sent
const chainId = 100
const gasLimit = '100000' // Depends on the contract interaction
// Any address can be used for destination. In this example, we use vitalik.eth
const destinationAddress = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
const withdrawAmount = ethers.utils.parseUnits('0.005', 'ether').toString()
// Create a transaction object
const safeTransactionData: MetaTransactionData = {
to: destinationAddress,
data: '0x',
value: withdrawAmount,
operation: OperationType.Call
}
const options: MetaTransactionOptions = {
gasLimit,
isSponsored: true
}
const ethAdapter = new EthersAdapter({
ethers,
signerOrProvider: signer
})
const safeSDK = await Safe.create({
ethAdapter,
safeAddress
})
const relayKit = new GelatoRelayPack(process.env.GELATO_RELAY_API_KEY!)
const safeTransaction = await safeSDK.createTransaction({ safeTransactionData })
const signedSafeTx = await safeSDK.signTransaction(safeTransaction)
const safeSingletonContract = await getSafeContract({
ethAdapter,
safeVersion: await safeSDK.getContractVersion()
})
const encodedTx = safeSingletonContract.encode('execTransaction', [
signedSafeTx.data.to,
signedSafeTx.data.value,
signedSafeTx.data.data,
signedSafeTx.data.operation,
signedSafeTx.data.safeTxGas,
signedSafeTx.data.baseGas,
signedSafeTx.data.gasPrice,
signedSafeTx.data.gasToken,
signedSafeTx.data.refundReceiver,
signedSafeTx.encodedSignatures()
])
const relayTransaction: RelayTransaction = {
target: safeAddress,
encodedTransaction: encodedTx,
chainId,
options
}
const response = await relayKit.relayTransaction(relayTransaction)
console.log(`Relay Transaction Task ID: https://relay.gelato.digital/tasks/status/${response.taskId}`)
Gelato SyncFee allows you to execute a transaction and pay the gas fees directly with funds in your Safe, even if you don't have ETH or the native blockchain token.
import { GelatoRelayPack } from '@safe-global/relay-kit'
const relayKit = new GelatoRelayPack()
relayKit.relayTransaction({
target: '0x...', // The Safe address
encodedTransaction: '0x...', // Encoded Safe transaction data
chainId: '100'
})
Last modified 2mo ago