Bridge Integration Guide
Last updated
Last updated
This is a step-by-step framework agnostic guide to help you integrate Across Protocol into your applications using @across-protocol/app-sdk.
The App-SDK makes it extremely easy to add a bridge experience to any app (wallet, DEX, staking, lending/borrowing, etc). It abstracts away a lot of nuances about fetching bridge quotes and executing deposits by simply following a 2 step process:
Request quotes using getQuote()
Initiate deposit using executeQuote()
Along with the above mentioned functions, there are several utilities that we can use to ensure that the entire process of integrating a bridge takes less than an hour. Let's dive in!
Before starting the integration, please ensure that you fill this form and get your integrator ID. This will allow us to support you better as you progress towards the production-release and accelerate co-marketing efforts from our side.
Once you fill out the form, we’ll get in touch and provide your integrator ID. In the meantime, you can proceed with the integration by following this guide and simply add the integrator ID once it’s shared with you.
A frontend framework of your choice (Next.js, Vue, Svelte, Vanilla JS/TS, etc).
Basic understanding of intents architecture in Across.
A web3 wallet kit of your choice.
Please ensure that you have followed all the necessary steps to setup your development environment. This may include - but is not limited to - setting up the frontend framework and adding a wallet kit along with any CSS frameworks.
We recommend Wagmi along with a wallet of your choice.
We will kickoff by initializing the @across-protocol/app-sdk. To do so, install the SDK:
We will be using some utilities provided by Viem to ensure a quick integration.
Now, set up the AcrossClient
, add in your integrator ID and configure the chains you want to support.
In case you don't have an integrator ID, please fill this form.
Depending on your state management approach, there are multiple ways to integrate the AcrossClient
. The key is to ensure that the AcrossClient
wraps the body of your app correctly.
You can achieve this by setting up a React Context or by leveraging sophisticated solutions like Tanstack Query for better efficiency and robustness.
A Quote refers to the user’s expressed intent for a crosschain transaction. Rather than detailing the exact execution path, the user defines the desired outcome, all encapsulated in a standardized order structure. Here are the parameters you must define while retrieving a quote:
originChainId
: chainId where the user's deposit is originating
destinationChainId
: chainId where the user intends to receive their funds
inputToken
: address of the token that the user is depositing on the origin chain
outputToken
: address of the token that the user intends to receive on the destination chain
inputAmount
: the raw amount the user is transferring. By raw amount, this means it should be represented exactly as it is in Solidity, meaning 1 USDC would be 1e6 or 1 ETH would be 1e18.
Here is an example:
When executed successfully, the output will be something like this:
Important fields to note here are:
deposit.outputAmount
: This is the amount of outputToken
the user will receive after deducting the totalRelayFee
from the inputAmount
.
estimatedFillTimeSec
: This is the estimated time for the deposit to be filled and user to receive funds on the destination chain.
fees.totalRelayFee
: This is the total fees (lpFee
+ capitalFee
+ destinationGasFee
) that the user will be charged for conducting the bridge transaction.
isAmountTooLow
: This is a warning for when the inputAmount
is too low for any relayer to fill. You can use this to show an error on the UI and request user to increase inputAmount
.
limits
: To make the UX seamless, we present you with minimum and maximum deposit limits of the system so you can help the user achieve maximum efficiency with their fill times on Across.
The Across App-SDK comes with the getSupportedChains()
function that allows developers to get all the necessary data about the origin and destination chain in less than a second.
With this, you can build dropdown menus and simply pass the information fetched by getSupportedChains()
to build a complete user experience in seconds with minimal effort.
To fetch supported chains, simply call the function with the SDK initialized like we had discussed above:
You can use the same function to get the details of a singular chain as well:
Upon running the above command with chainId = 1
, You will see inputTokens
and outputTokens
supported by Across on Ethereum. Along with this, there will be several other details that will allow you to build a seamless UX:
Once the quote is received, you will need the following parameters to execute it successfully:
deposit
: This is the deposit to execute. You can get this from the return value of the useQuote()
function that we discussed above.
walletClient
: This is the wallet client to use for the deposit. We recommend using wagmi for this.
onProgress
: This is a handler for the execution progress.
Quote execution has 3 steps:
Approve
: Approving the SpokePool contract to transfer the specified amount of tokens from your account.
Deposit
: Depositing the input token on the origin chain.
Fill
: Waiting for the deposit to be filled on the destination chain.
using the onProgress
handler you can track which step the current quote execution is on and debug if needed.
Here is how you can call the executeQuote() function in the Across App-SDK:
Upon successful execution, you will be able to see funds on the destinationChain
in the requested outputToken
.
Congratulations! You have now successfully integrated Across into your application.
You can find a complete App-SDK integration here for your reference.
To track the lifecycle of a deposit you can use the app.across.to/api/deposit/status endpoint with the following parameters:
originChainId
: chainId where the deposit originated from
depositId
: The deposit id that is emitted from the DepositV3
function call as a V3FundsDeposited
event
The recommended solution for tracking all Across deposits originating from your integration, for a single user, is to store the user's depositId
and originChainId
from each transaction originating from your app, and then get the status of each via the above endpoint.
In case you face any errors or need support, please feel free to reach out to us.