DeepBookV3 SDK
The DeepBookV3 TypeScript SDK abstracts away the transaction calls, allowing for direct interactions with the DeepBook package.
Install
To use the SDK in your projects, install the @mysten/deepbook package.
- npm
- Yarn
- pnpm
npm install @mysten/deepbook-v3
yarn add @mysten/deepbook-v3
pnpm add @mysten/deepbook-v3
Constants
The DeepBookV3 SDK includes a constants file (/utils/constants.ts) that maintains the latest deployed addresses for DeepBookV3, as well as a few staple coins and pools.
constants.ts
constants.tsDeepBookClient
To work with DeepBookV3, you must create a DeepBookClient. To construct the DeepBookClient, pass in a SuiClient, the sender address, and environment. The Sui TypeScript SDK provides the SuiClient and key functionality necessary to process transactions. The following example imports those libraries, as well.
import { DeepBookClient } from '@mysten/deepbook-v3';
import { getFullnodeUrl, SuiClient } from '@mysten/sui/client';
import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
class DeepBookMarketMaker {
dbClient: DeepBookClient; // For building transactions
suiClient: SuiClient; // For executing transactions
keypair: Ed25519Keypair; // For signing transactions
constructor(privateKey: string, env: 'testnet' | 'mainnet') {
this.keypair = this.getSignerFromPK(privateKey);
this.suiClient = new SuiClient({
url: getFullnodeUrl(env),
});
this.dbClient = new DeepBookClient({
address: this.getActiveAddress(),
env: env,
client: this.suiClient,
});
}
getSignerFromPK = (privateKey: string): Ed25519Keypair => {
const { schema, secretKey } = decodeSuiPrivateKey(privateKey);
if (schema === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);
throw new Error(`Unsupported schema: ${schema}`);
};
getActiveAddress() {
return this.keypair.toSuiAddress();
}
}
Keys: Coin, Pool, and Manager
Functions that require the input of a coin, pool, or a manager require the key of any such object as the parameter. The SDK manages a key:value relationship of this data in memory. Some default data comes with the SDK (as seen in utils/constants.ts). Coins are stored in a CoinMap and pools in a PoolMap in the config.
Balance manager
Before placing any trade, you must supply a balance manager address to the client. The manager key points to an object defined by the BalanceManager interface in the client. BalanceManager docs. Initialize the balance manager with the client. If you don't create a balance manager, you can rely on the client to create one, but then the user must reinitialize the client.
Example using an existing balance manager:
import { getFullnodeUrl, SuiClient } from '@mysten/sui/client';
import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { config } from 'dotenv';
import { DeepBookClient } from '../src';
import { BalanceManager } from './types';
config();
// Used wherever balance manager key is required
const BALANCE_MANAGER_KEY = 'MANAGER_1';
class DeepBookMarketMaker {
dbClient: DeepBookClient; // For building transactions
suiClient: SuiClient; // For executing transactions
keypair: Ed25519Keypair; // For signing transactions
env: 'testnet' | 'mainnet';
constructor(privateKey: string, env: 'testnet' | 'mainnet') {
this.env = env;
this.keypair = this.getSignerFromPK(privateKey);
this.suiClient = new SuiClient({
url: getFullnodeUrl(env),
});
this.dbClient = new DeepBookClient({
address: this.getActiveAddress(),
env: env,
client: this.suiClient,
balanceManagers: this.getBalanceManagers(),
});
}
getSignerFromPK = (privateKey: string): Ed25519Keypair => {
const { schema, secretKey } = decodeSuiPrivateKey(privateKey);
if (schema === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);
throw new Error(`Unsupported schema: ${schema}`);
};
getActiveAddress() {
return this.keypair.toSuiAddress();
}
getBalanceManagers(): { [key: string]: BalanceManager } {
// Used wherever balance manager key is required
const balanceManagerAddress = process.env.BALANCE_MANAGER_ADDRESS;
const balanceManagerTradeCap = process.env.BALANCE_MANAGER_TRADE_CAP;
if (!balanceManagerAddress) {
throw new Error('No balance manager address found');
}
return {
[BALANCE_MANAGER_KEY]: {
address: balanceManagerAddress,
tradeCap: balanceManagerTradeCap,
},
};
}
}
Example creating a balance manager:
import { getFullnodeUrl, SuiClient } from '@mysten/sui/client';
import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { Transaction } from '@mysten/sui/transactions';
import { DeepBookClient } from '../src';
import { BalanceManager } from './types';
// Used wherever balance manager key is required
const BALANCE_MANAGER_KEY = 'MANAGER_1';
class DeepBookMarketMaker {
dbClient: DeepBookClient; // For building transactions
suiClient: SuiClient; // For executing transactions
keypair: Ed25519Keypair; // For signing transactions
env: 'testnet' | 'mainnet';
constructor(privateKey: string, env: 'testnet' | 'mainnet') {
this.env = env;
this.keypair = this.getSignerFromPK(privateKey);
this.suiClient = new SuiClient({
url: getFullnodeUrl(env),
});
this.dbClient = new DeepBookClient({
address: this.getActiveAddress(),
env: env,
client: this.suiClient,
});
}
getSignerFromPK = (privateKey: string): Ed25519Keypair => {
const { schema, secretKey } = decodeSuiPrivateKey(privateKey);
if (schema === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);
throw new Error(`Unsupported schema: ${schema}`);
};
getActiveAddress() {
return this.keypair.toSuiAddress();
}
async createBalanceManagerAndReinitialize() {
let tx = new Transaction();
tx.add(this.dbClient.balanceManager.createAndShareBalanceManager());
const res = await this.suiClient.signAndExecuteTransaction({
transaction: tx,
signer: this.keypair,
options: {
showEffects: true,
showObjectChanges: true,
},
});
// @ts-ignore
const balanceManagerAddress = res.objectChanges?.find((change) => {
return change.type === 'created' && change.objectType.includes('BalanceManager');
})?.['objectId'];
const balanceManagers: { [key: string]: BalanceManager } = {
[BALANCE_MANAGER_KEY]: {
address: balanceManagerAddress,
tradeCap: undefined,
},
};
this.dbClient = new DeepBookClient({
address: this.getActiveAddress(),
env: this.env,
client: this.suiClient,
balanceManagers: balanceManagers,
});
}
}
Coin
The SDK comes with four default coins on Testnet and five default coins on Mainnet.
Default Testnet coins
- DEEP
- SUI
- DBUSDC
- DBUSDT
Default Mainnet coins
- DEEP
- SUI
- USDC
- USDT
- WETH
You can also initialize the SDK with custom coins to interact with pools that are not supported by default. To do this, create a CoinMap object and pass it to the constructor of the client.
Pool
Similar to coins, the SDK comes with default pools. You can provide a PoolMap during construction to override this behavior.
import { decodeSuiPrivateKey } from '@mysten/sui.js/cryptography';
import { getFullnodeUrl, SuiClient } from '@mysten/sui/client';
import type { Keypair } from '@mysten/sui/cryptography';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import type { Transaction } from '@mysten/sui/transactions';
import { DeepBookClient } from '../src/index.js'; // Adjust path according to new structure
import type { BalanceManager } from '../src/types/index.js';
export class DeepBookMarketMaker extends DeepBookClient {
keypair: Keypair;
suiClient: SuiClient;
constructor(
keypair: string | Keypair,
env: 'testnet' | 'mainnet',
balanceManagers?: { [key: string]: BalanceManager },
adminCap?: string,
) {
let resolvedKeypair: Keypair;
if (typeof keypair === 'string') {
resolvedKeypair = DeepBookMarketMaker.#getSignerFromPK(keypair);
} else {
resolvedKeypair = keypair;
}
const address = resolvedKeypair.toSuiAddress();
super({
address: address,
env: env,
client: new SuiClient({
url: getFullnodeUrl(env),
}),
balanceManagers: balanceManagers,
adminCap: adminCap,
});
this.keypair = resolvedKeypair;
this.suiClient = new SuiClient({
url: getFullnodeUrl(env),
});
}
static #getSignerFromPK = (privateKey: string) => {
const { schema, secretKey } = decodeSuiPrivateKey(privateKey);
if (schema === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);
throw new Error(`Unsupported schema: ${schema}`);
};
signAndExecute = async (tx: Transaction) => {
// remove arguments
return this.suiClient.signAndExecuteTransaction({
transaction: tx,
signer: this.keypair,
options: {
showEffects: true,
showObjectChanges: true,
},
});
};
getActiveAddress() {
return this.keypair.getPublicKey().toSuiAddress();
}
}
Example setup
The following example uses the default pools and coins provided.
import { Transaction } from '@mysten/sui/transactions';
import { DeepBookMarketMaker } from './deepbookMarketMaker.js';
(async () => {
const privateKey = ''; // Can encapsulate this in a .env file
// Initialize with balance managers if created
const balanceManagers = {
MANAGER_1: {
address: '',
tradeCap: '',
},
};
const mmClient = new DeepBookMarketMaker(privateKey, 'testnet', balanceManagers);
const tx = new Transaction();
// Read only call
console.log(await mmClient.checkManagerBalance('MANAGER_1', 'SUI'));
console.log(await mmClient.getLevel2Range('SUI_DBUSDC', 0.1, 100, true));
// Balance manager contract call
mmClient.balanceManager.depositIntoManager('MANAGER_1', 'DBUSDT', 10000)(tx);
mmClient.balanceManager.withdrawAllFromManager(
'MANAGER_1',
'DBUSDT',
mmClient.getActiveAddress(),
)(tx);
// Example custom PTB call in DeepBookMarketMaker class
mmClient.placeLimitOrderExample(tx);
mmClient.flashLoanExample(tx);
let res = await mmClient.signAndExecute(tx);
console.dir(res, { depth: null });
})();
Referral functions
The SDK provides functions for managing pool-specific referrals. Referrals allow users to earn a portion of trading fees from traders they refer.
Pool referral functions
These functions are available on the deepbook contract for managing referrals at the pool level.
The referral multiplier must be a multiple of 0.1 (e.g., 0.1, 0.2, 0.3, ...) and cannot exceed 2.0.
// Mint a new referral for a specific pool
// multiplier determines the portion of fees allocated to the referrer
// Valid values: 0.1, 0.2, 0.3, ... up to 2.0
dbClient.deepbook.mintReferral('SUI_DBUSDC', 0.1)(tx);
// Update the multiplier for an existing referral
dbClient.deepbook.updatePoolReferralMultiplier('SUI_DBUSDC', referralId, 0.2)(tx);
// Claim accumulated referral rewards (returns base, quote, and DEEP coins)
const { baseRewards, quoteRewards, deepRewards } = tx.add(
dbClient.deepbook.claimPoolReferralRewards('SUI_DBUSDC', referralId)
);
// Get the current balances for a referral
dbClient.deepbook.getPoolReferralBalances('SUI_DBUSDC', referralId)(tx);
// Get the multiplier for a referral
dbClient.deepbook.poolReferralMultiplier('SUI_DBUSDC', referralId)(tx);
Balance manager referral functions
These functions are available on the balanceManager contract for associating referrals with balance managers.
// Generate a trade cap first (needed for setting referrals)
const tradeCap = tx.add(dbClient.balanceManager.mintTradeCap('MANAGER_1'));
// Set a referral for a balance manager (pool-specific)
// Each balance manager can have different referrals for different pools
dbClient.balanceManager.setBalanceManagerReferral('MANAGER_1', referralId, tradeCap)(tx);
// Unset the referral for a specific pool
dbClient.balanceManager.unsetBalanceManagerReferral('MANAGER_1', 'SUI_DBUSDC', tradeCap)(tx);
// Get the referral ID associated with a balance manager for a specific pool
dbClient.balanceManager.getBalanceManagerReferralId('MANAGER_1', 'SUI_DBUSDC')(tx);
// Get the owner of a referral
dbClient.balanceManager.balanceManagerReferralOwner(referralId)(tx);
// Get the pool ID associated with a referral
dbClient.balanceManager.balanceManagerReferralPoolId(referralId)(tx);
Related links
The DeepBookV3 SDK repository on GitHub.
The DeepBookV3 SDK node package on NPM.
The DeepBookV3 repository on GitHub.