Skip to main content
Each event market is a full Move publish because Sui’s one-time-witness rule means each Coin type needs its own published module. scripts/create-binary-market.ts automates the whole flow.

Prerequisites

  • Repo cloned, .env populated (DARKPOOL_PACKAGE_ID, DUSDC_COIN_TYPE).
  • Sui CLI logged in with a funded testnet address (~0.5 SUI for gas).
  • The resolver address you want to control settlement (can be your own).

One command

pnpm binary-market:create \
  --slug btc_80k_eoy \
  --label "BTC > \$80k by EOY 2026" \
  --expiry-ms 1798761600000 \
  --resolver $(sui client active-address) \
  --execute

What happens

1

Materialize template

Copies packages/binary-market-template/ into .binary-markets/binary_market_btc_80k_eoy/.
2

Substitute slug + label

Replaces all <slug> / <label> placeholders in Move.toml, yes.move, no.move, settlement.move.
3

sui move build

Always runs. Catches substitution issues even in dry-run mode.
4

Publish (with --execute)

sui client publish --json. About 0.3 SUI gas, 30s wallclock. Extracts package id + both TreasuryCap ids from objectChanges.
5

create_market

Calls settlement::create_market<DUSDC>(yes_cap, no_cap, label, expiry_ms, resolver, ctx) which:
  • Wraps both TreasuryCaps into a shared Settlement<DUSDC>.
  • Mints a ResolverCap and transfers it to --resolver.
6

Append to registry

.binary-markets/registry.json gets a new entry with packageId, settlementId, resolverCapId, yesType, noType. The server reads it on every /v1/binary-markets request. The new market shows up instantly.

Slug rules

Must match /^[a-z0-9_]+$/. Also avoid Move reserved words (coin, balance, …) since the slug becomes the module path.

Audit

cat .binary-markets/registry.json | jq
# → the new entry has packageId, settlementId, resolverCapId, yesType, noType

curl -s http://localhost:8081/v1/binary-markets | jq
# → same data, enriched with the live Settlement state (finalOutcome = 0)

Recovery

If the sui client publish succeeded but create_market aborted (rare; usually CLI flakiness), use the recovery path:
pnpm binary-market:finish --digest <publish-tx-digest> --slug btc_80k_eoy --execute
It re-queries the chain for the package + TreasuryCaps, finishes market creation, and appends the registry entry.

Adding V3 pools

The scaffolded market trades on dedicated V3 pools Pool<YES, DUSDC> and Pool<NO, DUSDC>. Bootstrap them once you have 1000 testnet DEEP:
pnpm tsx scripts/create-v3-pools.ts --slug btc_80k_eoy --execute    # 500 DEEP / pool
pnpm tsx scripts/seed-v3-liquidity.ts --slug btc_80k_eoy --bid 0.45 --ask 0.55 --execute
The seeder mints YES+NO pairs from wallet DUSDC (5% fee headroom), deposits into a BalanceManager created + shared in-PTB, then POST_ONLYs bid/ask on both pools. Pool ids get written back into the registry. The frontend’s Trade on DeepBook panel auto-renders. No restart needed.

Adding OO bridge

Wire the optimistic oracle by adding ooMarketLinkId to the registry entry (post-registration via pnpm market:register --kind oo). The OOPanel then renders on the event detail page.