# Table of Contents - [What is Relay? - Relay](#what-is-relay-relay) - [API Overview - Relay](#api-overview-relay) - [Overview - Relay](#overview-relay) - [Getting Started - Relay](#getting-started-relay) - [Instant Bridging - Relay](#instant-bridging-relay) - [Cross-Chain Execution - Relay](#cross-chain-execution-relay) - [Bridging - Relay](#bridging-relay) - [Testnet Support - Relay](#testnet-support-relay) - [Swapping - Relay](#swapping-relay) - [Solana Support - Relay](#solana-support-relay) - [Relay Protocol - Relay](#relay-protocol-relay) - [The Reservoir Relayer - Relay](#the-reservoir-relayer-relay) - [Calling - Relay](#calling-relay) - [Contract Compatibility - Relay](#contract-compatibility-relay) - [Swapping - Relay](#swapping-relay) - [Fees - Relay](#fees-relay) - [Refunds - Relay](#refunds-relay) - [Trade Types - Relay](#trade-types-relay) - [Surplus & Shortage - Relay](#surplus-shortage-relay) - [Supported Chains - Relay](#supported-chains-relay) - [Contract Addresses - Relay](#contract-addresses-relay) - [Bounties - Relay](#bounties-relay) - [Handling Errors - Relay](#handling-errors-relay) - [Brand Assets - Relay](#brand-assets-relay) - [Getting Started - Relay](#getting-started-relay) - [Get Chains - Relay](#get-chains-relay) - [Step Execution Overview - Relay](#step-execution-overview-relay) - [createClient - Relay](#createclient-relay) - [Getting Started - Relay](#getting-started-relay) - [Get Config - Relay](#get-config-relay) - [Get Execution Status - Relay](#get-execution-status-relay) - [Adapters - Relay](#adapters-relay) - [Get Requests - Relay](#get-requests-relay) - [Get Currencies - Relay](#get-currencies-relay) - [Get Token Price - Relay](#get-token-price-relay) - [Typescript API Typings - Relay](#typescript-api-typings-relay) - [Get Price - Relay](#get-price-relay) - [Get Quote - Relay](#get-quote-relay) - [Transactions Index - Relay](#transactions-index-relay) - [Get Transactions Status - Relay](#get-transactions-status-relay) - [Swap Multi-Input - Relay](#swap-multi-input-relay) - [getPrice - Relay](#getprice-relay) - [usePrice - Relay](#useprice-relay) - [getQuote - Relay](#getquote-relay) - [ERC-4337 - Relay](#erc-4337-relay) - [Just-In-Time Gas - Relay](#just-in-time-gas-relay) - [useQuote - Relay](#usequote-relay) - [Overview - Relay](#overview-relay) - [useRelayChains - Relay](#userelaychains-relay) --- # What is Relay? - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Introduction What is Relay? [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay is a cross-chain payments system that enables instant, low-cost bridging and cross-chain execution. It works by connecting users with relayers - financial agents that act on users’ behalfs across chains in exchange for a small fee. Relay is designed to minimize gas costs and execution latency, making it ideal for price-sensitive applications, such as payments, bridging, nft minting and gas abstraction. It features the following key properties: * **Fast**: Relayers can fill orders optimistically, even before payment is confirmed. Small payments can confirm in seconds. * **Cheap**: As much logic as possible is performed off of expensive chains to reduce costs. * **Lightweight**: Can operate on any chain with just a single relayer [​](#how-does-it-work) How does it work? ------------------------------------------- Relay is powered by relayers. When a user wishes to bridge, they receive a quote from a relayer. They then accept the quote and submit a transfer to the relayer, who validates the order and sends the funds to the user on the destination chain. Relayers maintains a balance on all chains in order to make executions, and then periodically rebalance to ensure there is sufficient liquidity on all chains. Direct transfers are safe to send relayers because relayers post bonds in escrow that users may access in the case that a relayer does not fulfill their role. Today Relay is powered by the [Reservoir Relayer](/how-it-works/the-reservoir-relayer) . We are hard at work on the [Relay Protocol](/how-it-works/relay-protocol) , which will allow additional relayers to participate in Relay. [​](#how-is-it-so-fast) How is it so fast? --------------------------------------------- In traditional message-based bridges (LayerZero, Axelar, Wormhole, etc), there needs to be consensus amongst a group of actors that something happened on Chain A, before it can be acted upon on Chain B. This is because there are often shared liquidity pools on either side, and so you need to be certain that the action on Chain A was completed. For safety, this usually takes at least a couple of minutes. By contrast, when using a relayer model (Relay, Across, etc), a single relayer executes the order on Chain B using their own funds. This means they don’t need to wait for the action on Chain A to be fully confirmed, or to get consensus. When a user submits and order, the relayer fills as soon as possible, at which point the users desired intent is complete. This can happen in as little as a few seconds for low cost actions, like NFT mints and gas sponsorship. [​](#how-is-it-so-cheap) How is it so cheap? ----------------------------------------------- When bridging or swapping, there are typically three cost components: * **Asset transfer**: Moving assets from one wallet to another * **Order validation**: Ensuring that the user’s order was fulfilled correctly * **Fee collection**: Paying fees to actors such as a protocol, wallet or relayer In most systems, order validation and fee collection happen on the same chain as asset transfer, which is usually a high-cost chain like Ethereum. In Relay, order validation and fee collection happen on a cheaper settlment chain, while asset transfers are reduced to _direct_ transfers between the user and the relayer. This avoids the gas required when routing assets through onchain protocols. This reduces the cost to the absolute minimum possible. For example, for a crosschain bridge, the gas cost to use Relay is ~42,000 gas (origin & destination), while Across, the _cheapest_ alternative, is roughly ~250,000 gas. [​](#what-chains-are-supported) What chains are supported? ------------------------------------------------------------- In many systems, expanding to a new chain requires deploying contracts, getting consensus amongst a network of actors, or deploying liquidity pools. With Relay, you just need a single relayer who is willing to operate on a chain, and it’s permissionless for them to get started. This is critical in a world with an abundance of chains. If you are interested in having your chain supported, reach out! [​](#is-it-trustless) Is it trustless? ----------------------------------------- Not yet! We are hard at work developing the [Relay Protocol](/how-it-works/relay-protocol) , a trustless system that allows users to interact with a permissionless set of relayers. However today, Relay is powered by [Reservoir](https://reservoir.tools/) who is responsible for both order validation & relaying. We have mechanics in place to make sure orders are filled, and funds allocated in case of transaction failure. If you are interested in an enterprise agreement, please reach out. [​](#use-cases) Use Cases ---------------------------- Learn more about the powerful use cases that can be built on Relay: [Instant Bridging\ ----------------\ \ Get your docs set up locally for easy development](https://docs.relay.link/use-cases/instant-bridging) [Cross-chain Execution\ ---------------------\ \ Preview your changes before you push to make sure they’re perfect](https://docs.relay.link/use-cases/cross-chain-execution) [Instant Bridging](/use-cases/instant-bridging) On this page * [How does it work?](#how-does-it-work) * [How is it so fast?](#how-is-it-so-fast) * [How is it so cheap?](#how-is-it-so-cheap) * [What chains are supported?](#what-chains-are-supported) * [Is it trustless?](#is-it-trustless) * [Use Cases](#use-cases) --- # API Overview - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference API Overview [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) We offer multiple APIs to fully harness Relay’s tools. You can use our APIs for instant bridging or cross-chain execution. We recommend using the SDK over our APIs. The SDK will iterate the steps and return useful callback information. The APIs will require iterating through the [steps](/references/api/step-execution) manually. **Get started with the Relay SDK [here](/references/sdk/getting-started) .** | API | Description | | --- | --- | | [Get Chains](/references/api/get-chains) | Returns all possible chains available | | [Get Config](/references/api/get-config) | Returns solver capacity data & user data | | [Get Execution Status](/references/api/get-intents-status-v2) | Returns current execution status | | [Get Transaction Status](/references/api/get-transactions-status) | Returns current status of Transaction | | [Get Request](/references/api/get-requests) | Returns all the cross chain transactions | | [Get Token Price](/references/api/get-token-price) | Returns the price of a token on a specific chain | | [Get Price](/references/api/get-price) | Get a lightweight quote for a bridge, swap or call | | [Get Quote](/references/api/get-quote) | Get a fully executable quote for a bridge, swap or call | | [Transactions Index](/references/api/transactions-index) | Notify the backend about a transaction | [Step Execution Overview](/references/api/step-execution) --- # Overview - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation RelayKit Overview [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) RelayKit is comprised of multiple packages all with one goal in mind: supercharge Relay integration. Below is the directory of packages: SDK --- Craft an engaging and thoughtful user experience while the SDK takes care of fetching and executing quotes [**Docs**](/references/sdk/getting-started) | [**Github**](https://github.com/reservoirprotocol/relay-kit/tree/main/packages/sdk) Hooks ----- Powerful hooks that make fetching and executing quotes in React a breeze [**Docs**](/references/relay-kit/hooks/getting-started) | **Github** UI -- Jumpstart your Relay integration by embedding our fully featured widget [**Docs**](/references/relay-kit/ui/getting-started) | **Github** [Getting Started](/references/relay-kit/hooks/getting-started) --- # Getting Started - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation SDK Reference Getting Started [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) [​](#installation) Installation ---------------------------------- Install the [Relay SDK](https://github.com/reservoirprotocol/relay-sdk) and its peer dependency [viem](https://viem.sh/) #### [​](#environment-requirements) Environment Requirements: node 18+ typescript ^5.0.4 (if using typescript) [​](#configuration) Configuration ------------------------------------ To configure the SDK we first need to create a global instance of a RelayClient: import { createClient, convertViemChainToRelayChain, MAINNET_RELAY_API, TESTNET_RELAY_API } from '@reservoir0x/relay-sdk' import { mainnet } from 'viem/chains' createClient({ baseApiUrl: MAINNET_RELAY_API, source: "YOUR.SOURCE", chains: [convertViemChainToRelayChain(mainnet)] }); You can replace the `baseApiUrl` with `TESTNET_RELAY_API` when testing with testnets. In the example above we also pass in an array of RelayChains converted from a viem chain, the sdk exports a function (`convertViemChainToRelayChain`) to easily do this. [Learn more](/references/sdk/createClient) about the `createClient` options. ### [​](#optional-dynamically-configure-chains) (Optional) Dynamically Configure Chains: The sdk provides a utility function for fetching the supported chains dynamically and configuring the SDK. Below is an example of how you could set that up: import type { AppProps } from "next/app"; import React, { ReactNode, FC, useState, useEffect } from "react"; import { RainbowKitProvider, getDefaultWallets } from "@rainbow-me/rainbowkit"; import { WagmiConfig, createConfig, configureChains, Chain } from "wagmi"; import { publicProvider } from "wagmi/providers/public"; import { alchemyProvider } from "wagmi/providers/alchemy"; import { configureDynamicChains } from "@reservoir0x/relay-sdk"; import { RainbowKitChain } from "@rainbow-me/rainbowkit/dist/components/RainbowKitProvider/RainbowKitChainContext"; const AppWrapper: FC = ({ children }) => { const [wagmiConfig, setWagmiConfig] = useState< ReturnType["wagmiConfig"] | undefined >(); const [chains, setChains] = useState([]); useEffect(() => { configureDynamicChains() .then((newChains) => { const { wagmiConfig, chains } = createWagmiConfig( newChains.map(({ viemChain }) => viemChain as Chain) ); setWagmiConfig(wagmiConfig); setChains(chains); }) .catch((e) => { console.error(e); const { wagmiConfig, chains } = createWagmiConfig( relayClient.chains.map(({ viemChain }) => viemChain as Chain) ); setWagmiConfig(wagmiConfig); setChains(chains); }); }, []); if (!wagmiConfig) { return null; } return ( {children} ); }; function createWagmiConfig(dynamicChains: Chain[]) { const { chains, publicClient } = configureChains(dynamicChains, [\ alchemyProvider({ apiKey: ALCHEMY_KEY }),\ publicProvider(),\ ]); const { connectors } = getDefaultWallets({ appName: "Relay Demo", projectId: WALLET_CONNECT_PROJECT_ID, chains, }); const wagmiConfig = createConfig({ autoConnect: true, connectors, publicClient, }); return { wagmiConfig, chains, }; } The above example demonstrates how to setup dynamic chains in a react application. At the start of your application you would basically configure the dynamic chains in the SDK by using the `configureDynamicChains` method. Then with the new chains in the promise you would use the `viemChain` property to create the wagmi config (refer to the [wagmi docs](https://1.x.wagmi.sh/react/getting-started#create-a-wagmi-config) for this). Finally take the resulting chains and configure the `RainbowKitProvider`. Although in this example we used RainbowKit + Wagmi, you’re free to choose whatever libraries you’d like to connect a users wallet. You can call this method as often as you like to refresh the SDK’s chains. [createClient](/references/sdk/createClient) On this page * [Installation](#installation) * [Environment Requirements:](#environment-requirements) * [Configuration](#configuration) * [(Optional) Dynamically Configure Chains:](#optional-dynamically-configure-chains) --- # Instant Bridging - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Use Cases Instant Bridging [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay enables instant bridging (deposits & withdrawals) on supported chains. Learn more about how it works, how to integrate Relay, and how to get your chain supported below. [​](#how-it-works) How it Works ---------------------------------- Relay’s instant bridging is powered by cross-chain relaying. This model results in low-cost, low-latency (1-10 seconds) cross-chain transactions. When a user wishes to bridge, they receive a quote from Relay that describes the time and cost of bridging. When they accept the quote, the order is validated and they submit a transfer directly to the relayer. The relayer then fulfills the bridge on the destination chain. While the Relay Protocol is still in development, users rely on [Reservoir](https://reservoir.tools/) for order validation and relaying. Applications trust Reservoir to perform cross-chain relaying, and refund money in the case of disputes. The team will be releasing a fully decentralized and trustless protocol shortly, which you can learn more about in the [Relay Protocol Documentation](/how-it-works/relay-protocol) [​](#integrating-instant-bridging) Integrating Instant Bridging ------------------------------------------------------------------ The Relay SDK facilitates interacting with the underlying Relay API. To get started make sure that you install and configure the [Relay SDK](https://docs.relay.link/references/sdk/getting-started) . Ensure that everything is configured properly before moving on to implementing the getQuote and execute action. Instant Bridge import { getClient, Execute } from "@reservoir0x/relay-sdk"; import { createWalletClient, http } from 'viem' ... wallet = createWalletClient({ account: address, transport: http() }) //In this example we're bridging from zora to base const quote = await getClient()?.actions.getQuote({ wallet, chainId: 7777777, // The chain id to bridge from toChainId: 8453, // The chain id to bridge to amount: '100000000000000000', // Amount in wei to bridge currency: '0x0000000000000000000000000000', // ERC20 Address toCurrency: '0x0000000000000000000000000000', // ERC20 Address recipient, // A valid address to send the funds to }) await getClient()?.actions.execute({ quote, wallet, onProgress: (steps, fees, currentStep, currentStepItem) => { console.log(steps, fees, currentStep, currentStepItem) } }) [​](#adding-relay-to-your-chain) Adding Relay to Your Chain -------------------------------------------------------------- Relay can easily be added to any EVM-chain, such as OP stack rollups, Arbitrum Orbit chains, or more. Please feel free to [Reach Out](mailto:support@relay.link) to discuss getting your chain supported today! [What is Relay?](/what-is-relay) [Cross-Chain Execution](/use-cases/cross-chain-execution) On this page * [How it Works](#how-it-works) * [Integrating Instant Bridging](#integrating-instant-bridging) * [Adding Relay to Your Chain](#adding-relay-to-your-chain) --- # Cross-Chain Execution - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Use Cases Cross-Chain Execution [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay enables cross-chain execution for arbitrary cross-chain transactions, as well as being integrated with Reservoir’s pre-defined NFT actions (buy, sell, & mint). Using Relay, your users can pay for any action on any supported chain, by simply submitting the destination chain call data to Relay. [​](#how-it-works) How it Works ---------------------------------- Relay’s cross-chain execution is powered by cross-chain relaying. This model results in low-cost, low-latency (1-10 seconds) cross-chain transactions. When a user wishes to perform a cross-chain action, they submit the arbitrary call data to get a quote from relayers for execution. When they accept the quote, the order is validated and they submit a transfer directly to the relayer. The relayer then executes the calldata on the destination chain. While the Relay Protocol is still in development, users rely on [Reservoir](https://reservoir.tools/) for order validation and relaying. Applications trust Reservoir to perform cross-chain relaying, and refund money in the case of disputes. The team will be releasing a fully decentralized and trustless protocol shortly, which you can learn more about in the [Relay Protocol Documentation](/how-it-works/relay-protocol) . [​](#using-relays-cross-chain-execution) Using Relay’s Cross-chain Execution ------------------------------------------------------------------------------- You can use Relay Cross-chain Execution with custom call methods or with the pre-defined methods of the Reservoir Aggregator. ### [​](#custom-call-methods) Custom Call Methods Relay lets you execute arbitrary call data cross-chain using a custom call method. You can call custom contract methods, mint from custom contracts, mint + bridge (mint an NFT and bridge additional funds in one), or any other custom call execution. To get started make sure that you install and configure the [Relay SDK](/references/sdk/getting-started) . Ensure that everything is configured properly before moving on to implementing the call action. ### [​](#guides) Guides * [**Bridge**](/guides/bridging) : Bridge funds to another chain * [**Swap**](/guides/swapping) : Swap funds from one currency to another across different chains * [**Custom Contract Call**](/guides/calling) : Call a contract method across chains to perform a multitude of actions ### [​](#cross-chain-execution-with-the-reservoir-aggregator) Cross-chain Execution with the Reservoir Aggregator To use cross-chain execution with the Reservoir Aggregator, i.e. to mint, buy or sell NFTs aggregated by Reservoir, simply use the Reservoir SDK to trigger cross-chain execution with the appropriate method. When using the Reservoir SDK to trigger a cross-chain purchase all that’s required is additionally passing a `currencyChainId` to the buyToken method. This assumes you know which token you would like to buy or mint. You can leverage the Reservoir API to look at aggregated collection liquidity, or trending mints. Below is an example of what that would look like to buy a token from secondary: Cross-chain Example import { getClient, Execute } from "@reservoir0x/reservoir-sdk"; import { createWalletClient, http } from 'viem' ... address = "0x8ba1f109551bD432803012645Ac136ddd6000000" wallet = createWalletClient({ account: address, transport: http() }) getClient()?.actions.buyToken({ items: [{ token: "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d:1", quantity: 1 }], options: { currencyChainId: 10 }, wallet, onProgress: (steps: Execute['steps']) => { console.log(steps) } })``` [Instant Bridging](/use-cases/instant-bridging) [Bridging](/guides/bridging) On this page * [How it Works](#how-it-works) * [Using Relay’s Cross-chain Execution](#using-relays-cross-chain-execution) * [Custom Call Methods](#custom-call-methods) * [Guides](#guides) * [Cross-chain Execution with the Reservoir Aggregator](#cross-chain-execution-with-the-reservoir-aggregator) --- # Bridging - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Guides Bridging [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) ### [​](#summary) Summary 1 Fetch the Price [](#fetch-the-price) This optional step is quicker than fetching an executable quote but invaluable when crafting a snappy user experience. In this step we’ll fetch the price to display a quote preview to the user. This can be skipped if the bridge is on the server without user interaction. 2 Fetch the Quote [](#fetch-the-quote) In this step we’ll fetch a full quote that expires after 30s. It will be a complete quote with all the details required to execute it. 3 Execute the Quote [](#execute-the-quote) Once we have the quote all that’s left to do is execute the quote and display a progress state to the user. [​](#fetch-the-price) Fetch the Price ---------------------------------------- The Price is a lightweight quote, excluding steps and calldata but it includes a preview of what the full quote might contain. Prices are subject to change once you get the quote so you should handle price changes accordingly. Once you determine where to bridge from and to, the amount and the currency then you can pass everything into the [getPrice](/references/sdk/actions/getPrice) or the [usePrice](/references/relay-kit/hooks/usePrice) hook depending on if you’re using the sdk or the ui hooks: [​](#fetch-the-quote) Fetch the Quote ---------------------------------------- If you followed the previous step, you can pass that same data into the [getQuote](/references/sdk/actions/getQuote) action or [useQuote](/references/relay-kit/hooks/useQuote) hook. In the above example, we fetch the quote to bridge 0.1 ETH from Ethereum Mainnet to Zora. In the quote object we’ll get data on the fees required to do this bridge. You can learn more about fees [here](/how-it-works/fees) . **Note** - Quotes can go stale after 30 seconds. Clients should regularly fetch fresh quotes so that users are always submitting valid transactions. [Learn more](/how-it-works/the-reservoir-relayer#getting-a-quote) about Relay quotes. [​](#execute-the-quote) Execute the Quote -------------------------------------------- After getting the quote all that’s left is to execute the quote and render the progress to the user. Follow the code snippets below to execute the quote: While the quote is being executed if you’re rendering the quote in an interface you may want to display progress to the user. There’s a provided progress callback to get the updated state of execution. Learn more about the progress state [here](/references/sdk/actions/execute#handling-onprogress-updates) . ### [​](#preflight-checklist) Preflight Checklist ☐ Verify that the user has enough balance on the origin chain to cover the full bridge amount + fees. Check out our [fees](/how-it-works/fees) doc for more details on calculating the fees. ☐ Have the Relay SDK set up and the Relay hooks package installed if applicable ☐ Ensure the user is on the correct chain (it should match the chainId you get the quote from) ☐ Handle any errors that may come about ☐ Render the progress of the bridge to provide a best in class user experience [Cross-Chain Execution](/use-cases/cross-chain-execution) [Swapping](/guides/swapping) On this page * [Summary](#summary) * [Fetch the Price](#fetch-the-price) * [Fetch the Quote](#fetch-the-quote) * [Execute the Quote](#execute-the-quote) * [Preflight Checklist](#preflight-checklist) --- # Testnet Support - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Guides Testnet Support [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay supports a variety of testnet and tokens. We recommend using testnets and their tokens as a way to test bridging with no cost. Our testnet chains are full supported across all of our tools: APIs, SDK, and UI Kit. Feel free to explore the chains offered below. For the latest list, please explore our [Testnets Supported Chains](/resources/supported-chains#testnets) . **Testnets are not recommended for testing swaps.** Testnets typically lack real DEX liquidity making testnet swaps fail. We recommend using inexspensive L2s like Base or Arbitrum to test swapping. The cost of gas will outweight the time required to debug testnet-specific issues like illiquidity. [​](#testnets-supported) Testnets Supported ---------------------------------------------- You can see all the testnets we support in the table below. You can also query our API to get a JSON of the supported testnets: [https://api.testnets.relay.link/chains](https://api.testnets.relay.link/chains) The API response will also return chain IDs and other relevant information. [​](#api-support) API Support -------------------------------- To access testnets with our API, make sure to use the correct base URL: `https://api.testnets.relay.link` By using this base URL, you’ll be able to bridge, swap, and transact on testnets Relay supports. To get started, check out the [API documentation](/references/api/overview) . [​](#sdk-support) SDK Support -------------------------------- To access testnets with our SDK, make sure to use the correct base URL: `https://api.testnets.relay.link` You’ll pass this base URL in the `baseApiUrl` parameter when creating the client. To get started, check out the [SDK documentation](/references/sdk/getting-started) . [​](#ui-kit-support) UI Kit Support -------------------------------------- To access testnet with our UI kit, make sure to pass the testnet chain you want e.g. `base sepolia`, `sepolia`, etc. To get started, check out the [UI Kit documentation](/references/relay-kit/overview) . [Solana Support](/guides/solana) [Just-In-Time Gas](/guides/just-in-time-gas) On this page * [Testnets Supported](#testnets-supported) * [API Support](#api-support) * [SDK Support](#sdk-support) * [UI Kit Support](#ui-kit-support) --- # Swapping - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Guides Swapping [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) ### [​](#summary) Summary 1 Fetch the Price [](#fetch-the-price) This optional step is quicker than fetching an executable quote but invaluable when crafting a snappy user experience. In this step we’ll fetch the price to display a quote preview to the user. This can be skipped if the swap is on the server without user interaction. 2 Fetch the Quote [](#fetch-the-quote) In this step we’ll fetch a full quote that expires after 30s. It will be a complete quote with all the details required to execute it. 3 Execute the Quote [](#execute-the-quote) Once we have the quote all that’s left to do is execute the quote and display a progress state to the user. [​](#fetch-the-price) Fetch the Price ---------------------------------------- The Price is a lightweight quote, excluding steps and calldata but it includes a preview of what the full quote might contain. Prices are subject to change once you get the quote so you should handle price changes accordingly. Once you determine where to swap from and to, the amount and the currency then you can pass everything into the [getPrice](/references/sdk/actions/getPrice) or the [usePrice](/references/relay-kit/hooks/usePrice) hook depending on if you’re using the sdk or the ui hooks: [​](#fetch-the-quote) Fetch the Quote ---------------------------------------- If you followed the previous step, you can pass that same data into the [getQuote](/references/sdk/actions/getQuote) action or [useQuote](/references/relay-kit/hooks/useQuote) hook. In the above example, we fetch the quote to swap 0.1 ETH on Ethereum Mainnet to USDC on Base. In the quote object we’ll get data on the fees required to do this swap. You can learn more about fees [here](/how-it-works/fees) . **Note** - Quotes can go stale after 30 seconds. Clients should regularly fetch fresh quotes so that users are always submitting valid transactions. [Learn more](/how-it-works/the-reservoir-relayer#getting-a-quote) about Relay quotes. [​](#execute-the-quote) Execute the Quote -------------------------------------------- After getting the quote all that’s left is to execute the quote and render the progress to the user. Follow the code snippets below to execute the quote: While the quote is being executed if you’re rendering the quote in an interface you may want to display progress to the user. There’s a provided progress callback to get the updated state of execution. Learn more about the progress state [here](/references/sdk/actions/execute#handling-onprogress-updates) . ### [​](#preflight-checklist) Preflight Checklist ☐ Verify that the user has enough balance on the origin chain to cover the full swap amount + fees. Check out our [fees](/how-it-works/fees) doc for more details on calculating the fees. ☐ Have the Relay SDK set up and the Relay hooks package installed if applicable ☐ Ensure the user is on the correct chain (it should match the chainId you get the quote from) ☐ Handle any errors that may come about ☐ Render the progress of the swap to provide a best in class user experience [Bridging](/guides/bridging) [Calling](/guides/calling) On this page * [Summary](#summary) * [Fetch the Price](#fetch-the-price) * [Fetch the Quote](#fetch-the-quote) * [Execute the Quote](#execute-the-quote) * [Preflight Checklist](#preflight-checklist) --- # Solana Support - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Guides Solana Support [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay now fully supports depositing & withdrawing to Solana from any EVM chain we support. This is a great way to get users funds on Solana to complete transactions. You can onboard users funds from Blast ETH to Solana USDC to make transactions on a game. You could also swap funds from Solana SOL to Zora ETH for users to mint. The possibilities are limitless when you use Relay embedded in your app. [​](#required-information) Required Information -------------------------------------------------- There are few things that make transacting on Solana different than another EVM chain. The provided information below should review all the exceptions where your input is Solana specific. Solana wallet addresses are case sensitive. ### [​](#sdk-properties) SDK Properties | Action | Parameter | Input | Description | | --- | --- | --- | --- | | Deposit to Solana | `toChainId` | `792703809` | Chain ID assigned to access Solana for Relay’s tools. | | | `recipient` | User’s Solana Address | Must be a valid Solana address. Do **not** use an Ethereum wallet address. _Case Sensitive_ | | | `toCurrency` | Contract Address of Solana Token | Must be a valid Solana token address. Do **not** use an EVM address. We support all tokens tradeable on [Jupiter](https://jup.ag/)
. | | Withdraw from Solana | `chainId` | `792703809` | Chain ID assigned to access Solana for Relay’s tools. | | | `currency` | Contract Address of Solana Token | Must be a valid Solana token address. Do **not** use an EVM address. We support all tokens tradeable on [Jupiter](https://jup.ag/)
. | When withdrawing from Solana using the SDK, you will not need to speicify the depositing wallet address. ### [​](#api-params) API Params | Action | Parameter | Input | Description | | --- | --- | --- | --- | | Deposit to Solana | `recipient` | User’s Solana Address | Must be a valid Solana address. Do **not** use an Ethereum wallet address. _Case Sensitive_ | | | `destinationChainId` | `792703809` | Chain ID assigned to access Solana for Relay’s tools. | | | `destinationCurrency` | Contract Address of Solana Token | Must be a valid Solana token address. Do **not** use an EVM address. We support all tokens tradeable on [Jupiter](https://jup.ag/)
. | | Withdraw from Solana | `user` | User’s Solana Address | Must be a valid Solana address. Do **not** use an Ethereum wallet address. _Case Sensitive_ | | | `originChainId` | `792703809` | Chain ID assigned to access Solana for Relay’s tools. | | | `originCurrency` | Contract Address of Solana Token | Must be a valid Solana token address. Do **not** use an EVM address. We support all tokens tradeable on [Jupiter](https://jup.ag/)
. | ### [​](#solana-tokens) Solana Tokens In the table, we have provided the most frequently used Solana tokens & their contract addresses. We do support all tradeable tokens on [Jupiter](https://jup.ag/) . Solana token addresses are case sensitive. | Token | Token Address | Token Symbol | Decimals | | --- | --- | --- | --- | | SOL | `11111111111111111111111111111111` | SOL | 9 | | USDC | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` | USDC | 6 | | wSol | `So11111111111111111111111111111111111111112` | wSOL | 9 | | USDT | `Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB` | USDT | 6 | Relay supports **any** Solana token available on Jupiter. You can visit [Jupiter](https://jup.ag/) to explore all the tokens available. [​](#api) API ---------------- Once you have the necessary information, you can start utilizing our API for full Solana withdrawal and deposit support. To get started, check out the [execution steps](/references/api/step-execution) of our API. Then when you’re ready to swap, head over to the [Get Quote](/references/api/get-quote) API endpoint. Please note that instead of the usual calldata returned with EVM transactions, there’s different calldata that needs to be handled accordingly. [​](#sdk) SDK ---------------- You’ll need the information shared in the tables above to utilize the SDK to deposit or withdraw from Solana. In addition to that you’ll also need to install and configure the [relay solana adapter](/references/sdk/adapters/overview#what-adapters-are-available-out-of-the-box) . To get started, learn how to set up our [SDK client](/references/sdk/getting-started) . Afterwards, explore our [getQuote](/references/sdk/actions/getQuote) SDK action to start swapping. [Calling](/guides/calling) [Testnet Support](/guides/testnet) On this page * [Required Information](#required-information) * [SDK Properties](#sdk-properties) * [API Params](#api-params) * [Solana Tokens](#solana-tokens) * [API](#api) * [SDK](#sdk) --- # Relay Protocol - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation How it Works Relay Protocol [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) [​](#introduction) Introduction ---------------------------------- Relay Protocol is a cross-chain payments system that connects users to relayers willing to perform onchain actions on their behalf. Relay’s design minimizes gas costs, enables rapid chain expansion, and maximizes capital efficiency all while remaining open and trustless. Such a system is particularly well-suited for low-value, high frequency cross-chain actions such as those expected in a world of chain abstraction. [​](#background-cross-chain-relaying) Background: Cross-Chain Relaying ------------------------------------------------------------------------- Relay is similar to other “intent-based” protocols like Across, where liquidity providers known as _Relayers_ use their own capital to “fast fill” user requests to move between chains, and then rebalance using slow, expensive bridges under the hood. This design has two key advantages over typical bridging: * **Speed** - Because relayers are fronting their own capital, they can take on confirmation risk and fill optimistically, without waiting for global consensus * **Cost** - Because rebalancing is done infrequently and in batches, the security cost of using bridges is amortized across many users The typical flow for intent-based protocols is as follows: 1. User _escrows_ funds on the origin chain 2. Relayer _fills_ the order on the destination chain 3. Relayer later _settles_ the order on the origin, to claim _payment_ Each of these steps has a cost, which different protocols minimize in different ways. Across, which pioneered this design, reduces the cost of settlement with two optimizations: * Instead of proving every fill with an oracle or cross-chain message, settlement is done optimistically, by assuming it is correct, and having a challenge period * Settlement is done in large batches across the whole protocol, every 4 hours As a result, the vast majority of the remaining cost comes from the _Deposit_ (~77,000 gas) and _Fill_ (~120,000 gas). This is where **Relay** is able to achieve significant improvements: [​](#relays-design) Relay’s Design ------------------------------------- Relay shares the same core components as other escrow systems: escrow, fulfillment, settlement, and payment. However, it changes who, how and where they are executed, to improve efficiency. ### [​](#settlement-chain) Settlement Chain The key difference is that instead of users depositing funds into escrow on every chain that they want to pay from, relayers deposit into escrow on a single dedicated “Settlement Chain”. A number of significant benefits flow from this change: * **Gas efficiency** - Because users aren’t the ones escrowing funds, they can send payment directly to the relayer as an efficient raw transfer (only 21,000 gas) * **Deployment efficiency** - Because all escrow and settlement happens on a single dedicated chain, supporting new origin / destination chains is much simpler * **Capital efficiency** - Because this settlement chain can be a low-cost L2, orders can be settled immediately, preventing relayer capital from being locked up for hours * **Fee efficiency** - Because relayers hold ETH on this low-cost L2, granular fees can be paid out with near-zero overhead Each of these benefits is discussed more below. ### [​](#direct-transfers) Direct Transfers In Relay, the flow becomes: 1. Relayers _escrow_ funds on the “Settlement Chain” 2. User sends _payment_ directly to the relayer wallet on the origin 3. Relayer _fills_ directly to the user wallet on the destination 4. Relayer later _settles_, freeing their escrow to be used again in a future order The biggest unlock from this is that because the relayer’s escrowed funds act as a bond, the user and relayer can safely make direct transfers to each other, reducing the deposit and fill to highly efficient direct transfers (~21,000 gas each). This makes it up to 5x cheaper than alternative relaying protocols. This can make a huge difference to the sort of use-cases that are possible to implement cross-chain, especially when transaction values are low (e.g. $1 NFT mints). Intuitively, it might seem insecure to send funds directly to the relayer, but the risk and UX are similar to the typical flow: * User is transferring funds into a state where they no longer control them * The full value of their transaction is locked in escrow as collateral * In the event of the failure, user has a mechanism to get refunded, after a delay The main downside of direct transfers is that there is increased risk of user error. However, this can be counteracted with robust client-side validation. For many applications, the dramatically lower costs are worth the trade-offs. For others, there is always the option to use onchain validation on top of the base protocol. ### [​](#single-contract) Single Contract Interoperability protocols are often slow in expanding to new chains for a number of reasons: * Global consensus must be achieved amongst a set of validators or token holders to begin supporting a chain * Canonical smart contracts need to be deployed and managed on every supported chain by the core team * Liquidity pools need sufficient depth to offer good prices As a result, most protocols are not well-suited to supporting the long tail of chains in a world of abundant L2s. Relay was designed with this in mind. Because settlement happens on a single dedicated chain, and asset transfers happen through direct transfers, it means there are no smart contracts required on the origin and destination chains. All it takes is a single relayer that is willing to offer service on that chain, and it can be supported. No permission or deployments are required, while still being able to tap into the security that the protocol provides. ### [​](#immediate-settlement) Immediate Settlement Another advantage of having all settlement happen on a single chain is that you can choose a chain with optimal properties. On other protocols, where settlement happens on all chains, including high-security chains like Ethereum, batch settlement is critical to keep costs low. However, batch settlement has downsides: * Capital inefficiency - Relayer funds are tied up in between batches (4 hours for Across) * Inflexibility - All orders must use the same settlement mechanism For Relay, settlement is done on a low-cost L2 with a trust-minimized bridge to Ethereum, making it viable to settle every order individually and immediately. This adds some costs, but very minor, and unlocks massive capital efficiency and flexibility gains. Consider the case where orders are settled every 2 minutes, which is comparable to other interoperability protocols that do message validation like Wormhole, LayerZero, etc. This is around 240 times quicker than Across. Once you factor in that only half the relayer’s capital can be used for filling (because the rest is used as escrow), it works out around 120x more capital efficient. This means Relayer can either earn more or charge less for the same amount of capital. One other nice thing about individual settlement is that it doesn’t require global consensus or third party validation. You just need the two parties involved in the transaction, the user and the relayer, to agree that the order was filled. This allows even more aggressive settlement time. In Relay, actors will be incentivized (through reputation, bond penalties, etc.) to quickly “self-settle” orders and only rely on third party validation to settle disputes. This can result in even greater capital efficiency for relayers. ### [​](#relay-eth) Relay ETH One major factor that needs to be considered when striving to reduce costs is the efficient collection of fees. It’s quite common for fees to be collected by various actors in the order pipeline, beyond just the relayer: * Protocol fees * Interface / wallet fees * Aggregator API fees * Referrer fees In other protocols, these fees are collected on either the origin or destination chain. This can add considerable gas overhead, which is either passed onto the user in the form of increased costs, or forces participants to find other mechanisms to earn revenue. Relay solves this problem by collecting fees on the low cost settlement chain. This means that even when a transaction is occurring on expensive chains like Ethereum, granular fees can be collected at near zero cost. The way it works is that fees are paid out of the relayer’s escrowed balance. For example, consider a scenario where the user is bridging 1 ETH, the relayer is charging 0.001, and other actors charging 0.002: 1. User pays 1.003 to relayer on origin 2. Relayer pays 1 to user on destination 3. 0.002 in fees taken out of relayer balance on settlement chain In effect, the ETH that lives on the settlement chain has multiple purposes. It acts as a bond to secure transactions on other chains, but also can be used for low cost payments between different actors. Other use cases for Relay ETH include: * Users can hold it, and use it as a low-cost cross-chain spending balance * Unspent gas can be rebated as Relay ETH, removing the need for relayers to factor destination gas fluctuations in their quotes [​](#conclusion) Conclusion ------------------------------ The key theme of the Relay Protocol is the pursuit of maximum efficiency. This is because exciting new use cases only become possible once cost, latency and friction are reduced to an absolute minimum. Even as blockspace becomes abundant, designing a system that is maximally efficient remains important, because it allows savings to be passed on to users, relayers and apps. [​](#future-work) Future Work -------------------------------- This overview was designed to give a high level summary, and did not go into technical detail or discuss how adversarial scenarios are handled. These will be addressed in a future whitepaper. Additionally, this overview focused on instant bridging and cross-chain execution, which are the first use-cases being productized. However, Relay is effectively a generalized protocol for executing “non-atomic swaps”. While that makes it particularly well-suited to cross-chain actions, it can also have interesting applications for same-chain actions, which will be expanded upon at a later date. [ERC-4337](/guides/erc-4337) [The Reservoir Relayer](/how-it-works/the-reservoir-relayer) On this page * [Introduction](#introduction) * [Background: Cross-Chain Relaying](#background-cross-chain-relaying) * [Relay’s Design](#relays-design) * [Settlement Chain](#settlement-chain) * [Direct Transfers](#direct-transfers) * [Single Contract](#single-contract) * [Immediate Settlement](#immediate-settlement) * [Relay ETH](#relay-eth) * [Conclusion](#conclusion) * [Future Work](#future-work) --- # The Reservoir Relayer - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation How it Works The Reservoir Relayer [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) The Reservoir relayer is a production-grade relayer currently supporting Relay. Reservoir acts as a trusted party that performs cross-chain relays and order validation. [​](#how-does-it-work) How does it work? ------------------------------------------- When a user wishes to bridge, they submit an order and a transfer to the Reservoir relayer, who validates the order and sends the funds to the user on the destination chain. Reservoir maintains a balance on all chains in order to make executions, and then periodically rebalances to ensure there is sufficient liquidity on all chains. In the rare case of a transaction failure, Reservoir refunds the user directly as soon as possible. While this model requires trust in Reservoir as a service provider, it reduces the costs of executing cross-chain actions to an absolute minimum. Since each cross-chain action is simply an origin chain transfer and a destination chain transfer (42000 gas total), it is substantively cheaper than bridging on other bridges. [​](#why-start-with-a-trusted-system) Why start with a trusted system? ------------------------------------------------------------------------- The current state of Relay, which requires trust in Reservoir’s relayer, is an important part of the protocol development process. It is not intended as a final state of the system, but as a way to introduce the core concepts, and learn from users, developers, and relayers about what is most important in the future decentralized system. If you are interested in learning more about where Relay is headed, you can read the protocol overview [here](/how-it-works/relay-protocol) . ### [​](#technical-overview) Technical overview Here we walk through some technical details about how the Reservoir relayer functions. #### [​](#getting-a-quote) Getting a quote When a user wishes to Relay, the application receives an order (quote) from the [Relay SDK/API](/references/overview) . The quote returns both a cost for execution, and an expected time. The quote is a total value required by the user for the action to proceed. The quote encompasses the execution value, the estimated destination chain gas fee, and the relayer fee. This quote _covers the gas cost on the destination chain_. The transfer call data for order acceptance is also included in the returned data. #### [​](#quote-execution-flow) Quote Execution Flow: * User gets a quote which is valid for 30 seconds. * If the user submits within 30 seconds, the solver will fill the request. * If the user doesn’t submit in time, the solver will get a fresh quote. * If the new quote is higher than the old one, the fallback flow is triggered. * If the new quote is less than or equal to the old one, the solver proceeds with the request. * In the fallback case, the user is refunded either on the destination (default) or origin chain. (The `refundOnOrigin` param can be passed into the bridge/call apis and sdk actions to override the refund logic) **Note:** Because quotes can go stale after 30 seconds, it is crucial for the client to regularly fetch fresh quotes so that users are always submitting valid transactions. #### [​](#onchain-order-attribution) Onchain order attribution When the user accepts the order, they submit a transfer to the solver. An order ID associated with the quote is appended in the tx calldata. This order ID will be used on the destination chain to link fills across chains. #### [​](#order-validation-and-filling) Order validation and filling Upon validation of the inbound transfer transaction, the Reservoir relayer will fill the order on the destination chain. Included in the fill transaction is the order ID associated with the quote. Reservoir maps the origin and destination chain transactions together by order ID to ensure the transaction is filled appropriately. #### [​](#rebalancing) Rebalancing The Reservoir relayer uses a robust rebalancing algorithm to make sure funds are as available as possible for cross-chain executions. The user is not responsible for any rebalancing activity. If the Reservoir relayer becomes “off-balance”, the capacity for instant relaying may be limited. #### [​](#refunds) Refunds If for some reason the quoted execution is no longer available by the time of relay submission, the user may be refunded. Refunds are as instant as possible and are refunded on the destination chain by default, and the origin chain otherwise. The `refundOnOrigin` param can be passed into the bridge/call apis and sdk actions to override the refund logic. #### [​](#partial-fills) Partial fills If the user submits the transfer event after quote expiration, the relayer may not be able to fill the order at the quoted price if gas prices on the destination chain have increased substantially. In this case, the relayer will attempt to fill the order at the best possible price, and give the rest of the bridged value to the user. ### [​](#disputes) Disputes Due to the trusted nature of the current Relay design, disputes (i.e. cases where a user did not receive the expected outcome and was not refunded) should be brought directly to the Reservoir support team. [Relay Protocol](/how-it-works/relay-protocol) [Contract Compatibility](/how-it-works/contract-compatibility) On this page * [How does it work?](#how-does-it-work) * [Why start with a trusted system?](#why-start-with-a-trusted-system) * [Technical overview](#technical-overview) * [Getting a quote](#getting-a-quote) * [Quote Execution Flow:](#quote-execution-flow) * [Onchain order attribution](#onchain-order-attribution) * [Order validation and filling](#order-validation-and-filling) * [Rebalancing](#rebalancing) * [Refunds](#refunds) * [Partial fills](#partial-fills) * [Disputes](#disputes) --- # Calling - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Guides Calling [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) ### [​](#summary) Summary 1 Fetch the Price [](#fetch-the-price) This optional step is quicker than fetching an executable quote but invaluable when crafting a snappy user experience. In this step, we’ll fetch the price to display a quote preview to the user. This can be skipped if the call is on the server without user interaction. 2 Fetch the Quote [](#fetch-the-quote) In this step, we’ll fetch a full quote that expires after 30 seconds. It will be a complete quote with all the details required to execute it. 3 Execute the Quote [](#execute-the-quote) Once we have the quote all that’s left to do is execute the quote and display a progress state to the user. ### [​](#contract-compatibility) Contract Compatibility Before we begin it’s important to ensure that a contract is compatible with Relay. Please review our [Contract Compatibility](/how-it-works/contract-compatibility) overview to make any necessary changes. [​](#fetch-the-price) Fetch the Price ---------------------------------------- The price is a lightweight quote, excluding steps and calldata; but it includes a preview of what the full quote might contain. Prices are subject to change once you get the quote so you should handle price changes accordingly. You’ll need to determine where the user wants to call the contract from, where the contract has been deployed to, and their preferred payment currency. Afterwards, you can pass everything into the [getPrice](/references/sdk/actions/getPrice) SDK action or the [usePrice](/references/relay-kit/hooks/usePrice) UI hook. Note that for calling a contract across chains you’ll need to provide three key pieces of information in addition to the usual data required to call: * **tradeType** must be `EXACT_OUTPUT`. * **txs** can either be an array of `to`, `data` and `value` or it can be the response from viem’s [simulateContract](https://viem.sh/docs/contract/simulateContract) method. You can see an example below of how this is done. * **amount** must be the sum of all the txs values. [​](#fetch-the-quote) Fetch the Quote ---------------------------------------- If you followed the previous step, you can pass that same data into the [getQuote](/references/sdk/actions/getQuote) SDK action or [useQuote](/references/relay-kit/hooks/useQuote) UI hook. You’ll still need to meet the requirements for `tradeType`, `amount` and `txs`, refer to the previous step for more details. In the above example, we fetch the quote to call a Zora contract from Mainnet Ethereum. In the quote object, we’ll get data on the fees required to do this call. You can learn more about fees [here](/how-it-works/fees) . You’ll see that we provided an amount that matches the sum of the txs, that the tradeType is `EXACT_OUTPUT` and that we passed in a valid txs array. Quotes can go stale after 30 seconds. Clients should regularly fetch fresh quotes so that users are always submitting valid transactions. [Learn more](/how-it-works/the-reservoir-relayer#getting-a-quote) about Relay quotes. [​](#execute-the-quote) Execute the Quote -------------------------------------------- After getting the quote, all that’s left is to execute the quote and render the progress to the user. Follow the code snippets below to execute the quote: While the quote is being executed if you’re rendering the quote in an interface you may want to display progress to the user. There’s a provided progress callback to get the updated state of execution. Learn more about the progress state [here](/references/sdk/actions/execute#handling-onprogress-updates) . ### [​](#preflight-checklist) Preflight Checklist ☐ Verify that the user has enough balance on the origin chain to cover the full txs amount + fees. Check out our [fees](/how-it-works/fees) doc for more details on calculating the fees. ☐ Have the Relay SDK set up and the Relay hooks package installed if applicable ☐ Ensure the user is on the correct chain (it should match the chainId you get the quote from) ☐ Handle any errors that may come about ☐ Render the progress of the execution to provide a best in class user experience [Swapping](/guides/swapping) [Solana Support](/guides/solana) On this page * [Summary](#summary) * [Contract Compatibility](#contract-compatibility) * [Fetch the Price](#fetch-the-price) * [Fetch the Quote](#fetch-the-quote) * [Execute the Quote](#execute-the-quote) * [Preflight Checklist](#preflight-checklist) --- # Contract Compatibility - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation How it Works Contract Compatibility [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay allows a user to pay on Chain A for an arbitrary set of transactions to be executed on Chain B. These transactions are executed by a relayer, not the user themselves, which means you need to make special considerations to make sure your contract is compatible. [​](#general-overview) General overview ------------------------------------------ When Relayers execute transactions on behalf of users, they do so via a multicall contract (to be specific, we use Vectorized’s gas-optimized [Multicaller](https://github.com/Vectorized/multicaller) contract). This protects the Relayer from malicious transactions. One exception is simple bridge transactions, where the `data` is empty. For these, the Relayer will execute them directly to avoid the gas overhead of using Multicaller. [​](#sender-attribution) Sender Attribution ---------------------------------------------- Because transactions are executed via the Relayer / Multicaller, you can’t rely on `msg.sender` for authentication. There are a couple of ways around this: #### [​](#unauthenticated-delegation) Unauthenticated Delegation The simplest solution is if your contract allows one user to take an action on behalf of another user. This works great for actions that don’t require authentication, because they are purely net beneficial to the user: * buying an NFT * depositing into a vault * placing an auction bid You just need to allow passing the address that the action is being done on behalf of. Of course, you can’t do this for actions that potentially harm the user: * selling the NFT * withdrawing from the vault * canceling the bid, etc. Some contracts don’t require authentication, but also don’t have native delegation built into them. In such scenarios, it might be possible to use a router contract. E.g. if an NFT only supported minting to `msg.sender`, you could mint via a router contract then have it forwarded the NFT to the user. #### [​](#authenticated-delegation) Authenticated Delegation For authenticated actions, you can do those by passing in proof that the user authenticated the action. Currently, you need to build custom signature authentication into your contract, however, in the near future we will be adding support for more standardized flows, such as: * Selling tokens with permit signatures * MulticallerWithSigner * ERC2771 Trusted Forwarder #### [​](#just-in-time-gas) Just-In-Time Gas Alternatively, you can simply bridge a small amount of gas and have the user execute the transaction themselves. This is viable because of how fast and cheap Relay is, and is backwards compatible with any contract. We will soon add functionality to our SDK to handle this flow completely automatically, but until then, you can do it manually like this: * Estimate the cost of the transaction on destination * Get a quote to bridge enough gas (small buffer recommended to handle fluctuation) * User executes the bridge of gas money from Origin to Destination * User executes the action on Destination * (Optional) If selling an asset, User could potentially bridge the proceeds back to Origin This might seem like a lot, but especially when Origin and Destination are both L2s, it can be quite fast and cheap. Arguably, much better than the user needing to worry about having a balance on many chains. [The Reservoir Relayer](/how-it-works/the-reservoir-relayer) [Swapping](/how-it-works/swapping) On this page * [General overview](#general-overview) * [Sender Attribution](#sender-attribution) * [Unauthenticated Delegation](#unauthenticated-delegation) * [Authenticated Delegation](#authenticated-delegation) * [Just-In-Time Gas](#just-in-time-gas) --- # Swapping - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) ### [​](#introduction) Introduction Swapping is the act of taking one token and exchanging it for another. There are many protocols that help with this, notably, UniSwap, PancakeSwap, CowSwap, and many more. These protocols can either center around decentralized liquidity or centralized liquidity, with various different caveats for different use cases. The act of cross-chain swapping usually requires multiple steps by the user, each using a different protocol: 1. Swapping from an ERC20 to native currency 2. Going to a bridge and bridging the native currency 3. Swapping from native currency to an ERC20 on destination With Relay, we bundle these steps into one operation the user can take for the sake of cost and speed efficiency. ### [​](#cross-chain-swaps-via-relay) Cross-Chain Swaps via Relay Relay builds on top of our pre-existing bridging infrastructure to allow cross-chain swapping. Our bridging infrastructure allows the fast transfer of native and some preset ERC20 currencies across chains. We can extend this to swapping, by helping the user swap out of any currency into native currency on the origin, with us as the recipient. And with bridging, we can help the user get into any currency they want on the destination, using our native balance on that chain. Relay abstracts the complicated swapping layer and under the hood we use a combination of protocols, including ourselves sometimes, to help find the best prices for swapping. This way the user does not need to check multiple swap protocols to find the best price. ### [​](#user-experience) User Experience For the client, it feels like just a regular swap. We bundle multiple origin and cross-chain swaps into one simple and fast user operation. Usually the flow is something along: * If it’s an ERC20 input: * Approve us to spend your token on origin * We execute your swap on origin and your bridge, including any extra destination swaps or call execution (like mints) * If it’s an ETH input: * You send us ether * We execute your bridge, including any extra destination swaps or call execution (like mints) We built infrastructure to help provide the best quotes, which is why we also support same-chain swapping. With same-chain swapping, either the user can self-execute the swap, or Relay can help with executing the swap in situations where the user does not have enough gas to pay for the transaction. [Contract Compatibility](/how-it-works/contract-compatibility) [Fees](/how-it-works/fees) On this page * [Introduction](#introduction) * [Cross-Chain Swaps via Relay](#cross-chain-swaps-via-relay) * [User Experience](#user-experience) --- # Fees - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation How it Works Fees [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) ### [​](#fee-glossary) Fee Glossary Relay quotes include the following fees: `gas`, `relayerService`, and `relayerGas`. The two relayer fees (service and gas) are combined to make the full `relayer` fee. **gas**: The gas fee to be paid on the origin chain to execute the transaction. This is usually paid by the user to deposit funds to the relayer to initiate the bridge or swap. **relayer**: The sum of the relayerService and the relayerGas. **relayerService**: The service fee paid to the relayer to facilitate execution. **relayerGas**: The gas fee given to the solver to pay gas fees on the destination chain. **app**: Third party fees added on top of the existing fees, this fee is added by app developers and accrues offchain to minimize gas costs. Gas fees are estimates and may fluctuate over time, if using in a calculation we recommend adding a small buffer to account for these fluctuations. ### [​](#what-are-app-fees) What are app fees? App fees are third party fees added on top by app developers. The fees accrue offchain and can be claimed by the wallet at any point. This flow allows for us to be hyper gas efficient instead of sending fees on every transaction. You can accrue fees by including `appFees` in the [Quote API](https://docs.relay.link/references/api/get-quote) . #### [​](#how-do-i-know-my-offchain-balance) How do I know my offchain balance? Look up accrued offchain fees by using the [config](/references/api/get-config) api. Make sure that you pass in the originChainId as 0. Here’s an example of how the url should be constructed: [`https://api.relay.link/config/v2?originChainId=0¤cyId=eth&user=0x03508bB71268BBA25ECaCC8F620e01866650532c&destinationChainId=1`](https://api.relay.link/config/v2?originChainId=0¤cyId=eth&user=0x03508bB71268BBA25ECaCC8F620e01866650532c&destinationChainId=1) The user balance property will reflect the offchain balance: { "enabled": true, "user": { "balance": "111912125413088295", "maxBridgeAmount": "110982574378439751" }, "solver": { "address": "0xf70da97812cb96acdf810712aa562db8dfa3dbef", "balance": "164745206761785203599", "capacityPerRequest": "131796165409428162879" }, "supportsExternalLiquidity": false } #### [​](#how-can-i-claim-my-offchain-balance) How can I claim my offchain balance? To claim the funds, all you need to do is create a bridge to any chain from chainId 0, this will transfer the offchain balance to your wallet on the desired chain. Below are some examples of how to do this: [Swapping](/how-it-works/swapping) [Refunds](/how-it-works/refunds) On this page * [Fee Glossary](#fee-glossary) * [What are app fees?](#what-are-app-fees) * [How do I know my offchain balance?](#how-do-i-know-my-offchain-balance) * [How can I claim my offchain balance?](#how-can-i-claim-my-offchain-balance) --- # Refunds - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation How it Works Refunds [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay strives for 100% successful bridges & swaps. Occassionally, due to a variety of possible circumstances, a bridge or swap might be refunded instead of completed. Learn more about Relay’s refund logic and how it works. [​](#what-is-a-refund) What is a refund? ------------------------------------------- A refund is returned funds to a user due to a failed swap or bridge. Relay will refund the user’s their funds on the destination chain. If the destination chain is unavailable, Relay will refund the user’s funds on the deposit chain. The destination chain might be unavaible for a variety of reasons like a network outage. [​](#what-causes-refunds-to-happen) What causes refunds to happen? --------------------------------------------------------------------- A refund is triggered when the swap or bridge fails to complete. A failure can occur for a variety of reasons including but not exclusive to: * _Transactions Reverting:_ Before giving a quote, we simulate the transaction to insure it will succeed. Between the time the quote is given and the user accepts & deposits funds, the transaction could revert. Transactions reverting could be caused by if there is a contested mint or execution was delayed. * _User’s Wallet Address is Different Than Transaction Depositing Address:_ This happens when the user switches wallets right before signing the transaction. Users must execute the transaction with the wallet address that received the quote. * _User Deposits Too Little:_ There are two cases for how this can happen. 1. The user explicitly deposits a lower amount than Relay requested. 2. The user sent the deposit we requested but did so delayed so the original quote is no longer valid. Quotes expire after 1 minute then a new quote is generated. * _Destination Chain is Unavailable:_ Occasionally, the destination chain will have a network outage beyond our control. An example could be an RPC that is down or the chain is experiencing a large reorginization. * _User Sends Deposits With the Same Request ID in the Calldata Multiple Times_ * _User Send Deposits Without a Request ID in the Calldata_ [​](#when-is-there-no-refund-given) When is there no refund given? --------------------------------------------------------------------- If the refund amount is not enough to cover the cost of gas, Relay will mark the bridge or swap as failed & no refund will be sent. [​](#what-currency-is-used-for-refunds) What currency is used for refunds? ----------------------------------------------------------------------------- For bridges, Relay will refund the user in the original currency they sent. For swaps, Relay will refund users in the default currency of the chain. You can determine the default currency of a chain by looking at the fee currency. For example, if a chain’s default currency is ETH than ETH will be refunded. We have a few chains that their native currency is not ETH: Avalanche uses USDC, Polygon uses USDC, Xai uses Xai, and Degen uses Degen. [​](#are-refunds-automatic-and-instant) Are refunds automatic & instant? --------------------------------------------------------------------------- Yes, refunds happen automatically when swaps or bridges fail to complete. If a failure occurs, Relay will refund the user’s funds almost instantly. Please remember no refund is given if the refund amount cannot cover the cost of gas. [Fees](/how-it-works/fees) [Trade Types](/how-it-works/trade-types) On this page * [What is a refund?](#what-is-a-refund) * [What causes refunds to happen?](#what-causes-refunds-to-happen) * [When is there no refund given?](#when-is-there-no-refund-given) * [What currency is used for refunds?](#what-currency-is-used-for-refunds) * [Are refunds automatic & instant?](#are-refunds-automatic-and-instant) --- # Trade Types - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation How it Works Trade Types [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay supports three trade types: `exact_input`, `expected_output` and `exact_output`. [​](#exact-input) Exact Input -------------------------------- The first supported type is `EXACT_INPUT`. In this order type, the user specifies how much of the input currency they want to provide for a swap or brigde. The user is told how much of the output token they will receive for a given input. This trade type fails if the input amount is too small to cover associated fees with the request. Associated fees can include but are not limited to relay fees, app fees, and gas fees. [​](#expected-output) Expected Output ---------------------------------------- The second supported type is `EXPECTED_OUTPUT`. In this order type, the user quotes via specifying the general amount of output currency they expected to receive from the swap or bridge. The user is then told how much of the origin token this will require. The resulting output amount received can be less or more than what is requested, depending on slippage. This trade type automatically accounts for any associated fees including relay fees, app fees, and gas fees. We recommend using `EXPECTED_OUTPUT` for when an exact output amount is not necssary, or if calls do not need to be executed on destination. [​](#exact-output) Exact Output ---------------------------------- The third supported type is `EXACT_OUTPUT`. In this order type, the user specifies exactly how much of the output currency they want to receive from the swap or bridge. The user is told how much of the origin token this will require to receieve exactly the output amount. If the exact requested amount out cannot be filled, the request is failed and the user is refunded on origin. This trade type automatically accounts for any associated fees including relay fees, app fees, and gas fees. We recommend using `EXACT_OUTPUT` for bridge requests that involve destination calls, like minting using an exact erc20 amount [Refunds](/how-it-works/refunds) [Surplus & Shortage](/how-it-works/surplus-and-shortage) On this page * [Exact Input](#exact-input) * [Expected Output](#expected-output) * [Exact Output](#exact-output) --- # Surplus & Shortage - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation How it Works Surplus & Shortage [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay allows for users to instantly bridge or swap funds cross-chain while saving on gas. There are swaps or bridges where a surplus or shortage can happen. To understand how we handle either, we first need to understand how an origin operation can produce a surplus or shortage. [​](#origin-operation-types) Origin Operation Types ------------------------------------------------------ When starting a bridge or swap, Relay labels then as origin operations. After submission, origin operations send their output to the solver to complete the bridge or swap. There are three possible outcomes for an origin operation: 1. **Exact**: When the origin operation matches the solver’s input exactly, the destination operation proceeds as initially quoted. 2. **Surplus**: When the solver executes the origin operation input, there is positive slippage after the swap or bridge. This results in a surplus or extra funds. 3. **Shortage**: When the solver executes the oirgin operation input, there is negative slippage after the swap or bridge. This results in a shortage or less funds. [​](#how-are-surpluses-or-shortages-handled) How are surpluses or shortages handled? --------------------------------------------------------------------------------------- An origin operation can produce three possible outcomes. Depending on the outcome will determine how Relay handles the bridge or swap. 1. **Exact**: The expected amount is received. The destination operation proceeds as initially quoted. 2. **Surplus**: The solver receives more than expected. The quoted rate is used as a heuristic to determine whether to proceed with the operation. Specifically, if the solver can guarantee that the input amount can be swapped for at least the quoted rate of the expected amount, the operation continues. Surpluses typically result in the user receiving more than expected on the desitnation chain. 3. **Shortage**: The solver receives less than expected. The quoted rate is used as a heuristic to determine whether to proceed with the operation. Specifically, if the solver can guarantee that the input amount can be swapped for at least the quoted rate of the expected amount, the operation continues. Shortages typically result in the user receiving less than expected on the desitnation chain. [​](#surplus-example) Surplus Example ---------------------------------------- Consider the following quote to a user: * **Quoted Transaction**: 100 USDC → 0.01 ETH → 0.01 ETH → 100 DAI However, during the origin operation, this happens: * **Actual Transaction**: 100 USDC → 0.011 ETH In this case, the new output amount (0.011 ETH) is passed to the destination swap. The operation continues as long as the solver can swap 0.011 ETH at a rate of at least 0.01 ETH per 100 DAI, resulting in the user receiving a little extra. [​](#shortage-example) Shortage Example ------------------------------------------ Consider the following quote to a user: * **Quoted Transaction**: 100 USDC → 0.01 ETH → 0.01 ETH → 100 DAI However, during the origin operation, this happens: * **Actual Transaction**: 100 USDC → 0.009 ETH In this case, the new output amount (0.009 ETH) is passed to the destination swap. The operation continues as long as the solver can swap 0.009 ETH at a rate of at least 0.01 ETH per 100 DAI, resulting in the user receiving a little less. [Trade Types](/how-it-works/trade-types) [Supported Chains](/resources/supported-chains) On this page * [Origin Operation Types](#origin-operation-types) * [How are surpluses or shortages handled?](#how-are-surpluses-or-shortages-handled) * [Surplus Example](#surplus-example) * [Shortage Example](#shortage-example) --- # Supported Chains - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Resources Supported Chains [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay is currently supported on the following chains. Please reach out to learn more about how to add Relay to your chain. [​](#supported-chains) Supported Chains ------------------------------------------ ### [​](#mainnets) Mainnets ### [​](#testnets) Testnets [​](#adding-relay-to-your-chain) Adding Relay to Your Chain -------------------------------------------------------------- Relay can easily be added to any EVM-chain, such as OP stack rollups, Arbitrum Orbit chains, or more. Please feel free to [Reach Out](mailto:support@relay.link) to discuss getting your chain supported today! [Surplus & Shortage](/how-it-works/surplus-and-shortage) [Contract Addresses](/resources/contract-addresses) On this page * [Supported Chains](#supported-chains) * [Mainnets](#mainnets) * [Testnets](#testnets) * [Adding Relay to Your Chain](#adding-relay-to-your-chain) --- # Contract Addresses - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Resources Contract Addresses [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay’s contract addresses can be found below along with each chain. This is current as of August 27th, 2024. For the most up to date list, please check our [Mainnet Chains API](https://api.relay.link/chains) or [Testnet Chains API](https://api.testnets.relay.link/chains) . We are currently in the process of getting all contracts verified and audited. Please note that not all deployed contracts have the same address across all chains. Please check carefully to ensure you are using the correct contract address for the chain you are using. [​](#supported-chains) Supported Chains ------------------------------------------ ### [​](#mainnets) Mainnets ### [​](#testnets) Testnets [Supported Chains](/resources/supported-chains) [Bounties](/resources/bounties) On this page * [Supported Chains](#supported-chains) * [Mainnets](#mainnets) * [Testnets](#testnets) --- # Bounties - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Resources Bounties [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) We at Relay are committed to maintaining the highest security standards for our protocol and smart contracts. That’s why we are launching a bug bounty program for those who help us identify vulnerabilities in the Relay Protocol. With our bounty, we hope to incentivize ethical hackers to discover and report vulnerabilities in our contracts and protocol. Rewards will be dependent on the severity of the bug. We always provide monetary rewards for bug that fall under these categories: * Extract value from the solver * Exploiting our smart contracts in an unintended way that results in a loss of funds To be eligible for the monetary rewards, this bug must be investigated and confirmed by our team. Monetary reward amounts are 10% of the value at risk, with a maximum reward capped at $100,000 USD. “Value at risk” is defined as the total value that could be extracted within a 10 minute period. This is because our product has automatic circuit breakers and alarms that would prevent losses that take longer to extract. If you suspect you’ve encountered a bug, please reach out directly by email: [support@relay.link](emailto:support@relay.link) . We review all reports closely with the team. We will get back to you within 1 to 4 days regarding the next steps. Most responses are provided within 24 hours, barring holidays and weekends. [Contract Addresses](/resources/contract-addresses) [Brand Assets](/resources/brand-assets) --- # Handling Errors - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Handling Errors [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) When an endpoint returns an error it will be accompanied with a `code`. The code is a predictable way to anticipate errors and handle them accordingly. Below is a list of errors returned by various APIs | Name | Description | | --- | --- | | `AMOUNT_TOO_LOW` | Amount is too small to cover transaction fees | | `ERC20_ROUTER_ADDRESS_NOT_FOUND` | Router address for ERC20 token not found | | `EXTRA_TXS_NOT_SUPPORTED` | Extra transactions are not supported for this operation | | `INSUFFICIENT_FUNDS` | Insufficient balance to perform crosschain action | | `INSUFFICIENT_LIQUIDITY` | Solver liquidity is insufficient to fulfill order | | `INVALID_ADDRESS` | Address format is invalid or address has been blocked by OFAC | | `INVALID_EXTRA_TXS` | Provided extra transactions are invalid | | `NO_QUOTES` | No quotes available for the requested transaction | | `NO_SWAP_ROUTES_FOUND` | No valid swap routes found for the requested pair | | `PERMIT_FAILED` | Token permit operation failed | | `SWAP_IMPACT_TOO_HIGH` | Swap price impact exceeds acceptable threshold | | `SWAP_QUOTE_FAILED` | Failed to get quote for swap operation | | `UNAUTHORIZED` | Unauthorized access to authenticated endpoints | | `UNKNOWN_ERROR` | When the error is unknown | | `UNSUPPORTED_CHAIN` | Chain id supplied is unsupported | | `UNSUPPORTED_CURRENCY` | Currency is not a valid native currency or erc20 token | | `UNSUPPORTED_EXECUTION_TYPE` | Requested execution type is not supported | | `UNSUPPORTED_ROUTE` | Combination of chains and/or currencies is not supported | | `USER_RECIPIENT_MISMATCH` | User and recipient addresses do not match when required | These errors will be accompanied by a contextual message, for example: { "message": "Swap output amount is too small to cover fees required to execute swap", "code": "AMOUNT_TOO_LOW" } [Step Execution Overview](/references/api/step-execution) [Get Chains](/references/api/get-chains) --- # Brand Assets - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Resources Brand Assets [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) These are official Relay resources that you can include on your marketing materials, webpage, and/or mobile application. Download Relay brand assets [here](https://reservoir-labs.notion.site/Relay-Brand-Guideline-4f2c46264df64c11822d8f2ea9d5c480) . [Bounties](/resources/bounties) --- # Getting Started - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Hooks Getting Started [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) [​](#installation) Installation ---------------------------------- Use this lightweight React hook package to integrate Relay into your custom interface. Start by installing the required packages: If using typescript ensure that you’re on v5+. Refer to the package json for the latest version requirements for the peer dependencies. [​](#tanstack-query-setup) Tanstack Query Setup -------------------------------------------------- The hooks require [TanStack Query](https://tanstack.com/query/latest) to be installed and configured. Refer to the [Tanstack installation instructions](https://tanstack.com/query/latest/docs/framework/react/installation) . Once Tanstack is configured in your React application, that’s all you need to get started. [​](#hooks) Hooks -------------------- Each hook is configured separately to allow for as much flexibility as possible. All hooks come with a query function that can be used outside of a React context to fetch the data (useful when using SSR or in a context that doesn’t use React). * [useQuote](/references/relay-kit/hooks/useQuote) * [useRelayChains](/references/relay-kit/hooks/useRelayChains) * [useRequests](/references/relay-kit/hooks/useRequests) * [useTokenList](/references/relay-kit/hooks/useTokenList) [Overview](/references/relay-kit/overview) [usePrice](/references/relay-kit/hooks/usePrice) On this page * [Installation](#installation) * [Tanstack Query Setup](#tanstack-query-setup) * [Hooks](#hooks) --- # Get Chains - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Get Chains [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) GET / chains Try it #### Query Parameters [​](#parameter-include-chains) includeChains string | null #### Response 200 - application/json [​](#response-chains) chains object\[\] An array of supported chains Show child attributes [​](#response-chains-base-chain-id) chains.baseChainId number | null The chain id which the chain rolls up to. This is always set as Ethereum for L1 chains [​](#response-chains-block-production-lagging) chains.blockProductionLagging boolean If the chain is experiencing issues where blocks are lagging behind or not being produced [​](#response-chains-brand-color) chains.brandColor string | null Brand color code [​](#response-chains-contracts) chains.contracts object Relay contract addresses Show child attributes [​](#response-chains-contracts-approval-proxy) chains.contracts.approvalProxy string [​](#response-chains-contracts-erc20-router) chains.contracts.erc20Router string [​](#response-chains-contracts-multicall3) chains.contracts.multicall3 string [​](#response-chains-contracts-multicaller) chains.contracts.multicaller string [​](#response-chains-contracts-only-owner-multicaller) chains.contracts.onlyOwnerMulticaller string [​](#response-chains-contracts-relay-receiver) chains.contracts.relayReceiver string [​](#response-chains-currency) chains.currency object Show child attributes [​](#response-chains-currency-address) chains.currency.address string [​](#response-chains-currency-decimals) chains.currency.decimals number [​](#response-chains-currency-id) chains.currency.id string [​](#response-chains-currency-name) chains.currency.name string [​](#response-chains-currency-supports-bridging) chains.currency.supportsBridging boolean [​](#response-chains-currency-symbol) chains.currency.symbol string [​](#response-chains-deposit-enabled) chains.depositEnabled boolean If the network supports depositing to this chain, e.g. allows this chain to be set as the destination chain [​](#response-chains-deposit-fee) chains.depositFee number The fee in bps for depositing to this chain [​](#response-chains-disabled) chains.disabled boolean If relaying to and from this chain is disabled [​](#response-chains-display-name) chains.displayName string [​](#response-chains-erc20-currencies) chains.erc20Currencies object\[\] An array of erc20 currencies that the chain supports Show child attributes [​](#response-chains-erc20-currencies-address) chains.erc20Currencies.address string [​](#response-chains-erc20-currencies-decimals) chains.erc20Currencies.decimals number [​](#response-chains-erc20-currencies-deposit-fee) chains.erc20Currencies.depositFee number The fee in bps for depositing to this chain [​](#response-chains-erc20-currencies-id) chains.erc20Currencies.id string [​](#response-chains-erc20-currencies-name) chains.erc20Currencies.name string [​](#response-chains-erc20-currencies-supports-bridging) chains.erc20Currencies.supportsBridging boolean If the currency supports bridging [​](#response-chains-erc20-currencies-supports-permit) chains.erc20Currencies.supportsPermit boolean If the erc20 currency supports permit via signature (EIP-2612) [​](#response-chains-erc20-currencies-surge-enabled) chains.erc20Currencies.surgeEnabled boolean If the chain has surge pricing enabled [​](#response-chains-erc20-currencies-symbol) chains.erc20Currencies.symbol string [​](#response-chains-erc20-currencies-withdrawal-fee) chains.erc20Currencies.withdrawalFee number The fee in bps for withdrawing from this chain [​](#response-chains-explorer-name) chains.explorerName string [​](#response-chains-explorer-query-params) chains.explorerQueryParams object | null [​](#response-chains-explorer-url) chains.explorerUrl string [​](#response-chains-http-rpc-url) chains.httpRpcUrl string [​](#response-chains-icon-url) chains.iconUrl string | null The URL to the chain icon [​](#response-chains-id) chains.id number [​](#response-chains-logo-url) chains.logoUrl string | null The URL to the chain logo [​](#response-chains-name) chains.name string [​](#response-chains-partial-disable-limit) chains.partialDisableLimit number The value limit at which the chain is partially disabled, if 0, the chain is not partially disabled. i.e, 1000000000000000000 to designate 1 ETH max withdrawal/deposit [​](#response-chains-surge-enabled) chains.surgeEnabled boolean If the chain has surge pricing enabled [​](#response-chains-vm-type) chains.vmType enum The type of VM the chain runs on Available options: `bvm`, `evm`, `svm` [​](#response-chains-withdrawal-fee) chains.withdrawalFee number The fee in bps for withdrawing from this chain [​](#response-chains-ws-rpc-url) chains.wsRpcUrl string [Handling Errors](/references/api/handling-errors) [Get Config](/references/api/get-config) --- # Step Execution Overview - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Step Execution Overview [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) We recommend using the [SDK](/references/sdk/getting-started) over our APIs. The SDK will iterate the steps and return useful callback information. [​](#step-execution-using-the-api) Step Execution using the API ------------------------------------------------------------------ When executing orders using the API directly, there are often multiple steps, like submitting a deposit transaction to the solver or signing a message. These steps differ based on the desired action and best route to execute the action. To make this simple, you can use the execute endpoints, which return the exact steps that you need to follow, including descriptions that you can display to users. The flow looks like this: Fetching Steps Call the [Get Quote API](/references/api/get-quote) to start your execution. Iterate Through Steps Iterate through the steps and the items within a step, taking the necessary actions. Steps with no items, or an empty array of items, should be skipped. If step item data is missing then polling the api is necessary. Executing Steps As mentioned above each step contains an array of one or more items. These items need to be iterated and completed depending on the kind of step ([signature](/_sites/docs.relay.link/references/api/step-execution#signature-step) or [transaction](/_sites/docs.relay.link/references/api/step-execution#transaction-step) ). Checking the fill status After a step is signed or submitted you should check on the progress of the fill Success! Once all the steps are complete you can consider the action complete and notify the user. ### [​](#signature-step) Signature Step A message that needs to be signed. Every signature comes with sign data and post data. The first action we need to take is to sign the message, keep in mind the signatureKind and use the appropriate signing method. Refer to your crypto library of choice on how to sign (viem, web3, etc). **Posting the data** After the message is signed the second action is to submit the `post` body to the `endpoint` provided in the `post` data. You’ll also need to provide the signature that was generated from the sign data as a query parameter. If the request is successful we can mark the step item as complete locally. The design pattern of this API is completely generic, allowing for automatic support of new types of liquidity without needing to update the app. This data can be fed directly into an Ethereum library such as viem, making it easy to sign and submit the exact data that is needed. ### [​](#transaction-step) Transaction Step A transaction that needs to be submitted onchain. After the transaction is submitted onchain you can poll the step items `check` endpoint. The endpoint will return a status which when successful will return ‘success’. The step item can then be successfully marked as complete. _Note that the transaction step item contains a `chainId` for which the transaction should be submitted on._ ### [​](#steps-example) Steps Example Below is an example of steps you’ll encounter in the wild when working with the API. { "steps": [\ {\ "id": "deposit",\ "action": "Confirm transaction in your wallet",\ "description": "Deposit funds for executing the calls",\ "kind": "transaction",\ "items": [\ {\ "status": "incomplete",\ "data": {\ "from": "0x03508bB71268BBA25ECaCC8F620e01866650532c",\ "to": "0xf70da97812cb96acdf810712aa562db8dfa3dbef",\ "data": "0x58109c",\ "value": "995010715204139091",\ "maxFeePerGas": "18044119466",\ "maxPriorityFeePerGas": "2060264926",\ "chainId": 1,\ "gas": 21064\ },\ "check": {\ "endpoint": "/intents/status?requestId=0x341b28c6467bfbffb72ad78ec5ddf1f77b8f9c79be134223e3248a7d4fcd43b6",\ "method": "GET"\ }\ }\ ]\ }\ ], "fees": { "gas": "384398515652800", "gasCurrency": "eth", "relayer": "-4989478842712964", "relayerGas": "521157287036", "relayerService": "-4990000000000000", "relayerCurrency": "eth" }, "breakdown": { "value": "1000000000000000000", "timeEstimate": 10 }, "balances": { "userBalance": "54764083517303347", "requiredToSolve": "995010521157287036" } } Along with the steps you’ll see that the following objects are returned: fees, breakdown and balances. Information about fees is detailed [here](/how-it-works/fees) . Breakdown pertains to time estimation for the execution, broken down by value. The balances object is in regards to the user and how much they require to solve for the execution. ### [​](#checking-the-fill-status) Checking the fill status Along with the step data there’s an optional check object. You can use this object to check if the status of the transaction is complete. The object details the method and the endpoint to request. You should poll this until the endpoint returns `success`. { "check": { "endpoint": "/intents/status?requestId=0x341b28c6467bfbffb72ad78ec5ddf1f77b8f9c79be134223e3248a7d4fcd43b6", "method": "GET" } } The check api will always return a status, the expected statuses are as follows: | Status | Description | | --- | --- | | refund | Execution was refunded on the origin chain unless `refundOrigin` parameter is set to false, in which case the refund is made on the destination chain | | delayed | If the time pending is 2x the p50 fill time, we mark the request as delayed | | waiting | Waiting for a deposit | | failure | The fill has failed and was not refundable, check the details property for more information on the failure | | pending | Fill is currently pending | | success | Fill was successfully processed | * * * ### [​](#sdk-reference) SDK Reference To review the official way the SDK handles execution, please refer to the [executeSteps](https://github.com/reservoirprotocol/relay-sdk/blob/main/packages/sdk/src/utils/executeSteps.ts#L31) file which implements executing steps detailed above. [API Overview](/references/api/overview) [Handling Errors](/references/api/handling-errors) On this page * [Step Execution using the API](#step-execution-using-the-api) * [Signature Step](#signature-step) * [Transaction Step](#transaction-step) * [Steps Example](#steps-example) * [Checking the fill status](#checking-the-fill-status) * [SDK Reference](#sdk-reference) --- # createClient - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation SDK Reference createClient [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) This method is used to create the Relay client globally in your application. The client can then be retrieved with the `getClient` method. [​](#options) Options ------------------------ | Property | Description | Required | | --- | --- | --- | | **baseApiUrl** | The base api url to use when making requests, you can use the `MAINNET_RELAY_API` or the `TESTNET_RELAY_API` constants exported by the package. | ✅ | | **chains** | A list of Relay Chains, by default a list of backup chains is configured | ❌ | | **source** | The source to associate your onchain activity with, should make to a domain | ❌ | | **logLevel** | The level at which to log, refer to the `LogLevel` enum exported by the package | ❌ | | **pollingInterval** | How often to poll status and check apis, this value is in milliseconds | ❌ | | **maxPollingAttemptsBeforeTimeout** | The source to associate your onchain activity with, should be set to a domain | ❌ | import { createClient, convertViemChainToRelayChain, MAINNET_RELAY_API, } from "@reservoir0x/relay-sdk"; import { mainnet } from "viem/chains"; createClient({ baseApiUrl: MAINNET_RELAY_API, source: "YOUR.SOURCE", chains: [convertViemChainToRelayChain(mainnet)], }); [Getting Started](/references/sdk/getting-started) [getSolverCapacity](/references/sdk/actions/getSolverCapacity) On this page * [Options](#options) --- # Getting Started - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation UI Getting Started [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) [​](#installation) Installation ---------------------------------- Use this React ui package to smoothly embed a fully featured Relay powered interface into your application. Start by installing the required packages: If using typescript ensure that you’re on v5+. Refer to the package json for the latest version requirements for the peer dependencies. ### [​](#tanstack-query-setup) Tanstack Query Setup The hooks require [TanStack Query](https://tanstack.com/query/latest) to be installed and configured. Refer to the [Tanstack installation instructions](https://tanstack.com/query/latest/docs/framework/react/installation) . [​](#configuration) Configuration ------------------------------------ Once all dependencies are installed you can now configure and wrap your application with the `RelayKitProvider`. You’ll need to also wrap your application with the QueryClientProvider and the WagmiProvider. Note the order in the snippet below. import { RelayKitProvider } from '@reservoir0x/relay-kit-ui' import { convertViemChainToRelayChain } from '@reservoir0x/relay-sdk' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { http, createConfig, WagmiProvider } from '@wagmi/core' import { mainnet } from '@wagmi/core/chains' import { MAINNET_RELAY_API, TESTNET_RELAY_API } from '@reservoir0x/relay-sdk' import '@reservoir0x/relay-kit-ui/styles.css' const queryClient = new QueryClient() const chains = [convertViemChainToRelayChain(mainnet)] const wagmiConfig = createConfig({ appName: 'Relay Demo', chains: [mainnet], transports: { [mainnet.id]: http(), } }) const App = () => { return ( ) } If you’re using the `convertViemChainToRelayChain` you’ll need to install and import the `@reservoir0x/relay-sdk` to use this function. ### [​](#styling) Styling Make sure to import the styles.css globally otherwise the components will be unstyled: import '@reservoir0x/relay-kit-ui/styles.css' ### [​](#configuring-chains-dynamically) Configuring Chains Dynamically While you can easily supply chains that your application supports, you may want to fetch the supported Relay chains dynamically and configure them in your application. This can be done by using the [useRelayChains](/references/relay-kit/hooks/useRelayChains) hook. import { useRelayChains } from '@reservoir0x/relay-kit-hooks' import { RelayKitProvider } from '@reservoir0x/relay-kit-ui' import { convertViemChainToRelayChain } from '@reservoir0x/relay-sdk' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { http, createConfig, WagmiProvider } from '@wagmi/core' import { mainnet } from '@wagmi/core/chains' import { MAINNET_RELAY_API, TESTNET_RELAY_API } from '@reservoir0x/relay-sdk' const queryClient = new QueryClient() const App = () => { const [wagmiConfig, setWagmiConfig] = useState< ReturnType | undefined >() const { chains, viemChains } = useRelayChains(MAINNET_RELAY_API) useEffect(() => { if (!wagmiConfig && chains && viemChains) { setWagmiConfig( createConfig({ appName: 'Relay Demo', chains: (viemChains && viemChains.length === 0 ? [mainnet] : viemChains) as [Chain, ...Chain[]], transports: { [mainnet.id]: http(), } }) ) } }, [chains]) //Prevent loading the page until wagmi config is set, you can set a temporary config to swap out later to unblock the ui if (!wagmiConfig) { return null } return ( ) } Learn more about the `RelayKitProvider` [options](/references/relay-kit/ui/relay-kit-provider) . [​](#review) Review ---------------------- Let’s review with a checklist to make sure we got everything in: 1. Install the required dependencies 2. Configure Tanstack Query and Wagmi 3. Configure `RelayKitProvider` with chains and options 4. Import the `styles.css` file to style our ui components [useTokenList](/references/relay-kit/hooks/useTokenList) [RelayKitProvider](/references/relay-kit/ui/relay-kit-provider) On this page * [Installation](#installation) * [Tanstack Query Setup](#tanstack-query-setup) * [Configuration](#configuration) * [Styling](#styling) * [Configuring Chains Dynamically](#configuring-chains-dynamically) * [Review](#review) --- # Get Config - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Get Config [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) GET / config / v2 Try it #### Query Parameters [​](#parameter-origin-chain-id) originChainId string required [​](#parameter-destination-chain-id) destinationChainId string required [​](#parameter-user) user string User address, when supplied returns user balance and max bridge amount [​](#parameter-currency) currency enum Restricts the user balance and capacity to a particular currency when supplied with a currency id. Defaults to the native currency of the destination chain. Available options: `anime`, `btc`, `cgt`, `degen`, `eth`, `omi`, `pop`, `power`, `sipher`, `tg7`, `tia`, `topia`, `usdc`, `xai`, `weth`, `apeeth`, `ape`, `g`, `dmt`, `g7`, `god`, `pengu` #### Response 200 - application/json [​](#response-enabled) enabled boolean [​](#response-fee) fee string Total fee in the native or supplied currency for the bridge operation [​](#response-solver) solver object Show child attributes [​](#response-solver-address) solver.address string [​](#response-solver-balance) solver.balance string Balance of the solver on the destination chain. Denoted in wei [​](#response-solver-capacity-per-request) solver.capacityPerRequest string How much of the given currency is available to be bridged per bridge request. Denoted in wei [​](#response-supports-external-liquidity) supportsExternalLiquidity boolean This denotes if the chain combination supports canonical plus bridging [​](#response-user) user object Show child attributes [​](#response-user-balance) user.balance string Balance on the origin chain in the native or supplied currency [​](#response-user-max-bridge-amount) user.maxBridgeAmount string Maximum amount that the user can bridge after fees in the native or supplied currency [Get Chains](/references/api/get-chains) [Get Execution Status](/references/api/get-intents-status-v2) --- # Get Execution Status - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Get Execution Status [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) GET / intents / status / v2 Try it #### Query Parameters [​](#parameter-request-id) requestId string A unique id representing the execution in the Relay system. You can obtain this id from the requests api or the check object within the step items. #### Response 200 - application/json [​](#response-destination-chain-id) destinationChainId number [​](#response-details) details string [​](#response-in-tx-hashes) inTxHashes string\[\] Incoming transaction hashes [​](#response-origin-chain-id) originChainId number [​](#response-status) status enum Note that fallback is returned in the case of a refund Available options: `refund`, `delayed`, `waiting`, `failure`, `pending`, `success` [​](#response-time) time number The last timestamp the data was updated [​](#response-tx-hashes) txHashes string\[\] Outgoing transaction hashes [Get Config](/references/api/get-config) [Get Requests](/references/api/get-requests) --- # Adapters - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation SDK Reference Adapters [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) ### [​](#what-is-an-adapter-anyway) What is an adapter anyway? An adapter is a function that takes parameters and returns an object that adheres to this [interface](https://github.com/reservoirprotocol/relay-sdk/blob/main/packages/sdk/src/types/AdaptedWallet.ts) . Let’s review the interface in depth: | Property | Description | Required | | --- | --- | --- | | **vmType** | A string that can either be `'SOL'` or `'EVM'` | ✅ | | **getChainId** | An async function that returns a chain id | ✅ | | **handleSignMessageStep** | An async function that given a signature step item and a step generates a signature | ✅ | | **handleSendTransactionStep** | An async function that given a chain id, a transaction step item and a step returns a transaction hash | ✅ | | **handleConfirmTransactionStep** | An async function that given a transaction hash, a chain id, an onReplaced function and an onCancelled function returns a promise with either an evm receipt or an svm receipt | ✅ | | **address** | An async function that returns the currently connected to address, an address that can sign messages and submit transactions | ✅ | | **switchChain** | An async function that given a chain id switches to that chain, either by prompting the user or automatically switching chains | ✅ | | **transport** | An optional [transport](https://viem.sh/docs/clients/intro.html)
to use when making rpc calls. | ❌ | ### [​](#what-adapters-are-available-out-of-the-box) What adapters are available out of the box? The following adapters are officially maintained and developed by the Reservoir Relay team: [SVM Adapter](https://github.com/reservoirprotocol/relay-kit/tree/main/packages/relay-svm-wallet-adapter) : This adapter gives the sdk the ability to submit transactions on SVM (Solana Virtual Machine) networks. It does not support signing messages and under the hood it uses the [solana web3 sdk](https://solana-labs.github.io/solana-web3.js/) . [Viem Adapter](https://github.com/reservoirprotocol/relay-kit/blob/main/packages/sdk/src/utils/viemWallet.ts) : This adapter is the default one used when no adapter is provided. You can also import it yourself to convert any viem wallet client into an adapted wallet ready to be used in the sdk. [Ethers Adapter](https://github.com/reservoirprotocol/relay-kit/tree/main/packages/relay-ethers-wallet-adapter) : If your application uses ethers then you’ll need this adapter to use the SDK. You’ll still need to install viem as that’s required for polling transactions but you can pass in your ethers signer to submit transactions and sign messages. ### [​](#how-can-i-use-an-adapter) How can I use an adapter? You can either make your own adapter, as long as it adheres to the interface above or you can use one of the officials adapters developed and maintained by the Reservoir Relay team. All of our sdk methods handle a viem wallet or adapted wallet. The viem wallet adapter is used by default when a [viem wallet](https://viem.sh/docs/clients/wallet.html) is passed in for convenience. Refer below for implementation details: [execute](/references/sdk/actions/execute) [Typescript API Typings](/references/sdk/api-types) On this page * [What is an adapter anyway?](#what-is-an-adapter-anyway) * [What adapters are available out of the box?](#what-adapters-are-available-out-of-the-box) * [How can I use an adapter?](#how-can-i-use-an-adapter) --- # Get Requests - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Get Requests [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) GET / requests / v2 Try it #### Query Parameters [​](#parameter-limit) limit string default: 20 [​](#parameter-continuation) continuation string [​](#parameter-user) user string [​](#parameter-hash) hash string [​](#parameter-origin-chain-id) originChainId string [​](#parameter-destination-chain-id) destinationChainId string [​](#parameter-private-chains-to-include) privateChainsToInclude string [​](#parameter-id) id string [​](#parameter-start-timestamp) startTimestamp number [​](#parameter-end-timestamp) endTimestamp number [​](#parameter-start-block) startBlock number [​](#parameter-end-block) endBlock number [​](#parameter-chain-id) chainId string Get all requests for a single chain in either direction. Setting originChainId and/or destinationChainId will override this parameter. [​](#parameter-sort-by) sortBy enum default: createdAt Available options: `createdAt`, `updatedAt` #### Response 200 - application/json [​](#response-continuation) continuation string [​](#response-requests) requests object\[\] Show child attributes [​](#response-requests-created-at) requests.createdAt string [​](#response-requests-data) requests.data object Show child attributes [​](#response-requests-data-app-fees) requests.data.appFees object\[\] Show child attributes [​](#response-requests-data-app-fees-amount) requests.data.appFees.amount string [​](#response-requests-data-app-fees-recipient) requests.data.appFees.recipient string [​](#response-requests-data-currency) requests.data.currency string [​](#response-requests-data-currency-object) requests.data.currencyObject object Show child attributes [​](#response-requests-data-currency-object-address) requests.data.currencyObject.address string [​](#response-requests-data-currency-object-chain-id) requests.data.currencyObject.chainId number [​](#response-requests-data-currency-object-decimals) requests.data.currencyObject.decimals number [​](#response-requests-data-currency-object-metadata) requests.data.currencyObject.metadata object Show child attributes [​](#response-requests-data-currency-object-metadata-is-native) requests.data.currencyObject.metadata.isNative boolean [​](#response-requests-data-currency-object-metadata-logo-uri) requests.data.currencyObject.metadata.logoURI string [​](#response-requests-data-currency-object-metadata-verified) requests.data.currencyObject.metadata.verified boolean [​](#response-requests-data-currency-object-name) requests.data.currencyObject.name string [​](#response-requests-data-currency-object-symbol) requests.data.currencyObject.symbol string [​](#response-requests-data-fail-reason) requests.data.failReason enum Available options: `UNKNOWN`, `AMOUNT_TOO_LOW_TO_REFUND`, `DEPOSIT_ADDRESS_MISMATCH`, `DEPOSIT_CHAIN_MISMATCH`, `N/A` [​](#response-requests-data-fee-currency) requests.data.feeCurrency string [​](#response-requests-data-fee-currency-object) requests.data.feeCurrencyObject object Show child attributes [​](#response-requests-data-fee-currency-object-address) requests.data.feeCurrencyObject.address string [​](#response-requests-data-fee-currency-object-chain-id) requests.data.feeCurrencyObject.chainId number [​](#response-requests-data-fee-currency-object-decimals) requests.data.feeCurrencyObject.decimals number [​](#response-requests-data-fee-currency-object-metadata) requests.data.feeCurrencyObject.metadata object Show child attributes [​](#response-requests-data-fee-currency-object-metadata-is-native) requests.data.feeCurrencyObject.metadata.isNative boolean [​](#response-requests-data-fee-currency-object-metadata-logo-uri) requests.data.feeCurrencyObject.metadata.logoURI string [​](#response-requests-data-fee-currency-object-metadata-verified) requests.data.feeCurrencyObject.metadata.verified boolean [​](#response-requests-data-fee-currency-object-name) requests.data.feeCurrencyObject.name string [​](#response-requests-data-fee-currency-object-symbol) requests.data.feeCurrencyObject.symbol string [​](#response-requests-data-fees) requests.data.fees object Show child attributes [​](#response-requests-data-fees-fixed) requests.data.fees.fixed string The fixed fee which is always added to execution, in wei [​](#response-requests-data-fees-gas) requests.data.fees.gas string Estimated gas cost required for execution, in wei [​](#response-requests-data-fees-price) requests.data.fees.price string The dynamic fee which is a result of the chain and the amount, in wei [​](#response-requests-data-fees-usd) requests.data.feesUsd object Show child attributes [​](#response-requests-data-fees-usd-fixed) requests.data.feesUsd.fixed string [​](#response-requests-data-fees-usd-gas) requests.data.feesUsd.gas string [​](#response-requests-data-fees-usd-price) requests.data.feesUsd.price string [​](#response-requests-data-in-txs) requests.data.inTxs object\[\] Show child attributes [​](#response-requests-data-in-txs-block) requests.data.inTxs.block number [​](#response-requests-data-in-txs-chain-id) requests.data.inTxs.chainId number [​](#response-requests-data-in-txs-data) requests.data.inTxs.data any [​](#response-requests-data-in-txs-fee) requests.data.inTxs.fee string Total fees in wei [​](#response-requests-data-in-txs-hash) requests.data.inTxs.hash string [​](#response-requests-data-in-txs-state-changes) requests.data.inTxs.stateChanges any [​](#response-requests-data-in-txs-timestamp) requests.data.inTxs.timestamp number [​](#response-requests-data-in-txs-type) requests.data.inTxs.type string The type of transaction, always set to onchain [​](#response-requests-data-metadata) requests.data.metadata object Show child attributes [​](#response-requests-data-metadata-currency-in) requests.data.metadata.currencyIn object Show child attributes [​](#response-requests-data-metadata-currency-in-amount) requests.data.metadata.currencyIn.amount string [​](#response-requests-data-metadata-currency-in-amount-formatted) requests.data.metadata.currencyIn.amountFormatted string [​](#response-requests-data-metadata-currency-in-amount-usd) requests.data.metadata.currencyIn.amountUsd string [​](#response-requests-data-metadata-currency-in-currency) requests.data.metadata.currencyIn.currency object Show child attributes [​](#response-requests-data-metadata-currency-in-minimum-amount) requests.data.metadata.currencyIn.minimumAmount string [​](#response-requests-data-metadata-currency-out) requests.data.metadata.currencyOut object Show child attributes [​](#response-requests-data-metadata-currency-out-amount) requests.data.metadata.currencyOut.amount string [​](#response-requests-data-metadata-currency-out-amount-formatted) requests.data.metadata.currencyOut.amountFormatted string [​](#response-requests-data-metadata-currency-out-amount-usd) requests.data.metadata.currencyOut.amountUsd string [​](#response-requests-data-metadata-currency-out-currency) requests.data.metadata.currencyOut.currency object Show child attributes [​](#response-requests-data-metadata-currency-out-minimum-amount) requests.data.metadata.currencyOut.minimumAmount string [​](#response-requests-data-metadata-rate) requests.data.metadata.rate string [​](#response-requests-data-metadata-recipient) requests.data.metadata.recipient string [​](#response-requests-data-metadata-sender) requests.data.metadata.sender string [​](#response-requests-data-out-txs) requests.data.outTxs object\[\] Show child attributes [​](#response-requests-data-out-txs-block) requests.data.outTxs.block number [​](#response-requests-data-out-txs-chain-id) requests.data.outTxs.chainId number [​](#response-requests-data-out-txs-data) requests.data.outTxs.data any [​](#response-requests-data-out-txs-fee) requests.data.outTxs.fee string Total fees in wei [​](#response-requests-data-out-txs-hash) requests.data.outTxs.hash string [​](#response-requests-data-out-txs-state-changes) requests.data.outTxs.stateChanges any [​](#response-requests-data-out-txs-timestamp) requests.data.outTxs.timestamp number [​](#response-requests-data-out-txs-type) requests.data.outTxs.type string The type of transaction, always set to onchain [​](#response-requests-data-price) requests.data.price string [​](#response-requests-data-refund-currency-data) requests.data.refundCurrencyData object Show child attributes [​](#response-requests-data-refund-currency-data-amount) requests.data.refundCurrencyData.amount string [​](#response-requests-data-refund-currency-data-amount-formatted) requests.data.refundCurrencyData.amountFormatted string [​](#response-requests-data-refund-currency-data-amount-usd) requests.data.refundCurrencyData.amountUsd string [​](#response-requests-data-refund-currency-data-currency) requests.data.refundCurrencyData.currency object Show child attributes [​](#response-requests-data-refund-currency-data-currency-address) requests.data.refundCurrencyData.currency.address string [​](#response-requests-data-refund-currency-data-currency-chain-id) requests.data.refundCurrencyData.currency.chainId number [​](#response-requests-data-refund-currency-data-currency-decimals) requests.data.refundCurrencyData.currency.decimals number [​](#response-requests-data-refund-currency-data-currency-metadata) requests.data.refundCurrencyData.currency.metadata object Show child attributes [​](#response-requests-data-refund-currency-data-currency-name) requests.data.refundCurrencyData.currency.name string [​](#response-requests-data-refund-currency-data-currency-symbol) requests.data.refundCurrencyData.currency.symbol string [​](#response-requests-data-refund-currency-data-minimum-amount) requests.data.refundCurrencyData.minimumAmount string [​](#response-requests-data-time-estimate) requests.data.timeEstimate number [​](#response-requests-data-uses-external-liquidity) requests.data.usesExternalLiquidity boolean [​](#response-requests-id) requests.id string [​](#response-requests-recipient) requests.recipient string [​](#response-requests-status) requests.status enum Note that fallback is returned in the case of a refund Available options: `refund`, `delayed`, `waiting`, `failure`, `pending`, `success` [​](#response-requests-updated-at) requests.updatedAt string [​](#response-requests-user) requests.user string [Get Execution Status](/references/api/get-intents-status-v2) [Get Token Price](/references/api/get-token-price) --- # Get Currencies - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Get Currencies [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) POST / currencies / v1 Try it #### Body application/json [​](#body-address) address string Address of the currency contract [​](#body-chain-ids) chainIds number\[\] Chain IDs to search for currencies [​](#body-currency-id) currencyId string ID to search for a currency group [​](#body-default-list) defaultList boolean Return default currencies [​](#body-deposit-address-only) depositAddressOnly boolean Returns only currencies supported with deposit address bridging [​](#body-include-all-chains) includeAllChains boolean Include all chains for a currency when filtering by chainId and address [​](#body-limit) limit number Limit the number of results [​](#body-term) term string Search term for currencies [​](#body-tokens) tokens string\[\] List of token addresses, like: chainId:address [​](#body-use-external-search) useExternalSearch boolean Uses 3rd party API's to search for a token, in case relay does not have it indexed [​](#body-verified) verified boolean Filter verified currencies #### Response 200 - application/json List of currencies [Get Token Price](/references/api/get-token-price) [Get Price](/references/api/get-price) --- # Get Token Price - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Get Token Price [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) GET / currencies / token / price Try it #### Query Parameters [​](#parameter-address) address string required Token address to get price for [​](#parameter-chain-id) chainId number required Chain ID of the token #### Response 200 - application/json [​](#response-price) price number Token price in USD [Get Requests](/references/api/get-requests) [Get Currencies](/references/api/get-currencies) --- # Typescript API Typings - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation SDK Reference Typescript API Typings [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) The Relay SDK comes with built in API types to facilitate interacting with Relay APIs. The API types are useful for parsing API responses and determining what parameters an api accepts. Note that the types are exposed as part of the Relay SDK package, leaving where and how you use it up to you. There’s no requirement for React, or anything else, except for Typescript. Below we’ll dig into some examples: import { paths } from '@reservoir0x/relay-sdk' const parameters: paths['/execute/call']['post']['requestBody']['content']['application/json'] = { ... } With the Typescript types imported you can easily discover what query parameters an API might allow or what response an API will return. [Adapters](/references/sdk/adapters) --- # Get Price - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Get Price [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) POST / price Try it #### Body application/json [​](#body-amount) amount string required Amount to swap as the base amount (can be switched to exact input/output using the dedicated flag), denoted in the smallest unit of the specified currency (e.g., wei for ETH) [​](#body-destination-chain-id) destinationChainId number required [​](#body-destination-currency) destinationCurrency string required [​](#body-origin-chain-id) originChainId number required [​](#body-origin-currency) originCurrency string required [​](#body-trade-type) tradeType enum required Whether to use the amount as the output or the input for the basis of the swap Available options: `EXACT_INPUT`, `EXACT_OUTPUT`, `EXPECTED_OUTPUT` [​](#body-user) user string required Address that is depositing funds on the origin chain and submitting transactions or signatures [​](#body-app-fees) appFees object\[\] Show child attributes [​](#body-app-fees-fee) appFees.fee string App fees to be charged for execution in basis points, e.g. 100 = 1% [​](#body-app-fees-recipient) appFees.recipient string Address that will receive the app fee, if not specified then the user address is used [​](#body-recipient) recipient string Address that is receiving the funds on the destination chain, if not specified then this will default to the user address [​](#body-referrer) referrer string [​](#body-refund-on-origin) refundOnOrigin boolean Always refund on the origin chain in case of any issues [​](#body-refund-to) refundTo string Address to send the refund to in the case of failure, if not specified then the recipient address or user address is used [​](#body-slippage-tolerance) slippageTolerance string Slippage tolerance for the swap, if not specified then the slippage tolerance is automatically calculated to avoid front-running. This value is in basis points (1/100th of a percent), e.g. 50 for 0.5% slippage [​](#body-txs) txs object\[\] Show child attributes [​](#body-txs-data) txs.data string [​](#body-txs-to) txs.to string [​](#body-txs-value) txs.value string [​](#body-use-deposit-address) useDepositAddress boolean Enable this to use a deposit address when bridging, in scenarios where calldata cannot be sent alongside the transaction. only works on native currency bridges. [​](#body-use-external-liquidity) useExternalLiquidity boolean Enable this to use canonical+ bridging, trading speed for more liquidity [​](#body-use-permit) usePermit boolean Enable this to use permit (eip3009) when bridging, only works on supported currency such as usdc [​](#body-use-receiver) useReceiver boolean default: true Enable this to route payments via a receiver contract. This contract will emit an event when receiving payments before forwarding to the solver. This is needed when depositing from a smart contract as the payment will be an internal transaction and detecting such a transaction requires obtaining the transaction traces. #### Response 200 - application/json [​](#response-details) details object A summary of the swap and what the user should expect to happen given an input Show child attributes [​](#response-details-currency-in) details.currencyIn object Show child attributes [​](#response-details-currency-in-amount) details.currencyIn.amount string [​](#response-details-currency-in-amount-formatted) details.currencyIn.amountFormatted string [​](#response-details-currency-in-amount-usd) details.currencyIn.amountUsd string [​](#response-details-currency-in-currency) details.currencyIn.currency object Show child attributes [​](#response-details-currency-in-currency-address) details.currencyIn.currency.address string [​](#response-details-currency-in-currency-chain-id) details.currencyIn.currency.chainId number [​](#response-details-currency-in-currency-decimals) details.currencyIn.currency.decimals number [​](#response-details-currency-in-currency-metadata) details.currencyIn.currency.metadata object Show child attributes [​](#response-details-currency-in-currency-metadata-is-native) details.currencyIn.currency.metadata.isNative boolean [​](#response-details-currency-in-currency-metadata-logo-uri) details.currencyIn.currency.metadata.logoURI string [​](#response-details-currency-in-currency-metadata-verified) details.currencyIn.currency.metadata.verified boolean [​](#response-details-currency-in-currency-name) details.currencyIn.currency.name string [​](#response-details-currency-in-currency-symbol) details.currencyIn.currency.symbol string [​](#response-details-currency-in-minimum-amount) details.currencyIn.minimumAmount string [​](#response-details-currency-out) details.currencyOut object Show child attributes [​](#response-details-currency-out-amount) details.currencyOut.amount string [​](#response-details-currency-out-amount-formatted) details.currencyOut.amountFormatted string [​](#response-details-currency-out-amount-usd) details.currencyOut.amountUsd string [​](#response-details-currency-out-currency) details.currencyOut.currency object Show child attributes [​](#response-details-currency-out-currency-address) details.currencyOut.currency.address string [​](#response-details-currency-out-currency-chain-id) details.currencyOut.currency.chainId number [​](#response-details-currency-out-currency-decimals) details.currencyOut.currency.decimals number [​](#response-details-currency-out-currency-metadata) details.currencyOut.currency.metadata object Show child attributes [​](#response-details-currency-out-currency-metadata-is-native) details.currencyOut.currency.metadata.isNative boolean [​](#response-details-currency-out-currency-metadata-logo-uri) details.currencyOut.currency.metadata.logoURI string [​](#response-details-currency-out-currency-metadata-verified) details.currencyOut.currency.metadata.verified boolean [​](#response-details-currency-out-currency-name) details.currencyOut.currency.name string [​](#response-details-currency-out-currency-symbol) details.currencyOut.currency.symbol string [​](#response-details-currency-out-minimum-amount) details.currencyOut.minimumAmount string [​](#response-details-operation) details.operation string The operation that will be performed, possible options are send, swap, wrap, unwrap, bridge [​](#response-details-rate) details.rate string The swap rate which is equal to 1 input unit in the output unit, e.g. 1 USDC -> x ETH. This value can fluctuate based on gas and fees. [​](#response-details-recipient) details.recipient string The address that will be receiving the swap output [​](#response-details-sender) details.sender string The address that deposited the funds [​](#response-details-slippage-tolerance) details.slippageTolerance object Show child attributes [​](#response-details-slippage-tolerance-destination) details.slippageTolerance.destination object The slippage tolerance on the destination chain swap Show child attributes [​](#response-details-slippage-tolerance-destination-percent) details.slippageTolerance.destination.percent string [​](#response-details-slippage-tolerance-destination-usd) details.slippageTolerance.destination.usd string [​](#response-details-slippage-tolerance-destination-value) details.slippageTolerance.destination.value string [​](#response-details-slippage-tolerance-origin) details.slippageTolerance.origin object The slippage tolerance on the origin chain swap Show child attributes [​](#response-details-slippage-tolerance-origin-percent) details.slippageTolerance.origin.percent string [​](#response-details-slippage-tolerance-origin-usd) details.slippageTolerance.origin.usd string [​](#response-details-slippage-tolerance-origin-value) details.slippageTolerance.origin.value string [​](#response-details-swap-impact) details.swapImpact object The impact of the swap, not factoring in fees Show child attributes [​](#response-details-swap-impact-percent) details.swapImpact.percent string [​](#response-details-swap-impact-usd) details.swapImpact.usd string [​](#response-details-time-estimate) details.timeEstimate number Estimated swap time in seconds [​](#response-details-total-impact) details.totalImpact object The difference between the input and output values, including fees Show child attributes [​](#response-details-total-impact-percent) details.totalImpact.percent string [​](#response-details-total-impact-usd) details.totalImpact.usd string [​](#response-details-user-balance) details.userBalance string The user's balance in the given currency on the origin chain [​](#response-fees) fees object Show child attributes [​](#response-fees-app) fees.app object Fees paid to the app. Currency will be the same as the relayer fee currency. This needs to be claimed later by the app owner and is not immediately distributed to the app Show child attributes [​](#response-fees-app-amount) fees.app.amount string [​](#response-fees-app-amount-formatted) fees.app.amountFormatted string [​](#response-fees-app-amount-usd) fees.app.amountUsd string [​](#response-fees-app-currency) fees.app.currency object Show child attributes [​](#response-fees-app-currency-address) fees.app.currency.address string [​](#response-fees-app-currency-chain-id) fees.app.currency.chainId number [​](#response-fees-app-currency-decimals) fees.app.currency.decimals number [​](#response-fees-app-currency-metadata) fees.app.currency.metadata object Show child attributes [​](#response-fees-app-currency-metadata-is-native) fees.app.currency.metadata.isNative boolean [​](#response-fees-app-currency-metadata-logo-uri) fees.app.currency.metadata.logoURI string [​](#response-fees-app-currency-metadata-verified) fees.app.currency.metadata.verified boolean [​](#response-fees-app-currency-name) fees.app.currency.name string [​](#response-fees-app-currency-symbol) fees.app.currency.symbol string [​](#response-fees-app-minimum-amount) fees.app.minimumAmount string [​](#response-fees-gas) fees.gas object Origin chain gas fee Show child attributes [​](#response-fees-gas-amount) fees.gas.amount string [​](#response-fees-gas-amount-formatted) fees.gas.amountFormatted string [​](#response-fees-gas-amount-usd) fees.gas.amountUsd string [​](#response-fees-gas-currency) fees.gas.currency object Show child attributes [​](#response-fees-gas-currency-address) fees.gas.currency.address string [​](#response-fees-gas-currency-chain-id) fees.gas.currency.chainId number [​](#response-fees-gas-currency-decimals) fees.gas.currency.decimals number [​](#response-fees-gas-currency-metadata) fees.gas.currency.metadata object Show child attributes [​](#response-fees-gas-currency-metadata-is-native) fees.gas.currency.metadata.isNative boolean [​](#response-fees-gas-currency-metadata-logo-uri) fees.gas.currency.metadata.logoURI string [​](#response-fees-gas-currency-metadata-verified) fees.gas.currency.metadata.verified boolean [​](#response-fees-gas-currency-name) fees.gas.currency.name string [​](#response-fees-gas-currency-symbol) fees.gas.currency.symbol string [​](#response-fees-gas-minimum-amount) fees.gas.minimumAmount string [​](#response-fees-relayer) fees.relayer object Combination of the relayerGas and relayerService to give you the full relayer fee Show child attributes [​](#response-fees-relayer-amount) fees.relayer.amount string [​](#response-fees-relayer-amount-formatted) fees.relayer.amountFormatted string [​](#response-fees-relayer-amount-usd) fees.relayer.amountUsd string [​](#response-fees-relayer-currency) fees.relayer.currency object Show child attributes [​](#response-fees-relayer-currency-address) fees.relayer.currency.address string [​](#response-fees-relayer-currency-chain-id) fees.relayer.currency.chainId number [​](#response-fees-relayer-currency-decimals) fees.relayer.currency.decimals number [​](#response-fees-relayer-currency-metadata) fees.relayer.currency.metadata object Show child attributes [​](#response-fees-relayer-currency-metadata-is-native) fees.relayer.currency.metadata.isNative boolean [​](#response-fees-relayer-currency-metadata-logo-uri) fees.relayer.currency.metadata.logoURI string [​](#response-fees-relayer-currency-metadata-verified) fees.relayer.currency.metadata.verified boolean [​](#response-fees-relayer-currency-name) fees.relayer.currency.name string [​](#response-fees-relayer-currency-symbol) fees.relayer.currency.symbol string [​](#response-fees-relayer-minimum-amount) fees.relayer.minimumAmount string [​](#response-fees-relayer-gas) fees.relayerGas object Destination chain gas fee Show child attributes [​](#response-fees-relayer-gas-amount) fees.relayerGas.amount string [​](#response-fees-relayer-gas-amount-formatted) fees.relayerGas.amountFormatted string [​](#response-fees-relayer-gas-amount-usd) fees.relayerGas.amountUsd string [​](#response-fees-relayer-gas-currency) fees.relayerGas.currency object Show child attributes [​](#response-fees-relayer-gas-currency-address) fees.relayerGas.currency.address string [​](#response-fees-relayer-gas-currency-chain-id) fees.relayerGas.currency.chainId number [​](#response-fees-relayer-gas-currency-decimals) fees.relayerGas.currency.decimals number [​](#response-fees-relayer-gas-currency-metadata) fees.relayerGas.currency.metadata object Show child attributes [​](#response-fees-relayer-gas-currency-metadata-is-native) fees.relayerGas.currency.metadata.isNative boolean [​](#response-fees-relayer-gas-currency-metadata-logo-uri) fees.relayerGas.currency.metadata.logoURI string [​](#response-fees-relayer-gas-currency-metadata-verified) fees.relayerGas.currency.metadata.verified boolean [​](#response-fees-relayer-gas-currency-name) fees.relayerGas.currency.name string [​](#response-fees-relayer-gas-currency-symbol) fees.relayerGas.currency.symbol string [​](#response-fees-relayer-gas-minimum-amount) fees.relayerGas.minimumAmount string [​](#response-fees-relayer-service) fees.relayerService object Fees paid to the relay solver, note that this value can be negative (which represents network rewards for moving in a direction that optimizes liquidity distribution) Show child attributes [​](#response-fees-relayer-service-amount) fees.relayerService.amount string [​](#response-fees-relayer-service-amount-formatted) fees.relayerService.amountFormatted string [​](#response-fees-relayer-service-amount-usd) fees.relayerService.amountUsd string [​](#response-fees-relayer-service-currency) fees.relayerService.currency object Show child attributes [​](#response-fees-relayer-service-currency-address) fees.relayerService.currency.address string [​](#response-fees-relayer-service-currency-chain-id) fees.relayerService.currency.chainId number [​](#response-fees-relayer-service-currency-decimals) fees.relayerService.currency.decimals number [​](#response-fees-relayer-service-currency-metadata) fees.relayerService.currency.metadata object Show child attributes [​](#response-fees-relayer-service-currency-metadata-is-native) fees.relayerService.currency.metadata.isNative boolean [​](#response-fees-relayer-service-currency-metadata-logo-uri) fees.relayerService.currency.metadata.logoURI string [​](#response-fees-relayer-service-currency-metadata-verified) fees.relayerService.currency.metadata.verified boolean [​](#response-fees-relayer-service-currency-name) fees.relayerService.currency.name string [​](#response-fees-relayer-service-currency-symbol) fees.relayerService.currency.symbol string [​](#response-fees-relayer-service-minimum-amount) fees.relayerService.minimumAmount string [Get Currencies](/references/api/get-currencies) [Get Quote](/references/api/get-quote) --- # Get Quote - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Get Quote [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) POST / quote Try it #### Body application/json [​](#body-amount) amount string required Amount to swap as the base amount (can be switched to exact input/output using the dedicated flag), denoted in the smallest unit of the specified currency (e.g., wei for ETH) [​](#body-destination-chain-id) destinationChainId number required [​](#body-destination-currency) destinationCurrency string required [​](#body-origin-chain-id) originChainId number required [​](#body-origin-currency) originCurrency string required [​](#body-trade-type) tradeType enum required Whether to use the amount as the output or the input for the basis of the swap Available options: `EXACT_INPUT`, `EXACT_OUTPUT`, `EXPECTED_OUTPUT` [​](#body-user) user string required Address that is depositing funds on the origin chain and submitting transactions or signatures [​](#body-app-fees) appFees object\[\] Show child attributes [​](#body-app-fees-fee) appFees.fee string App fees to be charged for execution in basis points, e.g. 100 = 1% [​](#body-app-fees-recipient) appFees.recipient string Address that will receive the app fee, if not specified then the user address is used [​](#body-force-solver-execution) forceSolverExecution boolean Force executing swap requests via the solver (by default, same-chain swap requests are self-executed) [​](#body-gas-limit-for-deposit-specified-txs) gasLimitForDepositSpecifiedTxs number If the request involves specifying transactions to be executed during the deposit transaction, an explicit gas limit must be set when requesting the quote [​](#body-recipient) recipient string Address that is receiving the funds on the destination chain, if not specified then this will default to the user address [​](#body-referrer) referrer string [​](#body-refund-on-origin) refundOnOrigin boolean Always refund on the origin chain in case of any issues [​](#body-refund-to) refundTo string Address to send the refund to in the case of failure, if not specified then the recipient address or user address is used [​](#body-slippage-tolerance) slippageTolerance string Slippage tolerance for the swap, if not specified then the slippage tolerance is automatically calculated to avoid front-running. This value is in basis points (1/100th of a percent), e.g. 50 for 0.5% slippage [​](#body-txs) txs object\[\] Show child attributes [​](#body-txs-data) txs.data string [​](#body-txs-to) txs.to string [​](#body-txs-value) txs.value string [​](#body-use-deposit-address) useDepositAddress boolean Enable this to use a deposit address when bridging, in scenarios where calldata cannot be sent alongside the transaction. only works on native currency bridges. [​](#body-use-external-liquidity) useExternalLiquidity boolean Enable this to use canonical+ bridging, trading speed for more liquidity [​](#body-use-permit) usePermit boolean Enable this to use permit (eip3009) when bridging, only works on supported currency such as usdc [​](#body-use-receiver) useReceiver boolean default: true Enable this to route payments via a receiver contract. This contract will emit an event when receiving payments before forwarding to the solver. This is needed when depositing from a smart contract as the payment will be an internal transaction and detecting such a transaction requires obtaining the transaction traces. [​](#body-user-operation-gas-overhead) userOperationGasOverhead number Gas overhead for 4337 user operations, to be used for fees calculation #### Response 200 - application/json [​](#response-details) details object A summary of the swap and what the user should expect to happen given an input Show child attributes [​](#response-details-currency-in) details.currencyIn object Show child attributes [​](#response-details-currency-in-amount) details.currencyIn.amount string [​](#response-details-currency-in-amount-formatted) details.currencyIn.amountFormatted string [​](#response-details-currency-in-amount-usd) details.currencyIn.amountUsd string [​](#response-details-currency-in-currency) details.currencyIn.currency object Show child attributes [​](#response-details-currency-in-currency-address) details.currencyIn.currency.address string [​](#response-details-currency-in-currency-chain-id) details.currencyIn.currency.chainId number [​](#response-details-currency-in-currency-decimals) details.currencyIn.currency.decimals number [​](#response-details-currency-in-currency-metadata) details.currencyIn.currency.metadata object Show child attributes [​](#response-details-currency-in-currency-metadata-is-native) details.currencyIn.currency.metadata.isNative boolean [​](#response-details-currency-in-currency-metadata-logo-uri) details.currencyIn.currency.metadata.logoURI string [​](#response-details-currency-in-currency-metadata-verified) details.currencyIn.currency.metadata.verified boolean [​](#response-details-currency-in-currency-name) details.currencyIn.currency.name string [​](#response-details-currency-in-currency-symbol) details.currencyIn.currency.symbol string [​](#response-details-currency-in-minimum-amount) details.currencyIn.minimumAmount string [​](#response-details-currency-out) details.currencyOut object Show child attributes [​](#response-details-currency-out-amount) details.currencyOut.amount string [​](#response-details-currency-out-amount-formatted) details.currencyOut.amountFormatted string [​](#response-details-currency-out-amount-usd) details.currencyOut.amountUsd string [​](#response-details-currency-out-currency) details.currencyOut.currency object Show child attributes [​](#response-details-currency-out-currency-address) details.currencyOut.currency.address string [​](#response-details-currency-out-currency-chain-id) details.currencyOut.currency.chainId number [​](#response-details-currency-out-currency-decimals) details.currencyOut.currency.decimals number [​](#response-details-currency-out-currency-metadata) details.currencyOut.currency.metadata object Show child attributes [​](#response-details-currency-out-currency-metadata-is-native) details.currencyOut.currency.metadata.isNative boolean [​](#response-details-currency-out-currency-metadata-logo-uri) details.currencyOut.currency.metadata.logoURI string [​](#response-details-currency-out-currency-metadata-verified) details.currencyOut.currency.metadata.verified boolean [​](#response-details-currency-out-currency-name) details.currencyOut.currency.name string [​](#response-details-currency-out-currency-symbol) details.currencyOut.currency.symbol string [​](#response-details-currency-out-minimum-amount) details.currencyOut.minimumAmount string [​](#response-details-operation) details.operation string The operation that will be performed, possible options are send, swap, wrap, unwrap, bridge [​](#response-details-rate) details.rate string The swap rate which is equal to 1 input unit in the output unit, e.g. 1 USDC -> x ETH. This value can fluctuate based on gas and fees. [​](#response-details-recipient) details.recipient string The address that will be receiving the swap output [​](#response-details-sender) details.sender string The address that deposited the funds [​](#response-details-slippage-tolerance) details.slippageTolerance object Show child attributes [​](#response-details-slippage-tolerance-destination) details.slippageTolerance.destination object The slippage tolerance on the destination chain swap Show child attributes [​](#response-details-slippage-tolerance-destination-percent) details.slippageTolerance.destination.percent string [​](#response-details-slippage-tolerance-destination-usd) details.slippageTolerance.destination.usd string [​](#response-details-slippage-tolerance-destination-value) details.slippageTolerance.destination.value string [​](#response-details-slippage-tolerance-origin) details.slippageTolerance.origin object The slippage tolerance on the origin chain swap Show child attributes [​](#response-details-slippage-tolerance-origin-percent) details.slippageTolerance.origin.percent string [​](#response-details-slippage-tolerance-origin-usd) details.slippageTolerance.origin.usd string [​](#response-details-slippage-tolerance-origin-value) details.slippageTolerance.origin.value string [​](#response-details-swap-impact) details.swapImpact object The impact of the swap, not factoring in fees Show child attributes [​](#response-details-swap-impact-percent) details.swapImpact.percent string [​](#response-details-swap-impact-usd) details.swapImpact.usd string [​](#response-details-time-estimate) details.timeEstimate number Estimated swap time in seconds [​](#response-details-total-impact) details.totalImpact object The difference between the input and output values, including fees Show child attributes [​](#response-details-total-impact-percent) details.totalImpact.percent string [​](#response-details-total-impact-usd) details.totalImpact.usd string [​](#response-details-user-balance) details.userBalance string The user's balance in the given currency on the origin chain [​](#response-fees) fees object Show child attributes [​](#response-fees-app) fees.app object Fees paid to the app. Currency will be the same as the relayer fee currency. This needs to be claimed later by the app owner and is not immediately distributed to the app Show child attributes [​](#response-fees-app-amount) fees.app.amount string [​](#response-fees-app-amount-formatted) fees.app.amountFormatted string [​](#response-fees-app-amount-usd) fees.app.amountUsd string [​](#response-fees-app-currency) fees.app.currency object Show child attributes [​](#response-fees-app-currency-address) fees.app.currency.address string [​](#response-fees-app-currency-chain-id) fees.app.currency.chainId number [​](#response-fees-app-currency-decimals) fees.app.currency.decimals number [​](#response-fees-app-currency-metadata) fees.app.currency.metadata object Show child attributes [​](#response-fees-app-currency-metadata-is-native) fees.app.currency.metadata.isNative boolean [​](#response-fees-app-currency-metadata-logo-uri) fees.app.currency.metadata.logoURI string [​](#response-fees-app-currency-metadata-verified) fees.app.currency.metadata.verified boolean [​](#response-fees-app-currency-name) fees.app.currency.name string [​](#response-fees-app-currency-symbol) fees.app.currency.symbol string [​](#response-fees-app-minimum-amount) fees.app.minimumAmount string [​](#response-fees-gas) fees.gas object Origin chain gas fee Show child attributes [​](#response-fees-gas-amount) fees.gas.amount string [​](#response-fees-gas-amount-formatted) fees.gas.amountFormatted string [​](#response-fees-gas-amount-usd) fees.gas.amountUsd string [​](#response-fees-gas-currency) fees.gas.currency object Show child attributes [​](#response-fees-gas-currency-address) fees.gas.currency.address string [​](#response-fees-gas-currency-chain-id) fees.gas.currency.chainId number [​](#response-fees-gas-currency-decimals) fees.gas.currency.decimals number [​](#response-fees-gas-currency-metadata) fees.gas.currency.metadata object Show child attributes [​](#response-fees-gas-currency-metadata-is-native) fees.gas.currency.metadata.isNative boolean [​](#response-fees-gas-currency-metadata-logo-uri) fees.gas.currency.metadata.logoURI string [​](#response-fees-gas-currency-metadata-verified) fees.gas.currency.metadata.verified boolean [​](#response-fees-gas-currency-name) fees.gas.currency.name string [​](#response-fees-gas-currency-symbol) fees.gas.currency.symbol string [​](#response-fees-gas-minimum-amount) fees.gas.minimumAmount string [​](#response-fees-relayer) fees.relayer object Combination of the relayerGas and relayerService to give you the full relayer fee Show child attributes [​](#response-fees-relayer-amount) fees.relayer.amount string [​](#response-fees-relayer-amount-formatted) fees.relayer.amountFormatted string [​](#response-fees-relayer-amount-usd) fees.relayer.amountUsd string [​](#response-fees-relayer-currency) fees.relayer.currency object Show child attributes [​](#response-fees-relayer-currency-address) fees.relayer.currency.address string [​](#response-fees-relayer-currency-chain-id) fees.relayer.currency.chainId number [​](#response-fees-relayer-currency-decimals) fees.relayer.currency.decimals number [​](#response-fees-relayer-currency-metadata) fees.relayer.currency.metadata object Show child attributes [​](#response-fees-relayer-currency-metadata-is-native) fees.relayer.currency.metadata.isNative boolean [​](#response-fees-relayer-currency-metadata-logo-uri) fees.relayer.currency.metadata.logoURI string [​](#response-fees-relayer-currency-metadata-verified) fees.relayer.currency.metadata.verified boolean [​](#response-fees-relayer-currency-name) fees.relayer.currency.name string [​](#response-fees-relayer-currency-symbol) fees.relayer.currency.symbol string [​](#response-fees-relayer-minimum-amount) fees.relayer.minimumAmount string [​](#response-fees-relayer-gas) fees.relayerGas object Destination chain gas fee Show child attributes [​](#response-fees-relayer-gas-amount) fees.relayerGas.amount string [​](#response-fees-relayer-gas-amount-formatted) fees.relayerGas.amountFormatted string [​](#response-fees-relayer-gas-amount-usd) fees.relayerGas.amountUsd string [​](#response-fees-relayer-gas-currency) fees.relayerGas.currency object Show child attributes [​](#response-fees-relayer-gas-currency-address) fees.relayerGas.currency.address string [​](#response-fees-relayer-gas-currency-chain-id) fees.relayerGas.currency.chainId number [​](#response-fees-relayer-gas-currency-decimals) fees.relayerGas.currency.decimals number [​](#response-fees-relayer-gas-currency-metadata) fees.relayerGas.currency.metadata object Show child attributes [​](#response-fees-relayer-gas-currency-metadata-is-native) fees.relayerGas.currency.metadata.isNative boolean [​](#response-fees-relayer-gas-currency-metadata-logo-uri) fees.relayerGas.currency.metadata.logoURI string [​](#response-fees-relayer-gas-currency-metadata-verified) fees.relayerGas.currency.metadata.verified boolean [​](#response-fees-relayer-gas-currency-name) fees.relayerGas.currency.name string [​](#response-fees-relayer-gas-currency-symbol) fees.relayerGas.currency.symbol string [​](#response-fees-relayer-gas-minimum-amount) fees.relayerGas.minimumAmount string [​](#response-fees-relayer-service) fees.relayerService object Fees paid to the relay solver, note that this value can be negative (which represents network rewards for moving in a direction that optimizes liquidity distribution) Show child attributes [​](#response-fees-relayer-service-amount) fees.relayerService.amount string [​](#response-fees-relayer-service-amount-formatted) fees.relayerService.amountFormatted string [​](#response-fees-relayer-service-amount-usd) fees.relayerService.amountUsd string [​](#response-fees-relayer-service-currency) fees.relayerService.currency object Show child attributes [​](#response-fees-relayer-service-currency-address) fees.relayerService.currency.address string [​](#response-fees-relayer-service-currency-chain-id) fees.relayerService.currency.chainId number [​](#response-fees-relayer-service-currency-decimals) fees.relayerService.currency.decimals number [​](#response-fees-relayer-service-currency-metadata) fees.relayerService.currency.metadata object Show child attributes [​](#response-fees-relayer-service-currency-metadata-is-native) fees.relayerService.currency.metadata.isNative boolean [​](#response-fees-relayer-service-currency-metadata-logo-uri) fees.relayerService.currency.metadata.logoURI string [​](#response-fees-relayer-service-currency-metadata-verified) fees.relayerService.currency.metadata.verified boolean [​](#response-fees-relayer-service-currency-name) fees.relayerService.currency.name string [​](#response-fees-relayer-service-currency-symbol) fees.relayerService.currency.symbol string [​](#response-fees-relayer-service-minimum-amount) fees.relayerService.minimumAmount string [​](#response-steps) steps object\[\] An array of steps detailing what needs to be done to bridge, steps includes multiple items of the same kind (signature, transaction, etc) Show child attributes [​](#response-steps-action) steps.action string A call to action for the step [​](#response-steps-deposit-address) steps.depositAddress string The deposit address for the bridge request [​](#response-steps-description) steps.description string A short description of the step and what it entails [​](#response-steps-id) steps.id string Unique identifier tied to the step [​](#response-steps-items) steps.items object\[\] While uncommon it is possible for steps to contain multiple items of the same kind (transaction/signature) grouped together that can be executed simultaneously. Show child attributes [​](#response-steps-items-check) steps.items.check object Details an endpoint and a method you should poll to get confirmation, the endpoint should return a boolean success flag which can be used to determine if the step item is complete Show child attributes [​](#response-steps-items-check-endpoint) steps.items.check.endpoint string The endpoint to confirm that the step item was successfully completed [​](#response-steps-items-check-method) steps.items.check.method string The REST method to access the endpoint [​](#response-steps-items-data) steps.items.data any [​](#response-steps-items-status) steps.items.status string Can either be complete or incomplete, this can be locally controlled once the step item is completed (depending on the kind) and the check object (if returned) has been verified. Once all step items are complete, the bridge is complete [​](#response-steps-kind) steps.kind string The kind of step, can either be a transaction or a signature. Transaction steps require submitting a transaction while signature steps require submitting a signature [​](#response-steps-request-id) steps.requestId string A unique identifier for this step, tying all related transactions together [Get Price](/references/api/get-price) [Swap Multi-Input](/references/api/swap-multi-input) --- # Transactions Index - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Transactions Index [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) POST / transactions / index Try it #### Body application/json [​](#body-chain-id) chainId string required [​](#body-tx-hash) txHash string required #### Response 200 - application/json [​](#response-message) message string [Swap Multi-Input](/references/api/swap-multi-input) [Execute Call](/references/api/execute-call) --- # Get Transactions Status - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Get Transactions Status [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) GET / transactions / status Try it #### Query Parameters [​](#parameter-chain-id) chainId string [​](#parameter-hash) hash string #### Response 200 - application/json [​](#response-status) status string --- # Swap Multi-Input - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation API Reference Swap Multi-Input [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) POST / execute / swap / multi-input Try it #### Body application/json [​](#body-destination-chain-id) destinationChainId number required [​](#body-destination-currency) destinationCurrency string required [​](#body-origins) origins object\[\] required Show child attributes [​](#body-origins-amount) origins.amount string required [​](#body-origins-chain-id) origins.chainId number required [​](#body-origins-currency) origins.currency string required [​](#body-trade-type) tradeType enum required Available options: `EXACT_INPUT`, `EXACT_OUTPUT` [​](#body-user) user string required [​](#body-amount) amount string [​](#body-partial) partial boolean [​](#body-recipient) recipient string [​](#body-txs) txs object\[\] Show child attributes [​](#body-txs-data) txs.data string [​](#body-txs-to) txs.to string [​](#body-txs-value) txs.value string [​](#body-user-operation-gas-overhead) userOperationGasOverhead number [​](#body-use-user-operation) useUserOperation boolean #### Response 200 - application/json [​](#response-balances) balances object Show child attributes [​](#response-balances-required-to-solve) balances.requiredToSolve string The minimum balance the user needs to have to swap [​](#response-balances-user-balance) balances.userBalance string The user's balance in the given currency on the origin chain [​](#response-breakdown) breakdown object\[\] Show child attributes [​](#response-breakdown-time-estimate) breakdown.timeEstimate number Estimated swap time in seconds [​](#response-breakdown-value) breakdown.value string Amount that will be swapped in the estimated time [​](#response-details) details object A summary of the swap and what the user should expect to happen given an input Show child attributes [​](#response-details-currency-in) details.currencyIn object Show child attributes [​](#response-details-currency-in-amount) details.currencyIn.amount string [​](#response-details-currency-in-amount-formatted) details.currencyIn.amountFormatted string [​](#response-details-currency-in-amount-usd) details.currencyIn.amountUsd string [​](#response-details-currency-in-currency) details.currencyIn.currency object Show child attributes [​](#response-details-currency-in-currency-address) details.currencyIn.currency.address string [​](#response-details-currency-in-currency-chain-id) details.currencyIn.currency.chainId number [​](#response-details-currency-in-currency-decimals) details.currencyIn.currency.decimals number [​](#response-details-currency-in-currency-metadata) details.currencyIn.currency.metadata object Show child attributes [​](#response-details-currency-in-currency-metadata-is-native) details.currencyIn.currency.metadata.isNative boolean [​](#response-details-currency-in-currency-metadata-logo-uri) details.currencyIn.currency.metadata.logoURI string [​](#response-details-currency-in-currency-metadata-verified) details.currencyIn.currency.metadata.verified boolean [​](#response-details-currency-in-currency-name) details.currencyIn.currency.name string [​](#response-details-currency-in-currency-symbol) details.currencyIn.currency.symbol string [​](#response-details-currency-in-minimum-amount) details.currencyIn.minimumAmount string [​](#response-details-currency-out) details.currencyOut object Show child attributes [​](#response-details-currency-out-amount) details.currencyOut.amount string [​](#response-details-currency-out-amount-formatted) details.currencyOut.amountFormatted string [​](#response-details-currency-out-amount-usd) details.currencyOut.amountUsd string [​](#response-details-currency-out-currency) details.currencyOut.currency object Show child attributes [​](#response-details-currency-out-currency-address) details.currencyOut.currency.address string [​](#response-details-currency-out-currency-chain-id) details.currencyOut.currency.chainId number [​](#response-details-currency-out-currency-decimals) details.currencyOut.currency.decimals number [​](#response-details-currency-out-currency-metadata) details.currencyOut.currency.metadata object Show child attributes [​](#response-details-currency-out-currency-metadata-is-native) details.currencyOut.currency.metadata.isNative boolean [​](#response-details-currency-out-currency-metadata-logo-uri) details.currencyOut.currency.metadata.logoURI string [​](#response-details-currency-out-currency-metadata-verified) details.currencyOut.currency.metadata.verified boolean [​](#response-details-currency-out-currency-name) details.currencyOut.currency.name string [​](#response-details-currency-out-currency-symbol) details.currencyOut.currency.symbol string [​](#response-details-currency-out-minimum-amount) details.currencyOut.minimumAmount string [​](#response-details-operation) details.operation string The operation that will be performed, possible options are send, swap, wrap, unwrap, bridge [​](#response-details-rate) details.rate string The swap rate which is equal to 1 input unit in the output unit, e.g. 1 USDC -> x ETH. This value can fluctuate based on gas and fees. [​](#response-details-recipient) details.recipient string The address that will be receiving the swap output [​](#response-details-sender) details.sender string The address that deposited the funds [​](#response-details-slippage-tolerance) details.slippageTolerance object Show child attributes [​](#response-details-slippage-tolerance-destination) details.slippageTolerance.destination object The slippage tolerance on the destination chain swap Show child attributes [​](#response-details-slippage-tolerance-destination-percent) details.slippageTolerance.destination.percent string [​](#response-details-slippage-tolerance-destination-usd) details.slippageTolerance.destination.usd string [​](#response-details-slippage-tolerance-destination-value) details.slippageTolerance.destination.value string [​](#response-details-slippage-tolerance-origin) details.slippageTolerance.origin object The slippage tolerance on the origin chain swap Show child attributes [​](#response-details-slippage-tolerance-origin-percent) details.slippageTolerance.origin.percent string [​](#response-details-slippage-tolerance-origin-usd) details.slippageTolerance.origin.usd string [​](#response-details-slippage-tolerance-origin-value) details.slippageTolerance.origin.value string [​](#response-details-swap-impact) details.swapImpact object The impact of the swap, not factoring in fees Show child attributes [​](#response-details-swap-impact-percent) details.swapImpact.percent string [​](#response-details-swap-impact-usd) details.swapImpact.usd string [​](#response-details-time-estimate) details.timeEstimate number Estimated swap time in seconds [​](#response-details-total-impact) details.totalImpact object The difference between the input and output values, including fees Show child attributes [​](#response-details-total-impact-percent) details.totalImpact.percent string [​](#response-details-total-impact-usd) details.totalImpact.usd string [​](#response-details-user-balance) details.userBalance string The user's balance in the given currency on the origin chain [​](#response-fees) fees object Show child attributes [​](#response-fees-app) fees.app object Fees paid to the app. Currency will be the same as the relayer fee currency. This needs to be claimed later by the app owner and is not immediately distributed to the app Show child attributes [​](#response-fees-app-amount) fees.app.amount string [​](#response-fees-app-amount-formatted) fees.app.amountFormatted string [​](#response-fees-app-amount-usd) fees.app.amountUsd string [​](#response-fees-app-currency) fees.app.currency object Show child attributes [​](#response-fees-app-currency-address) fees.app.currency.address string [​](#response-fees-app-currency-chain-id) fees.app.currency.chainId number [​](#response-fees-app-currency-decimals) fees.app.currency.decimals number [​](#response-fees-app-currency-metadata) fees.app.currency.metadata object Show child attributes [​](#response-fees-app-currency-metadata-is-native) fees.app.currency.metadata.isNative boolean [​](#response-fees-app-currency-metadata-logo-uri) fees.app.currency.metadata.logoURI string [​](#response-fees-app-currency-metadata-verified) fees.app.currency.metadata.verified boolean [​](#response-fees-app-currency-name) fees.app.currency.name string [​](#response-fees-app-currency-symbol) fees.app.currency.symbol string [​](#response-fees-app-minimum-amount) fees.app.minimumAmount string [​](#response-fees-gas) fees.gas object Origin chain gas fee Show child attributes [​](#response-fees-gas-amount) fees.gas.amount string [​](#response-fees-gas-amount-formatted) fees.gas.amountFormatted string [​](#response-fees-gas-amount-usd) fees.gas.amountUsd string [​](#response-fees-gas-currency) fees.gas.currency object Show child attributes [​](#response-fees-gas-currency-address) fees.gas.currency.address string [​](#response-fees-gas-currency-chain-id) fees.gas.currency.chainId number [​](#response-fees-gas-currency-decimals) fees.gas.currency.decimals number [​](#response-fees-gas-currency-metadata) fees.gas.currency.metadata object Show child attributes [​](#response-fees-gas-currency-metadata-is-native) fees.gas.currency.metadata.isNative boolean [​](#response-fees-gas-currency-metadata-logo-uri) fees.gas.currency.metadata.logoURI string [​](#response-fees-gas-currency-metadata-verified) fees.gas.currency.metadata.verified boolean [​](#response-fees-gas-currency-name) fees.gas.currency.name string [​](#response-fees-gas-currency-symbol) fees.gas.currency.symbol string [​](#response-fees-gas-minimum-amount) fees.gas.minimumAmount string [​](#response-fees-relayer) fees.relayer object Combination of the relayerGas and relayerService to give you the full relayer fee Show child attributes [​](#response-fees-relayer-amount) fees.relayer.amount string [​](#response-fees-relayer-amount-formatted) fees.relayer.amountFormatted string [​](#response-fees-relayer-amount-usd) fees.relayer.amountUsd string [​](#response-fees-relayer-currency) fees.relayer.currency object Show child attributes [​](#response-fees-relayer-currency-address) fees.relayer.currency.address string [​](#response-fees-relayer-currency-chain-id) fees.relayer.currency.chainId number [​](#response-fees-relayer-currency-decimals) fees.relayer.currency.decimals number [​](#response-fees-relayer-currency-metadata) fees.relayer.currency.metadata object Show child attributes [​](#response-fees-relayer-currency-metadata-is-native) fees.relayer.currency.metadata.isNative boolean [​](#response-fees-relayer-currency-metadata-logo-uri) fees.relayer.currency.metadata.logoURI string [​](#response-fees-relayer-currency-metadata-verified) fees.relayer.currency.metadata.verified boolean [​](#response-fees-relayer-currency-name) fees.relayer.currency.name string [​](#response-fees-relayer-currency-symbol) fees.relayer.currency.symbol string [​](#response-fees-relayer-minimum-amount) fees.relayer.minimumAmount string [​](#response-fees-relayer-gas) fees.relayerGas object Destination chain gas fee Show child attributes [​](#response-fees-relayer-gas-amount) fees.relayerGas.amount string [​](#response-fees-relayer-gas-amount-formatted) fees.relayerGas.amountFormatted string [​](#response-fees-relayer-gas-amount-usd) fees.relayerGas.amountUsd string [​](#response-fees-relayer-gas-currency) fees.relayerGas.currency object Show child attributes [​](#response-fees-relayer-gas-currency-address) fees.relayerGas.currency.address string [​](#response-fees-relayer-gas-currency-chain-id) fees.relayerGas.currency.chainId number [​](#response-fees-relayer-gas-currency-decimals) fees.relayerGas.currency.decimals number [​](#response-fees-relayer-gas-currency-metadata) fees.relayerGas.currency.metadata object Show child attributes [​](#response-fees-relayer-gas-currency-metadata-is-native) fees.relayerGas.currency.metadata.isNative boolean [​](#response-fees-relayer-gas-currency-metadata-logo-uri) fees.relayerGas.currency.metadata.logoURI string [​](#response-fees-relayer-gas-currency-metadata-verified) fees.relayerGas.currency.metadata.verified boolean [​](#response-fees-relayer-gas-currency-name) fees.relayerGas.currency.name string [​](#response-fees-relayer-gas-currency-symbol) fees.relayerGas.currency.symbol string [​](#response-fees-relayer-gas-minimum-amount) fees.relayerGas.minimumAmount string [​](#response-fees-relayer-service) fees.relayerService object Fees paid to the relay solver, note that this value can be negative (which represents network rewards for moving in a direction that optimizes liquidity distribution) Show child attributes [​](#response-fees-relayer-service-amount) fees.relayerService.amount string [​](#response-fees-relayer-service-amount-formatted) fees.relayerService.amountFormatted string [​](#response-fees-relayer-service-amount-usd) fees.relayerService.amountUsd string [​](#response-fees-relayer-service-currency) fees.relayerService.currency object Show child attributes [​](#response-fees-relayer-service-currency-address) fees.relayerService.currency.address string [​](#response-fees-relayer-service-currency-chain-id) fees.relayerService.currency.chainId number [​](#response-fees-relayer-service-currency-decimals) fees.relayerService.currency.decimals number [​](#response-fees-relayer-service-currency-metadata) fees.relayerService.currency.metadata object Show child attributes [​](#response-fees-relayer-service-currency-metadata-is-native) fees.relayerService.currency.metadata.isNative boolean [​](#response-fees-relayer-service-currency-metadata-logo-uri) fees.relayerService.currency.metadata.logoURI string [​](#response-fees-relayer-service-currency-metadata-verified) fees.relayerService.currency.metadata.verified boolean [​](#response-fees-relayer-service-currency-name) fees.relayerService.currency.name string [​](#response-fees-relayer-service-currency-symbol) fees.relayerService.currency.symbol string [​](#response-fees-relayer-service-minimum-amount) fees.relayerService.minimumAmount string [​](#response-steps) steps object\[\] An array of steps detailing what needs to be done to bridge, steps includes multiple items of the same kind (signature, transaction, etc) Show child attributes [​](#response-steps-action) steps.action string A call to action for the step [​](#response-steps-description) steps.description string A short description of the step and what it entails [​](#response-steps-id) steps.id string Unique identifier tied to the step [​](#response-steps-items) steps.items object\[\] While uncommon it is possible for steps to contain multiple items of the same kind (transaction/signature) grouped together that can be executed simultaneously. Show child attributes [​](#response-steps-items-check) steps.items.check object Details an endpoint and a method you should poll to get confirmation, the endpoint should return a boolean success flag which can be used to determine if the step item is complete Show child attributes [​](#response-steps-items-check-endpoint) steps.items.check.endpoint string The endpoint to confirm that the step item was successfully completed [​](#response-steps-items-check-method) steps.items.check.method string The REST method to access the endpoint [​](#response-steps-items-data) steps.items.data any [​](#response-steps-items-status) steps.items.status string Can either be complete or incomplete, this can be locally controlled once the step item is completed (depending on the kind) and the check object (if returned) has been verified. Once all step items are complete, the bridge is complete [​](#response-steps-kind) steps.kind string The kind of step, can either be a transaction or a signature. Transaction steps require submitting a transaction while signature steps require submitting a signature [​](#response-steps-request-id) steps.requestId string A unique identifier for this step, tying all related transactions together [Get Quote](/references/api/get-quote) [Transactions Index](/references/api/transactions-index) --- # getPrice - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Actions getPrice [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) ### [​](#parameters) Parameters | Property | Description | Required | | --- | --- | --- | | **originChainId** | The chain id to deposit funds on | ✅ | | **destinationChainId** | The chain id to execute the txs on | ✅ | | **originCurrency** | Address for a supported native currency or valid erc20 | ✅ | | **destinationCurrency** | Address for a supported native currency or valid erc20 | ✅ | | **tradeType** | Either `EXACT_INPUT` for quoting via an input amount, or `EXPECTED_OUTPUT`/`EXACT_OUTPUT` for quoting via an output amount. | ✅ | | **amount** | Amount in wei, in the supplied `currency` | ❌ | | **user** | The wallet address initiating the relay | ❌ | | **recipient** | A valid address to send the funds to, defaults to wallet address if not sepcified | ❌ | | **txs** | An array of either transaction objects (made up of a to, data and value properties) or viem request objects returned from viem’s [simulateContract](https://viem.sh/docs/contract/simulateContract.html)
function | ❌ | | **options** | Additional options that map directly to the [price API](/references/api/get-price) | ❌ | ### [​](#native-bridge-example) Native Bridge Example import { getClient } from "@reservoir0x/relay-sdk"; import { useWalletClient } from "wagmi"; const { data: wallet } = useWalletClient(); const price = await getClient()?.actions.getPrice({ originChainId: 1, destinationChainId: 10, originCurrency: "0x0000000000000000000000000000000000000000", destinationCurrency: "0x0000000000000000000000000000000000000000", amount: "10000000000000000", // 0.01 ETH user: "0x03508bB71268BBA25ECaCC8F620e018666501111" }); ### [​](#cross-chain-swap-example) Cross-Chain Swap Example // Cross-Chain Swap from USDC on Ethereum to DAI on Optimism const price = await getClient()?.actions.getPrice({ originChainId: 1, destinationChainId: 10, originCurrency: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC on Ethereum destinationCurrency: "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1", // DAI on Optimism amount: "100000", // 100 USDC user: "0x03508bB71268BBA25ECaCC8F620e018666501111" }); ### [​](#wrap-unwrap-example) Wrap/Unwrap Example // Unwrap ETH const price = await getClient()?.actions.getPrice({ originChainId: 1, destinationChainId: 1, originCurrency: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // WETH destinationCurrency: "0x0000000000000000000000000000000000000000", amount: "10000000000000000", // 0.01 ETH user: "0x03508bB71268BBA25ECaCC8F620e018666501111" }); ### [​](#send-example) Send Example // Send ERC20 / Native Currency to another address on the same chain // Note: The recipient address must be specified for send transactions and be different from the wallet address const price = await getClient()?.actions.getPrice({ originChainId: 1, destinationChainId: 1, originCurrency: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC destinationCurrency: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", amount: "100000", // 100 USDC user: "0x03508bB71268BBA25ECaCC8F620e018666501111", recipient: "0x0000c3caa36e2d9a8cd5269c976ede05018f0000", }); The Price is a lightweight quote, excluding steps and calldata but it includes a preview of what the full quote might contain. Prices are subject to change once you [get the quote](/references/sdk/actions/getQuote) so you should handle price changes accordingly. [getSolverCapacity](/references/sdk/actions/getSolverCapacity) [getQuote](/references/sdk/actions/getQuote) On this page * [Parameters](#parameters) * [Native Bridge Example](#native-bridge-example) * [Cross-Chain Swap Example](#cross-chain-swap-example) * [Wrap/Unwrap Example](#wrap-unwrap-example) * [Send Example](#send-example) --- # usePrice - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Hooks usePrice [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) [​](#parameters) Parameters ------------------------------ | Parameter | Description | Required | | --- | --- | --- | | **client** | A RelayClient instance. You can create one using the [SDK](http://localhost:3000/references/sdk/createClient)
or retrieve one using the `useRelayClient` hook from the UI kit. | ✅ | | **options** | Options that map directly to the [price API](/references/api/get-price)
. | ✅ | | **onResponse** | A callback function that triggers when a response is returned. | ❌ | | **queryOptions** | Tanstack query options. Refer to the [Tanstack](https://tanstack.com/query/latest/docs/framework/react/guides/query-options)
docs. | ❌ | [​](#return-data) Return Data -------------------------------- The hook returns an object with the base [Tanstack Query response](https://tanstack.com/query/v5/docs/framework/react/reference/useQuery) . The data returned will be the response from the [price API](/references/api/get-price) . [​](#usage) Usage -------------------- [​](#query-function) Query Function -------------------------------------- import { queryPrice } from "@reservoir0x/relay-kit-hooks"; const response = queryPrice("https://api.relay.link", { user: address, originChainId: 1, destinationChainId: 10, originCurrency: "0x0000000000000000000000000000000000000000", destinationCurrency: "0x0000000000000000000000000000000000000000", tradeType: "EXACT_INPUT", amount: "10000000", }); [Getting Started](/references/relay-kit/hooks/getting-started) [useQuote](/references/relay-kit/hooks/useQuote) On this page * [Parameters](#parameters) * [Return Data](#return-data) * [Usage](#usage) * [Query Function](#query-function) --- # getQuote - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Actions getQuote [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) ### [​](#parameters) Parameters | Property | Description | Required | | --- | --- | --- | | **chainId** | The chain id to deposit funds on | ✅ | | **toChainId** | The chain id to execute the txs on | ✅ | | **currency** | Address for a supported native currency or valid erc20 | ✅ | | **toCurrency** | Address for a supported native currency or valid erc20 | ✅ | | **tradeType** | Either `EXACT_INPUT` for quoting via an input amount, or `EXPECTED_OUTPUT`/`EXACT_OUTPUT` for quoting via an output amount. | ✅ | | **amount** | Amount in wei, in the supplied `currency` | ❌ | | **wallet** | A valid WalletClient from viem or an adapted wallet generated from an adapter that meets this [interface](https://github.com/reservoirprotocol/relay-sdk/blob/main/packages/sdk/src/types/AdaptedWallet.ts)
. | ❌ | | **recipient** | A valid address to send the funds to, defaults to wallet address if not sepcified | ❌ | | **txs** | An array of either transaction objects (made up of a to, data and value properties) or viem request objects returned from viem’s [simulateContract](https://viem.sh/docs/contract/simulateContract.html)
function. | ❌ | | **options** | Additional options that map directly to the [quote API](/references/api/get-quote)
. | ❌ | ### [​](#native-bridge-example) Native Bridge Example import { getClient } from "@reservoir0x/relay-sdk"; import { useWalletClient } from "wagmi"; const { data: wallet } = useWalletClient(); const quote = await getClient()?.actions.getQuote({ chainId: 1, toChainId: 10, currency: "0x0000000000000000000000000000000000000000", toCurrency: "0x0000000000000000000000000000000000000000", amount: "10000000000000000", // 0.01 ETH wallet, }); ### [​](#cross-chain-swap-example) Cross-Chain Swap Example // Cross-Chain Swap from USDC on Ethereum to DAI on Optimism const quote = await getClient()?.actions.getQuote({ chainId: 1, toChainId: 10, currency: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC on Ethereum toCurrency: "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1", // DAI on Optimism amount: "100000", // 100 USDC wallet, }); ### [​](#wrap-unwrap-example) Wrap/Unwrap Example // Unwrap ETH const quote = await getClient()?.actions.getQuote({ chainId: 1, toChainId: 1, currency: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // WETH toCurrency: "0x0000000000000000000000000000000000000000", amount: "10000000000000000", // 0.01 ETH wallet, }); ### [​](#send-example) Send Example // Send ERC20 / Native Currency to another address on the same chain // Note: The recipient address must be specified for send transactions and be different from the wallet address const quote = await getClient()?.actions.getQuote({ chainId: 1, toChainId: 1, currency: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC toCurrency: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", amount: "100000", // 100 USDC wallet, recipient: "0x0000c3caa36e2d9a8cd5269c976ede05018f0000", }); **Note** - Quotes can go stale after 30 seconds. Clients should regularly fetch fresh quotes so that users are always submitting valid transactions. See [Getting a quote](/how-it-works/the-reservoir-relayer#getting-a-quote) for more information on how quotes work. [getPrice](/references/sdk/actions/getPrice) [execute](/references/sdk/actions/execute) On this page * [Parameters](#parameters) * [Native Bridge Example](#native-bridge-example) * [Cross-Chain Swap Example](#cross-chain-swap-example) * [Wrap/Unwrap Example](#wrap-unwrap-example) * [Send Example](#send-example) --- # ERC-4337 - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Advanced ERC-4337 [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) One can use ERC-4337 user operations to execute cross-chain transactions. There are three possible interactions that one can have: * Relaying only on the origin chain * Relaying only on the destination chain * Relaying on both the origin and destination chain [​](#relaying-only-on-the-origin-chain) Relaying only on the origin chain ---------------------------------------------------------------------------- Interacting with the solver using ERC-4337 user operations requires two additional steps on top of the standard `/quote` flow. * The first requires sending an extra field in the `/quote` request body, `userOperationGasOverhead`. This field indicates how much additional gas overhead will be necessary to include the user operation on the chain as compared to a normal EOA transaction. * The second step is optional, you can choose to send the user operation to the Solver’s `eth_sendUserOperation` JSON RPC endpoint or submit it to any Bundler of your choice. Once the user operation has been included on the chain either by the Solver or by another Bundler on the origin chain, the Solver will execute the destination chain transaction. One slightly different thing in the way the Solver accepts user operations is that the `maxFeePerGas` and `maxPriorityFeePerGas` should be set to 0. This is done to make sure that the solver does not get paid twice (once by the funds being moved in the call data and second by the on-chain compensation to the Bundler by the Entry Point). This also requires you to use a paymaster as the entry point logic does not allow such a user operation if a smart account has to pay for the operation. If using an external Bundler, you might need to send non-zero `maxFeePerGas` and `maxPriorityFeePerGas` as two different parties are being paid in this case. In the following example, we demonstrate how to use a Safe Smart Account with a Pimlico Paymaster and use Relay to get the quotes and submit the user operation. The script makes use of Viem’s `privateKeyToAccount` to create an owner but any other owner creation method is applicable. import { createPublicClient, http, toHex } from "viem"; import { baseSepolia } from "viem/chains"; import { privateKeyToAccount } from "viem/accounts"; import { createBundlerClient, entryPoint07Address, UserOperation, } from "viem/account-abstraction"; import { createPimlicoClient } from "permissionless/clients/pimlico"; import { toSafeSmartAccount } from "permissionless/accounts"; import axios from "axios"; const executeUserOperation = async () => { try { const owner = privateKeyToAccount(""); const publicClient = createPublicClient({ chain: baseSepolia, transport: http("https://sepolia.base.org"), }); const paymasterClient = createPimlicoClient({ transport: http(""), entryPoint: { address: entryPoint07Address, version: "0.7", }, }); const safeAccount = await toSafeSmartAccount({ client: publicClient, entryPoint: { address: entryPoint07Address, version: "0.7", }, owners: [owner], version: "1.4.1", }); const bundlerClient = createBundlerClient({ account: safeAccount, client: publicClient, paymaster: paymasterClient, transport: http(""), }); // Bridging ETH from Base Sepolia to ETH on Sepolia // userOperationGasOverhead set to 300000 const requestData = { user: safeAccount!.address, originChainId: 84532, destinationChainId: 11155111, originCurrency: "0x0000000000000000000000000000000000000000", destinationCurrency: "0x0000000000000000000000000000000000000000", recipient: owner.address, tradeType: "EXACT_INPUT", amount: "20000000000000000", referrer: "relay.link/swap", useExternalLiquidity: false, userOperationGasOverhead: 300000, }; const quoteResponse = await axios.post( "https://api.relay.link/quote", requestData, { headers: { "Content-Type": "application/json", }, }, ); // Fetch the transaction data from the response of the quote call const { steps } = quoteResponse.data; const item = steps[0].items[0]; const { to, data, value } = item.data; const callData = await safeAccount.encodeCalls([\ {\ to: to as `0x${string}`,\ data,\ value,\ },\ ]); const { callGasLimit, verificationGasLimit, preVerificationGas } = await bundlerClient.estimateUserOperationGas({ account: safeAccount, calls: [\ {\ to,\ value,\ data,\ },\ ], }); const userOperation = { sender: safeAccount.address, nonce: await safeAccount.getNonce(), callData, callGasLimit, maxFeePerGas: 0n, maxPriorityFeePerGas: 0n, preVerificationGas, verificationGasLimit, paymasterPostOpGasLimit: 100_000n, // can be estimated specific to a paymaster paymasterVerificationGasLimit: 200_000n, // can be estimated specific to a paymaster signature: await safeAccount.getStubSignature(), }; const { paymaster, paymasterData } = await paymasterClient.getPaymasterData({ ...userOperation, chainId: baseSepolia.id, entryPointAddress: entryPoint07Address, }); (userOperation as UserOperation).paymaster = paymaster; (userOperation as UserOperation).paymasterData = paymasterData; userOperation.signature = await safeAccount.signUserOperation(userOperation); // Convert all values to hex const hexUserOperation = Object.fromEntries( Object.entries(userOperation).map(([key, value]) => { if (typeof value === "number" || typeof value === "bigint") { return [key, toHex(value)]; } return [key, value]; }), ); const eth_sendUserOperationResponse = await axios.post( "https://api.relay.link/execute/user-op/84532", { jsonrpc: "2.0", id: 1, method: "eth_sendUserOperation", params: [hexUserOperation, entryPoint07Address], }, { headers: { "Content-Type": "application/json", }, }, ); const { result } = eth_sendUserOperationResponse.data; const transactionHash = await bundlerClient.waitForUserOperationReceipt({ hash: result, }); console.log("transactionHash", transactionHash); } catch (error) { console.error("Error:", error); } }; executeUserOperation(); [​](#relaying-only-on-the-destination-chain) Relaying only on the destination chain -------------------------------------------------------------------------------------- To execute user operations on the destinations, you can pass in the transaction details in the [txs](https://docs.relay.link/references/api/get-quote#body-txs) array while calling the quote API. import { encodeFunctionData } from 'viem'; // Sample user operation // The maxFeePerGas and maxPriorityFeePerGas should be "0x0" as the Solver is already compensated for its destination chain actions const userOperation = { "sender": "0xcD7cc356852c8db2C587f53409491396ac966ac7", "nonce": "0x193f25819da0000000000000000", "callData": "0x541d63c80000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff850000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb0000000000000000000000008a95a0e55d591b00cf18253148647daad25fa6a8000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000", "callGasLimit": "0xf4240", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", "preVerificationGas": "0xf4240", "verificationGasLimit": "0xf4240", "paymasterPostOpGasLimit": "0x186a0", "paymasterVerificationGasLimit": "0xf4240", "signature": "0x000000000000000000000000cf4ccb124579f0a9591d7a5e3df30e97b8fc08dd298bc9e8fdc476f1af7d756a4662f8b0ec251acffea2a24df6c13932874002644a626397749029b14097c0381c", "paymaster": "0x0000000000000039cd5e8aE05257CE51C473ddd1", "paymasterData": "0x00000067690ea8000000000000a51b902711bddd24df60863c9d8731db288186ecd72328ed9c7c2f5c6c3b3cb9366ab6328a28035ece11751680e217944682e3ea0d013919d9a086b1c3039c4e1c" } const beneficiary = "0x0000000000000000000000000000000000000000"; // this address is just for completion, no funds would be transfer here as maxFee values are set to 0 // Transaction object to be executed by the solver on destination chain const transaction = { to: "0x0000000071727De22E5E9d8BAf0edAc6f37da032" // ERC-4337 Entry Point address value: "0" // Value transfer will always be 0 as Solver to Entry Point data: encodeFunctionData({ abi: ENTRY_POINT_ABI, // https://etherscan.io/address/0x0000000071727De22E5E9d8BAf0edAc6f37da032#code functionName: 'handleOps', args: [userOperation, beneficiary] }) }; // txs array to be passed in the quote API call // One can add more transactions pre and post user operation execution const txs = [transaction]; Once the txs array has been created, pass it in the quote API call. [​](#relaying-on-both-the-origin-and-destination-chain) Relaying on both the origin and destination chain ------------------------------------------------------------------------------------------------------------ The ability to execute user operations on both the origin and destination chains can be done by individually following the above-mentioned steps. * Pass the userOperationGasOverhead while making the `/quote` call and also pass the destination chain Entry Point transaction encoded in the `txs` array. * Create the user operation using the transaction data returned in the response of the quote API. * Execute the origin chain user operation either by making a call to `eth_sendUserOperation` JSON RPC to the Solver or to any other Bundler. * After the user operation is included on the origin chain, the Solver will pick up the transaction and destination `txs` will be executed by the Solver [Deposit Address](/guides/deposit-address) [Relay Protocol](/how-it-works/relay-protocol) On this page * [Relaying only on the origin chain](#relaying-only-on-the-origin-chain) * [Relaying only on the destination chain](#relaying-only-on-the-destination-chain) * [Relaying on both the origin and destination chain](#relaying-on-both-the-origin-and-destination-chain) --- # Just-In-Time Gas - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Advanced Just-In-Time Gas [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) There are some actions and contracts where cross-chain execution with a relayer doesn’t work. For example, most ‘sell’ actions depend on `msg.sender` * Selling a nft * Swapping an erc20 * Bidding in an auction To get around this, you can simply bridge a small amount of ETH for gas and have the user execute the transaction themselves. This is only now possible because of how fast and cheap Relay makes bridging. We will soon add functionality to our SDK to handle this flow completely, but until then, this guide will demonstrate how you could implement this ux yourself. [​](#overview-of-steps) Overview of steps: --------------------------------------------- * #### Step 1: Estimate gas needed on the Destination Chain * #### Step 2: Bridge Just-In-Time gas money from Origin to Destination chain * #### Step 3: Execute transaction/s on the Destination chain * #### Step 4 (optional): Bridge back proceeds to Origin chain The following example assumes you are set up with the [Relay SDK](https://docs.relay.link/references/sdk/getting-started) as well as [viem](https://viem.sh/) . You can skip ahead to the full code and live example [here](/_sites/docs.relay.link/guides/just-in-time-gas#example) . #### [​](#step-1-estimate-gas-needed-on-the-destination-chain) Step 1: Estimate gas needed on the Destination Chain const estimatedGas = await publicClient.estimateContractGas({ ...wethContract, functionName: 'withdraw', args: [wethBalance], account: address, }) const gasPrice = await publicClient.getGasPrice() const totalGasEstimation = estimatedGas * gasPrice const totalGasEstimationWithBuffer = totalGasEstimation + (totalGasEstimation * BigInt(5)) / BigInt(100) // add 5% buffer to handle gas fluctuation We start by using viem’s [estimateContractGas](https://viem.sh/docs/contract/estimateContractGas) to calculate the gas required to successfully execute the transaction we want to make on the Destination Chain. We also use [getGasPrice](https://viem.sh/docs/actions/public/getGasPrice) to get the current price of gas on the Destination chain. We multiply these two values together to get the total gas estimate and add a 5% buffer to handle any fluctuation. #### [​](#step-2-bridge-just-in-time-gas-money-from-origin-to-destination-chain) Step 2: Bridge Just-In-Time gas money from Origin to Destination chain const quote = await relayClient.actions.getQuote({ chainId: baseSepolia.id, toChainId: sepolia.id, wallet, amount: totalGasEstimationWithBuffer.toString(), }) await relayClient.actions.execute({ quote, wallet, onProgress(steps) { setStep(getCurrentStepDescription(steps)) }, }) We use the Relay SDK’s [getQuote action](/references/sdk/actions/getQuote) to bridge the gas money from the Origin to the Destination chain. #### [​](#step-3-execute-transactions-on-the-destination-chain) Step 3: Execute transaction/s on the Destination chain const { request } = await publicClient.simulateContract({ ...wethContract, account: address, functionName: 'withdraw', args: [wethBalance], chain: sepolia, gas: estimatedGas, }) const hash = await wallet.writeContract(request) await publicClient.waitForTransactionReceipt({ hash, }) In this example we `withdraw` some WETH with viem’s [writeContract](https://viem.sh/docs/contract/writeContract) and wait for the transaction to complete with [waitForTransactionReceipt](https://viem.sh/docs/actions/public/waitForTransactionReceipt) . #### [​](#step-4-optional-bridge-back-proceeds-to-origin-chain) Step 4 (optional): Bridge back proceeds to Origin chain const destinationEthBalance = await getBalance(wagmiConfig, { address: address, chainId: sepolia.id, }) const quote = await relayClient.actions.getQuote({ chainId: sepolia.id, toChainId: baseSepolia.id, wallet, amount: destinationEthBalance.value.toString() }) const bufferedGasFee = BigInt(quote?.fees?.gas ?? 0) * (BigInt(100) + BigInt(5)) / BigInt(100) // add 5% buffer to handle flucation const amountToBridgeBack = destinationEthBalance.value - bufferedGasFee - BigInt(quote?.fees?.relayer ?? 0) await relayClient.actions.execute({ quote, wallet, onProgress(steps) { setStep(getCurrentStepDescription(steps)) }, }) This step is optional and the amount you bridge back would depend on your use case. In this example, we attempt to bridge back all of the ETH that the user has on the Destination chain. We first fetch the user’s ETH balance on Destination. We then calculate the required fees in order to bridge that ETH back (gas fee + relayer fee). Once we subtract those fees from the user’s Destination ETH balance, we get the total amount that we can afford to bridge and we can execute the bridge action. [​](#example) Example ------------------------ Check out this [codesandbox](https://stackblitz.com/~/github.com/ted-palmer/relay-example) to see a live example of just-in-time bridging. [Testnet Support](/guides/testnet) [Deep Linking](/guides/deep-linking) On this page * [Overview of steps:](#overview-of-steps) * [Step 1: Estimate gas needed on the Destination Chain](#step-1-estimate-gas-needed-on-the-destination-chain) * [Step 2: Bridge Just-In-Time gas money from Origin to Destination chain](#step-2-bridge-just-in-time-gas-money-from-origin-to-destination-chain) * [Step 3: Execute transaction/s on the Destination chain](#step-3-execute-transactions-on-the-destination-chain) * [Step 4 (optional): Bridge back proceeds to Origin chain](#step-4-optional-bridge-back-proceeds-to-origin-chain) * [Example](#example) --- # useQuote - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Hooks useQuote [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) [​](#parameters) Parameters ------------------------------ | Parameter | Description | Required | | --- | --- | --- | | **client** | A RelayClient instance. You can create one using the [SDK](http://localhost:3000/references/sdk/createClient)
or retrieve one using the `useRelayClient` hook from the UI kit. | ✅ | | **wallet** | A valid [WalletClient](https://viem.sh/docs/clients/wallet.html)
from Viem or an AdaptedWallet generated from an adapter. This parameter can be left empty if just retrieving a quote, but is required for executing a quote. | ❌ | | **options** | Options that map directly to the [quote API](/references/api/get-quote)
. | ✅ | | **onRequest** | A callback function that triggers when a request is made to fetch the quote. | ❌ | | **onResponse** | A callback function that triggers when a response is returned. | ❌ | | **queryOptions** | Tanstack query options. Refer to the [Tanstack](https://tanstack.com/query/latest/docs/framework/react/guides/query-options)
docs. | ❌ | [​](#return-data) Return Data -------------------------------- The hook returns an object with the base [Tanstack Query response](https://tanstack.com/query/v5/docs/framework/react/reference/useQuery) , it also returns an `executeQuote` function which allows you to conveniently execute the quote. The function takes one parameter, an [onProgress callback](/references/sdk/actions/execute) that mirrors the underlying execute action. from the SDK. [​](#usage) Usage -------------------- [​](#query-function) Query Function -------------------------------------- import { queryQuote } from "@reservoir0x/relay-kit-hooks"; const response = queryQuote("https://api.relay.link", { user: address, originChainId: 1, destinationChainId: 10, originCurrency: "0x0000000000000000000000000000000000000000", destinationCurrency: "0x0000000000000000000000000000000000000000", tradeType: "EXACT_INPUT", amount: "10000000", }); [usePrice](/references/relay-kit/hooks/usePrice) [useRelayChains](/references/relay-kit/hooks/useRelayChains) On this page * [Parameters](#parameters) * [Return Data](#return-data) * [Usage](#usage) * [Query Function](#query-function) --- # Overview - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Overview [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) Relay offers developer tools with our SDK and APIs. This tooling allows you to embed instant bridging & cross-chain execution to your app. We recommend using the SDK over our APIs. The SDK will iterate the steps and return useful callback information. The APIs will require iterating through the [steps](/references/api/step-execution) manually. [@reservoir0x/relay-sdk\ ----------------------\ \ For a smooth streamlined experience with any TypeScript/JavaScript project. To be used on either the server (Node.js) or the browser.](/references/sdk/getting-started) [Relay API\ ---------\ \ Integrate with the raw underlying API which powers the SDK. Look up transaction statuses, execute cross-chain actions, and more.](/references/api/get-chains) --- # useRelayChains - Relay [Relay home page![light logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-black.svg)![dark logo](https://mintlify.s3.us-west-1.amazonaws.com/unevenlabs/logo/relay-white.svg)](/) Search or ask... Search... Navigation Hooks useRelayChains [Documentation](/what-is-relay) [API Reference](/references/api/overview) [SDK Reference](/references/sdk/getting-started) [UI Kit](/references/relay-kit/overview) [​](#parameters) Parameters ------------------------------ | Parameter | Description | Required | | --- | --- | --- | | **baseApiUrl** | Base api url for the relay api, defaults to [https://api.relay.link](https://api.relay.link)
but can also be configured to [https://api.testnets.relay.link](https://api.testnets.relay.link) | ❌ | | **options** | Query parameters that map directly to the [chains api](/references/api/get-chains) | ❌ | | **queryOptions** | Tanstack query options. Refer to the [Tanstack](https://tanstack.com/query/latest/docs/framework/react/guides/query-options)
docs. | ❌ | [​](#return-data) Return Data -------------------------------- The hook returns an object with the base [Tanstack Query response](https://tanstack.com/query/v5/docs/framework/react/reference/useQuery) . The data property maps to the object returned in the aforementioned [chains api](/references/api/get-chains) . You’ll also get back chains (an array of RelayChains) and viemChains (an array of viem compatible chains). You can use the viem chains in your wagmi config. [​](#usage) Usage -------------------- [​](#query-function) Query Function -------------------------------------- import { queryRelayChains } from '@reservoir0x/relay-kit-hooks' queryRelayChains() [useQuote](/references/relay-kit/hooks/useQuote) [useRequests](/references/relay-kit/hooks/useRequests) On this page * [Parameters](#parameters) * [Return Data](#return-data) * [Usage](#usage) * [Query Function](#query-function) ---