Skip to content
Merged
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
50 changes: 50 additions & 0 deletions .changeset/deepbook-margin-upgraded-pyth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
'@mysten/deepbook-v3': major
---

Move the margin surface onto Pyth's upgraded Core and drop the legacy Pyth surface.

Pyth is replacing Core with a separately published Sui package rather than upgrading it in place, so
its `PriceInfoObject` is a distinct Move type that the existing margin entrypoints can never accept
— their signatures are frozen by the `compatible` upgrade policy. `deepbook_margin` therefore
exposes the upgraded surface as parallel modules (`margin_manager_upgraded`, `pool_proxy_upgraded`)
and `margin_liquidation` as parallel entrypoints (`liquidate_base_upgraded`,
`liquidate_quote_upgraded`), all under the same function names.

**This SDK now targets only the upgraded deployment.** Legacy Core is being retired, so carrying
both was short-lived complexity. It carries no legacy/upgraded switch — the parallel surfaces were
weighed during development and dropped before release, so there is nothing to migrate off. `pyth` is the upgraded deployment's state objects and
`priceInfoObjectId` is its price object. Every margin method keeps its name and signature; what
changes is the module each one targets and the price object it passes. Entrypoints that take no
oracle — manager creation, repayment, referrals, cancels, staking, governance and every getter —
stay on the base modules, which is the only place they exist.

**Requires the upgraded margin package on the target network, enabled.** The upgraded modules do not
exist in earlier `deepbook_margin` publications, so this release must not be used against a network
whose margin package predates them. Publication alone is not enough: each package asserts its own
`MARGIN_VERSION` against the registry's allowed versions, so the version must also be enabled on
that network's `MarginRegistry` or every entrypoint aborts `EPackageVersionDisabled`.

**`liquidateBase` / `liquidateQuote` have no mainnet target yet.** They call
`liquidation_vault::liquidate_base_upgraded` / `liquidate_quote_upgraded`, which exist in
`margin_liquidation` on testnet but not in the current mainnet publication. Every other vault
method takes no oracle and is unaffected.

Price update data is now fetched from Hermes v2 (`/v2/updates/price/latest`) instead of the
deprecated v1 `/api/latest_vaas`; the update bytes are identical, though the response envelopes
differ. The client gains a `pythAccessToken` option (and `pyth.accessToken` beneath it), sent as
`Authorization: Bearer`: the endpoint serving the upgraded Core answers 401 without it, so price
updates need either this or a `pyth.hermesEndpoint` that supplies credentials itself. The name
converges with the in-flight `@mysten/suins` Pyth migration (ts-sdks#1158), which takes the same
credential — that is unpublished, so a convergence target rather than an existing convention. It
composes with the built-in Pyth state objects rather than replacing them the
way a whole `pyth` config does. Supply the token at runtime; no credential ships with the SDK. Consumers who supply none are intended to
fall back to a DeepBook-operated proxy, which is not deployed yet, so that path currently throws a
`ConfigurationError` naming the field to set.

Package ids move to `deepbook_margin` v16 on testnet and v7 on mainnet, and `margin_liquidation` v4
on testnet; mainnet `margin_liquidation` is unchanged, having no upgraded publication. Testnet coins
carry the feed ids its migrated `MarginRegistry` is configured with. DBTC is testnet's wrapped BTC
and takes Crypto.XBTC/USD, the same feed mainnet XBTC uses, the upgraded deployment carrying no
distinct DBTC feed. Mainnet XBTC's upgraded price object was created on
2026-08-17 and is included, so all six mainnet-configured coins now have one.
7 changes: 6 additions & 1 deletion packages/deepbook-v3/examples/pythExample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@ const getSigner = () => {
console.log(`Network: ${network}\n`);

const client = new SuiGrpcClient({ network, baseUrl: GRPC_URLS[network] }).$extend(
deepbook({ address }),
deepbook({
address,
// Margin prices against Pyth's upgraded Core, whose Hermes answers 401 without a
// token. Supply PYTH_TOKEN to push price updates.
pythAccessToken: process.env.PYTH_TOKEN,
}),
);

// Coins to update prices for
Expand Down
3 changes: 3 additions & 0 deletions packages/deepbook-v3/examples/tpslExample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ const GRPC_URLS = {
deepbook({
address: getActiveAddress(),
marginManagers,
// Margin prices against Pyth's upgraded Core, whose Hermes answers 401 without a
// token. Supply PYTH_TOKEN to push price updates.
pythAccessToken: process.env.PYTH_TOKEN,
}),
);

Expand Down
10 changes: 8 additions & 2 deletions packages/deepbook-v3/examples/updateCurrentPriceExample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,16 @@ const getSigner = () => {
console.log(`Network: ${network}\n`);

const client = new SuiGrpcClient({ network, baseUrl: GRPC_URLS[network] }).$extend(
deepbook({ address }),
deepbook({
address,
// Margin prices against Pyth's upgraded Core, whose Hermes answers 401 without a
// token. Supply PYTH_TOKEN to push price updates.
pythAccessToken: process.env.PYTH_TOKEN,
}),
);

// All 4 mainnet assets with Pyth price feeds
// The four assets these pools price against. Seven mainnet coins carry feeds;
// this example refreshes only the ones the pools below need.
const coinKeys = ['SUI', 'USDC', 'DEEP', 'WAL'];

// Pools to update current price for
Expand Down
10 changes: 9 additions & 1 deletion packages/deepbook-v3/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import type {
PoolBookParams,
PoolDeepPrice,
PoolTradeParams,
PythConfig,
QuantityOut,
QuoteQuantityIn,
QuoteQuantityOut,
Expand All @@ -73,7 +74,12 @@ export interface DeepBookOptions<Name = 'deepbook'> {
marginAdminCap?: string;
marginMaintainerCap?: string;
packageIds?: DeepbookPackageIds;
pyth?: { pythStateId: string; wormholeStateId: string };
pyth?: PythConfig;
/**
* Bearer token for the Hermes serving Pyth's upgraded Core. Matches the option of the
* same name in `@mysten/suins`, which takes the same credential.
*/
pythAccessToken?: string;
name?: Name;
}

Expand Down Expand Up @@ -144,6 +150,7 @@ export class DeepBookClient {
marginMaintainerCap,
packageIds,
pyth,
pythAccessToken,
}: DeepBookClientOptions) {
const normalizedAddress = normalizeSuiAddress(address);
const config = new DeepBookConfig({
Expand All @@ -158,6 +165,7 @@ export class DeepBookClient {
marginMaintainerCap,
packageIds,
pyth,
pythAccessToken,
});

this.balanceManager = new BalanceManagerContract(config);
Expand Down
150 changes: 140 additions & 10 deletions packages/deepbook-v3/src/contracts/deepbook_margin/margin_manager.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading