Quote and Execute Symbiosis Routes
Quote an exact-input Symbiosis route, review it with the user, and execute it from an EVM source account.
Community modules are developed and maintained independently by third-party contributors.
Tether and the WDK Team do not endorse or assume responsibility for their code, security, or maintenance. Use your own judgment and proceed at your own risk.
This guide covers route options, quotes, user review, EVM execution, and fee caps.
Prerequisites
Complete Get Started: a signing account bound to a SymbiosisProtocol instance whose chain matches the account's network.
Build exact-input route options
The same options object drives both the quote and the execution:
const options = {
fromToken: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
toToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
toChain: 'Arbitrum One',
recipient: '0xRecipient...',
fromTokenAmount: 100_000_000n,
slippage: 0.02
}fromTokenAmountis the exact input in source-token base units.100_000_000nis 100 USDT with 6 decimals. Missing, zero, negative, and non-integer values throwValidationErrorbefore an API request.slippageis a decimal;0.02means 2% and is converted to 200 basis points for the provider. When omitted,defaultSlippageapplies.toChaindefaults to the configured source chain, which produces a same-chain swap.recipientdefaults to the bound account's address.
Only exact-input routes are supported. Passing toTokenAmount throws ExactOutNotSupportedError; there is no way to request an exact destination amount.
Quote the route
quoteSwidge() performs no wallet write and returns an indicative result:
const quote = await symbiosis.quoteSwidge(options)
console.log('Expected output:', quote.toTokenAmount)
console.log('Minimum output:', quote.toTokenAmountMin)
console.log('Estimated seconds:', quote.estimatedDuration)
console.log('Fees:', quote.fees)Quoted fees are already reflected in toTokenAmount; do not subtract them again. The provider does not return a quote expiry, so treat the numbers as a snapshot rather than a reservation.
Review before execution
Show the user the source token and amount, the destination token and chain, the recipient, the expected and minimum output, the itemized fees, and the selected slippage.
swidge() does not consume the earlier quote. It requests a fresh execution response and proceeds internally to fee checks, approvals, and the source broadcast without exposing that response for a second confirmation. Fee caps limit only the mapped provider fees in that fresh response; they do not bind its output amount, spender, payload, deposit address, or wallet chain fee.
Execute an EVM route
Call swidge() only after the user confirms:
const result = await symbiosis.swidge(options, {
maxProtocolFeeBps: 100
})
console.log('Operation ID:', result.id)
console.log('Source transaction:', result.hash)
console.log('Recorded transactions:', result.transactions)For a non-native EVM input token the method:
- Reads the current allowance for the spender returned by the fresh execution response.
- Resets a non-zero insufficient allowance to zero first, as required by tokens such as USDT on Ethereum.
- Approves the exact input amount.
- Waits for each approval to mine (when the account supports receipt lookup) before broadcasting the route transaction.
If the allowance lookup fails, the module falls back to a direct approval without the reset; see Approval behavior for the full decision table.
Approval hashes are appended to result.transactions with type approval, followed by the source transaction with type source. The method returns after the source broadcast; destination settlement continues asynchronously. Track it with the returned result.id as described in Track Settlement.
Set skipApproval: true in the constructor config only when the host application manages allowance itself; the module then broadcasts the route transaction without checking allowance, and an insufficient allowance surfaces as an on-chain failure.
Cap provider fees
maxProtocolFeeBps bounds the fees mapped as protocol in basis points of the input amount, checked against the fresh execution response before any wallet write:
const symbiosis = new SymbiosisProtocol(account, {
chain: 'Ethereum',
maxProtocolFeeBps: 100
})
await symbiosis.swidge(options, { maxProtocolFeeBps: 75 })A fee whose description is exactly Partner fee maps to affiliate and is not constrained by either cap. No fee maps to network in this release, so maxNetworkFeeBps does not bound the wallet transaction's own chain fee. When the cap is exceeded, swidge() throws FeeLimitExceededError before touching the wallet.
Next steps
Poll the operation in Track Settlement, or branch on the typed error family in Handle Errors.