Integrations

Pick your path

Five integration paths into Motoswap. Pick by what you are building, not by what you already know.

Motoswap looks like Uniswap V2 from a distance and behaves like it in the math. It does not behave like it at the entry points, and every integration that assumes a vanilla V2 fork breaks in the same three places. Pick your path below; each page front-loads the differences that matter for that job.

You are buildingPathWhat you'll usePage
An aggregator or routing engineQuote and execute through FeeRouterChain reads: the core router's getAmountsOut plus the fee legsAggregators
A trading or Telegram botOne swap loop: discover, quote, submit, confirmREST + chain writesTrading bots
A scanner, indexer, or analytics pipelineEvent streams and enumerationRPC logs + the event catalogScanners and indexers
An AI agent or data consumerREST only, no keys, ETag-cachedThe public APIAI agents
A listing site, chart site, or launch trackerDiscover coins, price a curve, catch graduationCurve reads + RESTListing moto.fun coins

The three facts every integrator needs

These are repeated on every path page because getting any one wrong ships a bug.

1. You cannot call the pair or the core router

MotoSwapPair.swap requires factory.swapAllowed(msg.sender), and so does every swap function on MotoSwapRouter02, the core router. Only the core router and the FeeRouter are admitted. FeeRouter is the only public way to swap, it is exact-input only, and it charges the full fee. There are no flash swaps. Liquidity functions and the read functions on the core router stay permissionless.

2. There is no hardcoded init code hash

Pairs are ERC-1967 beacon proxies. The CREATE2 init code hash depends on the deployment, so derive pair addresses with the hash from factory.pairCodeHash(), or skip derivation and read factory.getPair. A pasted Uniswap-style hex"96e8ac..." constant will compute addresses that do not exist.

3. The protocol fee lands on the quote leg, and the side moves

FeeRouter skims protocolFeeBps, plus creatorFeeBps for a token with an active creator, from whichever end of the path is the more senior quote asset (WETH > USDT > USDC > MOTO at launch settings), or from the first interior quote leg when neither endpoint is quote. Quote your trade on the wrong side and your amountOutMin is unfillable. The contract tells you the side: feeRouter.feeOnOutput(path) is a public view. There is no quote view; the recipe is on the aggregators page.

One deployment, three phases

The deployment has moved through three launch phases, and the contract set changed with them: prelaunch and vamp (the MOTO token and the launch farm, no DEX) came before dex, which is the live phase. GET /config is the single source of truth:

  • launchPhase is "prelaunch", "vamp", or "dex". It reads "dex": the Motoswap DEX contracts and the moto.fun curve are deployed. In "vamp" the MOTO token and the launch farm were deployed and the DEX contracts were not. Per-contract status is on addresses.
  • A zero address means that contract is unset for the current phase. Never hardcode addresses; they also change on redeploy.
  • The DEX surface documented across these pages (factory, FeeRouter, pools, Rakeback) is the dex phase. Branch on the phase before you route: during vamp (launch farming), trading ran on canonical Uniswap V2 (uniswapV2Router / uniswapV2Factory in the same response) and the launch farm accepted Uniswap LP.
const cfg = await fetch("https://api.motoswap.org/config")
  .then((r) => r.json());

if (cfg.launchPhase !== "dex") {
  // The Motoswap AMM is not the trading venue yet. cfg.addresses.feeRouter
  // is the zero address in this state. Do not take an address from anywhere else.
}

On this page