Skip to main content
The headless core gives you Trustware’s routing and transaction logic without the prebuilt widget. You build your own UI and the SDK handles route construction, quotes, wallet calls, settlement, and transaction submission.

When to use this pattern

Choose this pattern when:
  • you want full control over the deposit UI
  • your design system requires a custom amount entry or confirmation flow
  • you want to embed deposit logic into an existing interface without a floating widget
  • you need a flow the widget does not provide, such as withdrawing from an embedded wallet
  • you need to deposit into a contract on the destination chain, such as depositing into a vault destination
If you want built-in wallet selection, token picker, amount entry, and confirmation screens, use the drop-in widget instead.

Setup

The headless core still requires TrustwareProvider for config context. Mount it once near the root of your app; you do not need to render TrustwareWidget.
Then import the core in any component or hook:

Wallet setup

You have two options for attaching a wallet to the headless core.

Bring your own wallet

Adapt an existing Wagmi wallet client into Trustware using useWallet:

Let Trustware detect wallets

If you do not manage wallet state, call autoDetect once at startup:

Core operations

1. Build a route

buildRoute constructs a route. Use this when you want to inspect route details before asking the user to confirm.
BuildRouteBody shape: (? indicates optional)
hooks.postHook executes a contract call on the destination chain once routed funds arrive, instead of paying the destination token to toAddress. It requires SDK 1.1.10 or later, is fully optional, and omitting hooks leaves route behavior unchanged. See PostHookRequest for the field reference and vault destinations for the end-to-end flow.

2. Inspect route details

The returned BuildRouteResult contains exchange rate information you can display to the user before they confirm.
BuildRouteResult shape:
The txReq type is not exported under its own name. Refer to it as BuildRouteResult["txReq"] rather than importing a named type.

3. Sign and send a route

sendRouteTransaction switches the wallet to the route’s chain if needed, grants any ERC-20 allowance the route requires, and then sends the route transaction. It returns the source transaction hash.
On EVM routes, allowance handling is automatic. When the route response includes route.execution.approvals, the SDK reads the current allowance, submits an approval for the exact amount when one is missing, waits for that approval to confirm, and only then requests the route signature. Plan your UI around two consequences:
  • The user can see more than one wallet prompt for a single deposit. An ERC-20 source asset usually means an approval prompt followed by the deposit prompt.
  • Each approval must confirm on chain before the route signature is requested, so the call can stay pending for a minute or more.
Approvals are always for the exact amount required, never an unlimited allowance. They are skipped when the route carries valid gas sponsorship. If you sign transactions yourself, process route.execution.approvals in the same order: read, approve, wait, then send.

4. Run the full flow

runTopUp handles route construction, wallet approval, transaction submission, and status polling in a single call. Use this when you want the SDK to orchestrate the full deposit path. Only fromAmount is required; every other field is optional and falls back to the corresponding value in your TrustwareConfigOptions.routes config when omitted.
Full signature:

Working with chains and tokens

The same chain and token discovery the widget uses internally is available to your own UI through three helpers on the Trustware facade. All three respect the active TrustwareProvider config and reuse its cache.

Trustware.useChains()

React hook that returns the supported chain list, split into popular and other groups, with loading and error state. Use it to drive your own chain selector.

Trustware.useTokens(chainId)

React hook that returns the token list for a given chain with built-in pagination and search. Pass null to skip fetching.

Trustware.validateAddressForChain(address, chain)

Synchronous helper that returns { isValid: boolean; error?: string } for the given destination address against the rules of the selected chain (EVM checksum, Solana base58, Bitcoin, Cosmos prefixes, etc.). Use it for live form validation.

Lifecycle callbacks

TrustwareConfigOptions exposes three optional callbacks you can pass alongside your routes config to react to SDK activity:
  • onEvent fires for every lifecycle event the SDK emits. It receives the full TrustwareEvent discriminated union, which you can narrow by type (transaction_started, transaction_success, wallet_connected, etc.).
  • onSuccess fires once when a deposit settles on the destination chain. It receives the resolved Transaction with destTxHash populated.
  • onError fires for any TrustwareError thrown during a route or transaction operation. Use it as a single place to log errors or push them into your UI state. RateLimitError extends native Error (not TrustwareError) and does not flow through this callback; handle it with the imperative try/catch pattern below.
onError runs in addition to any try/catch you wrap around individual core calls; see Error handling below for the imperative pattern. See lifecycle events for the full list of event types.

Error handling

Wrap core calls in try/catch. Import RateLimitError to handle rate-limiting specifically:

When to use the widget instead

If you want built-in wallet selection, token picker, amount input, and processing/success screens, the widget patterns require significantly less code. The headless core is best when your UI requirements cannot be met by the prebuilt widget.