Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/deepbook-predict/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
dist/
package-lock.json
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.next/
.swc/
out/
CHANGELOG.md
30 changes: 30 additions & 0 deletions packages/deepbook-predict/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# `@mysten/deepbook-predict`

TypeScript SDK for the DeepBook **Predict** protocol — on-chain European cash-settled range digitals
on Sui.

> **Status: pre-launch, unstable.** Predict is not yet deployed to any network and its on-chain
> interface is still changing. There are no published package addresses; construct `PredictConfig`
> with explicit `packageIds` overrides. The API here will change without notice until the protocol
> ships to testnet.

## Layout

- `src/contracts/**` — generated Move bindings (`@mysten/codegen`), used as the BCS-schema source.
Regenerate with `pnpm codegen`.
- `src/transactions/**` — hand-written transaction builders (trader, LP, ...).
- `src/queries/**` — on-chain (`devInspect`) reads plus optional predict-server indexer helpers.
- `src/types/orderId.ts` — codec for the packed-`u256` order ID (mirrors `deepbook_predict::order`;
the Move module exposes no public accessors).
- `src/utils/{config,constants}.ts` — `PredictConfig` and protocol constants.

## Codegen

`pnpm codegen` runs `sui move summary` for each configured Move package (from the sibling
`deepbookv3` checkout) and regenerates `src/contracts/**`. Requires the Sui CLI (`>= 1.51.1`) and
the `deepbookv3` repo checked out alongside `ts-sdks`.

## Scope (v1)

Trader and LP flows; oracle **read-only**; slippage-guard-based trading (no off-chain quote
previewer). Keeper/admin/market-lifecycle and oracle publishing are deferred to later milestones.
56 changes: 56 additions & 0 deletions packages/deepbook-predict/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "@mysten/deepbook-predict",
"author": "Mysten Labs <build@mystenlabs.com>",
"description": "Sui DeepBook Predict SDK",
"version": "0.0.0",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.mjs",
"types": "./dist/index.d.mts",
"exports": {
".": {
"types": "./dist/index.d.mts",
"import": "./dist/index.mjs",
"default": "./dist/index.mjs"
}
},
"files": [
"CHANGELOG.md",
"dist",
"src"
],
"engines": {
"node": ">=22"
},
"repository": {
"type": "git",
"url": "git+https://github.com/MystenLabs/ts-sdks.git"
},
"bugs": {
"url": "https://github.com/MystenLabs/ts-sdks/issues/new"
},
"scripts": {
"clean": "rm -rf tsconfig.tsbuildinfo ./dist",
"build": "rm -rf dist && tsc --noEmit && tsdown",
"codegen": "pnpm sui-ts-codegen generate && pnpm lint:fix",
"prettier:check": "prettier -c --ignore-unknown .",
"prettier:fix": "prettier -w --ignore-unknown .",
"oxlint:check": "oxlint .",
"oxlint:fix": "oxlint --fix",
"test": "vitest",
"lint": "pnpm run oxlint:check && pnpm run prettier:check",
"lint:fix": "pnpm run oxlint:fix && pnpm run prettier:fix"
},
"dependencies": {
"@mysten/bcs": "workspace:^"
},
"devDependencies": {
"@mysten/codegen": "workspace:^",
"@types/node": "^25.0.8",
"typescript": "^5.9.3",
"vitest": "^4.0.17"
},
"peerDependencies": {
"@mysten/sui": "workspace:^"
}
}
95 changes: 95 additions & 0 deletions packages/deepbook-predict/src/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import type { ClientWithCoreApi, SuiClientRegistration, SuiClientTypes } from '@mysten/sui/client';
import { normalizeSuiAddress } from '@mysten/sui/utils';

import { IndexerClient } from './queries/indexerClient.js';
import { MarketQueries } from './queries/marketQueries.js';
import { VaultQueries } from './queries/vaultQueries.js';
import { AccountContract } from './transactions/account.js';
import { FlushContract } from './transactions/flush.js';
import { LpContract } from './transactions/lp.js';
import { PredictAccountContract } from './transactions/predictAccount.js';
import { TradeContract } from './transactions/trade.js';
import { PredictConfig } from './utils/config.js';
import type { PredictIds, PredictNetwork } from './utils/config.js';

/** A Sui client with the core API (`client.core.simulateTransaction`) the queries use. */
export interface PredictCompatibleClient extends ClientWithCoreApi {}

export interface PredictOptions<Name = 'predict'> {
/** Default sender for built transactions. */
address: string;
/** On-chain package + shared-object ids. Required until Predict is published. */
ids: PredictIds;
/** Optional `predict-server` base URL enabling the indexer read helpers. */
indexerUrl?: string;
name?: Name;
}

export interface PredictClientOptions extends PredictOptions {
client: PredictCompatibleClient;
network: SuiClientTypes.Network;
}

/**
* Facade over the Predict transaction builders + on-chain/indexer queries.
*
* Construct directly, or register onto a Sui client with
* `suiClient.$extend(predict({ address, ids }))` and use `suiClient.predict`.
*/
export class PredictClient {
readonly config: PredictConfig;

// Transaction builders
readonly account: AccountContract;
readonly predictAccount: PredictAccountContract;
readonly trade: TradeContract;
readonly lp: LpContract;
readonly flush: FlushContract;

// On-chain read helpers
readonly market: MarketQueries;
readonly vault: VaultQueries;

/** Indexer read helpers; present only when `indexerUrl` was configured. */
readonly indexer?: IndexerClient;

constructor({ client, network, address, ids, indexerUrl }: PredictClientOptions) {
const normalizedAddress = normalizeSuiAddress(address);
this.config = new PredictConfig({
network: network as PredictNetwork,
address: normalizedAddress,
indexerUrl,
ids,
});

this.account = new AccountContract(this.config);
this.predictAccount = new PredictAccountContract(this.config);
this.trade = new TradeContract(this.config);
this.lp = new LpContract(this.config);
this.flush = new FlushContract(this.config);

const ctx = { client, config: this.config, address: normalizedAddress };
this.market = new MarketQueries(ctx);
this.vault = new VaultQueries(ctx);

if (indexerUrl) {
this.indexer = new IndexerClient({ baseUrl: indexerUrl });
}
}
}

/** `$extend` registration: `suiClient.$extend(predict({ address, ids }))`. */
export function predict<Name extends string = 'predict'>({
name = 'predict' as Name,
...options
}: PredictOptions<Name>): SuiClientRegistration<PredictCompatibleClient, Name, PredictClient> {
return {
name,
register: (client) => {
return new PredictClient({ client, network: client.network, ...options });
},
};
}
Loading