Skip to main content

Quickstart

This guide will help you place your first order on Sera.

Prerequisites

  • An Ethereum wallet with Sepolia ETH
  • Some test tokens (available from Sepolia faucets)

Contract Addresses (Sepolia)

const SERA_CONTRACTS = {
  MARKET_ROUTER: "0x82bfe1b31b6c1c3d201a0256416a18d93331d99e",
  MARKET_FACTORY: "0xe54648526027e236604f0d91413a6aad3a80c01e"
};

Step 1: Approve Token Spending

Before placing an order, approve the Router to spend your tokens:
import { ethers } from "ethers";

const tokenAbi = ["function approve(address spender, uint256 amount) returns (bool)"];
const tokenContract = new ethers.Contract(tokenAddress, tokenAbi, signer);

// Approve max amount
await tokenContract.approve(
  SERA_CONTRACTS.MARKET_ROUTER,
  ethers.MaxUint256
);

Step 2: Place a Limit Order

Placing a Limit Bid (Buy Order)

const routerAbi = [
  "function limitBid((address market, uint64 deadline, address user, uint16 priceIndex, uint64 rawAmount, bool postOnly, bool useNative, uint256 baseAmount) params) payable returns (uint256)"
];

const router = new ethers.Contract(
  SERA_CONTRACTS.MARKET_ROUTER,
  routerAbi,
  signer
);

const params = {
  market: "0x...",              // Market address
  deadline: Math.floor(Date.now() / 1000) + 3600,  // 1 hour from now
  user: await signer.getAddress(),
  priceIndex: 6500,             // Price book index
  rawAmount: 1000000n,          // Quote amount in raw units
  postOnly: false,              // Set true to ensure no immediate fill
  useNative: false,             // Set true if using ETH
  baseAmount: 0n                // Not used for bids
};

const tx = await router.limitBid(params);
const receipt = await tx.wait();

console.log("Order placed! TX:", receipt.hash);

Placing a Limit Ask (Sell Order)

const params = {
  market: "0x...",
  deadline: Math.floor(Date.now() / 1000) + 3600,
  user: await signer.getAddress(),
  priceIndex: 6600,             // Price book index
  rawAmount: 0n,                // Not used for asks
  postOnly: false,
  useNative: false,
  baseAmount: 1000000000000000000n  // 1 token (18 decimals)
};

const tx = await router.limitAsk(params);

Step 3: Query Your Orders

Use the GraphQL API to check your orders:
query MyOrders($user: String!) {
  openOrders(
    where: { user: $user, status: "open" }
    orderBy: createdAt
    orderDirection: desc
  ) {
    id
    nftId
    market { id }
    priceIndex
    price
    isBid
    rawAmount
    baseAmount
    quoteAmount
    status
    createdAt
  }
}

Step 4: Claim Filled Orders

When your order is filled, claim your proceeds:
const routerAbi = [
  "function claim(uint64 deadline, (address market, (uint16 priceIndex, uint256 orderIndex, bool isBid)[] orderKeys)[] paramsList)"
];

const claimParams = [{
  market: "0x...",
  orderKeys: [{
    priceIndex: 6500,
    orderIndex: 42,
    isBid: true
  }]
}];

const tx = await router.claim(
  Math.floor(Date.now() / 1000) + 3600,
  claimParams
);

Next Steps