BLK ———

SDK reference

@quotient/sdk is a viem-based TypeScript package. It ships typed ABIs generated from the Foundry artifacts, the chain definitions, the quote codec, a maker client, swap helpers and subscriptions.

pnpm add @quotient/sdk viem

Chains

import { elysiumTestnet, elysiumMainnet, CANONICAL_TOKENS, NATIVE } from '@quotient/sdk';

Do not use viem's built-in elysiumTestnet from viem/chains: that is an unrelated network (chain ID 1338).

Quote codec

FunctionPurpose
encodeQuote(fields) / decodeQuote(slot)pack and unpack the 32-byte slot
quoteFromHuman({ price, decimals0, decimals1, bidBps, askBps, maxFill, … })build fields from human units
stampQuote(slot, l2Block)the slot as stored on-chain after inclusion
encodeBatch(entries) / decodeBatch(packed)the updateQuotes payload
midFromHuman(price, d0, d1) / midToHuman(mid, d0, d1)price conversions

Swap math

fillExactIn, fillExactOut and bestFill reproduce the hook's pricing in TypeScript, bit for bit. Use them to simulate before you send, or to price from indexed state without an RPC call.

const r = fillExactIn(makerState, true, 10n ** 18n, 1, currentBlock);
if (r.ok) console.log(r.amountOut, r.price, r.spread);

Maker client

import { makerClient } from '@quotient/sdk';

const m = makerClient({ wallet, publicClient, chainId: 99801 });
await m.registerMaker();
await m.setOperator(operator, true);
await m.deposit(poolId, currency, amount);
await m.withdraw(poolId, currency, amount, to);
await m.setPaused(true);

// operator side: build and send one batched update, nonce tracked locally
const q = m.quoteBatcher();
q.set(0, slotForPool0);
q.set(1, slotForPool1);
await q.flush({ priorityFeeWei: 1n });

Swaps

import { swapClient, encodeUniversalSwap } from '@quotient/sdk';

const s = swapClient({ wallet, publicClient, chainId: 99801 });
const quote = await s.quoteExactIn(poolKey, true, amountIn);
await s.swapExactIn(poolKey, true, amountIn, (quote.amountOut * 995n) / 1000n);

Subscriptions

Elysium has no public mempool, so the SDK watches blocks and logs:

import { watchHeads, watchVenueLogs } from '@quotient/sdk';

const stop = watchHeads(wsClient, (block) => { /* every ~100–150 ms */ });
const stopLogs = watchVenueLogs(publicClient, { hook, fromBlock }, (log) => { /* Filled, QuoteUpdated, … */ });

watchVenueLogs paginates backfills in windows that respect the provider's block-range limit (a 10,000-block eth_getLogs window is only ~17–40 minutes of Elysium time).

Data source

import { createDataSource } from '@quotient/sdk';
const ds = createDataSource({ indexerUrl });
const pools = await ds.pools();

createDataSource is the one place the SDK decides between live data and the synthetic venue used before contracts exist; callers never branch on it.