What this looks like on Ethereum
- Source: the intent transaction is an ordinary Ethereum transaction signed by the user’s wallet.
ChainKeys.ETHEREUM_MAINNET('ethereum') identifies the network everywhere in the SDK. - Reach: any solver-compatible asset on any SODAX network is a valid destination, 166 assets today. The on-Ethereum asset list only bounds what users hold on Ethereum itself, not what they can swap into.
- Tokens: ETH plus standard ERC-20s. Read addresses and decimals from the SDK config; never hard-code them.
- Settlement: output lands on the destination network at
dstAddress. Swaps into Ethereum settle as ordinary ETH or ERC-20 balances at the recipient address.
Approvals
swap() does not approve the input token for you. ETH is the native token and needs no approval. Every ERC-20 does: SODAX’s asset manager pulls it through the ERC-20 interface, so check the allowance first and approve when it falls short.
params is the same intent params object you pass to swap().
USDT approvals
Ethereum USDT comes from the 2017 TetherToken contract, which rejects an allowance change from one non-zero value to another. A wallet that already holds a USDT allowance for the asset manager, smaller than the new amount, cannot approve directly: the allowance has to go to zero first. The SDK handles this for you. It simulates the approval before sending, and when the simulation shows a reset is needed, the signedapprove call sends approve(0), waits for it to be mined, then sends the real approval. The user signs twice, and approve still resolves to one hash, the last transaction’s. If your UI shows an approving state, expect a second wallet prompt on USDT. Detection is by simulation, not a token list, so any other token with the same behavior is handled the same way.
If you build unsigned transactions instead (raw: true), approve returns only one transaction. Use buildApproveTxs, which returns the reset when one is needed:
sendAndWait stands for your own signer: broadcast the transaction and wait for its receipt. resetTx is absent for every other token and for a wallet with no allowance yet, so the common path is a single transaction.
Quoting
The solver API quotes both directions:getQuote deducts any configured partner fee before quoting, so quoted_amount is the net output the user actually receives.
Fees
Using SODAX is free to integrate. Two fees can apply to a trade:- Base fee: a fixed 0.1% of the input, taken by the protocol. Not configurable; compute it ahead of time with
getSolverFee(inputAmount). - Your fee: optional platform fee on top, set by you and paid to you. It is the only fee you control. Configure it at SDK setup and check it with
getPartnerFee(inputAmount). See Monetize SDK.
raw: true and estimate it:
Executing
Preferswap(). It creates the intent on Ethereum, verifies it landed, submits it to the relay, waits for the packet on the hub, and notifies the solver. The Quickstart has the complete call. Track progress with getStatus(request), and cancel unfilled intents with cancelIntent. Limit orders (intents without deadlines) work from Ethereum too, via createLimitOrder.
Orchestrating manually with createIntent and submitIntent works the same as on any EVM network: Ethereum intents need no relay extra data.
Error handling
Operations returnResult<T> instead of throwing. The core methods (swap, createIntent, postExecution) return a typed SodaxError union you can switch on by error.code.
Full reference, including raw mode, limit orders, cancellation, and the complete error-code table: Swaps.