- Encode the destination contract call with viem or ethers
Trustware.buildRoute()withhooks.postHookto get a signable route- Show the user the final route estimate
Trustware.sendRouteTransaction()to sign and send on the source chainTrustware.submitReceipt()andTrustware.pollStatus()to track settlement- Read the destination contract to confirm the deposit landed
Requires
@trustware/sdk 1.1.10 or later, through the
headless core or the
REST API. The widget and Trustware.runTopUp() do not
accept hooks.When to use this pattern
Choose this pattern when:- your product holds user funds in a vault, staking contract, or margin account and you want deposits to arrive already credited
- your users hold assets on chains your contract is not deployed on
- you want to remove the step where a user has to approve and deposit on the destination chain themselves
Trustware.setDestinationAddress(). A posthook is only for running a contract call.
Requirements and support
fundAmount is the destination-token amount for the contract call. It is unrelated to fixedFromAmount, which locks the widget’s source USD amount; see fixed deposit amounts.
Destination contract calls are an EVM-only capability. postHook.target must be a valid EVM address, and the destination chain must be an EVM chain.
Some capabilities depend on which liquidity provider resolves the route.
How the flow works
The user signs one route transaction on the source chain, plus a source token approval if the source asset is an ERC-20 without sufficient allowance. The provider then executes your call on the destination chain, funded with the destination asset. There is no second signature. The destination call is executed by the provider, not by the user’s wallet and not by a Trustware contract. Trustware builds and tracks the route; it never holds the funds. The destination call is a separate on-chain execution, so a route can move value and still have the call fail. There is no destination-call status field, so confirm the route reached a terminalsuccess status and then read the destination contract, as in steps 5 and 6.
1. Encode the destination call
Encode the function you want to run on the destination chain. This example uses viem.depositNativeFor(address) and nativeBalanceOf(address) are illustrative.
Substitute your own deposit function, balance accessor, and ABI. If your deposit
function takes an amount argument, encode the same value you pass as
fundAmount, or the call and the funds disagree.2. Build the route with a destination posthook
Pass the encoded call ashooks.postHook. Everything outside hooks is a normal route request.
hooks is optional and additive. Omit it and buildRoute behaves exactly as it did before 1.1.10.
Posthook fields
3. Review the final route estimate
Build the route withhooks attached before the user confirms, and show that route’s estimate. A quote taken without hooks is not execution truth: a destination call changes gas and can change the selected provider.
fundAmount you encoded. If it does not, lower fundAmount, raise fromAmount, or rebuild the route.
4. Sign and send the source transaction
sendRouteTransaction switches the wallet to the source chain if needed, grants any source token allowance the route requires, then sends the route transaction. An ERC-20 source asset can mean an approval prompt before the deposit prompt, so plan for more than one signature. See source token approvals.
5. Submit the receipt and poll status
6. Verify the deposit landed
Read your own contract before you build the route and again after settlement, so you are asserting a change rather than an absolute value.finalStatus.destTxHash and finalStatus.toChainTxUrl give you the destination-chain execution to inspect or to attach to a support request alongside route.intentId.
finalStatus.toAmountWei reports the destination amount, but treat it as an estimate unless finalStatus.landed_amount_verified is true. That flag means Trustware read the amount from the destination chain rather than carrying forward a pre-trade quote. Check it before crediting a user or triggering anything automatic.
That is the primary recipe: a predetermined destination-token amount funding a
native-value call. For ERC-20 funding, provider-patched landed amounts, fallback
addresses, deposit-address routes, source token approvals, and the posthook and
approval errors to handle, see
destination call options.
Security considerations
- You own the calldata. Trustware encodes nothing on your behalf. Build
callDatafrom an ABI you control, on your own backend or from a constant in your app, never from unvalidated user input. - Pin
target. Treat the destination contract address as configuration, not something a client can choose. A posthook calls whatever address you give it. - Keep the encoded amount and the funding amount in agreement. If your function takes an amount argument and you are not using dynamic landed-balance mode, encode the same value you pass as
fundAmount. - Do not treat a settled route as a credited deposit. Read your own contract, as in step 6.
- Non-custodial throughout. Trustware never holds the funds and never signs on the user’s behalf. The route transaction is signed by the user’s wallet and the destination call is executed by the provider.
Complete example
Related reference
Destination call options
ERC-20 destination calls, dynamic landed-balance mode, fallback, deposit-address routes, and error handling.
Headless core
The full
Trustware namespace API, including buildRoute, sendRouteTransaction, and pollStatus.POST /route
The REST request and response schema, including
hooks.postHook and route.execution.approvals.TypeScript types
PostHookRequest, RouteApproval, RoutePlan, and RouteEstimate.Error handling
Posthook validation errors, approval failures, and the imperative try/catch pattern.
