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);
}
}
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 want | Use |
|---|
| Full built-in UX | Drop-in widget |
| Widget with your own wallet | Host wallet |
| Programmatic open/close | Controlled widget |
| Custom UI, SDK routing | Headless core (this page) |