npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@magistery/sdk

v0.1.4

Published

TypeScript SDK for Magistery, a permissionless prediction market order book on Polygon using USDC and Conditional Tokens.

Readme

@magistery/sdk

TypeScript SDK for Magistery — permissionless prediction market protocol on Polygon. On-chain order book, pluggable resolution, USDC settlement.

Documentation

Install

npm install @magistery/sdk

Requires Node.js 18+.

Quick Start

import { createPublicClient, createWalletClient, http } from "viem";
import { polygon } from "viem/chains";
import { MagisteryClient, DEPLOYED_ADDRESSES } from "@magistery/sdk";

// Read-only client (no wallet needed)
const publicClient = createPublicClient({
  chain: polygon,
  transport: http("https://polygon-rpc.com"),
});

const sdk = new MagisteryClient({
  publicClient,
  addresses: DEPLOYED_ADDRESSES,
});

// Read a market
const market = await sdk.getMarket(conditionId);
console.log(market.questionId, market.deadline, market.resolved);

With a wallet (for writes)

import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount("0x...");
const walletClient = createWalletClient({
  account,
  chain: polygon,
  transport: http("https://polygon-rpc.com"),
});

const sdk = new MagisteryClient({
  publicClient,
  walletClient,
  addresses: DEPLOYED_ADDRESSES,
});

// Create a market
const conditionId = await sdk.createMarket(
  "Will ETH hit $10k by end of 2026?",
  2,                    // binary: YES/NO
  1798761600n,          // deadline (unix timestamp)
  DEPLOYED_ADDRESSES.umaResolver!,
);

API Reference

Constructor

new MagisteryClient({
  publicClient: PublicClient,       // viem public client (Polygon)
  walletClient?: WalletClient,      // optional, required for writes
  addresses: ProtocolAddresses,     // use DEPLOYED_ADDRESSES for mainnet
})

Reads

| Method | Returns | Description | |--------|---------|-------------| | getMarket(conditionId) | Market | Market struct (questionId, deadline, outcomes, resolved, creator, resolver) | | nextOrderId() | bigint | Next order ID that will be assigned | | isTrading(conditionId) | boolean | True if market exists and not resolved | | isResolvable(conditionId) | boolean | True if past deadline and not yet resolved | | getOrder(orderId) | Order | Order struct (maker, side, price, amount, filled, cancelled) | | getPosition(owner, conditionId, outcomeIndex) | Position | Token balance for a specific outcome | | getPositionId(conditionId, outcomeIndex) | bigint | CTF position ID for an outcome | | bondAmount(resolverType?) | bigint | Current UMA/Kalshi bond requirement (default: "uma") | | getActiveAssertion(conditionId, resolverType?) | Hex | Active UMA/Kalshi assertion ID (0x0 if none) | | getKalshiTicker(conditionId) | Hex | Linked Kalshi ticker for a market | | getPolymarketCondition(conditionId) | Hex | Linked Polymarket condition ID |

Fee Math (pure, no RPC)

| Method | Returns | Description | |--------|---------|-------------| | calculateFee(amount) | bigint | Protocol fee (0.1%, rounded up) | | estimateFillBuyVsBuy(price0, remaining0, price1, remaining1) | FillEstimate | Estimate fill for two opposing buy orders | | estimateFillBuyVsSell(buyPrice, buyRemaining, sellPrice, sellRemaining) | FillEstimate | Estimate fill for buy vs sell on same outcome |

Writes (require wallet)

Markets

| Method | Returns | Description | |--------|---------|-------------| | createMarket(question, outcomeSlotCount, deadline, resolver) | Hex (conditionId) | Create a new market | | forceVoid(conditionId) | Hex (tx hash) | Void a stale market (90d timeout, 180d emergency) | | withdrawFees(token) | Hex (tx hash) | Withdraw accumulated fees to treasury recipient |

Orders

| Method | Returns | Description | |--------|---------|-------------| | placeBuyOrder(conditionId, outcomeIndex, price, amount) | bigint (orderId) | Place a limit buy order | | placeBuyOrders(conditionIds[], outcomeIndexes[], prices[], amounts[]) | bigint[] (orderIds) | Batch place buy orders | | placeSellOrder(conditionId, outcomeIndex, price, amount) | bigint (orderId) | Place a limit sell order | | fillBuyVsBuy(buyId0, buyId1, fillAmount) | Hex (tx hash) | Match two opposing buy orders | | fillBuyVsSell(buyId, sellId, fillAmount) | Hex (tx hash) | Match buy and sell on same outcome | | cancelOrder(orderId) | Hex (tx hash) | Cancel your own order | | cancelOrders(orderIds[]) | Hex (tx hash) | Batch cancel orders | | cancelExpiredOrder(orderId) | Hex (tx hash) | Cancel any order on a resolved market |

Approvals

| Method | Returns | Description | |--------|---------|-------------| | approveUsdc(spender, amount?) | Hex (tx hash) | Approve USDC spending (default: max) | | approveCtf(operator) | Hex (tx hash) | Approve CTF token transfers |

Resolution (UMA)

| Method | Returns | Description | |--------|---------|-------------| | assertOutcome(conditionId, assertedOutcome) | Hex (tx hash) | Assert market outcome (requires bond) | | assertOutcomeFor(conditionId, assertedOutcome, asserter) | Hex (tx hash) | Assert on behalf of another (bond from caller) | | settleAssertion(assertionId, resolverType?) | Hex (tx hash) | Settle after liveness period |

Resolution (Kalshi)

| Method | Returns | Description | |--------|---------|-------------| | kalshiLinkMarket(conditionId, ticker) | Hex (tx hash) | Link market to Kalshi ticker | | kalshiAssertOutcome(conditionId, assertedOutcome) | Hex (tx hash) | Assert via Kalshi resolver | | kalshiAssertOutcomeFor(conditionId, assertedOutcome, asserter) | Hex (tx hash) | Assert on behalf via Kalshi |

Resolution (Polymarket)

| Method | Returns | Description | |--------|---------|-------------| | polymarketLinkMarket(conditionId, polymarketConditionId) | Hex (tx hash) | Link to Polymarket condition | | polymarketResolve(conditionId) | Hex (tx hash) | Resolve from Polymarket outcome |

Resolution (Operator)

For operator-deployed resolver contracts (community resolution, bot-managed markets).

| Method | Returns | Description | |--------|---------|-------------| | operatorResolve(conditionId, winnerIndex, evidenceHash?) | Hex (tx hash) | Resolve directly (operator only) | | operatorResolveBySig(conditionId, winnerIndex, evidenceHash, nonce, expiry, signature) | Hex (tx hash) | Resolve via EIP-712 signature | | operatorResolverOperator() | Address | Get the operator address | | operatorResolverDomainSeparator() | Hex | EIP-712 domain separator | | operatorResolverNonceUsed(nonce) | boolean | Check if signature nonce is consumed |

Redemption

| Method | Returns | Description | |--------|---------|-------------| | redeemWinnings(conditionId, outcomeIndices[]) | Hex (tx hash) | Redeem winning outcome tokens for USDC |

Multi-Outcome (NegRisk)

| Method | Returns | Description | |--------|---------|-------------| | createMultiOutcomeMarket(question, labels[], deadline, resolver) | bigint (marketId) | Create multi-outcome market (3+ outcomes) | | getOutcomeCount(marketId) | bigint | Number of outcomes | | getOutcomeConditionId(marketId, outcomeIndex) | Hex | ConditionId for a specific leg | | getAllConditionIds(marketId) | Hex[] | All leg conditionIds | | getOutcomeLabel(marketId, outcomeIndex) | string | Label for a specific outcome | | isMultiOutcomeResolved(marketId) | boolean | True if all legs resolved |

Safety Helpers (for frontends)

| Method | Returns | Description | |--------|---------|-------------| | isTrustedResolver(conditionId, trustedAddresses[]) | boolean | Check resolver against whitelist | | isKalshiLinked(conditionId) | boolean | Check if Kalshi market is linked to a ticker | | isPolymarketLinked(conditionId) | boolean | Check if Polymarket market is linked | | isPastDeadline(conditionId) | boolean | True if past deadline and not resolved (danger zone) |

Types

interface Market {
  questionId: Hex;
  conditionId: Hex;
  deadline: bigint;
  outcomeSlotCount: number;
  resolved: boolean;
  creator: Address;
  resolver: Address;
}

interface Order {
  orderId: bigint;
  maker: Address;
  side: Side;          // Side.BUY (0) or Side.SELL (1)
  cancelled: boolean;
  conditionId: Hex;
  outcomeIndex: bigint;
  price: bigint;       // 6 decimals (1e6 = $1.00)
  amount: bigint;
  filled: bigint;
}

interface Position {
  conditionId: Hex;
  outcomeIndex: number;
  positionId: bigint;
  balance: bigint;
}

interface FillEstimate {
  fillAmount: bigint;
  cost: bigint;
  fee: bigint;
  surplus: bigint;
  sellerProceeds: bigint;
}

interface ProtocolAddresses {
  factory: Address;
  orderBook: Address;
  treasury: Address;
  negRiskAdapter: Address;
  umaResolver?: Address;
  kalshiResolver?: Address;
  polymarketResolver?: Address;
  operatorResolver?: Address;
}

Constants

import {
  DEPLOYED_ADDRESSES,    // All 7 mainnet contract addresses
  CTF_ADDRESS,           // Gnosis CTF (0x4D97...045)
  USDC_ADDRESS,          // Native USDC (0x3c49...359)
  UMA_OOV3_ADDRESS,      // UMA Oracle (0x5953...3D)
  POLYGON_CHAIN_ID,      // 137
  PRICE_SCALE,           // 1_000_000n ($1.00)
  MIN_ORDER_COST,        // 10_000n ($0.01)
  FEE_BPS,               // 10n (0.1%)
  BOND_AMOUNT,           // 750_000_000n (750 USDC)
  LIVENESS,              // 7200n (2 hours)
  VOID_TIMEOUT,          // 7_776_000n (90 days)
  EMERGENCY_VOID_TIMEOUT,// 15_552_000n (180 days)
} from "@magistery/sdk";

Price Scale

All prices use 6 decimals (USDC decimals). 1_000_000n = $1.00.

| Price | Meaning | |-------|---------| | 650_000n | $0.65 (65% probability) | | 1_000_000n | $1.00 (100% — max) | | 10_000n | $0.01 (1% — minimum order) |

Approval Flow

Before placing orders, approve the OrderBook to spend your USDC and transfer your CTF tokens:

await sdk.approveUsdc(DEPLOYED_ADDRESSES.orderBook);
await sdk.approveCtf(DEPLOYED_ADDRESSES.orderBook);

Before asserting outcomes (UMA/Kalshi), approve the resolver to spend the bond:

const bond = await sdk.bondAmount(); // 750 USDC
await sdk.approveUsdc(DEPLOYED_ADDRESSES.umaResolver!, bond);

Example: Full Trading Flow

// 1. Create market
const cid = await sdk.createMarket("Will X happen?", 2, deadline, resolver);

// 2. Place buy order on YES at $0.60
const buyId = await sdk.placeBuyOrder(cid, 0, 600_000n, 10_000_000n);

// 3. Someone else places buy on NO at $0.45
const noId = await sdk.placeBuyOrder(cid, 1, 450_000n, 10_000_000n);

// 4. Match the orders (anyone can call this)
await sdk.fillBuyVsBuy(buyId, noId, 10_000_000n);

// 5. After resolution, redeem winnings
await sdk.redeemWinnings(cid, [0]); // redeem YES tokens

CLI

The SDK ships a CLI for direct protocol interaction. No code required.

# Set environment
export POLYGON_RPC_URL=https://...
export MAGISTERY_PRIVATE_KEY=0x...  # only for write commands

# Read commands
npx @magistery/sdk market get <conditionId>
npx @magistery/sdk market list
npx @magistery/sdk market search "ETH"
npx @magistery/sdk order get <orderId>
npx @magistery/sdk position list

# Trading
npx @magistery/sdk order buy <conditionId> 0 0.55 100
npx @magistery/sdk order sell <conditionId> 0 0.6 50
npx @magistery/sdk order cancel <orderId>

# Resolution
npx @magistery/sdk market assert <conditionId> 0
npx @magistery/sdk market settle <assertionId>
npx @magistery/sdk market redeem <conditionId>

All commands output JSON. Prices are 0–1 exclusive. Amounts are in shares with max 6 decimal precision.

Testing

# Unit tests (no RPC needed)
pnpm test

# Fork tests (requires Polygon RPC)
POLYGON_RPC=https://... pnpm test:fork

135 tests total (84 unit + 51 fork).

License

MIT