Skip to content

Xian DEX

xian-dex owns the DEX product: the canonical AMM contracts, the SnakX web frontend, and the hash-pinned contract bundle that downstream consumers deploy and verify against.

Contracts and frontend ship together as one tightly-coupled system. Operator automation that watches DEX events and reacts to them lives in xian-dex-automation, not in the product repo.

  • Owning repo: xian-dex
  • Contract bundle: xian-dex/contract-bundle.json
  • Bootstrap script: xian-dex/scripts/bootstrap_dex.py
  • Web app: SnakX (xian-dex/web/)
  • Companion service: xian-dex-automation

Lifecycle

  • Install phase: post-genesis
  • Included in genesis: no
  • Shipped with node image: no
  • Installer: xian-dex/scripts/bootstrap_dex.py

On-Chain Contracts

The bundle deploys four contracts in a pinned order:

ContractRole
con_pairspair factory, reserve bookkeeping, and LP mint/burn (total-supply) logic
con_dexrouter-style liquidity and swap entrypoints
con_dex_helperconvenience helper around the router for single-pair buy/sell flows
con_lp_tokenXSC-0001-compatible LP token template; each pair binds its own instance, which holds the per-account LP balances and approvals

Behavior worth knowing before integrating:

  • Pair balance crediting is router-driven; unsolicited token transfers into con_pairs are not attributed to any pair.
  • The standard swap fee path is 30 bps. Router-owner-approved signers can be flagged with set_zero_fee_trader(...) for zero-fee routing through the router; direct pair swaps stay on the standard fee path.
  • Factory-owner calls to con_pairs.enableFee(...) advance the protocol-fee epoch. Each pair establishes a fresh kLast baseline at its next liquidity event, so fee-off growth is not charged retroactively after re-enabling.
  • Every pair binds an XSC-0001 LP token contract. The factory owner registers the canonical LP token with registerLpToken(tokenA, tokenB, lpToken) before the pair exists. createPair(tokenA, tokenB) and router auto-creation during addLiquidity use the registered token; an optional lpToken argument is accepted only when it matches that registration.
  • An account's LP balance and allowances live in that pair's bound con_lp_token instance — read <lpToken>.balances / <lpToken>.approvals, not con_pairs. To remove liquidity, approve the router (con_dex) on the LP token (<lpToken>.approve(amount, to="con_dex")) and then call removeLiquidity(...). Resolve the per-pair LP token from con_pairs.pairs[pair_id, "lpToken"] (or con_pairs.lpTokenFor(pair_id)).
  • Fee-on-transfer tokens must be flagged with set_fee_on_transfer_token(...); plain swap routes reject flagged tokens and require the supporting-fee router path instead.
  • Tokens exposing get_metadata().precision route with precision-aware amount normalization.
  • con_dex_helper requires an explicit absolute deadline value.

SnakX Web Frontend

The SnakX frontend (web/, Vite + React + TypeScript) talks to the canonical contract names through @xian-tech/client for reads, consumes @xian-tech/dex for deterministic route and transaction planning, and uses the injected browser wallet provider for writes:

RoutePurpose
/swapquote and execute swaps with live price impact, slippage, deadline, and approval handling
/poolssearchable, sortable list of every pair with reserves and mid-prices
/pools/:idpair detail: live candlestick chart (1m–1W, built on the node's /dex_candles BDS endpoint), reserves, prices, LP balance, and pool share
/liquidityadd/remove liquidity, new-pair creation, router and LP-token approvals
/portfolioall token balances plus every LP position
bash
cd xian-dex/web
npm install
npm run dev

Installing The DEX

Products are installed from their owning repo after a chain exists. Validate the hash-pinned bundle with the generic xian-cli helper, then run the repo-owned bootstrap against a healthy node:

bash
uv run --project ../xian-cli xian contract bundle validate contract-bundle.json
XIAN_NODE_URL=http://127.0.0.1:26657 \
XIAN_WALLET_PRIVATE_KEY="$XIAN_PRIVATE_KEY" \
  uv run python scripts/bootstrap_dex.py --recipe local-demo

The core recipe deploys only the DEX contracts; local-demo also seeds a demo token and liquidity for local testing. For a stack-managed localnet, see Local DEX Bootstrap.

Both recipes use automatic simulation-based chi estimation by default. Use --chi-budget-mode fixed only when deliberately exercising the bundle's fixed deployment ceilings.

Reading DEX State From SDKs

For reusable TypeScript route enumeration, quotes, price impact, slippage, deadlines, and ordered approval/swap call plans, use the canonical Xian DEX v1 adapter from @xian-tech/dex. The package keeps protocol-neutral routing and constant-product math separate from this contract ABI. Callers supply current pair reserves and own RPC reads, simulation, signing, and submission. See xian-js for an example.

python
from xian_py import Xian

with Xian("http://127.0.0.1:26657") as client:
    pair = client.contract("con_pairs").call(
        "pairFor", tokenA="currency", tokenB="demo_token",
    )
    quote = client.contract("con_dex").call(
        "getAmountsOut", amountIn=10, src="currency", path=[pair],
    )
ts
import { XianClient } from "@xian-tech/client";

const client = new XianClient({ rpcUrl: "http://127.0.0.1:26657" });
const pair = await client.contract("con_pairs").call("pairFor", {
  tokenA: "currency",
  tokenB: "demo_token",
});

Agent Event Delivery

xian-mcp-server exposes two complementary DEX event tools:

  • dex_wait_live_event opens a bounded CometBFT WebSocket wait. It sees finalized events with low latency and does not require BDS. Start it before the activity being observed.
  • dex_list_events reads BDS-indexed history with an after_id cursor. Use it for replay, restart recovery, and reconciliation after a disconnect.

Live delivery is non-durable: an event finalized before subscription, during a disconnect, or while the MCP server is restarting can be missed. Agent services that must not miss events should use the live wait for responsiveness and the indexed cursor for recovery rather than treating either one as a replacement for the other.

Deployment Readiness

The package is a candidate deployment: its contracts and bootstrap are tested, but operators should complete independent review, workload testing, monitoring, and incident planning before using it with material value.