Skip to content
Poolix

Integration

Poolix’s service layer is plain TypeScript over viem, with no React dependency. The same functions that drive the interface can be imported directly.

Connect a client

TypeScript
import { createPublicClient, http } from "viem";
import { resolvePoolixConfig } from "@/config/resolve";
import { createUniswapV2Source } from "@/services/liquidity/uniswap-v2/adapter";

const config = resolvePoolixConfig({
  network: "mainnet",
  rpcUrl: undefined,
  uniswapV2Factory: undefined,
  uniswapV2Router: undefined,
});

const client = createPublicClient({
  transport: http(config.rpcUrl, { batch: { wait: 16 } }),
});

const source = createUniswapV2Source(client, config);

The transport batches JSON-RPC requests rather than using a multicall contract, because Robinhood Chain’s L2 Multicall has no aggregate3.

Quote a swap

quoteExactIn ranks the direct pair against the WETH-bridged route, then asks the router to price the winner. It resolves to null when no route exists — it never returns an estimate it could not confirm onchain.

TypeScript
const quote = await source.quoteExactIn({
  currencyIn: { kind: "native", symbol: "ETH", decimals: 18 },
  currencyOut: {
    kind: "erc20",
    address: "0x…",
    symbol: "TOKEN",
    name: "Token",
    decimals: 18,
  },
  amountIn: 10n ** 16n,  // 0.01 ETH
  slippageBps: 50,       // 0.50%
});

if (quote === null) {
  // No pool with liquidity for this pair.
} else {
  quote.amountOut;        // bigint, from router.getAmountsOut
  quote.minimumAmountOut; // amountOut floored by slippageBps
  quote.priceImpactBps;   // excludes the LP fee, which is shown separately
  quote.route;            // [tokenIn, …, tokenOut]
  quote.approvalSpender;  // null when the input is native
}

Build the transaction

buildSwap returns calldata rather than sending anything, so the caller decides how it is signed. Stamp the deadline at the moment of sending, not when quoting.

TypeScript
const call = source.buildSwap({
  quote,
  recipient: account,
  deadline: BigInt(Math.floor(Date.now() / 1000) + 20 * 60),
});

// call.to, call.data, call.value — pass to your signer.

Simulate before you prompt a wallet

Poolix runs eth_call against the prepared transaction first. A revert caught there surfaces the real reason — slippage, an expired deadline, missing liquidity — instead of an opaque wallet estimation failure.

Derive a pair address

Pair addresses are deterministic, so a lookup costs nothing. This derivation is asserted against live pairs by npm run verify:chain.

TypeScript
import { computePairAddress } from "@/services/liquidity/uniswap-v2/pair";

const pair = computePairAddress(factory, tokenA, tokenB);
// Argument order does not matter; the result is checksummed.

Environment

.env.local
NEXT_PUBLIC_POOLIX_NETWORK=mainnet

# Browser RPC. Visible to every visitor, so never a keyed URL.
NEXT_PUBLIC_RPC_URL=

# Server-only RPC, used by route handlers and the pool scan.
# A keyed provider widens the scan and enables archive queries.
RPC_URL=

# How many of the newest pairs the pool scan looks at.
POOLIX_POOL_SCAN_WINDOW=400

Chain ID, explorer, WETH and the Uniswap deployment are not environment variables. They are verified constants; only values that genuinely vary per deployment live in the environment. Default RPC today: https://robinhood-rpc.publicnode.com.