Skip to content

Smart Routing Address React UI

@zerodev/smart-routing-address-react-ui is a drop-in deposit UI for Smart Routing Address: a provider that creates and caches the routing address, a prebuilt deposit screen, and hooks for driving your own UI. To work with the address directly instead, use the SDK.

Installation

Install the package alongside its peer dependencies:

npm
npm i @zerodev/smart-routing-address-react-ui @zerodev/smart-routing-address viem

Import the stylesheet once at your app entry:

import '@zerodev/smart-routing-address-react-ui/styles.css'

Usage

Wrap the subtree with SmartRoutingAddressProvider and render <SmartRoutingAddress /> where the deposit UI should appear. On mount it creates the routing address for recipient and shows the deposit screen — the address with a QR code, the supported source tokens with fee estimates, and the deposits as they arrive. Past deposits and per-deposit transaction details are built-in steps.

import {
  SmartRoutingAddress,
  SmartRoutingAddressProvider,
} from '@zerodev/smart-routing-address-react-ui'
import { arbitrum } from 'viem/chains'
 
function DepositModal({ userAddress, onClose }) {
  return (
    <SmartRoutingAddressProvider config={{ targetChainId: arbitrum.id }}>
      <SmartRoutingAddress recipient={userAddress} onClose={onClose} />
    </SmartRoutingAddressProvider>
  )
}

The provider holds the config and the lazily created address; the screen is rendered inline by you, so it fits any surface — a modal, a drawer, or a page.

Config

SmartRoutingAddressProvider takes a single config:

OptionTypeDescription
targetChainIdnumberChain id where funds settle. Required.
projectIdstringZeroDev project id; when non-empty it is appended to the server URL for every request.
versionSmartRoutingAddressVersionSmart routing address version. Defaults to the latest stable.
actionsCreateSmartRoutingAddressParams['actions']Destination actions per token type. When omitted, funds are simply transferred to the recipient.
slippagenumberMax slippage in basis points (50 = 0.5%).
baseUrlstringOverride the smart routing address server root URL; the projectId is appended to it.
pollingIntervalnumberDeposit status polling interval in ms. Defaults to 5000.
estimatedFillTimeSecondsnumber | Record<number, number>Expected fill time in seconds, either a flat value or per source chain id.

Props

PropTypeDescription
recipientAddressRecipient the routing address is created for. Required.
onClose() => voidCalled when the top-right × button is clicked. Required.
onHelp() => voidCalled when the top-left ? button is clicked on the deposit step. When omitted, no help button is shown.
size'sm' | 'md' | 'lg'Card size.
classNamestringExtra classes for the card.

Hooks

Use the hooks to drive your own UI around — or instead of — the prebuilt screen. All of them read from SmartRoutingAddressProvider.

useSmartRoutingAddress

Access the address creation state from anywhere inside the provider:

const { addressState, ensureAddress, activeRoute } = useSmartRoutingAddress()
  • addressStateidle, loading, success (with the address and fee estimates), or error.
  • ensureAddress(recipient) — create the address if needed. Repeat calls for the same recipient reuse the same request, so calling it early — before the deposit UI is opened — starts the creation in the background and the screen opens with the address already there.
  • activeRoute — the source token, chain, and estimated fee the deposit UI currently shows; null until a selection exists. Useful for mirroring the selection elsewhere, such as analytics.

useDepositStatus

Polls the deposit status for an address and returns the current deposits — the same data the prebuilt screen shows. See Fetching Status for the underlying endpoint.

const { deposits, totalCount, hasLoaded, isLoading, error, refetch } =
  useDepositStatus({ address })

Polling runs while enabled (defaults to true) and address is set, at pollingInterval ms (defaults to 5000). refetch triggers an immediate poll — for a retry button after an error.

useNewDeposits

Filters a deposit list down to the deposits that arrived after the hook mounted — for "your deposit just landed" moments, ignoring history:

const newDeposits = useNewDeposits(deposits, hasLoaded)

The second argument marks when the baseline is taken: pass hasLoaded so pre-existing deposits from the first response don't count as new.