Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.trustware.io/llms.txt

Use this file to discover all available pages before exploring further.

The headless core gives you Trustware’s routing and transaction logic without the prebuilt widget. You build your own UI — the SDK handles route construction, quotes, wallet calls, 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
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.
import { TrustwareProvider, type TrustwareConfigOptions } from "@trustware/sdk";

const trustwareConfig = {
  apiKey: process.env.NEXT_PUBLIC_TRUSTWARE_API_KEY!,
  routes: {
    toChain: "8453",
    toToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
    defaultSlippage: 1,
    options: {
      routeRefreshMs: 15000,
    },
  },
} satisfies TrustwareConfigOptions;

export function App() {
  return (
    <TrustwareProvider config={trustwareConfig}>
      {/* your custom UI goes here */}
    </TrustwareProvider>
  );
}
Then import the core in any component or hook:
import { Trustware } from "@trustware/sdk";

Wallet setup

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

Bring your own wallet

Bridge an existing Wagmi wallet client into Trustware using useWallet:
import { useEffect } from "react";
import { useWalletClient } from "wagmi";
import { useWagmi } from "@trustware/sdk/wallet";
import { Trustware } from "@trustware/sdk";

export function useTrustwareWalletBridge() {
  const { data } = useWalletClient();

  useEffect(() => {
    if (!data) return;
    Trustware.useWallet(useWagmi(data));
  }, [data]);
}

Let Trustware detect wallets

If you do not manage wallet state, call autoDetect once at startup:
await Trustware.autoDetect();

Core operations

1. Build a route

buildRoute constructs a cross-chain route. Use this when you want to inspect route details before asking the user to confirm.
const route = await Trustware.buildRoute({
  fromChain: "1",
  toChain: "8453",
  fromToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  toToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
  fromAmount: "1000000", // amount in token's smallest unit
  fromAddress: await Trustware.getAddress(),
  toAddress: "0xDestination...",
});

2. Inspect route details

The returned BuildRouteResult contains exchange rate information you can display to the user before they confirm.
const route = await Trustware.buildRoute({
  fromChain: "1",
  toChain: "8453",
  fromToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  toToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
  fromAmount: "1000000",
  fromAddress: await Trustware.getAddress(),
  toAddress: "0xDestination...",
});

// Show the user what they will receive before confirming
console.log(route.finalExchangeRate.fromAmountUSD);
console.log(route.finalExchangeRate.toAmountMinUSD);
BuildRouteResult shape:
type BuildRouteResult = {
  intentId: string;              // pass to receipt and status calls
  txReq: TxRequest;              // transaction object to sign and broadcast
  actions: unknown[];
  finalExchangeRate: {
    fromAmountUSD?: string;
    toAmountMinUSD?: string;
  };
  route: RoutePlan | undefined;
};

3. 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.
const result = await Trustware.runTopUp({
  fromAmount: "1000000", // required — amount in token's smallest unit
});

if (result.status === "success") {
  console.log("Deposit complete:", result.destTxHash);
}
Full signature:
Trustware.runTopUp(params: {
  fromAmount: string | number;  // required
  fromChain?: string;            // overrides config.routes.fromChain
  toChain?: string;              // overrides config.routes.toChain
  fromToken?: string;            // overrides config.routes.fromToken
  toToken?: string;              // overrides config.routes.toToken
  toAddress?: string;            // overrides config.routes.toAddress
});

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.
import { Trustware } from "@trustware/sdk";

const useTrustwareChains = Trustware.useChains;

function ChainPicker() {
  const { popularChains, otherChains, chains, isLoading, error } =
    useTrustwareChains();

  if (isLoading) return <Spinner />;
  if (error) return <ErrorState message={error} />;
  return <ChainList chains={[...popularChains, ...otherChains]} />;
}

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.
const {
  filteredTokens,
  hasNextPage,
  isLoading,
  isLoadingMore,
  error,
  loadMore,
  searchQuery,
  setSearchQuery,
} = Trustware.useTokens(activeChain?.chainId ?? null);

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.
const validation = Trustware.validateAddressForChain(
  destinationAddress,
  activeChain,
);

if (!validation.isValid) {
  showError(validation.error);
}

Listening to events

Subscribe to events by passing onEvent in your config. This callback receives the full TrustwareEvent discriminated union, which you can narrow by type:
const config = {
  apiKey: process.env.NEXT_PUBLIC_TRUSTWARE_API_KEY!,
  routes: {
    toChain: "8453",
    toToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
  },
  onEvent: (event) => {
    if (event.type === "transaction_success") {
      console.log("TX hash:", event.txHash);
    }
    if (event.type === "wallet_connected") {
      console.log("Wallet:", event.address);
    }
  },
  onSuccess: (transaction) => {
    console.log("Deposit complete:", transaction.destTxHash);
  },
} satisfies TrustwareConfigOptions;
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:
import { RateLimitError, Trustware } from "@trustware/sdk";

try {
  const route = await Trustware.buildRoute({
    fromChain: "1",
    toChain: "8453",
    fromToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    toToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
    fromAmount: "1000000",
    fromAddress: await Trustware.getAddress(),
    toAddress: "0xDestination...",
  });
} catch (error) {
  if (error instanceof RateLimitError) {
    console.error("Rate limited", error.rateLimitInfo);
  }
}

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.
You wantUse
Full built-in UXDrop-in widget
Widget with your own walletHost wallet
Programmatic open/closeControlled widget
Custom UI, SDK routingHeadless core (this page)