DeepBook Margin SDK
DeepBook Margin TypeScript SDK는 트랜잭션 call을 추상화하여 leveraged trading을 위한 DeepBook Margin 패키지와 직접 상호작용할 수 있게 한다.
설치
프로젝트에서 SDK를 사용하려면, margin trading 기능을 포함하는 @mysten/deepbook-v3 패키지를 설치한다.
- npm
- Yarn
- pnpm
npm install @mysten/deepbook-v3
yarn add @mysten/deepbook-v3
pnpm add @mysten/deepbook-v3
constant
DeepBook SDK에는 DeepBook Margin의 최신 배포 주소와 마진 풀 및 configuration을 유지하는 constants file(/utils/constants.ts)이 포함된다.
constants.ts
constants.tsDeepBookClient
DeepBook Margin으로 작업하려면, 클라이언트 extension을 사용해 Sui 클라이언트에 DeepBook 기능을 추가한다. Sui TypeScript SDK는 트랜잭션을 처리하는 데 필요한 SuiGrpcClient와 핵심 기능을 제공한다. 다음 예시는 이 라이브러리도 함께 import한다.
import { deepbook, type DeepBookClient } from '@mysten/deepbook-v3';
import type { ClientWithExtensions } from '@mysten/sui/client';
import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
import { SuiGrpcClient } from '@mysten/sui/grpc';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
class DeepBookMarginTrader {
client: ClientWithExtensions<{ deepbook: DeepBookClient }>;
keypair: Ed25519Keypair;
constructor(privateKey: string, env: 'testnet' | 'mainnet') {
this.keypair = this.getSignerFromPK(privateKey);
this.client = new SuiGrpcClient({
network: env,
baseUrl:
env === 'mainnet'
? 'https://fullnode.mainnet.sui.io:443'
: 'https://fullnode.testnet.sui.io:443',
}).$extend(
deepbook({
address: this.getActiveAddress(),
}),
);
}
getSignerFromPK = (privateKey: string): Ed25519Keypair => {
const { scheme, secretKey } = decodeSuiPrivateKey(privateKey);
if (scheme === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);
throw new Error(`Unsupported scheme: ${scheme}`);
};
getActiveAddress() {
return this.keypair.toSuiAddress();
}
}
Keys: Coin, Pool, and MarginManager
코인, 풀, 또는 margin manager의 입력을 요구하는 함수는 파라미터로 해당 객체의 key를 요구한다. SDK는 이 데이터를 메모리에서 key:value 관계로 관리한다. 일부 기본 데이터는 SDK와 함께 제공된다(utils/constants.ts 참조). 코인은 CoinMap에 저장되고, 풀은 PoolMap에 저장되며, margin manager는 config의 MarginManagerMap에 저장된다.
margin manager
margin trade를 배치하기 전에, 클라이언트에 margin manager 주소를 제공해야 한다. manager key는 클라이언트에서 MarginManager interface로 정의된 객체를 가리킨다. 마진 매니저를 참고한다. 클라이언트로 margin manager를 initialize한다. margin manager를 생성하지 않으면 클라이언트가 margin manager를 생성하도록 의존할 수 있지만, 이 경우 사용자는 클라이언트를 다시 initialize해야 한다.
기존 margin manager를 사용하는 예시:
import { deepbook, type DeepBookClient } from '@mysten/deepbook-v3';
import type { MarginManager } from '@mysten/deepbook-v3';
import type { ClientWithExtensions } from '@mysten/sui/client';
import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
import { SuiGrpcClient } from '@mysten/sui/grpc';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { config } from 'dotenv';
config();
const MARGIN_MANAGER_KEY = 'MARGIN_MANAGER_1';
class DeepBookMarginTrader {
client: ClientWithExtensions<{ deepbook: DeepBookClient }>;
keypair: Ed25519Keypair;
constructor(privateKey: string, env: 'testnet' | 'mainnet') {
this.keypair = this.getSignerFromPK(privateKey);
this.client = new SuiGrpcClient({
network: env,
baseUrl:
env === 'mainnet'
? 'https://fullnode.mainnet.sui.io:443'
: 'https://fullnode.testnet.sui.io:443',
}).$extend(
deepbook({
address: this.getActiveAddress(),
marginManagers: this.getMarginManagers(),
}),
);
}
getSignerFromPK = (privateKey: string): Ed25519Keypair => {
const { scheme, secretKey } = decodeSuiPrivateKey(privateKey);
if (scheme === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);
throw new Error(`Unsupported scheme: ${scheme}`);
};
getActiveAddress() {
return this.keypair.toSuiAddress();
}
getMarginManagers(): { [key: string]: MarginManager } {
const marginManagerAddress = process.env.MARGIN_MANAGER_ADDRESS;
const poolKey = process.env.POOL_KEY || 'SUI_DBUSDC';
if (!marginManagerAddress) {
throw new Error('No margin manager address found');
}
return {
[MARGIN_MANAGER_KEY]: {
address: marginManagerAddress,
poolKey: poolKey,
},
};
}
}
margin manager를 생성하는 예시:
import { deepbook, type DeepBookClient } from '@mysten/deepbook-v3';
import type { MarginManager } from '@mysten/deepbook-v3';
import type { ClientWithExtensions } from '@mysten/sui/client';
import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
import { SuiGrpcClient } from '@mysten/sui/grpc';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { Transaction } from '@mysten/sui/transactions';
const MARGIN_MANAGER_KEY = 'MARGIN_MANAGER_1';
class DeepBookMarginTrader {
client: ClientWithExtensions<{ deepbook: DeepBookClient }>;
keypair: Ed25519Keypair;
env: 'testnet' | 'mainnet';
constructor(privateKey: string, env: 'testnet' | 'mainnet') {
this.env = env;
this.keypair = this.getSignerFromPK(privateKey);
this.client = this.#createClient(env);
}
#createClient(env: 'testnet' | 'mainnet', marginManagers?: { [key: string]: MarginManager }) {
return new SuiGrpcClient({
network: env,
baseUrl:
env === 'mainnet'
? 'https://fullnode.mainnet.sui.io:443'
: 'https://fullnode.testnet.sui.io:443',
}).$extend(
deepbook({
address: this.getActiveAddress(),
marginManagers,
}),
);
}
getSignerFromPK = (privateKey: string): Ed25519Keypair => {
const { scheme, secretKey } = decodeSuiPrivateKey(privateKey);
if (scheme === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);
throw new Error(`Unsupported scheme: ${scheme}`);
};
getActiveAddress() {
return this.keypair.toSuiAddress();
}
async createMarginManagerAndReinitialize() {
let tx = new Transaction();
const poolKey = 'SUI_DBUSDC';
tx.add(this.client.deepbook.marginManager.newMarginManager(poolKey));
const result = await this.client.core.signAndExecuteTransaction({
transaction: tx,
signer: this.keypair,
include: { effects: true, objectTypes: true },
});
if (result.$kind === 'FailedTransaction') {
throw new Error('Transaction failed');
}
const objectTypes = result.Transaction?.objectTypes ?? {};
const marginManagerAddress = result.Transaction?.effects?.changedObjects?.find(
(obj) =>
obj.idOperation === 'Created' && objectTypes[obj.objectId]?.includes('MarginManager'),
)?.objectId;
if (!marginManagerAddress) {
throw new Error('Failed to create margin manager');
}
const marginManagers: { [key: string]: MarginManager } = {
[MARGIN_MANAGER_KEY]: {
address: marginManagerAddress,
poolKey: poolKey,
},
};
this.client = this.#createClient(this.env, marginManagers);
}
}