@kanalabs/perpetual-sdk
v1.0.24
Published
perpetual sdk functionalities
Readme
INSTALLATION
npm i @kanalabs/perpetual-sdk
TESTNET
// Note --> Currently we using APT-USD --> "marketID: 1338" // Note --> Currently we using BTC-USD --> "marketID: 1339" // Note --> Currently we using ETH-USD --> "marketID: 1340"
MAINNET
// Note --> Currently we using APT-USD --> "marketID: 14" // Note --> Currently we using BTC-USD --> "marketID: 15" // Note --> Currently we using ETH-USD --> "marketID: 16"
MODULE IMPORTS AND INITIALISING THE SDK
import { PerpsMarkets } from '@kanalabs/perpetual-sdk';
const marketIds = [1338, 1339];
const perpsMarketsInstance = new PerpsMarkets({
network: process.env.PERPS_APTOS_NETWORK!,
nodeurl: process.env.PERPS_APTOS_INDEXER_NODE_URL!,
apikey: process.env.PERPS_APTOS_INDEXER_API_KEY!
});
await perpsMarketsInstance.init(marketIds);SETUP THE CLIENT
const clientConfig: ClientConfig = {
API_KEY: process.env.PERPS_APTOS_INDEXER_API_KEY as string,
};
const config = new AptosConfig({
fullnode: process.env.PERPS_APTOS_INDEXER_NODE_URL,
network: process.env.PERPS_APTOS_NETWORK as Network,
clientConfig
});
const aptos = new Aptos(config);
const formattedPrivateKey = PrivateKey.formatPrivateKey(
process.env.APTOS_PRIVATEKEY || "",
'ed25519' as PrivateKeyVariants
);
const account = Account.fromPrivateKey({
privateKey: new Ed25519PrivateKey(formattedPrivateKey),
});TESTNET APT FAUCET
const amount = 300000000;
const response = await perpsMarketsInstance.aptTestnetFaucet(account.accountAddress, amount);TESTNET USDT FAUCET
const amount = 300000000;
const payload = await perpsMarketsInstance.usdcTestnetFaucet(amount);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});DEPOSIT
const amount = 50000000; //50 USDC
const payload = perpsMarketsInstance.deposit(amount)
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});WITHDRAW
const marketId = 12;
const amount = 7989000;
const payload = perpsMarketsInstance.withdraw(marketId, amount)
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});// NOTE : trade-side: true for long side and false for short side direction: false for open position and true for close position
PLACE LIMIT OPEN LONG OR OPEN SHORT
const marketId = 17;
const tradeSide = true;
const direction = false;
const size = 2000;
const price = 5000;
const leverage = 10;
const restriction = undefined;
const takeProfit = 6000;
const stopLoss = 4000;
const payload = await perpsMarketsInstance.placeLimitOrder(marketId, tradeSide, direction, size, price, leverage, restriction, takeProfit, stopLoss);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});// NOTE : trade-side: true for long side and false for short side direction: false for open position and true for close position
PLACE LIMIT CLOSE LONG OR CLOSE SHORT
const marketId = 17;
const tradeSide = true;
const direction = true;
const size = 2000;
const price = 5000;
const leverage = 10;
const takeProfit = 6000;
const stopLoss = 4000;
const restriction = undefined;
const payload = await perpsMarketsInstance.placeLimitOrder(marketId, tradeSide, direction, size, price, leverage, restriction, takeProfit, stopLoss);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});// NOTE : trade-side: true for long side and false for short side direction: false for open position and true for close position
PLACE MARKET OPEN LONG OR OPEN SHORT
const marketId = 12;
const tradeSide = false;
const direction = false;
const size = 2000; // 2 APT
const leverage = 10;
const takeProfit = 4000;
const stopLoss = 6000;
const payload = await perpsMarketsInstance.placeMarketOrder(marketId, tradeSide, direction, size, leverage, takeProfit, stopLoss);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});PLACE MARKET CLOSE LONG OR CLOSE SHORT
const marketId = 12;
const tradeSide = false;
const direction = true;
const size = 2000;
const leverage = 1;
const payload = perpsMarketsInstance.placeMarketOrder(marketId, tradeSide, direction, size, leverage);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});// NOTE : trade-side: true for long side and false for short side direction: false for open position and true for close position orderTypes: true for limit orders and false for market orders
PLACE MULTIPLE ORDERS
const marketId = 17;
const orderTypes = [true, true]
const tradeSide = [true, true];
const direction = [false, false];
const size = [2000, 5000];
const price = [5000, 6000];
const leverage = [10, 8];
const takeProfit = [6000, 8000];
const stopLoss = [4000, 3000];
const restrictions = [undefined, undefined];
const payload = await perpsMarketsInstance.placeMultipleOrders(marketId, orderTypes, tradeSides, directions, sizes, prices, leverages, restrictions, takeProfits, stopLosses);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});// NOTE : trade-side: true for long side and false for short side direction: false for open position and true for close position orderTypes: true for limit orders and false for market orders
CANCEL AND PLACE MULTIPLE ORDERS
const marketId = 17;
const orderIds = ['11529215609061372858372', '11510769146441165185932'];
const orderSides = [true, false];
const orderTypes = [true, true]
const tradeSide = [true, true];
const direction = [false, false];
const size = [2000, 5000];
const price = [5000, 6000];
const leverage = [10, 8];
const takeProfit = [6000, 8000];
const stopLoss = [4000, 3000];
const restrictions = [undefined, undefined];
const payload = await perpsMarketsInstance.cancelAndlaceMultipleOrders(marketId, orderIds, orderSides, orderTypes, tradeSides, directions, sizes, prices, leverages, restrictions, takeProfits, stopLosses);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});ADD INSURANCE
const amount = 1000;
const payload = await perpsMarketsInstance.addInsurance(amount);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});UPDATE TAKE PROFIT
const marketId = 17;
const newTakeProfitPrice = 7000;
const tradeSide = true;
const payload = await perpsMarketsInstance.updateTakeProfit(marketId, tradeSide, newTakeProfitPrice);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});UPDATE STOP LOSS
const marketId = 17;
const newStopLossPrice = 7000;
const tradeSide = true;
const payload = await perpsMarketsInstance.updateStopLoss(marketId, tradeSide, newStopLossPrice);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});// Note : orderSides: true for long side and false for short side
CANCELING AN MULTIPLE ORDERS
const marketId = 3;
const orderIds = ['368935022224564295536', '368935022224564295537'];
const orderSides = [true, false];
const payload = perpsMarketsInstance.cancelMultipleOrders(marketId, orderIds, orderSides);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});GET ORDER BOOK
const marketId = 10;
const maxAsks = 100;
const maxBids = 100;
const orderBook = await perpsMarketsInstance.orderBook(marketId, maxAsks, maxBids);
;Example Response
{
"asks": [
{
"custodian_id": "0",
"market_id": "12",
"order_id": "7268018150302766077060",
"price": "5252",
"remaining_size": "1888916",
"side": true,
"user": "0x7676c6ad191680ee72a03f724aa750a66a9570ca90c7b6861c94a7c2c4ec5515"
},
{
"custodian_id": "0",
"market_id": "12",
"order_id": "7304911497704106890377",
"price": "5257",
"remaining_size": "2010119",
"side": true,
"user": "0x7676c6ad191680ee72a03f724aa750a66a9570ca90c7b6861c94a7c2c4ec5515"
}
],
"bids": [
{
"custodian_id": "0",
"market_id": "12",
"order_id": "7249570702494370108524",
"price": "5228",
"remaining_size": "1573323",
"side": false,
"user": "0x7676c6ad191680ee72a03f724aa750a66a9570ca90c7b6861c94a7c2c4ec5515"
},
{
"custodian_id": "0",
"market_id": "12",
"order_id": "7286464612811304604775",
"price": "5223",
"remaining_size": "1955227",
"side": false,
"user": "0x7676c6ad191680ee72a03f724aa750a66a9570ca90c7b6861c94a7c2c4ec5515"
}
]
}GET OPEN ORDERS
const address = '0xbd9c426a78b43441fd949044963aaefc383678be70dbef773f802f4b1ba34009';
const marketId = 10;
const openOrders = await perpsMarketsInstance.getOpenOrders(address, marketId);Example Response
{
"success": true,
"message": "Current open orders data fetched successfully",
"data": [
{
"marketOrderId": "92233861123215989592",
"orderSide": false,
"marketPrice": "7000",
"marketSize": "100000000",
"leverage": 2,
"tradeType": 1,
"timestamp": "2024-12-31T04:21:27.892309+00:00"
},
{
"marketOrderId": "110680745925823961945",
"orderSide": false,
"marketPrice": "7001",
"marketSize": "200000000",
"leverage": 2,
"tradeType": 3,
"timestamp": "2024-12-31T04:21:27.892309+00:00"
},
{
"marketOrderId": "147574374827911291688",
"orderSide": false,
"marketPrice": "9000",
"marketSize": "100000000",
"leverage": 2,
"tradeType": 3,
"timestamp": "2024-12-31T12:25:19.368272+00:00"
}
]
}GET ALL ORDER HISTORY
const address = '0xbd9c426a78b43441fd949044963aaefc383678be70dbef773f802f4b1ba34009';
const orderHistory = await perpsMarketsInstance.orderHistory(address);Example Response
[
{
"market_id": 10,
"order_id": "1844674548125623391112",
"created_at": "2024-05-06T17:43:06.581062+00:00",
"last_updated_at": "2024-05-06T19:10:20.215508+00:00",
"integrator": "0xc0de11113b427d35ece1d8991865a941c0578b0f349acabbe9753863c24109ff",
"total_filled": 0,
"remaining_size": 2000,
"order_status": "cancelled",
"order_type": "limit",
"user": "0x925366e03a856f25f47873222c6707eaeb00f79898fe904c357dc4b15e8718a1",
"direction": "bid",
"price": 5000,
"average_execution_price": null,
"custodian_id": 2,
"self_match_behavior": 0,
"restriction": 0,
"last_increase_stamp": null,
"min_base": null,
"max_base": null,
"min_quote": null,
"max_quote": null,
"total_fees_paid_in_quote_subunits": 0
},
{
"market_id": 10,
"order_id": "1826227663297245609984",
"created_at": "2024-05-06T17:42:24.052761+00:00",
"last_updated_at": "2024-05-06T17:42:24.052761+00:00",
"integrator": "0xc0de11113b427d35ece1d8991865a941c0578b0f349acabbe9753863c24109ff",
"total_filled": 2000,
"remaining_size": 0,
"order_status": "closed",
"order_type": "market",
"user": "0x925366e03a856f25f47873222c6707eaeb00f79898fe904c357dc4b15e8718a1",
"direction": "buy",
"price": null,
"average_execution_price": 5000,
"custodian_id": 2,
"self_match_behavior": 0,
"restriction": null,
"last_increase_stamp": null,
"min_base": null,
"max_base": null,
"min_quote": null,
"max_quote": null,
"total_fees_paid_in_quote_subunits": 5000,
"leverage": 2,
"trade_type": 2,
"timestamp": "2024-09-24T13:49:40.000Z"
}
]GET MARKET INFO
const marketId = 12;
const response = await perpsMarketsInstance.getMarketInfo(marketId);Example Response
{
"status": true,
"message": "Market information fetched successfully",
"data": [
{
"base_decimals": 8,
"base_name": "ETH/USDC",
"counter": "0",
"creator_address": "0xb61d7b57333abf8ac036e752f19d0ba0c4baa5404db1cbf868c57dac3628f2bf",
"lot_size": "10000",
"maintenance_margin": "250",
"market_address": "0xd42a3190891d0be84a106124a596020dfe54b692e1665df9c39d1eef5e418609",
"market_id": "303",
"max_leverage": "20",
"max_lots": "100000",
"min_lots": "10",
"quote_decimals": 6,
"quote_precision": 1,
"tick_size": "10"
}
]
}VIEW POSITIONS
const address = '0xbd9c426a78b43441fd949044963aaefc383678be70dbef773f802f4b1ba34009';
const response = await perpsMarketsInstance.getPosition(address, marketId);Example Response
{
"success": true,
"message": "View position data fetched successfully",
"data": {
"longViewData": {
"close_size": "0",
"close_taker_fee": "0",
"collateral": "15001000",
"entry_price": "700100000000",
"exit_price": "0",
"filled_close_size": "0",
"filled_open_size": "100000000",
"leverage": 2,
"limit_orders": [],
"liquidation_price": "3590",
"open_size": "400000000",
"open_taker_fee": "0",
"position_value": "30002000",
"quote_contribution": "15001000",
"stop_loss": "0",
"take_profit": "0",
"trade_id": "55340232221128655149"
},
"shortViewData": {
"base_contribution": "0",
"close_size": "0",
"close_taker_fee": "0",
"collateral": "0",
"entry_price": "0",
"exit_price": "0",
"filled_close_size": "0",
"filled_open_size": "0",
"leverage": 0,
"limit_orders": [],
"liquidation_price": "0",
"open_size": "0",
"open_taker_fee": "0",
"position_value": "0",
"stop_loss": "0",
"take_profit": "0",
"trade_id": "0"
}
}
}UPDATE POSITION
const address = '0xbd9c426a78b43441fd949044963aaefc383678be70dbef773f802f4b1ba34009';
const marketId = 10;
const updatePnlPayload = await perpsMarketsInstance.updatePosition(address, marketId);
const viewOptions = {
payload: updatePnlPayload.data,
};
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});CANDLE STICK DATA
const resolutions = await perpsMarketsInstance.getCandleStickData(900,3)Example Response
[
{
"market_id": 12,
"resolution": 900,
"start_time": "2023-11-06T10:45:00+00:00",
"open": 6589,
"high": 6589,
"low": 6589,
"close": 6589,
"volume": 42828500
},
{
"market_id": 12,
"resolution": 900,
"start_time": "2023-11-06T10:30:00+00:00",
"open": 6589,
"high": 6589,
"low": 6589,
"close": 6589,
"volume": 167505558
},
{
"market_id": 12,
"resolution": 900,
"start_time": "2023-11-06T10:15:00+00:00",
"open": 6589,
"high": 6589,
"low": 6589,
"close": 6589,
"volume": 42828500
}
]GET PYTH ORACLE PRICE
const marketId = 17;
const getPythOraclePrice = await perpsMarketsInstance.getPythOraclePrice(marketId);Example Response
{
"success": "true",
"message": "Fetched Latest Pyth Oracle Price Successfully",
"data": "885514423"
}GET LAST PLACED EXECUTION PRICE
const marketId = 17;
const getLastPrice = await perpsMarketsInstance.getLastExecutionPrice(marketId);Example Response
{
"success": "true",
"message": "Fetched Last Execution Price Successfully",
"data": "10900"
}GET MARKET ORDER BEST BIDS AND ASKS
const marketId = 17;
const price = await perpsMarketsInstance.getMarketPrice(marketId);Example Response
{
"success": true,
"message": "Fetched Market Price Successfully",
"bestAskPrice": null,
"bestBidPrice": 9000
}GET TRADING ACCOUNT BALANCE
const marketId = 17;
const address = '0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770';
const accountBalance = await perpsMarketsInstance.getTradingAccountBalance(marketId,address);Example Response
{
"success": true,
"message": "Fetched Trading Account Balance Successfully",
"data": "47500000"
}COLLAPSE POSITION
const marketId = 66;
const collapsePayload = await perpsMarketsInstance.collapsePosition(marketId);
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: collapsePayload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});GET ALL Trades --> Recent trades
const marketId = '301';
const orderHistory = await perpsMarketsInstance.recentTrades(marketId);WITHDRAW ALL MARKETS
const amount = 1000000;
const marketIds = [396, 397, 398];
const payload = perpsMarketsInstance.withdrawAllMarkets(amount, marketIds)
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});ADD MARGIN
const marketId = 396;
const tradeSide = true;
const amount = 2000000;
const payload = perpsMarketsInstance.addMargin(marketId, tradeSide, amount)
const transactionPayload = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: payload.data
});
const committedTxn = await aptos.transaction.signAndSubmitTransaction({
transaction: transactionPayload,
signer: account,
});
const response = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});Example Response
{
"success": true,
"message": "Recent trades fetched successfully",
"data": [
{
"txn_version": 6582606213,
"event_idx": 4,
"emit_address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770",
"time": "2024-12-31T07:58:59.763275+00:00",
"maker_address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770",
"maker_custodian_id": 41,
"maker_order_id": "110680745925823961945",
"maker_side": false,
"market_id": 301,
"price": 7001,
"sequence_number_for_trade": 0,
"size": 1000,
"taker_address": "0x3a6b332c7889784fe57ea61f507b5056e386db8f56c6323b4d898485f468f0c2",
"taker_custodian_id": 41,
"taker_order_id": "129127208515966861312",
"taker_quote_fees_paid": 3500
},
{
"txn_version": 6582606213,
"event_idx": 3,
"emit_address": "0x3a6b332c7889784fe57ea61f507b5056e386db8f56c6323b4d898485f468f0c2",
"time": "2024-12-31T07:58:59.763275+00:00",
"maker_address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770",
"maker_custodian_id": 41,
"maker_order_id": "110680745925823961945",
"maker_side": false,
"market_id": 301,
"price": 7001,
"sequence_number_for_trade": 0,
"size": 1000,
"taker_address": "0x3a6b332c7889784fe57ea61f507b5056e386db8f56c6323b4d898485f468f0c2",
"taker_custodian_id": 41,
"taker_order_id": "129127208515966861312",
"taker_quote_fees_paid": 3500
}
]
}GET WALLET APT BALANCE
const userAddress = "0xb80d13f962962d16dd21cd4092ae9a94ea544e990c5133b671dbe30ac3560f50";
const response = await perpsMarketsInstance.getWalletAptBalance(
userAddress
);
console.log("response: ", response);Example Response
{
"success": true,
"message": "Fetched wallet apt balance successfully",
"data:": 10
}GET WALLET USDT BALANCE
const userAddress = "0xb80d13f962962d16dd21cd4092ae9a94ea544e990c5133b671dbe30ac3560f50";
const response = await perpsMarketsInstance.getWalletUsdtBalance(
userAddress
);
console.log("response: ", response);Example Response
{
"success": true,
"message": "Fetched wallet usdt balance successfully",
"data:": 200
}GET ALL MARKET INFO
const response = await perpsMarketsInstance.getAllMarketInfo({ });
console.log("response: ", response);Example Response
{
"success": true,
"message": "Fetched all market infos successfully",
"data": [
{
"creator": "0xb61d7b57333abf8ac036e752f19d0ba0c4baa5404db1cbf868c57dac3628f2bf",
"market_id": "1335",
"base_name": "APT/USDC",
"lot_size": "100000",
"tick_size": "1",
"min_lots": "500",
"quote_precision": "3",
"base_decimals": "8",
"quote_decimals": "6",
"maintenance_margin": "250",
"max_leverage": "20",
"custodian_id": "72",
"underwriter_id": "70",
"timestamp": 1745075797,
"market_status": "1",
"is_recognised": false,
"transaction_version": 6693087360
},
{
"creator": "0xb61d7b57333abf8ac036e752f19d0ba0c4baa5404db1cbf868c57dac3628f2bf",
"market_id": "1336",
"base_name": "BTC/USDC",
"lot_size": "1000",
"tick_size": "10",
"min_lots": "10",
"quote_precision": "0",
"base_decimals": "8",
"quote_decimals": "6",
"maintenance_margin": "250",
"max_leverage": "20",
"custodian_id": "73",
"underwriter_id": "71",
"timestamp": 1745075910,
"market_status": "1",
"is_recognised": false,
"transaction_version": 6693088438
}
]
}