Documentation Index
Fetch the complete documentation index at: https://docs.rhino.fi/llms.txt
Use this file to discover all available pages before exploring further.
Quickstart
The whole process consists of:
Authentication
Get a JWT to authenticate your requests.
Fetching bridge configs
Retrieve supported chains and tokens.
Getting a quote
Obtain transaction details, including fees.
Committing the quote
Confirm the transaction.
Executing the bridge transaction
Interact with the smart contract to complete the transfer.
1. Authentication
All non-public API endpoints are authenticated using a JSON Web Token. To authenticate your requests, include the token in the Authorization header. Learn about API authentication.
2. Fetch Bridge Configs
Retrieve available chains to ensure your transaction uses the correct parameters.
export const getBridgeConfigs = async () => {
const request = await fetch('https://api.rhino.fi/bridge/configs')
return request.json()
}
For the exact response format and more details, see the API Reference.
3. Fetch Swap token config
Retrieve available tokens for swap transactions.
export const getSwapTokenConfig = async () => {
const request = await fetch('https://api.rhino.fi/bridge/bridge-swap-token-configs')
return request.json()
}
For the exact response format and more details, see the API Reference.
4. Get a Bridge & Swap Quote
Before executing a bridge transaction, you must generate a quote that provides transaction details, including fees and amounts.
getBridgeSwapUserQuote.js
export const getBridgeSwapUserQuote = async (payload, jwt) => {
const request = await fetch(`https://api.rhino.fi/bridge/quote/bridge-swap/user`, {
headers: {
"content-type": "application/json",
"authorization": jwt
},
method: "POST",
body: JSON.stringify(payload)
})
return request.json()
}
For the exact request / response format and more details, see the API Reference.
5. Commit the Quote
Once you have a quote, you must commit it to confirm the transaction before execution.
commitBridgeSwapUserQuote.js
export const commitBridgeSwapUserQuote = async (quoteId, jwt) => {
const request = await fetch(`https://api.rhino.fi/bridge/quote/commit/${quoteId}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'authorization': jwt
}
})
return request.json()
}
For the exact request / response format and more details, see the API Reference.
6. Execute the Bridge & Swap Transaction
Now, you can execute the bridge transaction by interacting with the smart contract.
See examples for interacting with the bridge smart contracts across different blockchain environments.
7. Full Example
Here’s the complete implementation combining all the steps above:
import { getBridgeSwapUserQuote } from "./getBridgeSwapUserQuote";
import { getBridgeConfigs } from "./getBridgeConfigs";
import { getSwapTokenConfig } from "./getSwapTokenConfig";
import { commitBridgeSwapUserQuote } from "./commitBridgeSwapUserQuote";
const JWT = 'YOUR_JWT'; // Replace with your JWT generated from our API
const amount = '1';
const chainIn = 'BASE';
const chainOut = 'ARBITRUM';
const tokenIn = 'USDT';
const tokenOut = 'USDC';
const depositorAddress = '0x0000000000000000000000000000000000000000'; // Replace with your depositor address
const recipientAddress = '0x0000000000000000000000000000000000000000'; // Replace with your recipient address
const bridgeAndSwap = async () => {
// Get bridge configs to determine supported chains and tokens or later use for the contract call
const configs = await getBridgeConfigs();
const swapTokenConfig = await getSwapTokenConfig();
// Get a bridge quote for the transaction
const quote = await getBridgeSwapUserQuote({
amount,
chainIn,
chainOut,
tokenIn,
tokenOut,
mode: 'pay',
depositor: depositorAddress,
recipient: recipientAddress,
amountNative: '0'
}, JWT);
if (!quote?.quoteId) throw new Error('Failed to generate user quote.');
// Commit the quote to confirm the transaction when you are ready to send on-chain
const commitResult = await commitBridgeSwapUserQuote(quote.quoteId, JWT);
if (!commitResult?.quoteId) throw new Error('Failed to commit user quote.');
const chainConfig = configs[chainIn];
const swapConfig = swapTokenConfig[chainIn][tokenIn];
// Execute the bridge transaction by interacting with the smart contract -- see contract examples section on exact implementation
await callBridgeContract({
chainConfig,
swapConfig,
amount: quote.payAmount,
tokenIn,
commitmentId: commitResult.quoteId,
callback: (hash) => console.info('Transaction hash:', hash)
});
};
bridgeAndSwap();
For a detailed breakdown of API endpoints and parameters, check the API Reference.
Same-chain swaps
When chainIn === chainOut, the quote response is flagged as an atomic same-chain swap (isAtomicSwap: true). These go through a separate contract and a different transaction format than a regular bridge deposit — broadcasting a depositWithId / depositNativeWithId for an atomic same-chain swap commitment will be rejected by the deposit watcher.
Same-chain swaps are EVM-only.
The flow is identical up to step 5 (commit), then diverges:
Detect the case
After fetching the quote in step 4, check the response:
const isSameChainSwap =
quote.chainIn === quote.chainOut && quote.isAtomicSwap === true
Use a different approval target
For ERC-20 same-chain swaps, the approval target is the chain’s sameChainSwapsAddress (returned in GET /bridge/configs under the chain entry) — not the regular contractAddress. Native-token swaps don’t require an approval.
Fetch the swap calldata instead of building a deposit tx
Instead of calling the deposit contract, fetch the prepared calldata. The commitmentId is the quoteId you committed.
export const getSwapCalldata = async (commitmentId, jwt) => {
const request = await fetch(`https://api.rhino.fi/bridge/swap/calldata/${commitmentId}`, {
headers: { 'authorization': jwt }
})
return request.json()
}
The response contains a JSON-stringified transaction object:
{
"calldata": "{\"to\":\"0x...\",\"data\":\"0x...\",\"value\":\"...\"}"
}
Parse it and submit it as a raw EVM transaction from the depositor wallet:
import { ethers } from 'ethers'
const { calldata } = await getSwapCalldata(commitResult.quoteId, JWT)
const { to, data, value } = JSON.parse(calldata)
const tx = await wallet.sendTransaction({ to, data, value: BigInt(value ?? 0) })
await tx.wait()
Do not call depositWithId / depositNativeWithId on the regular deposit contract for same-chain swaps.
Next steps
For the smart contract integration see - contract examples
To track your bridge transaction status, see Bridge Status & History.