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 viemPeer 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
bigintticks 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
| Method | Description |
|---|---|
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
| Method | Description |
|---|---|
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
| Method | Description |
|---|---|
client.trade.placeOrder(params) / placeOrderSimple | Place a limit order |
client.trade.placeMarketOrder(params) / placeMarketOrderSimple | Place 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) / batchPlaceOrdersSimple | Up to 20 orders, same market |
client.trade.batchCancelOrders(orderIds) | Up to 100 cancels across any markets |
client.trade.cancelAndReplace(params) / cancelAndReplaceSimple | Atomic 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.
| Method | Description |
|---|---|
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.
| Method | Description |
|---|---|
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.
| Method | Description |
|---|---|
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.
| Method | Description |
|---|---|
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.
| Method | Description |
|---|---|
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'); // 0nDecimals are cached per chainId-tokenAddress, so conversions are cheap after the first call.
Approvals
Most write operations require prior token approvals:
| Operation | Approval Required |
|---|---|
| Limit/market order (BUY) | USDC.approve(diamond, amount) |
| Limit/market order (SELL) | CTF.setApprovalForAll(diamond, true) |
| Split position | USDC.approve(diamond, amount) |
| Merge positions | CTF.setApprovalForAll(diamond, true) |
| Market creation fee | USDC.approve(diamond, creationFee) |
| UMA assertion bond | USDC.approve(diamond, bond) |
Most Simple variants accept an autoApprove: true flag and handle approvals for you when the caller is EOA.
What's Next
- Access Control → — configure who can trade and create markets
- Creating Markets → — market creation examples (binary, grouped, price)
- Batch Operations → — batch place, cancel, and replace
- Resolution → — UMA and Pyth resolution flows
- Price Markets → — Pyth-fed auto-resolving markets