SDK - @motoswap/sdk
TypeScript library of pure functions for routing, pricing, slippage, and APR math.
TypeScript library of pure functions used by the Motoswap frontend and backend. No network I/O, no wallet state. Feed it live values (reserves, prices, positions) and it returns the same math the app runs.
Full API reference: reference/sdk-full-inventory.
Availability
@motoswap/sdk is not published yet. It is not on any public registry and there is no install
path for an outside integrator. The samples on the SDK pages show call shapes; they cannot run
until the package is published.
Until then, treat this page and the
full inventory as the specification. Every function is a few
lines of bigint math with its formula written out, so you can port what you need. The
constant-product quote, the slippage floor and the price impact formula are all you need for a
single-pool swap. The guides inline this math or use viem directly, so they run without the package.
Modules
| Module | What it does | Key exports |
|---|---|---|
routing | Multi-hop swap routing (the same router the Motoswap app and API use). | bestRoute, bestSplitRoute, bestMidRate, pathMidRate, splitMidRate, getAmountsOut |
pricing | Price a token from stable-paired reserves. | priceFromReserves, toUsd |
slippage | Slippage floors, execution-vs-mid price impact. | amountOutMin, amountInMax, submitAmountOutMin, midPriceBps, executionPriceBps, priceImpactBps |
zap | Single-sided LP math. | optimalSwapInput, getAmountOut, sqrtBigInt |
apr | APR math for farm/pool + vault. | computeMasterChefPoolAPR, computeVaultAPR |
positions | Position aggregation + lock helpers. | effectiveStake, isUnlocked, summarizeUserPositions |
vanity | CREATE2 salt grinding for the retired TokenLauncher contract. Legacy; do not build against it. | grindVanitySalt |
Constants live in @motoswap/shared
@motoswap/sdk exports functions and types only - no constants. The
constants live in @motoswap/shared:
SWAP_FEE_BPS = 30n- per-pool V2 fee (0.30%). Prefer readingfactory.swapFeeBps()live; the constant is the shipped default.BLOCKS_PER_YEAR- for APR annualization.
(VAULT_IDS / VAULT_CONFIG still exist in @motoswap/shared. Their
multipliers are static values: MotoStaking holds one position per wallet with
a lock option 0 to 3, and the source of truth is
MotoStaking.boostBps(durationOption), the extra on top of a 1x base, which
governance can change. Do not build against the constants.)
Typical integrator recipe
Call shapes, with real reserves so you can check a port of the math against the printed values
(75871730613401515247916n 6n 75492371960334507671676n).
import { bestRoute, amountOutMin, priceImpactBps, type RoutePair } from "@motoswap/sdk";
const WETH = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
const MOTO = "0xbd965230588eaa536de6aa45e8ebbc01638535e0";
// Reserves you read yourself with getReserves(), as bigint.
const pairs: RoutePair[] = [
{ token0: MOTO, token1: WETH, reserve0: 133_292_018_598_175_373_111_408_005n, reserve1: 175_053_998_838_797_275_747n },
];
const amountIn = 10n ** 17n; // 0.1 WETH
const feeBps = 30n; // the pool's LP fee: factory.swapFeeBps(), or 30 on Uniswap V2
// 1. Quote a multi-hop trade.
const route = bestRoute(WETH, MOTO, pairs, amountIn, 2, feeBps);
if (!route) throw new Error("no route");
// 2. Show price impact for the first hop. feeBps is required.
const impact = priceImpactBps({
amountIn,
reserveIn: pairs[0].reserve1,
reserveOut: pairs[0].reserve0,
feeBps,
});
// 3. Apply user slippage tolerance for calldata.
const minOut = amountOutMin(route.amountOut, 50n); // 0.5%
console.log(route.amountOut, impact, minOut);Design principles
Pure & deterministic
No fetches, no wallet, no Math.random. Same inputs → same outputs. Safe to
run in a worker / edge / node.
bigint everywhere
Token amounts and USD (µ-USD) are bigints. Doubles are only for Percent /
Apr / Ratio (display).
One math implementation
bestRoute is the exact same function the Motoswap frontend uses. No
client/server drift.
Branded types
Address, Wei, Usd, Percent, Apr, Ratio, VaultId come from
@motoswap/shared/domain. Use them; the compiler catches shape errors
before runtime.
When to use REST vs SDK
- REST for historical windows, TVL, per-user metrics, leaderboard, the full pool universe. The backend has already computed these.
- SDK for live-quote math on reserves you fetched yourself (chain-direct), and for anything you want to render deterministically at pre-submit time (slippage floor, price impact, split fill, zap balance).