@dipcoinlab/perp-client-ts
v0.5.0
Published
TypeScript SDK for DipCoin Perpetual Trading on Sui blockchain
Downloads
565
Maintainers
Readme
DipCoin Perpetual Trading SDK
TypeScript SDK for DipCoin Perpetual Trading on Sui blockchain.
Table of Contents
📦 Installation
npm install @dipcoinlab/perp-client-ts
# or
yarn add @dipcoinlab/perp-client-ts🚀 Quick Start
1. Install Dependencies
npm install2. Configure Environment
Create a .env file in the project root:
PRIVATE_KEY=your-private-key-here3. Run Example
npm run example
# or
RUN_LIMIT_ORDER=1 npm run exampleThis command executes the unified script at examples/index.ts.
Each trading action (deposits, withdrawals, order placement, margin edits, TP/SL flows, etc.) is disabled by default and can be opt‑in via environment flags. See USAGE.md for the complete flag matrix and safety notes.
🎯 Unified Demo Script
The legacy example files have been consolidated into examples/index.ts.
It executes a curated workflow in the following order:
- Wallet setup & authentication (prints the derived wallet address and target network)
- Optional on-chain funding (deposit / withdraw) driven by
DEPOSIT_AMOUNTandWITHDRAW_AMOUNT - Account, position, and open-order snapshots for the primary
DEMO_SYMBOL - Market and limit order placement with optional post-placement cancellation
- Market data inspection (order book snapshot + ticker snapshot with spread calculations)
- Leverage & margin utilities, including preferred leverage adjustments and isolated margin add/remove flows
- TP/SL lifecycle management (create, list, edit, and cancel position-level TP/SL plans)
All on-chain or order-creating steps are opt-in. Enable only the pieces you wish to test:
| Flag | Purpose | Default |
| --- | --- | --- |
| RUN_DEPOSIT / RUN_WITHDRAW | Move funds between wallet & exchange | 0 |
| RUN_MARKET_ORDER | Submit a market order | 0 |
| RUN_LIMIT_ORDER | Submit a limit order (configure LIMIT_ORDER_PRICE) | 0 |
| RUN_CANCEL_ORDER | Cancel the first open order | 0 |
| RUN_MARKET_DATA | Print order book + ticker snapshots | 1 |
| RUN_ADJUST_LEVERAGE | Update preferred leverage (off-chain) | 0 |
| RUN_MARGIN_ADD / RUN_MARGIN_REMOVE | Add/remove isolated margin (on-chain) | 0 |
| RUN_TPSL_DEMO | Create TP/SL orders for a position | 0 |
| RUN_TPSL_EDIT | Edit existing TP/SL plans (needs plan IDs) | 0 |
Additional tuning variables such as DEPOSIT_AMOUNT, MARKET_ORDER_QTY, LIMIT_ORDER_SIDE, MARGIN_SYMBOL, TPSL_SYMBOL, etc. mirror the names from the previous standalone scripts to remain backwards compatible.
Need a quick way to only inspect or update preferred leverage? Run
npm run example:leverage(seeUSAGE.mdfor flags such asSET_LEVERAGE,LEVERAGE_TARGET,LEVERAGE_SYMBOL).
Script Flow Details
Each major block inside examples/index.ts is wrapped in a helper such as maybeDeposit, maybePlaceMarketOrder, or maybeRunTpSlFlow.
Those helpers gate their logic behind the environment switches above, print labeled sections (via logSection), and provide success/error emojis so you can visually trace the execution in your terminal logs. The script also:
- Fetches trading pairs and resolves the
perpIdautomatically for the configured symbol (falls back tosdk.getPerpetualID). - Shows wallet/account diagnostics before any trading action so you can confirm balances and exposure.
- Prints the top-of-book bids/asks plus percentage spread by using BigNumber math, making it easier to compare against the web UI.
- Surfaces TP/SL plan IDs and hashes so that subsequent edits or cancellations can reuse real identifiers without manual API calls.
Environment Parameters
Beyond the boolean toggles, the demo reads the following configuration values (all optional, shown with defaults from the script):
| Variable | Purpose | Default |
| --- | --- | --- |
| NETWORK | mainnet or testnet selection passed to initDipCoinPerpSDK. | testnet |
| DEMO_SYMBOL | Primary symbol inspected by the snapshots and trading actions. | BTC-PERP |
| PRIVATE_KEY | Private key for signing transactions (required). | none |
| DEPOSIT_AMOUNT / WITHDRAW_AMOUNT | USDC amounts for bank transfers. | 10 / 5 |
| MARKET_ORDER_QTY, MARKET_ORDER_LEVERAGE, MARKET_ORDER_SIDE | Market order size, leverage, and side (BUY/SELL). | 0.01, 20, BUY |
| LIMIT_ORDER_QTY, LIMIT_ORDER_PRICE, LIMIT_ORDER_LEVERAGE, LIMIT_ORDER_SIDE | Limit order parameters. | 0.01, 85000, 20, BUY |
| MARGIN_SYMBOL, MARGIN_ADD_AMOUNT, MARGIN_REMOVE_AMOUNT | Target symbol and USDC sizes for margin utilities. | DEMO_SYMBOL, 10, 5 |
| MARGIN_TARGET_LEVERAGE, MARGIN_TYPE | Preferred leverage update payload. | 20, ISOLATED |
| TPSL_SYMBOL, POSITION_ID | Symbol/position used when fetching TP/SL plans (falls back to detected positions). | DEMO_SYMBOL, auto-detected |
| TPSL_EDIT_TP_PLAN_ID, TPSL_EDIT_SL_PLAN_ID, TPSL_CANCEL_HASH | Explicit plan IDs/hashes for TP/SL edit and cancel flows. | auto-resolved when possible |
Example: run just the limit-order workflow against ETH with a tighter size.
DEMO_SYMBOL=ETH-PERP RUN_LIMIT_ORDER=1 LIMIT_ORDER_QTY=0.05 LIMIT_ORDER_PRICE=3800 npm run exampleBecause the script exits on authentication failure or missing PRIVATE_KEY, you can safely iterate by tweaking .env without risking partial executions. When testing on-chain actions, double-check gas budgets and balances before enabling their flags.
Leverage Utility Recipes
The demo exposes two leverage helpers:
showPreferredLeverage→ callssdk.getUserConfig(symbol)to fetch the current leverage, margin type, and raw on-chain value.maybeAdjustPreferredLeverage→ conditionally invokessdk.adjustLeverage(...)whenRUN_ADJUST_LEVERAGE=1(orRUN_SET_LEVERAGE=1) and prints the post-update config.
Run the leverage inspection on its own:
RUN_MARKET_DATA=0 RUN_ADJUST_LEVERAGE=0 npm run exampleUpdate the preferred leverage for ETH perpetuals to 12x isolated:
MARGIN_SYMBOL=ETH-PERP RUN_ADJUST_LEVERAGE=1 MARGIN_TARGET_LEVERAGE=12 MARGIN_TYPE=ISOLATED npm run exampleBehind the scenes the SDK sequence is:
const current = await sdk.getUserConfig("ETH-PERP");
console.log("Current leverage:", current.data?.leverage);
await sdk.adjustLeverage({ symbol: "ETH-PERP", leverage: "12", marginType: "ISOLATED" });TP/SL Utility Recipes
maybeRunTpSlFlow orchestrates the entire lifecycle:
- Detect or fetch
POSITION_IDfor the configuredTPSL_SYMBOL. - Place TP/SL plans when
RUN_TPSL_DEMO=1viasdk.placePositionTpSlOrders. - Read back the plan list with
sdk.getPositionTpSl(positionId, "position"). - Edit existing plans when
RUN_TPSL_EDIT=1andTPSL_EDIT_TP_PLAN_ID/TPSL_EDIT_SL_PLAN_IDare provided (or auto-detected). - Cancel a specific plan by hash with
sdk.cancelTpSlOrders.
Minimal command to list current TP/SL plans for BTC and stop after the fetch:
RUN_TPSL_DEMO=0 RUN_TPSL_EDIT=0 TPSL_SYMBOL=BTC-PERP POSITION_ID=<position-id> npm run exampleDemo new TP/SL orders on ETH using the auto-detected position and Perpetual ID:
TPSL_SYMBOL=ETH-PERP RUN_TPSL_DEMO=1 npm run exampleEdit an existing TP plan and cancel another by hash:
RUN_TPSL_EDIT=1 TPSL_EDIT_TP_PLAN_ID=<plan-id> TPSL_CANCEL_HASH=<plan-hash> npm run exampleThese flows map directly to the SDK calls shown in the Manage Existing Position TP/SL Orders section if you prefer to script them manually.
📖 Usage Guide
Initialize SDK
import { initDipCoinPerpSDK } from "@dipcoinlab/perp-client-ts";
// Initialize with private key string
const sdk = initDipCoinPerpSDK("your-private-key-string", {
network: "mainnet", // or "testnet"
apiBaseUrl: "https://api.dipcoin.io", // Optional, defaults based on network
});
// Or initialize with Keypair
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
const keypair = Ed25519Keypair.fromSecretKey(/* your secret key */);
const sdk = initDipCoinPerpSDK(keypair, {
network: "mainnet",
});Core Features
Authentication (Onboarding)
Before using the SDK, you need to authenticate first. The SDK will automatically handle authentication when you call any API method, but you can also authenticate manually:
// Manual authentication
const authResult = await sdk.authenticate();
if (authResult.status) {
console.log("Authenticated! JWT Token:", authResult.data);
} else {
console.error("Authentication failed:", authResult.error);
}
// Get JWT token (authenticates if needed)
const tokenResult = await sdk.getJWTToken();
if (tokenResult.status) {
console.log("JWT Token:", tokenResult.data);
}
// Force refresh token
const refreshResult = await sdk.getJWTToken(true);
// Clear authentication (logout)
sdk.clearAuth();Note: All API methods automatically authenticate if needed, so you don't need to call authenticate() manually in most cases.
Account Information
Get account balance and trading information:
const accountInfo = await sdk.getAccountInfo();
if (accountInfo.status && accountInfo.data) {
console.log("Wallet Balance:", accountInfo.data.walletBalance);
console.log("Account Value:", accountInfo.data.accountValue);
console.log("Free Collateral:", accountInfo.data.freeCollateral);
console.log("Unrealized PnL:", accountInfo.data.totalUnrealizedProfit);
}Deposit and Withdraw
Deposit USDC to the exchange bank account for trading collateral, or withdraw USDC back to your wallet:
// Deposit USDC to bank (deposit funds for trading)
const depositResult = await sdk.depositToBank(100); // Deposit 100 USDC
if (depositResult) {
console.log("Deposit successful!");
}
// Withdraw USDC from bank (withdraw funds to wallet)
const withdrawResult = await sdk.withdrawFromBank(50); // Withdraw 50 USDC
if (withdrawResult) {
console.log("Withdraw successful!");
}Note: These methods execute on-chain transactions on Sui blockchain. Make sure you have sufficient USDC balance in your wallet before depositing, and sufficient balance in your exchange account before withdrawing.
Adjust Preferred Leverage
Match the web client's leverage settings through the same REST API:
await sdk.adjustLeverage({
symbol: "BTC-PERP",
leverage: "5", // 5x leverage
marginType: "ISOLATED", // optional, defaults to ISOLATED
});Add or Remove Position Margin (On-chain)
Interact with the on-chain contracts to add or remove isolated margin. These actions spend gas and require sufficient balances.
// Add 2 USDC margin to BTC-PERP
await sdk.addMargin({
amount: 2,
symbol: "BTC-PERP",
});
// Remove 1 USDC margin from BTC-PERP
await sdk.removeMargin({
amount: 1,
symbol: "BTC-PERP",
});⚠️ Margin operations are on-chain transactions. Double-check the amount and symbol before running them.
Place Order
Place a market or limit order:
import { OrderSide, OrderType } from "@dipcoinlab/perp-client-ts";
// Market order
const result = await sdk.placeOrder({
symbol: "BTC-PERP",
side: OrderSide.BUY,
orderType: OrderType.MARKET,
quantity: "0.1", // 0.1 BTC
leverage: "10", // 10x leverage
});
// Limit order
const limitResult = await sdk.placeOrder({
symbol: "BTC-PERP",
side: OrderSide.BUY,
orderType: OrderType.LIMIT,
quantity: "0.1",
price: "50000", // Limit price
leverage: "10",
reduceOnly: false, // Optional: only reduce position
});
if (result.status) {
console.log("Order placed successfully:", result.data);
} else {
console.error("Order failed:", result.error);
}Place Order with TP/SL
Place an order with take profit and stop loss:
const result = await sdk.placeOrder({
symbol: "BTC-PERP",
side: OrderSide.BUY,
orderType: OrderType.MARKET,
quantity: "0.1",
leverage: "10",
// Take profit
tpTriggerPrice: "55000",
tpOrderType: OrderType.MARKET,
// Stop loss
slTriggerPrice: "45000",
slOrderType: OrderType.MARKET,
});Manage Existing Position TP/SL Orders
await sdk.placePositionTpSlOrders({
symbol: "BTC-PERP",
market: "<perpetual-id>",
side: OrderSide.SELL,
isLong: false,
leverage: "10",
quantity: "0.05",
tp: {
triggerPrice: "90000",
orderType: OrderType.LIMIT,
orderPrice: "90000",
tpslType: "position",
},
sl: {
triggerPrice: "70000",
orderType: OrderType.MARKET,
tpslType: "position",
},
});
const tpSlOrders = await sdk.getPositionTpSl("<position-id>", "position");
await sdk.cancelTpSlOrders({
symbol: "BTC-PERP",
orderHashes: ["0xabc..."],
});Market Data (Ticker & Order Book)
const ticker = await sdk.getTicker("BTC-PERP");
const orderBook = await sdk.getOrderBook("BTC-PERP");Cancel Order
Cancel one or more orders:
const result = await sdk.cancelOrder({
symbol: "BTC-PERP",
orderHashes: ["0x1234...", "0x5678..."], // Array of order hashes
});
if (result.status) {
console.log("Orders cancelled successfully");
} else {
console.error("Cancel failed:", result.error);
}Get Positions
Get current positions:
// Get all positions
const positions = await sdk.getPositions();
// Get positions for specific symbol
const btcPositions = await sdk.getPositions("BTC-PERP");
if (positions.status && positions.data) {
positions.data.forEach((position) => {
console.log("Symbol:", position.symbol);
console.log("Side:", position.side);
console.log("Quantity:", position.quantity);
console.log("Entry Price:", position.avgEntryPrice);
console.log("Unrealized PnL:", position.unrealizedProfit);
console.log("Liquidation Price:", position.liquidationPrice);
});
}Get Open Orders
Get current open orders:
// Get all open orders
const orders = await sdk.getOpenOrders();
// Get open orders for specific symbol
const btcOrders = await sdk.getOpenOrders("BTC-PERP");
if (orders.status && orders.data) {
orders.data.forEach((order) => {
console.log("Symbol:", order.symbol);
console.log("Side:", order.side);
console.log("Type:", order.orderType);
console.log("Price:", order.price);
console.log("Quantity:", order.quantity);
console.log("Filled:", order.filledQty);
});
}API Reference
DipCoinPerpSDK
Main SDK class for interacting with DipCoin Perpetual Trading.
Methods
placeOrder(params: PlaceOrderParams): Promise<SDKResponse<OrderResponse>>
Place a new order.
Parameters:
symbol: Trading symbol (e.g., "BTC-PERP")side: Order side (OrderSide.BUYorOrderSide.SELL)orderType: Order type (OrderType.MARKETorOrderType.LIMIT)quantity: Order quantity (number or string)price: Order price (required for LIMIT orders)leverage: Leverage multiplier (number or string)market: Optional market IDreduceOnly: Optional, only reduce positionclientId: Optional client order IDtpTriggerPrice: Optional take profit trigger pricetpOrderType: Optional take profit order typetpOrderPrice: Optional take profit order priceslTriggerPrice: Optional stop loss trigger priceslOrderType: Optional stop loss order typeslOrderPrice: Optional stop loss order price
cancelOrder(params: CancelOrderParams): Promise<SDKResponse<OrderResponse>>
Cancel one or more orders.
Parameters:
symbol: Trading symbolorderHashes: Array of order hashes to cancelparentAddress: Optional parent address (defaults to wallet address)
getAccountInfo(): Promise<SDKResponse<AccountInfo>>
Get account information including balance, collateral, and PnL.
getPositions(symbol?: string): Promise<SDKResponse<Position[]>>
Get current positions. Optionally filter by symbol.
getOpenOrders(symbol?: string): Promise<SDKResponse<OpenOrder[]>>
Get current open orders. Optionally filter by symbol.
depositToBank(amount: number): Promise<any>
Deposit USDC from wallet to exchange bank account for trading collateral.
Parameters:
amount: Deposit amount in USDC (standard units, e.g., 100 means 100 USDC)
Returns: On-chain transaction result
Note: This is an on-chain transaction on Sui blockchain. Ensure you have sufficient USDC balance in your wallet.
withdrawFromBank(amount: number): Promise<any>
Withdraw USDC from exchange bank account back to wallet.
Parameters:
amount: Withdraw amount in USDC (standard units, e.g., 50 means 50 USDC)
Returns: On-chain transaction result
Note: This is an on-chain transaction on Sui blockchain. Ensure you have sufficient balance in your exchange account.
Types
OrderSide
enum OrderSide {
BUY = "BUY",
SELL = "SELL",
}OrderType
enum OrderType {
MARKET = "MARKET",
LIMIT = "LIMIT",
}AccountInfo
interface AccountInfo {
walletBalance: string;
totalUnrealizedProfit: string;
accountValue: string;
freeCollateral: string;
totalMargin: string;
}Position
interface Position {
symbol: string;
side: string;
quantity: string;
avgEntryPrice: string;
leverage: string;
margin: string;
unrealizedProfit: string;
liquidationPrice: string;
// ... more fields
}OpenOrder
interface OpenOrder {
hash: string;
symbol: string;
side: string;
orderType: string;
price: string;
quantity: string;
filledQty: string;
leverage: string;
status: string;
// ... more fields
}Error Handling
All SDK methods return a SDKResponse object with the following structure:
interface SDKResponse<T> {
status: boolean; // Operation success status
data?: T; // Response data if successful
error?: string; // Error message if failed
}Always check the status field before accessing data:
const result = await sdk.placeOrder(/* ... */);
if (result.status) {
// Success - use result.data
console.log(result.data);
} else {
// Error - use result.error
console.error(result.error);
}Examples
Complete Trading Flow
import { initDipCoinPerpSDK, OrderSide, OrderType } from "@dipcoinlab/perp-client-ts";
// Initialize SDK
const sdk = initDipCoinPerpSDK("your-private-key", {
network: "testnet",
});
async function tradingFlow() {
// 1. Deposit funds to exchange bank account
console.log("Depositing 100 USDC to bank...");
await sdk.depositToBank(100);
// 2. Check account balance
const account = await sdk.getAccountInfo();
if (account.status) {
console.log("Account Value:", account.data?.accountValue);
}
// 3. Check existing positions
const positions = await sdk.getPositions();
if (positions.status) {
console.log("Current Positions:", positions.data);
}
// 4. Place a market order
const orderResult = await sdk.placeOrder({
symbol: "BTC-PERP",
side: OrderSide.BUY,
orderType: OrderType.MARKET,
quantity: "0.1",
leverage: "10",
});
if (orderResult.status) {
console.log("Order placed:", orderResult.data);
}
// 5. Adjust preferred leverage for BTC perpetuals
const leverageUpdate = await sdk.adjustLeverage({
symbol: "BTC-PERP",
leverage: "12",
marginType: "ISOLATED",
});
if (leverageUpdate.status) {
console.log("Leverage updated:", leverageUpdate.data);
} else {
console.warn("Leverage update failed:", leverageUpdate.error);
}
// 6. Create and manage TP/SL plans for the active BTC position
const tpSlResult = await sdk.placePositionTpSlOrders({
symbol: "BTC-PERP",
side: OrderSide.SELL,
isLong: true,
leverage: "10",
quantity: "0.1",
tp: {
triggerPrice: "55000",
orderType: OrderType.LIMIT,
orderPrice: "55000",
tpslType: "position",
},
sl: {
triggerPrice: "45000",
orderType: OrderType.MARKET,
tpslType: "position",
},
});
if (tpSlResult.status) {
console.log("TP/SL plans placed:", tpSlResult.data);
const positionId = tpSlResult.data?.positionId ?? "<position-id>";
const plans = await sdk.getPositionTpSl(positionId, "position");
if (plans.status) {
console.log("Current TP/SL plans:", plans.data);
if (plans.data && plans.data.length > 0) {
const cancelTpSl = await sdk.cancelTpSlOrders({
symbol: "BTC-PERP",
orderHashes: [plans.data[0].hash],
});
console.log("Cancelled TP/SL plan:", cancelTpSl);
}
}
} else {
console.warn("TP/SL placement failed:", tpSlResult.error);
}
// 7. Check open orders
const openOrders = await sdk.getOpenOrders("BTC-PERP");
if (openOrders.status) {
console.log("Open Orders:", openOrders.data);
}
// 8. Cancel an order (if needed)
if (openOrders.status && openOrders.data && openOrders.data.length > 0) {
const cancelResult = await sdk.cancelOrder({
symbol: "BTC-PERP",
orderHashes: [openOrders.data[0].hash],
});
console.log("Cancel result:", cancelResult);
}
// 9. Withdraw funds from exchange bank account
console.log("Withdrawing 50 USDC from bank...");
await sdk.withdrawFromBank(50);
}
tradingFlow();Example Scripts
npm run example– Runsexamples/index.ts. Enable extra steps with env flags such asRUN_LIMIT_ORDER=1,RUN_MARGIN_ADD=1,RUN_TPSL_DEMO=1, etc.
License
Apache License 2.0
