Skip to content
Gasless Transactions
Smart Contract Wallet (Recommended)


A smart contract wallet is a wallet that is controlled by code instead of a private key. Transactions can be sent through the wallet if the wallets owners approve of the transaction.

Smart contract wallets offer many benefits to users including batched transactions (e.g. an approval and a swap in the same transaction), gasless transactions, social recovery, and more!

Under the hood our smart contract wallet is a safe. Safe is a popular and battletested smart contract wallet, and our recommended option for offering gasless transactions.

We are also adding support for EIP4337 (Account Abstraction). Let us know if you're interested.

Getting Started

import { Web3Provider } from "@ethersproject/providers";
import { SafeRelayProvider } from "@simplecrypto/relay-provider";

const safeProvider = SafeRelayProvider.fromSimpleCryptoDefault(window.ethereum, {
		ownerAccount: userWalletAddress,
		chainId: 137
    baseURL: "",
    apiKey: "<your_api_key>"

const txHash = await safeProvider.execTransactions([{
	to: gnosisSafeProvider.safeAddress,
	value: 1,
}]); // Send 1 wei to itself

const web3Provider = new Web3Provider(safeProvider);

const transactionReceipt = await web3Provider.waitForTransaction(txHash);

API Reference


new SafeRelayProvider(provider: ExternalProvider, safeContractOptions: SafeContractConstructorOptions, providerOptions: ProviderOptions)

providerExternalProviderA wallet’s rpcProvider. Typically this will be an although legacy providers are also supported.
safeContractOptions.initCodeHashstringThe hash of the init code used to deploy the safe’s proxy via create2
safeContractOptions.factoryContractAddressstringThe address of the factory contract that deploys the gnosis safes
safeContractOptions.factoryContractNamestringThe name of the factory contract that deploys the gnosis safes
safeContractOptions.ownerAccountstringThe address of the account that owns the gnosis safe
safeContractOptions.safeTxTypeHash?stringThe typehash for the Safe contract. The default is 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8 which is the typehash for gnosis safe v3. This typehash is used in signatures that are verified by the safe.
safeContractOptions.domainSeparatorTypeHashstringThe domain separator typehash for the Safe. the default is 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218 which is the domain separator typehash for gnosis safe v3. This typehash is used in signatures that are verified by the safe.
safeContractOptions.multisendContractAddress?stringThe address of the multisend contract to use. The default address is 0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761
providerOptions.baseURLstringThe baseURL for the Simple Crypto API. This will be the URL you’ve set up in the Proxy API setup.
providerOptions.authToken?string(Optional) Your Simple Crypto API token. It is highly recommended that you do not use this option client-side in production as you will expose your API key. This option can be useful for testing in development, though.

SafeRelayProvider.ownerAddress: string

The address that owns the safe smart contract wallet.

SafeRelayProvider.safeAddress: string

The address for the gnosis safe that is owned by safeContractOptions.ownerAccount

async execTransactions(transactions: SafeTransaction[], options?: ExecTransactionOptions): Promise<string>

Execute a transaction through the user’s safe proxy wallet


transactionsSafeTransaction[]The transactions to send. This type is defined below.
options.removeDeployedCheck?booleanWhether to remove the check for whether the safe is already deployed. Removing this check removes an RPC call but comes with the risk of accidentally trying to execute a transaction at an address with no associated code.
options.gasToken?stringThe token for repaying the relayer for sending the transactions
options.refundReceiver?stringThe address to refund for relaying the transaction.


Promise<string> Returns a promise that resolves with the hash of the transaction.

async getSafeNonce(): Promise<BigNumber>

Get the current nonce of the safe




Promise<BigNumber> The current nonce of the safe

async isSafeDeployed(): Promise<boolean>

Check whether the safe is currently deployed





async createSafe(options?: CreateSafeOptions): Promise<string>

Create a new safe smart contract wallet.


options.paymentToken?stringThe token that the safe owner will use to repay the paymentReceiver for deploying the safe
options.paymentReceiver?stringThe address to be repaid with payment amount of paymentToken for the safe deployment


Promise<string> Returns the hash of the transaction.

Last updated on February 7, 2023