@sdk.markets/sdk is currently a preview package. These docs show the SDK surface we're building toward.Join the waitlist
markets sdk
Advanced

Reference

The public SDK surface and the parimutuel contract model underneath it.

This page documents the public surface we are standardizing around. Some hosted product modules are still planned and are marked as such.

MarketsClient

The top-level client.

new MarketsClient({
  environment?: "sandbox" | "production",
  apiKey?: string,
  publicClient?: PublicClient,
  walletClient?: WalletClient,
  chain?: Chain,
  addresses?: Partial<MarketsAddresses>,
  executor?: CreateMarketTransactionExecutor,
})

Modules

client.markets

Hosted creation plus market reads and direct lifecycle writes.

client.markets.get(address)
client.markets.getMany(addresses)
client.markets.getStatus(input)
client.markets.getUserPosition({ marketAddress, user })
client.markets.canFinalize(input)
client.markets.isChallengeWindowActive(input)
client.markets.isResolved(input)
client.markets.create(hostedCreateInput)
client.markets.createAndWait(hostedCreateInput)
client.markets.createDirect(input)
client.markets.createWithExecutor(input, executor?)
client.markets.prepareCreateTransaction(input, account)
client.markets.parseCreateReceipt(receipt)
client.markets.buyIn(input)
client.markets.addToWhitelist(input)
client.markets.removeFromWhitelist(input)
client.markets.submitResolution(input)
client.markets.submitAdminVote(input)
client.markets.submitDispute(input)
client.markets.finalize(input)
client.markets.redeem(input)
client.markets.refund(input)
client.markets.voidMarket(input)

client.drafts

Planned hosted draft creation and validation.

client.drafts.validate(input)
client.drafts.generate(input)
client.drafts.get(id)
client.drafts.getValidation(id)

The namespace is present in the package today, but methods throw explicit "not available" errors until the hosted draft endpoints are published.

client.account

Wallet- and token-aware helpers.

client.account.getUsdcBalance(input)
client.account.getUsdcAllowance(input)
client.account.approveUsdc(input)
client.account.getWalletState()

client.jobs

Async hosted job status.

client.jobs.get(jobId)

React surface

Planned companion package:

useMarket(marketAddress)
useMarkets(addresses)
useMarketPosition(marketAddress, user?)
useCreateMarketDirect()
useBuyIn()
useSubmitMarketDraftAndWait()
useMarketsWalletState()

Hosted action model

Default hosted flows should use:

  • project API key
  • authenticated end-user session
  • managed wallet execution behind the scenes

Explicit wallet-address and signature payloads are still relevant later for advanced signed-hosted flows such as CLOB orders, but they should not be the default model for parimutuel creation.

Parimutuel direct create input

The contract-shaped direct input remains:

type CreateMarketInput = {
  question: string;
  options: string[];
  closeTime: Date | bigint | number;
  challengeWindow: Duration;
  resolution:
    | { mode: "single"; admin: Address }
    | { mode: "multi"; admins: Address[]; quorum: number }
    | { mode: "aiOracle" };
  whitelistEnabled?: boolean;
  creatorFeeBps?: number;
  creatorFeeRecipient?: Address;
};

MarketInfo

type MarketInfo = {
  address: Address;
  question: string;
  options: string[];
  status: MarketStatus;
  resolutionMode: ResolutionMode;
  creator: Address;
  closeTime: Date;
  challengeWindow: bigint;              // seconds
  challengeDeadline: Date | null;       // null until resolution is submitted
  totalPool: bigint;
  optionPools: bigint[];
  winningOptionIndex: number | null;
  evidenceUrl: string | null;
  creatorFeeBps: number;
  platformFeeBps: number;
  eligibleParticipantCount: bigint;
  disputeVoteCount: bigint;
};

UserPosition

type UserPosition = {
  stakes: bigint[];                     // per-option stake
  totalStake: bigint;
  isEligibleParticipant: boolean;
  hasDisputed: boolean;
  hasRedeemed: boolean;
  hasRefunded: boolean;
};

Duration

type Duration = number | `${number}s` | `${number}m` | `${number}h` | `${number}d`;

Enums

enum MarketStatus {
  Open = 0,
  Closed = 1,
  ResolvedPendingFinality = 2,
  Finalized = 3,
  Voided = 4,
}

enum ResolutionMode {
  SingleAdmin = 0,
  MultiAdmin = 1,
  AiOracle = 2,
}

MarketStatusLabels[status] gives a human‑readable string.

Helpers

parseUsdc(amount: string | number): bigint       // "10"   → 10_000_000n
formatUsdc(amount: bigint): string               // 10n..  → "10.000000"
durationToSeconds(duration: Duration): bigint
toUnixSeconds(time: Date | bigint | number): bigint
fromUnixSeconds(seconds: bigint): Date

Addresses

import { Addresses, addressesForChainId } from "@sdk.markets/sdk";

Addresses.baseSepolia.marketFactory;   // "0xc773..."
Addresses.baseSepolia.usdc;            // "0x036C..."

addressesForChainId(84532);            // same as Addresses.baseSepolia

Base mainnet addresses are null until the contracts pass final audit — publish your own via the addresses option on new MarketsClient({...}) if you've deployed elsewhere.

Raw ABIs

The SDK also re‑exports the contract ABIs for anyone doing direct writeContract / readContract calls:

import { MarketFactoryAbi, ParimutuelMarketAbi, Erc20Abi } from "@sdk.markets/sdk";

Contract signatures (appendix)

The underlying Solidity surface, for reference when reading events or diagnosing reverts.

MarketFactory

function createMarket(CreateMarketParams calldata params) external returns (address market);
event MarketCreated(address indexed market, address indexed creator, string question, uint256 closeTime, uint8 resolutionMode);

ParimutuelMarket

function buyIn(uint8 optionIndex, uint256 amount) external;
function addToWhitelist(address user) external;
function addManyToWhitelist(address[] calldata users) external;
function removeFromWhitelist(address user) external;
function submitAdminVote(uint8 optionIndex) external;
function submitResolution(uint8 optionIndex, string calldata evidenceUrl, bytes32 evidenceHash) external;
function submitDispute() external;
function finalizeMarket() external;
function voidMarket() external;
function redeem() external;
function refund() external;

event BuyIn(address indexed user, uint8 indexed optionIndex, uint256 amount);
event MarketClosed(uint256 timestamp);
event AdminVoteSubmitted(address indexed admin, uint8 indexed optionIndex, uint256 voteCount);
event ResolutionSubmitted(address indexed resolver, uint8 indexed winningOptionIndex, string evidenceUrl, bytes32 evidenceHash, uint256 challengeDeadline);
event DisputeSubmitted(address indexed user, uint256 disputeVoteCount, uint256 eligibleParticipantCount);
event MarketVoided(uint256 timestamp);
event MarketFinalized(uint8 indexed winningOptionIndex, uint256 timestamp);
event FeesPaid(uint256 creatorFeeAmount, uint256 platformFeeAmount, address indexed creatorFeeRecipient, address indexed platformFeeRecipient);
event Redeemed(address indexed user, uint256 payout);
event Refunded(address indexed user, uint256 amount);

Bounds

ParameterMinMax
question.length1200
options.length28
Each option length150
challengeWindow5m72h
Multi‑admin count15
creatorFeeBps0500
platformFeeBps0500
Combined fees1,000

On this page