Skip to main content
Use TradeWidget props to control the widget’s runtime behavior, preselected assets, and available networks or tokens.

Runtime configuration

All runtime options live under the required config prop.
<TradeWidget
  config={{
    apiKey: "your-api-key",
    integrator: "my-dapp",
    fee: 0.03,
    slippage: 0.005,
    walletConnectProjectId: "your-walletconnect-project-id",
    termsUrl: "/legal/terms",
    privacyPolicyUrl: "/legal/privacy",
  }}
/>
FieldTypeDescription
apiUrlstringDelora API base used for /v1/chains, /v1/tokens, and /v1/quotes
apiKeystringOptional x-api-key header for Delora API requests
rpcUrlsTradeWidgetRpcUrlsByChainIdPer-chain RPC override map used for on-chain reads and execution helpers
integratorstringForwarded to quote requests
feenumberForwarded to quote requests. Valid range: 0..0.1
slippagenumberInitial slippage value. Valid range: 0..1
excludeBridgesstring[]Quote denylist for bridges
excludeExchangesstring[]Quote denylist for exchanges
assetBaseUrlstringBase URL for resolving relative token and network image paths
termsUrlstringURL used in the wallet consent footer
privacyPolicyUrlstringURL used in the wallet consent footer
walletConnectProjectIdstringWalletConnect Cloud project id for the EVM QR flow
If apiUrl is not set, the widget uses https://api.delora.build. If assetBaseUrl is not set, it falls back to config.apiUrl and then to the default Delora API base. If you pass apiKey from a browser application, that key is exposed to the client. Treat it as a public integration key, not as a secret. If termsUrl or privacyPolicyUrl is omitted, the connect modal falls back to:
  • ${window.location.origin}/documentation/termsofuse
  • ${window.location.origin}/documentation/privacypolicy
For third-party embeds, it is usually better to set both URLs explicitly.

Initial selections

You can preselect both networks and tokens.
<TradeWidget
  config={{}}
  initialSellNetworkId={1}
  initialBuyNetworkId={1000000001}
  initialSellToken={{
    chainId: 1,
    address: "0x0000000000000000000000000000000000000000",
  }}
  initialBuyToken={{
    chainId: 1000000001,
    address: "11111111111111111111111111111111",
  }}
/>
If an initial network or token is not available in loaded metadata, the widget reports it through onError. The same happens when a host-provided initial selection becomes invalid after filters are applied.

Lock tokens or networks

Use lock props when you want the host app to keep part of the form fixed.
<TradeWidget
  config={{}}
  initialBuyToken={{ chainId: 1, address: "0xA0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" }}
  lockBuyToken
/>
Supported lock props:
  • lockSellToken
  • lockBuyToken
  • lockSellNetwork
  • lockBuyNetwork
Behavior:
  • Locking a token also locks its network, because the token already implies a chain
  • Locking a network still allows token changes inside that network
  • Any lock disables the center “swap sides” button to avoid breaking host-provided constraints

Filter available networks and tokens

Use filters to restrict the sell and buy sides independently.
<TradeWidget
  config={{}}
  filters={{
    sell: {
      includeNetworkIds: [1, 8453],
      excludeTokens: [
        {
          chainId: 1,
          address: "0x0000000000000000000000000000000000000000",
        },
      ],
    },
    buy: {
      includeTokens: [
        {
          chainId: 1000000001,
          address: "11111111111111111111111111111111",
        },
      ],
    },
  }}
/>
Each side supports:
  • includeNetworkIds
  • excludeNetworkIds
  • includeTokens
  • excludeTokens
Important filter behavior:
  • Filters are applied per side, so sell and buy restrictions can be different
  • Networks that end up with no available tokens are removed automatically
  • Conflicting filters produce onError events with source: "configuration"
  • If no networks remain on a side after filtering, the widget enters a configuration error state

Custom token lookup

When a side does not use includeTokens, the token selector can import a token by contract or mint address if the address is valid for the active network. Imported tokens become part of the current browser session and can also be restored from persisted selection state. When includeTokens is set for a side, custom token import is disabled on that side.

Persistence

The widget stores the latest selected sell and buy networks and tokens in browser localStorage, so the next mount can restore the previous selection when the host app does not explicitly override it. Slippage and internal wallet choices are also persisted separately.

Quote lifecycle and refresh behavior

The widget does not request a quote on every keystroke. Quote loading has a small client-side lifecycle:
  • sell input is debounced by about 1 second before a quote request is sent
  • successful quotes auto-refresh every 60 seconds while the current selection stays stable
  • auto-refresh stops after 5 consecutive refresh cycles until the user changes the selection or amount
  • the quote countdown ring in the UI can also be clicked to request a manual refresh immediately
The widget also applies a local cooldown around quote refreshes to avoid excessive request loops:
  • more than 5 quote requests within 5 seconds starts a local cooldown
  • the cooldown lasts 5 seconds
  • during that window, the widget can emit onError({ source: "quote", statusCode: 429 }) even if the backend did not return 429
If you build analytics or retry logic around quote errors, treat this as widget-side throttling as well as possible API-side rate limiting.