@drift-labs/common
Version:
Common functions for Drift
148 lines • 5.34 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildNonMarketOrderParams = exports.resolveBaseAssetAmount = exports.convertToBaseAssetAmount = void 0;
const sdk_1 = require("@drift-labs/sdk");
const utils_1 = require("../../utils");
/**
* Converts amount and assetType to base asset amount
* @param amount - The amount to convert
* @param assetType - 'base' or 'quote'
* @param limitPrice - Required when assetType is 'quote' for conversion
* @returns Base asset amount
*/
function convertToBaseAssetAmount(amount, assetType, limitPrice) {
if (assetType === 'quote') {
if (!limitPrice || limitPrice.isZero()) {
throw new Error('When using quote asset type, limitPrice is required for conversion to base amount');
}
// Convert quote amount to base amount: quoteAmount / price = baseAmount
// Using PRICE_PRECISION as the limit price is in price precision
const PRICE_PRECISION = new sdk_1.BN(10).pow(new sdk_1.BN(6));
return amount.mul(PRICE_PRECISION).div(limitPrice);
}
else {
// Base amount, use directly
return amount;
}
}
exports.convertToBaseAssetAmount = convertToBaseAssetAmount;
/**
* Resolves amount parameters from either new (amount + assetType) or legacy (baseAssetAmount) approach
*/
function resolveBaseAssetAmount(params) {
const { amount, assetType, baseAssetAmount, limitPrice } = params;
if (amount && assetType) {
// New approach: convert if needed
return convertToBaseAssetAmount(amount, assetType, limitPrice);
}
else if (baseAssetAmount) {
// Legacy approach
return baseAssetAmount;
}
else {
throw new Error('Either (amount + assetType) or baseAssetAmount must be provided');
}
}
exports.resolveBaseAssetAmount = resolveBaseAssetAmount;
/**
* Determine trigger condition based on direction
* For stop orders: ABOVE when long, BELOW when short
* For take profit orders: BELOW when long, ABOVE when short
*/
const getTriggerCondition = (direction, tpOrSl) => {
const isTakeProfit = tpOrSl === 'takeProfit';
const isLong = utils_1.ENUM_UTILS.match(direction, sdk_1.PositionDirection.LONG);
if (isTakeProfit) {
if (isLong) {
return sdk_1.OrderTriggerCondition.BELOW;
}
else {
return sdk_1.OrderTriggerCondition.ABOVE;
}
}
else {
// Stop loss
if (isLong) {
return sdk_1.OrderTriggerCondition.ABOVE;
}
else {
return sdk_1.OrderTriggerCondition.BELOW;
}
}
};
/**
* Builds proper order parameters for non-market orders using the same logic as the UI
*/
function buildNonMarketOrderParams({ marketIndex, marketType, direction, baseAssetAmount, orderConfig, reduceOnly = false, postOnly = sdk_1.PostOnlyParams.NONE, userOrderId = 0, }) {
const orderType = orderConfig.orderType;
// Build order params based on order type using SDK functions
if (orderType === 'limit') {
if (!orderConfig.limitPrice) {
throw new Error('LIMIT orders require limitPrice');
}
return (0, sdk_1.getLimitOrderParams)({
marketIndex,
marketType,
direction,
baseAssetAmount,
price: orderConfig.limitPrice,
reduceOnly,
postOnly,
userOrderId,
});
}
if (orderType === 'takeProfit' || orderType === 'stopLoss') {
if (!orderConfig.triggerPrice) {
throw new Error('TRIGGER_MARKET orders require triggerPrice');
}
const triggerCondition = getTriggerCondition(direction, orderType);
const hasLimitPrice = !!orderConfig.limitPrice;
if (hasLimitPrice) {
return (0, sdk_1.getTriggerLimitOrderParams)({
marketIndex,
marketType,
direction,
baseAssetAmount,
triggerPrice: orderConfig.triggerPrice,
price: orderConfig.limitPrice,
triggerCondition,
reduceOnly,
postOnly,
userOrderId,
});
}
else {
return (0, sdk_1.getTriggerMarketOrderParams)({
marketIndex,
marketType,
direction,
baseAssetAmount,
triggerPrice: orderConfig.triggerPrice,
price: orderConfig.limitPrice,
triggerCondition,
reduceOnly,
postOnly,
userOrderId,
});
}
}
if (orderType === 'oracleLimit') {
if (!orderConfig.oraclePriceOffset) {
throw new Error('ORACLE orders require oraclePriceOffset');
}
return (0, sdk_1.getLimitOrderParams)({
marketIndex,
marketType,
direction,
baseAssetAmount,
price: sdk_1.ZERO,
oraclePriceOffset: orderConfig.oraclePriceOffset.toNumber(),
userOrderId,
postOnly,
reduceOnly,
});
}
throw new Error(`Unsupported order type: ${orderType}`);
}
exports.buildNonMarketOrderParams = buildNonMarketOrderParams;
//# sourceMappingURL=orderParams.js.map