Skip to main content
The Smart Deposit Addresses feature is currently in beta.
Please contact us with the details of your use case if you are interested in using it and we can set you up with testnet and mainnet access.

Introduction

To bridge funds through Rhino you would normally need to generate a quote, commit it and then interact with the bridge contract on the origin chain to initiate the bridge. However, this is not always an option for all use cases where a smart contract interaction is not possible or very inconvenient.
To also cater to those use cases, Rhino is supporting bridging through manual transfers.

How it works

1

Generate address

Call our API with deposit chain, destination chain and destination address.
2

Transfer funds

Make a standard ERC20 transfer to the generated address.
3

Receive funds

After the deposit has been confirmed on chain, the funds will be automatically bridged to the specified destination.
Smart Deposit Addresses are reusable and can be used for multiple bridges indefinetely (see caveats below). This makes bridging accessible to any wallet or app that supports standard ERC20 transfers.

Fees

Standard bridging fees apply to bridging with Smart Deposit Addresss (see Get a Bridge Quote or try our bridge). Integrating partners can adjust the way fees are charged to their customers. Get in touch for more details at partnerships@rhino.fi.

Smart Deposit Address expiration

To conserve resources when monitoring Smart Deposit Addresses, we will stop monitoring addresses that have not been used for a certain period of time. This is basically a timer that runs down from initial creation and is reset whenever a bridge is performed through an address.
An inactive Smart Deposit Address can still be used for bridging by manually reactivating it through the API if it is needed. Funds that are sent to an inactive Smart Deposit Address are not lost, they will only require one API call to activate the address and initate a bridge for the transfers made while inactive.

Supported chains

Deposit addresses are enabled on Ethereum, Arbitrum, BSC, and Tron, as well as other chains. The general bridge config endpoint provides a boolean enabledDepositAddress flag that can be used to find chains that Smart Deposit Addresses are enabled for. Example:
const response = await fetch('https://api.rhino.fi/bridge/configs')
The response will then specify which chains have Smart Deposit Addresses enabled:
{
  "ETHEREUM": {
    "name": "Ethereum",
    ...,
    "enabledDepositAddress": true,
  },
  "SOLANA": {
    "name": "Solana",
    ...,
    "enabledDepositAddress": false,
  },
}

API interactions

The following examples showcase the use of our API to manage Smart Deposit Addresses. All those calls require authentication, see details on this here.

Generating a Smart Deposit Address

You can generate a new Smart Deposit Address with the following API call:
const response = await fetch('https://api.rhino.fi/bridge/deposit-addresses', {
  method: 'POST',
  body: JSON.stringify({
    depositChains: ['ETHEREUM'],
    destinationChain: 'BASE',
    destinationAddress: '0x123...',
  }),
  headers: {
    'Content-Type': 'application/json',
    'authorization': 'YOUR_JWT',
  },
})
The response will then look like this:
[{
  "depositChain": "ETHEREUM",
  "depositAddress": "0x456...",
  "destinationChain": "BASE",
  "destinationAddress": "0x123...",
  "supportedTokens": [
    {
      "symbol": "USDT",
      "address": "0x789...",
      "maxDepositLimitUsd": 100000,
      "minDepositLimitUsd": 10,
    }
  ],
  "isActive": true,
}]
The first highlighted line contains the generated Smart Deposit Address. Funds can be sent there to be bridged.
However, only tokens from the supportedTokens list will be processed. Transfers of tokens that are not in this list will not be processed. Transfers that are smaller than the minDepositLimitUsd or larger than the maxDepositLimitUsd will not be processed (there is a β€œgrace” window to account for different price sources and price fluctuations). If this happens, funds can be returned through our customer service.

Multiple deposit chains

You can provide multiple deposit chains in the request. The API will then generate one Smart Deposit Address that can be used on all the provided chains. This is why the response is also a list - one element for each chain provided. The Smart Deposit Addresses in the individual elements will be identical in this case.
Please note that providing multiple deposit chains only works for EVM chains currently. Only then can the same address be used for all of them.

Swaps

When creating a Smart Deposit Address you can also specify a tokenOut field. This will cause all withdrawals on the destination chain to be in that token, swapping if needed. This is currently only supported for stablecoins (USDC and USDT). The given tokenOut needs to be a bridgable token on the destination chain, otherwise creation of the SDA will fail.

Post Bridge Data

Rhino provides the option to execute contract calls as part of the withdrawal process on the destination chain. Then every bridge through the deposit address will execute this action on the destination. For security reasons, only predefined actions are available. Please contact us with details on your use case if interested.

Refund address

Rhino provides the option to pass a refund address when creating a Smart Deposit Address. If for some reason there is an issue with your smart deposit, the funds deposited will be refunded to the specified refund address.

Custom data and reusing of addresses

When creating a Smart Deposit Address you can provide a addressNote field to be stored in our database. This field will be returned from all status endpoints as well.
Additionally, a reusePolicy can be specified when creating a Smart Deposit Address. It can have the following values:
  • reuse-existing: Reuse an existing Smart Deposit Address if it exists. Only create a new one if no existing address matches the given parameters. An existing Smart Deposit Address that is reused this way is also reactivated automatically.
  • create-new: Always create a new Smart Deposit Address.
When no reusePolicy is specified it defaults to reuse-existing. To determine if a Smart Deposit Address already exists, the following combination of fields is used:
  • depositChain
  • destinationChain
  • destinationAddress
  • userId (only Smart Deposit Addresses previously created by you will be considered)
  • addressNote if provided
  • tokenOut if provided
  • postBridgeData if provided
  • webhookUrl if provided
  • refundAddress if provided
Example use cases for this feature:
  • Your users have unique destination addresses and you want to show users their previously used Smart Deposit Address.
  • You consolidate multiple Smart Deposit Addresses into the same destination address but store a user ID in the addressNote field to make sure to only have one address per user.

Checking Smart Deposit Address status

You can also check the current status of a Smart Deposit Address with the following call:
const depositAddress = '0x123...'
const depositChain = 'ETHEREUM'
const response = await fetch(`https://api.rhino.fi/bridge/deposit-addresses/${depositAddress}/${depositChain}`, {
  headers: {
    'authorization': 'YOUR_JWT',
  },
})
The response format will be the same as the one returned when generating a new Smart Deposit Address with the exception of the destinationAddress. That field will only be included if the request was made with a secret API key.

Checking Smart Deposit Address history

You can check the history of a Smart Deposit Address with the following call:
const depositAddress = '0x123...'
const depositChain = 'ETHEREUM'
const response = await fetch(`https://api.rhino.fi/bridge/deposit-addresses/${depositAddress}/${depositChain}/history`, {
  headers: {
    'authorization': 'YOUR_JWT_FROM_SECRET_KEY',
  },
})
The response will contain a list of transfers that have been processed through the Smart Deposit Address. By default it gives you the transfers from the last 7 days. To see older transfers you can provide a from and to query parameter with a timestamp in milliseconds. Only a SECRET_ key is allowed to access history.

Checking Smart Deposit Address bridge status with a PUBLIC API key

Generally the above history endpoint can be used to track the bridges through a Smart Deposit Address. However it is not possible to use this in a frontend integration as a SECRET API key would be exposed in an unsafe browser environment.
To also track bridges in this case, a public status endpoint exists. However, this endpoint additionally takes a destinationAddress as query parameter that has to match the requested Smart Deposit Address (this value should still be available in the local state after creating a Smart Deposit Address). If it does not match, the request will be rejected.
Example:
const depositAddress = '0x123...'
const depositChain = 'ETHEREUM'
const destinationAddress = '0x456...'
const response = await fetch(`https://api.rhino.fi/bridge/deposit-addresses/${depositAddress}/${depositChain}/public-status?destinationAddress=${destinationAddress}`, {
  headers: {
    'authorization': 'YOUR_JWT_FROM_SECRET_KEY',
  },
})
The response will contain the last bridge (accepted or rejected) through the Smart Deposit Address in the lastBridges field. If this array is empty it means that no transfer has been picked up yet.
Please note that this array will currently only contain the last event. In the future this endpoint will be expanded with the option to return all bridges after a certain timestamp.

Reactivating a Smart Deposit Address

If the isActive flag returned by the status check is false you can reactivate the Smart Deposit Address manually with the following call:
const depositAddress = '0x123...'
const depositChain = 'ETHEREUM'
const response = await fetch(`https://api.rhino.fi/bridge/deposit-addresses/${depositAddress}/${depositChain}/activate`, {
  method: 'PATCH',
  headers: {
    'authorization': 'YOUR_JWT',
  },
})
This will cause the address to be monitored again. Additionally the address will be checked for transfers since the last activity to process transfers made while the address was inactive.

Supported tokens

To get the list of tokens supported between a deposit chain and destination chain you can execute the following code:
const depositChain = 'ETHEREUM'
const destinationChain = 'BASE'
const tokenOut = 'USDT' // optional
const response = await fetch(`https://api.rhino.fi/bridge/deposit-addresses/${depositChain}/${destinationChain}/supported-tokens?tokenOut=${tokenOut}`, {
  method: 'GET',
  headers: {
    'authorization': 'YOUR_JWT',
  },
})
It will return the list of supported tokens between the 2 specified chains along with their associated deposit limit.

Search your addresses

Rhino provides an endpoint that allows you to search for your Smart Deposit Addresses with some optional filters. This endpoint is authenticated and will only returns the addresses associated with your user. The result is paginated and you can set the pageToken field to get to the next page. If not provided, it’ll return the first page of results and a nextTokenPage value that can be used to query for the next page. The following filters are available (all are optional and can be combined):
  • addressNote
  • depositChain
  • destinationChain
  • destinationAddress: requires destinationChain to be set as well
// all filters are optional and can be combined
const addressNote = 'my_note'
const depositChain = 'ETHEREUM'
const destinationChain = 'BASE'
const destinationAddress = '0x....'

const pageSize = 20 // optional, default to 20, max 50
const pageToken = "eyJkZXBvc2l0Q2hhaW4iOiJCQVNFIiwiZGVwb3NpdEFkZHJlc3MiOiIweDlmYTE1MDdiNTY0YzRlNWM1YmJjN2E5Yzc1ZWQ1MmFhMTc5ODIxNjkifQ==" // optional, returns the first page of results if not provided

const response = await fetch(
  `https://api.rhino.fi/bridge/deposit-addresses/search?addressNote=${addressNote}&depositChain=${depositChain}&destinationChain=${destinationChain}&destinationAddress=${destinationAddress}&page=${page}&limit=${limit}`,
  {
    method: 'GET',
    headers: {
      'authorization': 'YOUR_JWT',
    },
  },
)