Skip to main content
One address in. Any token, any chain. Exactly what you asked for, out. Connect-wallet flows kill conversion, for two reasons. Many payers can’t connect at all: a customer paying from a centralized exchange can only send to an address. And for those who can, connecting a wallet to an unfamiliar site and signing arbitrary calldata is scary, a pattern that has repeatedly proven risky. Every wallet-connect prompt is a drop-off point, right when your customer was ready to pay. One address. The payer sends anything to it, any token on any of 85+ chains, or same chain, and you receive the asset and chain you run on, like USDC on Base. Relay prices, routes, converts, and settles. Nothing to connect, nothing to sign, no arbitrary calldata to execute: just a transfer, the same behavior users already know from every exchange withdrawal and QR payment. Funds stay theirs until the order fills, and you can accept from chains you don’t natively support, with no wallet UI or per-chain build. Every chain and asset your customers already hold becomes something you can accept, through one integration. “We can’t take that” becomes captured volume. For a payment processor, it’s the wedge that serves your entire book from a single build.

Open and Strict

Open is reusable for the same route and tolerates variable amounts: each new deposit triggers a fresh quote and fill. Best for general-purpose acceptance and top-up flows. Strict is bound to one order and single-use: you specify exactly what you receive, overpayments refund the excess, underpayments refund in full. Best for payment processors and fixed-price checkout. Quick rule: exact per-order payout, use Strict; reusable and tolerant of variable amounts, use Open. Configuration details are in the integration guide below.

How it works

  1. Request an address via the API with your destination chain, output asset, and trade type.
  2. Deposit: the user sends any supported token, any chain, or same chain. No wallet connection.
  3. Fill: on confirmed deposit, the order fills while user funds sit in non-custodial escrow.
  4. Settle: you receive your asset on your chain; track status deposit-to-fill via the API.
From a centralized exchange, the whole flow is: copy the address, paste it into the exchange’s withdrawal screen, withdraw. No wallet required.

Why it matters

For integrators
  • Increase conversion. No wallet-connect wall between the payer and the payment.
  • Accept centralized exchange deposits, demand you’d otherwise turn away.
  • One integration, 85+ chains, including chains you have no wallet UI for. No per-chain build, no liquidity to manage.
  • Simple reconciliation. Settle to the one asset and chain you already run on.
For your users
  • Nothing to connect or sign. Just send funds to an address.
  • Pay with whatever they hold, from wherever they hold it: an exchange withdrawal or a QR scan is the whole flow.
  • Safe by default. A wrong amount or a failed fill refunds automatically.

Who it’s for

  • Payment Service Providers: merchants want to accept crypto, but wallet-connect checkouts leak conversion and exclude exchange-held funds. One integration accepts from every chain, settling to your one stablecoin. A $5 checkout: the customer picks any supported asset on any chain, and you receive your settlement currency.
  • Wallets & Wallet Infrastructure: every manual bridge or connect step is a drop-off. Add scan-to-pay and crosschain top-ups with no signing flow. A QR code is the address.
  • On / Off Ramps: stablecoin deposits arrive from more chains and issuers than you’ve built support for. One address receives any of them and hands settlement to your fiat rails; adding a chain stops being an integration project.
  • Merchant Acceptance: no customer gets turned away for holding the wrong stablecoin on the wrong chain. Accept any of them, settle to the one you run on.
You keep the merchant relationship, checkout, ledger, and compliance policy. Relay is the rail underneath.

What you get

Compliance screening on arrival, refund-to-address on under/overpayment or failure, optional app fees collected at settlement, and same chain plus crosschain through one integration.

Limitations

Long-tail tokens with unknown liquidity can’t be sent to a deposit address (a negligible share of volume). Per-order ceilings and route coverage constraints apply; see the integration guide below. For exact 1:1 stablecoin acceptance, pair deposit addresses with fee sponsorship and price stabilization.

Technical integration

  1. Quote — Integrator requests a quote with useDepositAddress: true. The response includes a depositAddress and requestId.
  2. User Deposit — User sends funds to the deposit address (wallet transfer or exchange withdrawal).
  3. Detect + Sweep — Relay detects the deposit onchain and sweeps funds to the depository contract. For open-ended addresses, the amount, currency, and chain are validated and the quote may be regenerated if different from the original. For strict addresses, the deposit is validated against the original order.
  4. Fill — Relay fills on the destination chain from pre-positioned liquidity. Funds are delivered to the recipient address.

Key Parameters

Address Reuse

Open deposit addresses can be reused for the same route (same origin currency, origin chain, destination currency, and destination chain). Each new deposit triggers a fresh quote and fill. Strict addresses should not be presented as reusable. They are bound to the original order and intended for single-use payment instructions.

Open vs Strict Deposit Addresses

Relay supports two deposit address modes that differ in how flexible they are when handling deposits.

Open Deposit Addresses

Open-ended deposit addresses are the flexible mode for supported routes. They can handle variable deposit amounts, and on some supported chain families they can also adapt to a different supported input token or a deposit on a different chain within the same VM. Adapting to a different token or a wrong chain is not always automatic — recovery may require manual reindexing before the deposit is recognized.
  • refundTo is recommended. Omitting refundTo disables automatic refund — there is no internal fallback.
  • Best for: general-purpose integrations where you want tolerance for user variability.

Strict Deposit Addresses

Strict deposit addresses are bound to the original order and should be treated as predictable payment instructions. They are not flexible intake points.
  • refundTo is required. The request will fail without it.
  • Set strict: true in your /quote/v2 request.
  • Best for: integrations that need predictable behavior and explicit refund handling (e.g., payment processors).

Comparison

Example Request and Response

Open Deposit Address

Bridging 0.01 ETH from Base to Optimism using an open deposit address:

Strict Deposit Address

Same route, but using a strict deposit address. Note the addition of strict: true and the required refundTo:
Key differences in the strict request:
  • strict is set to true
  • refundTo is required — the request fails without it
  • The deposit address is bound to this specific order and is not reusable

Quote Regeneration

When funds arrive at a deposit address, Relay evaluates what was sent versus what was originally quoted. How mismatches are handled depends on the deposit address mode.

Open-Ended Addresses

Same Token, Different Amount

  • Exact match — The original quote is reused and the fill proceeds directly.
  • More than quoted — A new quote is generated for the larger amount, and the fill proceeds.
  • Less than quoted — If the smaller amount still covers fees and the minimum fill, a new quote is generated and the fill proceeds. If not, the deposit is refunded to the refundTo address (if set).

Different Token (Solver Currency)

On some chain families, if the user sends a different token that is a solver currency, Relay can regenerate the quote using the actual currency deposited and fill the order. This is not universal across all chains — some chain families will fail or refund on token mismatch. If a different supported token was sent and nothing happens immediately, use the reindex endpoint as a fallback.

Different Chain (Same VM)

Open and custodial deposit addresses exist at the same address across chains within a VM family (e.g. all EVM chains), so a deposit can land on a chain other than the one quoted. This is supported but not always automatic: Relay’s background monitor watches the chain the address was registered on, so a wrong-chain deposit may not be recognized until it is reindexed. If a wrong-chain deposit isn’t picked up within a few minutes, trigger detection manually with the Deposit Address Reindex endpoint, setting targetChainId to the chain the funds actually landed on. Once detected, Relay sweeps the funds and proceeds with a fresh quote and fill. Behavior varies by chain family — some families refund a wrong-chain deposit instead of re-routing it. Strict addresses have no wrong-chain recovery (see Strict Addresses).

Different Chain (Different VM)

This is not possible — deposit address formats differ across VM types (e.g., EVM vs Solana vs Bitcoin), so a user cannot accidentally send to the wrong VM.

Strict Addresses

Strict addresses are bound to the original order. The handling is narrower:
  • Exact amount — The fill proceeds using the original order.
  • Underpayment — The deposit fails and is refunded to refundTo. The fill does not proceed.
  • Overpayment — The fill proceeds for the originally quoted amount and the excess is returned to refundTo as a separate refund leg. The fill itself is never scaled up.
  • Wrong token or wrong chain — Not supported. Strict addresses do not have automatic wrong-token or wrong-chain recovery paths.
Open-ended mismatches often create a new requestId. Always track transactions by deposit address, not by requestId. See Tracking Transactions.

Refund Behavior

What happens when a deposit can’t be processed depends on the token type and the refundTo configuration.

Refund Flows

There are two distinct refund scenarios:
  1. Correct currency, fill failed (e.g., slippage, network issues) — If refundTo is set, the deposit is automatically refunded to that address, minus the cost of gas. No additional fees are taken.
  2. Wrong currency (non-solver token) — Not supported and not currently recoverable.
If a wrong solver currency was sent and the deposit didn’t auto-resolve, users can recover it at relay.link/withdraw.
A same-VM wrong-chain deposit to an open or custodial address is recoverable but may not re-route or refund on its own. Trigger reindexing with targetChainId set to the chain the funds landed on. Strict addresses have no automatic wrong-chain recovery.

refundTo Configuration

If users may send from a centralized exchange, do not set refundTo as the user’s address — neither an explicit user address you don’t control nor the native-currency-address auto-refund opt-in — the sender address will be the exchange’s hot wallet, not the user’s. Use an app-controlled address instead so your support team can handle the last mile. If you still want depositor auto-detection for self-custodied senders, pair the auto-refund opt-in with a recoveryAddress as the fallback.
When auto-refund to the original depositor is triggered, the request’s outTxs will contain two refund transactions. The first transaction is the solver-to-depositor transfer that actually returns funds to the depositor — this is the one to track from your integration. The second is an internal protocol-settlement transaction that does not move user funds and can be ignored by integrators.

recoveryAddress

recoveryAddress is for cases where Relay cannot auto-refund. It should be an integrator-controlled EOA on the origin chain. Use recoveryAddress when an integrator wants to use Relay’s depositor detection, but also needs a fallback recovery path if the detected depositor cannot safely receive an automatic refund. This is most relevant for deposits from custodial sources like centralized exchanges, unsupported currency deposits, or blocked depositor addresses. When recoveryAddress is supplied:
  • Relay still attempts to auto-refund where possible.
  • If Relay cannot auto-refund, the integrator can recover funds using recoveryAddress.
  • Existing refundTo behavior remains unchanged for flows that do not supply recoveryAddress.
recoveryAddress never receives refunds — it is only used to withdraw funds from the depository contract in the case that we cannot fill or refund.
Constraints:
  • Requires useDepositAddress: true — the request is rejected otherwise.
  • Must be a valid address on the origin chain and cannot be the origin chain’s native-currency address.
  • Strict deposit addresses still require refundTo even when recoveryAddress is set.
  • Open deposit addresses: Set refundTo to the user’s address for automatic refunds.
  • Strict deposit addresses: Always set refundTo. If the sender is unknown (e.g., CEX withdrawal), use an app-controlled address so your support team can manage refunds.
  • Auto-refund to depositor: When users deposit from wallets they control, you can pass refundTo as the origin chain’s native-currency address (EVM 0x0000000000000000000000000000000000000000, Bitcoin bc1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmql8k8, Solana 11111111111111111111111111111111) to refund to the original depositor automatically. The first of the two resulting outTxs is the transfer to the depositor — track that one for refund delivery. Avoid this when deposits may originate from a centralized exchange, or pair it with a recoveryAddress so funds Relay cannot safely auto-refund remain recoverable.

Tracking Transactions

Querying by Deposit Address

The most reliable way to track deposit address transactions is to poll the Get Requests API using the depositAddress query parameter:

Handling Quote Regeneration

When a quote is regenerated (different amount, token, or chain), a new requestId may be generated. Use includeChildRequests=true to find all related requests, including regenerated ones:
When a regeneration happens, the original request stays under its original requestId and public status while the actual sweep and fill move under the regenerated request. To follow the handoff directly, read the top-level supersededByRequestId on the original request in GET /requests/v3 (or data.supersededByRequestId on the legacy GET /requests/v2) — it returns the regenerated requestId that now owns the fill lifecycle.
Use supersededByRequestId when you have the original requestId and want a direct pointer to the request that owns the fill. Use includeChildRequests=true when you want every related request in one response.

Request-Level Status

Once you have a requestId, you can use Get Status for detailed status polling. To avoid polling, you can also configure a webhook — webhook payloads include a depositAddress object for deposit address requests.

Reindexing Stuck Deposits

Relay’s background monitor only checks the originally quoted input token. If a user sent a different supported (solver) token, the monitor may not detect it automatically. Use the Deposit Address Reindex endpoint to trigger on-demand re-detection — it checks every solver-depositable currency on the chain and queues a sweep for any non-zero balances.
chainId is the chain the deposit address was originally registered on. Pass targetChainId to run the reindex on a different chain — useful when funds were sent to the right address but on the wrong chain (e.g. the address was registered for Arbitrum but funds landed on Ethereum). This is the chain being reindexed, not the destination chain of the original quote. Pass currency to scope the reindex to a single currency address instead of iterating every depositable currency. Any currency registered with Relay on the target chain is accepted — including currencies outside the standard solver-depositable list (e.g. a HyperCore-registered token when the deposit address was created for HyperEVM).
The deposit transaction hash cannot be used to look up the status of a deposit address bridge. Always use the deposit address itself or the requestId to track status.

Caveats

Gas Overhead

Deposit addresses add gas overhead compared to direct calldata execution because Relay must sweep funds from the deposit address: For very small amounts, the gas overhead may make deposit addresses less cost-effective than direct calldata execution.

Supported Currencies

Only tokens listed as solver currencies for a given chain can be processed by deposit addresses. The input token must be a solver-depositable currency for the requested route. The destination token can differ and be completed through a destination-side swap — in that case, refundTo is required. Relay treats certain tokens as equivalent within currency groups (e.g., ETH and WETH) — depositing any token in a group triggers the same fill behavior. The table below is loaded live from the chains API. Each chain’s solverCurrencies array is the authoritative source for which tokens are supported.
Non-solver tokens and NFTs sent to deposit addresses are not recoverable through normal processes. Always verify the token is a solver currency before depositing.

Chain-Specific Notes

  • Bitcoin — Standard deposits are processed after 1 block confirmation. High-value deposits (above the per-currency threshold) wait for 2 block confirmations to reduce reorg risk. Deposits are detected via mempool monitoring but only acted on after the applicable confirmation count.
  • Solana — Supports SPL tokens through the protocol deposit method. Native SOL and SPL tokens like USDC are solver currencies on Solana.
  • Hyperliquid — Uses bridged USDC (USDC.e) with different decimal precision than native USDC on other chains. Be aware of decimal mismatches when computing amounts.

Other Limitations

  • Calldata execution on destination is not allowed.