Read
Select a market, verify its binding and page the order book at one block.
Trade
Quote with the contract, approve the payment ceiling and submit a guarded fill.
Reconcile
Decode settlement events and re-read the order after confirmation.
Integration model
Each market is an independent proxy with its own order ids, roles, pause state, escrow and configuration. The identity of an order is therefore:Production registry
Network: Kaia mainnet · chain id 8217Public RPC:
https://public-en.node.kaia.ioExplorer:
https://kaiascan.io
All current markets use contract version 1.2.0 and the same quote token:
Addresses can change only through a new market or Lens deployment; runtime settings can change at
any time. Keep the registry versioned, but read pause, roles, minimums, fees, oracle status and
order data on-chain. Deployment details.
Obtain the ABI
The complete user-facing signatures and tuple layout are described in Contract API, and the full Swapper and Lens arrays are directly available on ABI JSON. For a client that discovers and takes orders, use the smaller copy-ready viem fragments below. They contain only the entries that flow needs. The maker extension appears in Maker integration.1. Connect and verify the selected market
The examples use viem, but the call sequence is library-independent.symbol() and decimals(). The registry value is useful for validation,
not a reason to run every token through JPYC’s 18-decimal conversion.
2. Read a consistent order book
PreferLens.openOrders to a separate openOrderIds → getOrders sequence. It returns each id and
its tuple atomically. Pin a block across pages so an order closing between page requests cannot move
an unseen id into a page already consumed.
Interpret an Order
If
sellToken == baseToken, the maker offers the regional stablecoin and the taker pays USDT. If
sellToken == quoteToken, the maker offers USDT and the taker pays the regional stablecoin.
Profitability is not a settlement guard. The contract accepts a valid in-band fixed order even when
its current taker edge is negative. If your product promises “best” or “profitable” orders, compute
and disclose that policy separately using the current oracle and the net output after fees.
3. Quote from what the taker wants to pay
Users commonly enter the token leaving their wallet, whilefillOrder takes the gross output
released from escrow. Convert the payment with previewFillForAmountIn:
sellAmountOut: gross escrow released and the second argument tofillOrder.actualAmountIn: what the taker currently pays. It can be below the typed amount when the order remainder caps the fill.fee: retained in the order’ssellToken.netOut = sellAmountOut - fee: what reaches the taker’s wallet.
previewFill and previewFillForAmountIn price a fill but do not prove that it can settle. A quote
can still be blocked by pause, expiry, size, role, balance or allowance. Use the Lens preflight and
a transaction simulation before opening the wallet.
Minimum-fill rule
A full fill ofsellRemaining is always allowed. Otherwise, while the order itself is at least
minOrderAmount[sellToken], sellAmountOut must also reach that minimum. The rule is about the
gross output in this fill, not the payment and not the remainder left behind.
4. Preflight, approve and fill
For Fixed orders,maxAmountIn should equal the quote because their rate cannot change. Pegged
orders reprice from the five-minute Orakl reference when mined, so add a user-selected tolerance:
maxAmountIn, not only the current Pegged quote. The
Lens checks the current amountIn; fillOrder is the component that enforces the final ceiling.
Lens FillProblem
Even
None is not a settlement guarantee: the order may change before inclusion, maxAmountIn
may be crossed, or a token transfer may be unavailable. Always simulate the exact
transaction and still handle an on-chain revert.
5. Confirm and reconcile the settlement
DecodeOrderFilled from the successful receipt. Its amounts are authoritative:
The maker’s average realised rate for a partially filled Pegged order must be reconstructed from
its
OrderFilled events because every fill can use a different oracle price. Sum raw amountIn and
gross amountOut first, then apply token decimals when displaying the ratio.
After the receipt, re-read getOrder(orderId). Do not predict whether the order is still open from
the submitted amount alone: another fill may have landed first.
For event indexing, scan from the market’s First event block in the registry, not genesis.
Use bounded block windows because public RPC providers limit eth_getLogs, persist the last
confirmed block, and make (chainId, proxy, txHash, logIndex) the event key. The events required to
reconstruct the book are documented in Events & errors.
Maker integration
Making is permissioned per market. CheckisMaker(account) before presenting an order form. Both
order types escrow sellToken, so approve the Swapper for sellAmount before creation.
Add these entries when supporting makers:
Fixed order
- Read
minOrderAmount(sellToken),maxOrderDuration,bandBpsand oracle freshness. - Convert both amounts using their own decimals.
- Call
isWithinBand(sellToken,sellAmount,buyToken,buyAmount). - Simulate and send
createOrder(address,uint256,address,uint256,uint64). - Decode
OrderCreatedfrom the receipt to obtain the finalorderId.
Oracle-pegged order
- Read
feeBps,bandBps,maxPremiumBps,maxOrderDurationand the current oracle state. - Ensure
premiumBps <= maxPremiumBps. - Read
currentRate = peggedRateNow(sellToken,premiumBps,feeBps). - Choose a floor tolerance no wider than
bandBpsand calculateminRate = currentRate × (10,000 − toleranceBps) / 10,000. - Simulate and send
createPeggedOrder(sellToken,sellAmount,premiumBps,minRate,expiry). - Decode
PeggedOrderCreatedfor theorderIdand terms accepted on-chain.
minRate is buy-token raw units per RATE_SCALE = 1e18 gross sell-token units. Do not construct it
from a formatted decimal string; use peggedRateNow and integer arithmetic. A Pegged fill requires
a fresh oracle and stops automatically below the maker’s floor. Cancellation remains available.
Makers cancel with cancelOrder(orderId). It works while paused and after expiry, and returns the
remaining escrow. Anyone may call expireOrders(ids) after deadlines; refunds still go only to the
makers.
Decode failures into user actions
Add the following directly provided error ABI when simulating or decoding:OrderNotOpen, OrderExpired, BelowMinFill,
ExceedsRemaining, SlippageExceeded, StaleOracle, OracleTwapUnavailable, BelowMakerFloor, EnforcedPause,
TakerNotWhitelisted and ERC-20 transfer failures. Refresh order and configuration state after any
revert instead of resubmitting the same arguments. Complete error meanings.
Integration checklist
- Assert Kaia chain id 8217 before every write.
- Treat
(chainId, proxy, orderId)as the order identity. - Verify
version,baseToken,quoteTokenandlens.swapperat startup. - Read token symbols and decimals from the actual token contracts.
- Pin one block across all order-book pages.
- Filter dynamically expired orders even if stored status is still
Open. - Use contract quotes for transaction arguments; local math is display-only.
- Remember that
sellAmountOutis gross and the taker receivessellAmountOut - fee. - For Pegged orders, approve and fund
maxAmountIn, not only the current quote. - Run Lens preflight, then simulate the exact write with the real account.
- Decode the receipt event and re-read the order after confirmation.
Related references
Contract API
User-facing callable signatures and tuple layout.
ABI JSON
Complete copy-ready Swapper and Lens ABI arrays.
The Lens
Atomic paging and guard-aware preflight behaviour.
Events & errors
Settlement logs and recoverable revert reasons.
Building an interface
UX rules once the direct contract integration is correct.

