OddMaki
Customization

SDK Reference

TypeScript SDK for OddMaki — create venues, manage markets, place orders (including batch), resolve via UMA or Pyth, and build custom UIs.

The @oddmaki-protocol/sdk provides a typed TypeScript client for interacting with the OddMaki protocol on Base. It wraps the Diamond ABIs, handles decimal/tick conversions, and exposes subgraph queries through a single ergonomic client.

Installation

pnpm add @oddmaki-protocol/sdk viem

Peer dependencies: viem. The SDK is built on viem clients — bring your own PublicClient and WalletClient.

Client Setup

import { createOddMakiClient } from '@oddmaki-protocol/sdk';
import { baseSepolia } from 'viem/chains';
import { createPublicClient, createWalletClient, custom, http } from 'viem';

const publicClient = createPublicClient({
  chain: baseSepolia,
  transport: http(),
});

const walletClient = createWalletClient({
  chain: baseSepolia,
  transport: custom(window.ethereum!),
});

const client = createOddMakiClient({
  publicClient,
  walletClient,
  // chain defaults to baseSepolia; subgraph + diamond address pulled from config
});

The client exposes eight modules: venue, market, trade, priceMarket, accessControl, public, token, and uma.

Raw vs. Simple API

Most trading and market methods come in two flavours:

  • Raw — accepts bigint ticks and on-chain units. Use for backend bots or when you've already done the math.
  • Simple — accepts human strings like "0.80" for price, "100" for quantity, "24h" for expiry. The SDK parses them.

Prefer Simple variants when building UIs; prefer raw variants when precision matters and inputs are already canonical.

Modules

Venue

MethodDescription
client.venue.createVenue(params)Create a new venue
client.venue.updateVenue(params)Update name, metadata, access control, fee recipient
client.venue.updateFees(params)Update venue and creator fee bps
client.venue.updateOracleParams(params)Update UMA reward and min bond
client.venue.setPaused(venueId, paused)Pause or unpause a venue
client.venue.getVenue(venueId)Read full venue configuration
client.venue.canTrade(user, venueId)Check venue-level trading access
client.venue.canCreateMarket(user, venueId)Check venue-level creation access

Market

MethodDescription
client.market.createMarket(params)Create a binary market
client.market.createMarketGroup(params)Create a market group
client.market.addMarketToGroup(params)Add an outcome to a group
client.market.addPlaceholderMarkets(params)Reserve slots for late additions
client.market.activateMarketGroup(params)Activate a market group for trading
client.market.activatePlaceholder(params)Activate a placeholder with real data
client.market.convertPositions(params)NegRisk position conversion
client.market.pauseMarket(marketId)Pause an individual market (operator/creator)
client.market.unpauseMarket(marketId)Unpause an individual market
client.market.updateMarketTags(params)Update event-only tags
client.market.updateMarketMetadata(params)Update event-only metadata URI
client.market.updateMarketGroupTags(params)Update group tags
client.market.updateMarketGroupMetadata(params)Update group metadata URI

Trade

MethodDescription
client.trade.placeOrder(params) / placeOrderSimplePlace a limit order
client.trade.placeMarketOrder(params) / placeMarketOrderSimplePlace a market order (FOK/FAK)
client.trade.placeMarketSellSimple(params)Sell existing tokens at market
client.trade.previewMarketOrder(params)Simulate a market order
client.trade.cancelOrder(orderId)Cancel a resting order
client.trade.cancelOrdersOnResolvedMarket(marketId, ids)Bulk-refund orders after resolution
client.trade.batchPlaceOrders(params) / batchPlaceOrdersSimpleUp to 20 orders, same market
client.trade.batchCancelOrders(orderIds)Up to 100 cancels across any markets
client.trade.cancelAndReplace(params) / cancelAndReplaceSimpleAtomic cancel + place
client.trade.matchOrders(params)Trigger order matching (earns operator fee)
client.trade.splitPosition(marketId, amount)Split collateral into YES + NO
client.trade.mergePositions(marketId, amount)Merge YES + NO into collateral
client.trade.getOrder(orderId)Read a single order
client.trade.getOrderBook(params)Top-of-book summary
client.trade.getTickLevel(params)Detail for a given tick

PriceMarket

Pyth-powered price markets — create, query, and resolve.

MethodDescription
client.priceMarket.createPyth(params)Create an Up/Down or Strike price market
client.priceMarket.resolvePyth(marketId)Resolve from Pyth historical price at closeTime
client.priceMarket.canResolve(marketId)True if closeTime has passed and market is unresolved
client.priceMarket.isPriceMarket(marketId)Distinguish price markets from UMA-resolved markets
client.priceMarket.get(marketId)Full PriceMarketData (feed, times, strike, resolved flag)
client.priceMarket.getPythContract()Pyth contract address configured on the Diamond

UMA

For discretionary binary and grouped markets.

MethodDescription
client.uma.assertMarketOutcome(params)Assert an outcome with bond
client.uma.settleAssertion(assertionId)Settle after liveness
client.uma.reportResolution(params)Report outcome to CTF
client.uma.redeemWinnings(marketId)Redeem winning tokens
client.uma.getMarketStatus(marketId)Get resolution phase
client.uma.getQuestionData(marketId)Get oracle config
client.uma.getAssertionDetails(assertionId)Get UMA assertion details
client.uma.getResolutionStatus(marketId)Get CTF resolution state

AccessControl

Deploy pre-built access-control contracts and set per-venue or per-market overrides.

MethodDescription
client.accessControl.deployWhitelist()Deploy a WhitelistAccessControl
client.accessControl.deployTokenGated(params)Deploy a TokenGatedAccessControl
client.accessControl.deployNFTGated(params)Deploy an NFTGatedAccessControl
client.accessControl.setMarketTradingAC(params)Set trading AC for a specific market
client.accessControl.removeMarketTradingAC(params)Remove per-market trading AC override
client.accessControl.getMarketTradingAC(params)Read the effective per-market AC
client.accessControl.canTradeOnMarket(params)Check if a user can trade on a market
client.accessControl.addToWhitelist(params)Add addresses to a whitelist
client.accessControl.removeFromWhitelist(params)Remove addresses
client.accessControl.isWhitelisted(params)Check whitelist membership

Factory methods return a tx hash — extract the deployed contract from the AccessControlDeployed event in the receipt.

Public

Read-only queries via the subgraph.

MethodDescription
client.public.getVenues(params)List venues
client.public.getTopVenues(first)Top venues by volume
client.public.listMarkets(params)Markets filtered by venue, tag, or status
client.public.getOrders(params)Orders for a market
client.public.getTradeHistory(params)Trade history for a market
client.public.getRecentTrades(params)Recent trades across markets
client.public.getTopOfBook(marketId)Top-of-book snapshot
client.public.getLeaderboard(params)Trader rankings
client.public.getTraderProfile(address)PnL and positions for a trader

Token

ERC-20 helpers for the collateral token.

MethodDescription
client.token.balanceOf(owner, token)ERC-20 balance
client.token.allowance(owner, spender, token)Current allowance
client.token.approve(spender, amount, token)Set allowance
client.token.metadata(token)Name, symbol, decimals

Conversion Utilities

import {
  priceToTick,
  tickToPrice,
  parseTokenAmount,
  formatAmount,
  createExpiry,
} from '@oddmaki-protocol/sdk';

priceToTick('0.75');                     // 75n (at 1% tick size)
tickToPrice(75n);                        // "0.75"
parseTokenAmount('100.5', 6);            // 100500000n (USDC, 6 decimals)
formatAmount(100500000n, 6);             // "100.5"
createExpiry('24h');                     // BigInt(now + 86400)
createExpiry('gtc');                     // 0n

Decimals are cached per chainId-tokenAddress, so conversions are cheap after the first call.

Approvals

Most write operations require prior token approvals:

OperationApproval Required
Limit/market order (BUY)USDC.approve(diamond, amount)
Limit/market order (SELL)CTF.setApprovalForAll(diamond, true)
Split positionUSDC.approve(diamond, amount)
Merge positionsCTF.setApprovalForAll(diamond, true)
Market creation feeUSDC.approve(diamond, creationFee)
UMA assertion bondUSDC.approve(diamond, bond)

Most Simple variants accept an autoApprove: true flag and handle approvals for you when the caller is EOA.

What's Next