@drift-labs/sdk 0.1.18-orders.2 → 0.1.18-orders.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/accounts/bulkAccountLoader.d.ts +3 -4
- package/lib/accounts/bulkAccountLoader.js +23 -4
- package/lib/accounts/pollingUserAccountSubscriber.js +8 -5
- package/lib/accounts/types.d.ts +4 -0
- package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -2
- package/lib/accounts/webSocketAccountSubscriber.js +43 -12
- package/lib/clearingHouse.d.ts +4 -0
- package/lib/clearingHouse.js +40 -0
- package/lib/clearingHouseUser.d.ts +8 -3
- package/lib/clearingHouseUser.js +23 -20
- package/lib/config.js +1 -1
- package/lib/constants/markets.d.ts +2 -1
- package/lib/constants/markets.js +20 -15
- package/lib/constants/numericConstants.d.ts +4 -1
- package/lib/constants/numericConstants.js +16 -17
- package/lib/examples/makeTradeExample.js +1 -1
- package/lib/idl/clearing_house.json +8 -4
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -5
- package/lib/math/conversion.d.ts +1 -1
- package/lib/math/insuranceFund.d.ts +2 -1
- package/lib/math/insuranceFund.js +3 -6
- package/lib/math/orders.js +2 -1
- package/lib/math/position.d.ts +2 -1
- package/lib/math/position.js +2 -5
- package/lib/math/utils.d.ts +2 -1
- package/lib/math/utils.js +3 -6
- package/lib/mockUSDCFaucet.d.ts +2 -1
- package/lib/orderParams.d.ts +2 -2
- package/lib/orderParams.js +7 -7
- package/lib/orders.d.ts +3 -2
- package/lib/orders.js +8 -8
- package/lib/types.d.ts +8 -5
- package/lib/types.js +2 -2
- package/package.json +9 -1
- package/src/accounts/bulkAccountLoader.ts +35 -15
- package/src/accounts/pollingUserAccountSubscriber.ts +13 -5
- package/src/accounts/types.ts +5 -0
- package/src/accounts/webSocketAccountSubscriber.ts +67 -17
- package/src/clearingHouse.ts +56 -0
- package/src/clearingHouseUser.ts +12 -2
- package/src/config.ts +1 -1
- package/src/constants/markets.ts +9 -1
- package/src/constants/numericConstants.ts +3 -1
- package/src/examples/makeTradeExample.ts +4 -1
- package/src/idl/clearing_house.json +8 -4
- package/src/index.ts +1 -1
- package/src/math/conversion.ts +1 -1
- package/src/math/insuranceFund.ts +1 -1
- package/src/math/orders.ts +4 -2
- package/src/math/position.ts +1 -1
- package/src/math/utils.ts +1 -1
- package/src/mockUSDCFaucet.ts +1 -1
- package/src/orderParams.ts +4 -4
- package/src/orders.ts +13 -7
- package/src/types.ts +5 -3
|
@@ -53,7 +53,7 @@ const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
53
53
|
// Get current price
|
|
54
54
|
const solMarketInfo = __2.Markets.find((market) => market.baseAssetSymbol === 'SOL');
|
|
55
55
|
const currentMarketPrice = __2.calculateMarkPrice(clearingHouse.getMarket(solMarketInfo.marketIndex));
|
|
56
|
-
const formattedPrice = __2.convertToNumber(currentMarketPrice, __2.
|
|
56
|
+
const formattedPrice = __2.convertToNumber(currentMarketPrice, __2.MARK_PRICE_PRECISION);
|
|
57
57
|
console.log(`Current Market Price is $${formattedPrice}`);
|
|
58
58
|
// Estimate the slippage for a $5000 LONG trade
|
|
59
59
|
const solMarketAccount = clearingHouse.getMarket(solMarketInfo.marketIndex);
|
|
@@ -572,7 +572,7 @@
|
|
|
572
572
|
},
|
|
573
573
|
{
|
|
574
574
|
"name": "markets",
|
|
575
|
-
"isMut":
|
|
575
|
+
"isMut": false,
|
|
576
576
|
"isSigner": false
|
|
577
577
|
},
|
|
578
578
|
{
|
|
@@ -628,7 +628,7 @@
|
|
|
628
628
|
},
|
|
629
629
|
{
|
|
630
630
|
"name": "markets",
|
|
631
|
-
"isMut":
|
|
631
|
+
"isMut": false,
|
|
632
632
|
"isSigner": false
|
|
633
633
|
},
|
|
634
634
|
{
|
|
@@ -3547,6 +3547,10 @@
|
|
|
3547
3547
|
"name": "price",
|
|
3548
3548
|
"type": "u128"
|
|
3549
3549
|
},
|
|
3550
|
+
{
|
|
3551
|
+
"name": "userBaseAssetAmount",
|
|
3552
|
+
"type": "i128"
|
|
3553
|
+
},
|
|
3550
3554
|
{
|
|
3551
3555
|
"name": "quoteAssetAmount",
|
|
3552
3556
|
"type": "u128"
|
|
@@ -3734,10 +3738,10 @@
|
|
|
3734
3738
|
"name": "Limit"
|
|
3735
3739
|
},
|
|
3736
3740
|
{
|
|
3737
|
-
"name": "
|
|
3741
|
+
"name": "TriggerMarket"
|
|
3738
3742
|
},
|
|
3739
3743
|
{
|
|
3740
|
-
"name": "
|
|
3744
|
+
"name": "TriggerLimit"
|
|
3741
3745
|
}
|
|
3742
3746
|
]
|
|
3743
3747
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -9,13 +9,10 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
9
9
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
10
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
11
|
};
|
|
12
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
-
};
|
|
15
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
13
|
exports.PublicKey = exports.BN = void 0;
|
|
17
|
-
const
|
|
18
|
-
exports
|
|
14
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
15
|
+
Object.defineProperty(exports, "BN", { enumerable: true, get: function () { return anchor_1.BN; } });
|
|
19
16
|
const web3_js_1 = require("@solana/web3.js");
|
|
20
17
|
Object.defineProperty(exports, "PublicKey", { enumerable: true, get: function () { return web3_js_1.PublicKey; } });
|
|
21
18
|
__exportStar(require("./mockUSDCFaucet"), exports);
|
package/lib/math/conversion.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
1
2
|
import { MarketsAccount, StateAccount } from '../types';
|
|
2
|
-
import BN from '
|
|
3
|
+
import { BN } from '../';
|
|
3
4
|
import { Connection } from '@solana/web3.js';
|
|
4
5
|
/**
|
|
5
6
|
* In the case of a levered loss, the exchange first pays out undistributed fees and then the insurance fund.
|
|
@@ -8,12 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
12
|
exports.calculateInsuranceFundSize = void 0;
|
|
16
|
-
const
|
|
13
|
+
const __1 = require("../");
|
|
17
14
|
/**
|
|
18
15
|
* In the case of a levered loss, the exchange first pays out undistributed fees and then the insurance fund.
|
|
19
16
|
* Thus the de facto size of the insurance fund is the amount in the insurance vault plus the sum of each markets
|
|
@@ -27,9 +24,9 @@ const bn_js_1 = __importDefault(require("bn.js"));
|
|
|
27
24
|
function calculateInsuranceFundSize(connection, state, marketsAccount) {
|
|
28
25
|
return __awaiter(this, void 0, void 0, function* () {
|
|
29
26
|
const insuranceVaultPublicKey = state.insuranceVault;
|
|
30
|
-
const insuranceVaultAmount = new
|
|
27
|
+
const insuranceVaultAmount = new __1.BN((yield connection.getTokenAccountBalance(insuranceVaultPublicKey)).value.amount);
|
|
31
28
|
return marketsAccount.markets.reduce((insuranceVaultAmount, market) => {
|
|
32
|
-
return insuranceVaultAmount.add(market.amm.totalFee.div(new
|
|
29
|
+
return insuranceVaultAmount.add(market.amm.totalFee.div(new __1.BN(2)));
|
|
33
30
|
}, insuranceVaultAmount);
|
|
34
31
|
});
|
|
35
32
|
}
|
package/lib/math/orders.js
CHANGED
|
@@ -23,8 +23,9 @@ function isOrderRiskIncreasing(user, order) {
|
|
|
23
23
|
return true;
|
|
24
24
|
}
|
|
25
25
|
// if order will flip position
|
|
26
|
-
if (position.baseAssetAmount.abs().
|
|
26
|
+
if (order.baseAssetAmountFilled.gt(position.baseAssetAmount.abs().mul(numericConstants_1.TWO))) {
|
|
27
27
|
return true;
|
|
28
28
|
}
|
|
29
|
+
return false;
|
|
29
30
|
}
|
|
30
31
|
exports.isOrderRiskIncreasing = isOrderRiskIncreasing;
|
package/lib/math/position.d.ts
CHANGED
package/lib/math/position.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.calculatePositionFundingPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
|
|
7
|
-
const
|
|
4
|
+
const __1 = require("../");
|
|
8
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
9
6
|
const types_1 = require("../types");
|
|
10
7
|
const amm_1 = require("./amm");
|
|
@@ -84,7 +81,7 @@ function calculatePositionFundingPNL(market, marketPosition) {
|
|
|
84
81
|
.mul(marketPosition.baseAssetAmount)
|
|
85
82
|
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
86
83
|
.div(numericConstants_1.FUNDING_PAYMENT_PRECISION)
|
|
87
|
-
.mul(new
|
|
84
|
+
.mul(new __1.BN(-1));
|
|
88
85
|
return perPositionFundingRate;
|
|
89
86
|
}
|
|
90
87
|
exports.calculatePositionFundingPNL = calculatePositionFundingPNL;
|
package/lib/math/utils.d.ts
CHANGED
package/lib/math/utils.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.squareRootBN = void 0;
|
|
7
|
-
const
|
|
8
|
-
const squareRootBN = (n, closeness = new
|
|
4
|
+
const __1 = require("../");
|
|
5
|
+
const squareRootBN = (n, closeness = new __1.BN(1)) => {
|
|
9
6
|
// Assuming the sqrt of n as n only
|
|
10
7
|
let x = n;
|
|
11
8
|
// The closed guess will be stored in the root
|
|
12
9
|
let root;
|
|
13
10
|
// To count the number of iterations
|
|
14
11
|
let count = 0;
|
|
15
|
-
const TWO = new
|
|
12
|
+
const TWO = new __1.BN(2);
|
|
16
13
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
17
14
|
while (count < Number.MAX_SAFE_INTEGER) {
|
|
18
15
|
count++;
|
package/lib/mockUSDCFaucet.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
1
2
|
import * as anchor from '@project-serum/anchor';
|
|
2
3
|
import { Program, Provider } from '@project-serum/anchor';
|
|
3
4
|
import { AccountInfo } from '@solana/spl-token';
|
|
4
5
|
import { ConfirmOptions, Connection, PublicKey, TransactionInstruction, TransactionSignature } from '@solana/web3.js';
|
|
5
|
-
import BN from '
|
|
6
|
+
import { BN } from '.';
|
|
6
7
|
import { IWallet } from './types';
|
|
7
8
|
export declare class MockUSDCFaucet {
|
|
8
9
|
connection: Connection;
|
package/lib/orderParams.d.ts
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
import { OrderParams, OrderTriggerCondition, PositionDirection } from './types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
4
|
export declare function getLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
5
|
+
export declare function getTriggerMarketOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
|
|
6
|
+
export declare function getTriggerLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
|
|
7
7
|
export declare function getMarketOrderParams(marketIndex: BN, direction: PositionDirection, quoteAssetAmount: BN, baseAssetAmount: BN, reduceOnly: boolean, price?: BN, discountToken?: boolean, referrer?: boolean): OrderParams;
|
package/lib/orderParams.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getMarketOrderParams = exports.
|
|
3
|
+
exports.getMarketOrderParams = exports.getTriggerLimitOrderParams = exports.getTriggerMarketOrderParams = exports.getLimitOrderParams = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
5
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
6
6
|
function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, reduceOnly, discountToken = false, referrer = false, userOrderId = 0) {
|
|
@@ -28,9 +28,9 @@ function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, red
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
exports.getLimitOrderParams = getLimitOrderParams;
|
|
31
|
-
function
|
|
31
|
+
function getTriggerMarketOrderParams(marketIndex, direction, baseAssetAmount, triggerPrice, triggerCondition, reduceOnly, discountToken = false, referrer = false, userOrderId = 0) {
|
|
32
32
|
return {
|
|
33
|
-
orderType: types_1.OrderType.
|
|
33
|
+
orderType: types_1.OrderType.TRIGGER_MARKET,
|
|
34
34
|
userOrderId,
|
|
35
35
|
marketIndex,
|
|
36
36
|
direction,
|
|
@@ -52,10 +52,10 @@ function getStopOrderParams(marketIndex, direction, baseAssetAmount, triggerPric
|
|
|
52
52
|
oraclePriceOffset: numericConstants_1.ZERO,
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
-
exports.
|
|
56
|
-
function
|
|
55
|
+
exports.getTriggerMarketOrderParams = getTriggerMarketOrderParams;
|
|
56
|
+
function getTriggerLimitOrderParams(marketIndex, direction, baseAssetAmount, price, triggerPrice, triggerCondition, reduceOnly, discountToken = false, referrer = false, userOrderId = 0) {
|
|
57
57
|
return {
|
|
58
|
-
orderType: types_1.OrderType.
|
|
58
|
+
orderType: types_1.OrderType.TRIGGER_LIMIT,
|
|
59
59
|
userOrderId,
|
|
60
60
|
marketIndex,
|
|
61
61
|
direction,
|
|
@@ -77,7 +77,7 @@ function getStopLimitOrderParams(marketIndex, direction, baseAssetAmount, price,
|
|
|
77
77
|
oraclePriceOffset: numericConstants_1.ZERO,
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
|
-
exports.
|
|
80
|
+
exports.getTriggerLimitOrderParams = getTriggerLimitOrderParams;
|
|
81
81
|
function getMarketOrderParams(marketIndex, direction, quoteAssetAmount, baseAssetAmount, reduceOnly, price = numericConstants_1.ZERO, discountToken = false, referrer = false) {
|
|
82
82
|
if (baseAssetAmount.eq(numericConstants_1.ZERO) && quoteAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
83
83
|
throw Error('baseAssetAmount or quoteAssetAmount must be zero');
|
package/lib/orders.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
1
2
|
import { Market, Order, UserAccount, UserPosition } from './types';
|
|
2
|
-
import BN from '
|
|
3
|
+
import { BN } from '.';
|
|
3
4
|
export declare function calculateNewStateAfterOrder(userAccount: UserAccount, userPosition: UserPosition, market: Market, order: Order): [UserAccount, UserPosition, Market] | null;
|
|
4
5
|
export declare function calculateAmountToTradeForLimit(market: Market, order: Order): BN;
|
|
5
|
-
export declare function
|
|
6
|
+
export declare function calculateAmountToTradeForTriggerLimit(market: Market, order: Order): BN;
|
package/lib/orders.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateNewStateAfterOrder = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
5
|
const market_1 = require("./math/market");
|
|
6
6
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
@@ -83,15 +83,15 @@ function calculateAmountToTrade(market, order) {
|
|
|
83
83
|
if (types_1.isVariant(order.orderType, 'limit')) {
|
|
84
84
|
return calculateAmountToTradeForLimit(market, order);
|
|
85
85
|
}
|
|
86
|
-
else if (types_1.isVariant(order.orderType, '
|
|
87
|
-
return
|
|
86
|
+
else if (types_1.isVariant(order.orderType, 'triggerLimit')) {
|
|
87
|
+
return calculateAmountToTradeForTriggerLimit(market, order);
|
|
88
88
|
}
|
|
89
89
|
else if (types_1.isVariant(order.orderType, 'market')) {
|
|
90
90
|
// should never be a market order queued
|
|
91
91
|
return numericConstants_1.ZERO;
|
|
92
92
|
}
|
|
93
93
|
else {
|
|
94
|
-
return
|
|
94
|
+
return calculateAmountToTradeForTriggerMarket(market, order);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
function calculateAmountToTradeForLimit(market, order) {
|
|
@@ -106,21 +106,21 @@ function calculateAmountToTradeForLimit(market, order) {
|
|
|
106
106
|
: maxAmountToTrade;
|
|
107
107
|
}
|
|
108
108
|
exports.calculateAmountToTradeForLimit = calculateAmountToTradeForLimit;
|
|
109
|
-
function
|
|
109
|
+
function calculateAmountToTradeForTriggerLimit(market, order) {
|
|
110
110
|
if (order.baseAssetAmountFilled.eq(numericConstants_1.ZERO)) {
|
|
111
|
-
const baseAssetAmount =
|
|
111
|
+
const baseAssetAmount = calculateAmountToTradeForTriggerMarket(market, order);
|
|
112
112
|
if (baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
113
113
|
return numericConstants_1.ZERO;
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
return calculateAmountToTradeForLimit(market, order);
|
|
117
117
|
}
|
|
118
|
-
exports.
|
|
118
|
+
exports.calculateAmountToTradeForTriggerLimit = calculateAmountToTradeForTriggerLimit;
|
|
119
119
|
function isSameDirection(firstDirection, secondDirection) {
|
|
120
120
|
return ((types_1.isVariant(firstDirection, 'long') && types_1.isVariant(secondDirection, 'long')) ||
|
|
121
121
|
(types_1.isVariant(firstDirection, 'short') && types_1.isVariant(secondDirection, 'short')));
|
|
122
122
|
}
|
|
123
|
-
function
|
|
123
|
+
function calculateAmountToTradeForTriggerMarket(market, order) {
|
|
124
124
|
return isTriggerConditionSatisfied(market, order)
|
|
125
125
|
? order.baseAssetAmount
|
|
126
126
|
: numericConstants_1.ZERO;
|
package/lib/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
1
2
|
import { PublicKey, Transaction } from '@solana/web3.js';
|
|
2
|
-
import BN from '
|
|
3
|
+
import { BN } from '.';
|
|
3
4
|
export declare class SwapDirection {
|
|
4
5
|
static readonly ADD: {
|
|
5
6
|
add: {};
|
|
@@ -28,11 +29,11 @@ export declare class OrderType {
|
|
|
28
29
|
static readonly LIMIT: {
|
|
29
30
|
limit: {};
|
|
30
31
|
};
|
|
31
|
-
static readonly
|
|
32
|
-
|
|
32
|
+
static readonly TRIGGER_MARKET: {
|
|
33
|
+
triggerMarket: {};
|
|
33
34
|
};
|
|
34
|
-
static readonly
|
|
35
|
-
|
|
35
|
+
static readonly TRIGGER_LIMIT: {
|
|
36
|
+
triggerLimit: {};
|
|
36
37
|
};
|
|
37
38
|
static readonly MARKET: {
|
|
38
39
|
market: {};
|
|
@@ -341,6 +342,7 @@ export declare type Order = {
|
|
|
341
342
|
userOrderId: number;
|
|
342
343
|
marketIndex: BN;
|
|
343
344
|
price: BN;
|
|
345
|
+
userBaseAssetAmount: BN;
|
|
344
346
|
baseAssetAmount: BN;
|
|
345
347
|
baseAssetAmountFilled: BN;
|
|
346
348
|
quoteAssetAmount: BN;
|
|
@@ -354,6 +356,7 @@ export declare type Order = {
|
|
|
354
356
|
referrer: PublicKey;
|
|
355
357
|
postOnly: boolean;
|
|
356
358
|
immediateOrCancel: boolean;
|
|
359
|
+
oraclePriceOffset: BN;
|
|
357
360
|
};
|
|
358
361
|
export declare type OrderParams = {
|
|
359
362
|
orderType: OrderType;
|
package/lib/types.js
CHANGED
|
@@ -21,8 +21,8 @@ class OrderType {
|
|
|
21
21
|
}
|
|
22
22
|
exports.OrderType = OrderType;
|
|
23
23
|
OrderType.LIMIT = { limit: {} };
|
|
24
|
-
OrderType.
|
|
25
|
-
OrderType.
|
|
24
|
+
OrderType.TRIGGER_MARKET = { triggerMarket: {} };
|
|
25
|
+
OrderType.TRIGGER_LIMIT = { triggerLimit: {} };
|
|
26
26
|
OrderType.MARKET = { market: {} };
|
|
27
27
|
class OrderStatus {
|
|
28
28
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-labs/sdk",
|
|
3
|
-
"version": "0.1.18-orders.
|
|
3
|
+
"version": "0.1.18-orders.6",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"author": "crispheaney",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"url": "git@github.com:drift-labs/protocol-v1.git"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
+
"lint": "eslint './**/*.{ts,tsx}' --quiet",
|
|
13
14
|
"build": "yarn clean && tsc",
|
|
14
15
|
"clean": "rm -rf lib",
|
|
15
16
|
"patch-and-pub": "npm version patch --force && npm publish"
|
|
@@ -34,6 +35,13 @@
|
|
|
34
35
|
"strict-event-emitter-types": "^2.0.0",
|
|
35
36
|
"uuid": "^8.3.2"
|
|
36
37
|
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@typescript-eslint/eslint-plugin": "^4.28.0",
|
|
40
|
+
"@typescript-eslint/parser": "^4.28.0",
|
|
41
|
+
"eslint": "^7.29.0",
|
|
42
|
+
"eslint-config-prettier": "^8.3.0",
|
|
43
|
+
"eslint-plugin-prettier": "^3.4.0"
|
|
44
|
+
},
|
|
37
45
|
"description": "SDK for Drift Protocol v1",
|
|
38
46
|
"engines": {
|
|
39
47
|
"node": ">=12"
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { AccountData } from './types';
|
|
3
4
|
|
|
4
5
|
type AccountToLoad = {
|
|
5
6
|
publicKey: PublicKey;
|
|
6
7
|
callbacks: Map<string, (buffer: Buffer) => void>;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
type AccountData = {
|
|
10
|
-
slot: number;
|
|
11
|
-
buffer: Buffer | undefined;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
10
|
const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
|
|
15
11
|
|
|
16
12
|
export class BulkAccountLoader {
|
|
@@ -21,6 +17,9 @@ export class BulkAccountLoader {
|
|
|
21
17
|
accountData = new Map<string, AccountData>();
|
|
22
18
|
errorCallbacks = new Map<string, (e) => void>();
|
|
23
19
|
intervalId?: NodeJS.Timer;
|
|
20
|
+
// to handle clients spamming load
|
|
21
|
+
loadPromise?: Promise<void>;
|
|
22
|
+
loadPromiseResolver: () => void;
|
|
24
23
|
|
|
25
24
|
public constructor(
|
|
26
25
|
connection: Connection,
|
|
@@ -56,6 +55,9 @@ export class BulkAccountLoader {
|
|
|
56
55
|
this.startPolling();
|
|
57
56
|
}
|
|
58
57
|
|
|
58
|
+
// if a new account needs to be polled, remove the cached loadPromise in case client calls load immediately after
|
|
59
|
+
this.loadPromise = undefined;
|
|
60
|
+
|
|
59
61
|
return callbackId;
|
|
60
62
|
}
|
|
61
63
|
|
|
@@ -91,16 +93,34 @@ export class BulkAccountLoader {
|
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
public async load(): Promise<void> {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
if (this.loadPromise) {
|
|
97
|
+
return this.loadPromise;
|
|
98
|
+
}
|
|
99
|
+
this.loadPromise = new Promise((resolver) => {
|
|
100
|
+
this.loadPromiseResolver = resolver;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const chunks = this.chunks(
|
|
105
|
+
Array.from(this.accountsToLoad.values()),
|
|
106
|
+
GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
await Promise.all(
|
|
110
|
+
chunks.map((chunk) => {
|
|
111
|
+
return this.loadChunk(chunk);
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
} catch (e) {
|
|
115
|
+
console.error(`Error in bulkAccountLoader.load()`);
|
|
116
|
+
console.error(e);
|
|
117
|
+
for (const [_, callback] of this.errorCallbacks) {
|
|
118
|
+
callback(e);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
this.loadPromiseResolver();
|
|
123
|
+
this.loadPromise = undefined;
|
|
104
124
|
}
|
|
105
125
|
|
|
106
126
|
async loadChunk(accountsToLoad: AccountToLoad[]): Promise<void> {
|
|
@@ -89,11 +89,19 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
89
89
|
userPublicKey
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
const userOrdersExist =
|
|
93
|
+
(
|
|
94
|
+
await this.program.provider.connection.getParsedAccountInfo(
|
|
95
|
+
userOrdersPublicKey
|
|
96
|
+
)
|
|
97
|
+
).value !== null;
|
|
98
|
+
if (userOrdersExist) {
|
|
99
|
+
this.accountsToPoll.set(userOrdersPublicKey.toString(), {
|
|
100
|
+
key: 'userOrders',
|
|
101
|
+
publicKey: userOrdersPublicKey,
|
|
102
|
+
eventType: 'userOrdersData',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
97
105
|
|
|
98
106
|
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
99
107
|
accountToPoll.callbackId = this.accountLoader.addAccount(
|
package/src/accounts/types.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { AccountSubscriber } from './types';
|
|
1
|
+
import { AccountData, AccountSubscriber } from './types';
|
|
2
2
|
import { Program } from '@project-serum/anchor';
|
|
3
|
-
import { PublicKey } from '@solana/web3.js';
|
|
3
|
+
import { AccountInfo, Context, PublicKey } from '@solana/web3.js';
|
|
4
|
+
import { capitalize } from './utils';
|
|
5
|
+
import * as Buffer from 'buffer';
|
|
4
6
|
|
|
5
7
|
export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
6
8
|
data?: T;
|
|
9
|
+
accountData?: AccountData;
|
|
7
10
|
accountName: string;
|
|
8
11
|
program: Program;
|
|
9
12
|
accountPublicKey: PublicKey;
|
|
10
13
|
onChange: (data: T) => void;
|
|
14
|
+
listenerId?: number;
|
|
11
15
|
|
|
12
16
|
public constructor(
|
|
13
17
|
accountName: string,
|
|
@@ -20,32 +24,78 @@ export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
async subscribe(onChange: (data: T) => void): Promise<void> {
|
|
27
|
+
if (this.listenerId) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
this.onChange = onChange;
|
|
24
32
|
await this.fetch();
|
|
25
33
|
|
|
26
|
-
this.program.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
this.listenerId = this.program.provider.connection.onAccountChange(
|
|
35
|
+
this.accountPublicKey,
|
|
36
|
+
(accountInfo, context) => {
|
|
37
|
+
this.handleRpcResponse(context, accountInfo);
|
|
38
|
+
},
|
|
39
|
+
this.program.provider.opts.commitment
|
|
40
|
+
);
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
async fetch(): Promise<void> {
|
|
35
|
-
const
|
|
36
|
-
this.
|
|
37
|
-
|
|
44
|
+
const rpcResponse =
|
|
45
|
+
await this.program.provider.connection.getAccountInfoAndContext(
|
|
46
|
+
this.accountPublicKey,
|
|
47
|
+
this.program.provider.opts.commitment
|
|
48
|
+
);
|
|
49
|
+
this.handleRpcResponse(rpcResponse.context, rpcResponse?.value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
handleRpcResponse(context: Context, accountInfo?: AccountInfo<Buffer>): void {
|
|
53
|
+
const newSlot = context.slot;
|
|
54
|
+
let newBuffer: Buffer | undefined = undefined;
|
|
55
|
+
if (accountInfo) {
|
|
56
|
+
newBuffer = accountInfo.data;
|
|
57
|
+
}
|
|
38
58
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
if (!this.accountData) {
|
|
60
|
+
this.accountData = {
|
|
61
|
+
buffer: newBuffer,
|
|
62
|
+
slot: newSlot,
|
|
63
|
+
};
|
|
64
|
+
if (newBuffer) {
|
|
65
|
+
this.data = this.program.account[
|
|
66
|
+
this.accountName
|
|
67
|
+
].coder.accounts.decode(capitalize(this.accountName), newBuffer);
|
|
68
|
+
this.onChange(this.data);
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (newSlot <= this.accountData.slot) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const oldBuffer = this.accountData.buffer;
|
|
78
|
+
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
79
|
+
this.accountData = {
|
|
80
|
+
buffer: newBuffer,
|
|
81
|
+
slot: newSlot,
|
|
82
|
+
};
|
|
83
|
+
this.data = this.program.account[this.accountName].coder.accounts.decode(
|
|
84
|
+
capitalize(this.accountName),
|
|
85
|
+
newBuffer
|
|
86
|
+
);
|
|
42
87
|
this.onChange(this.data);
|
|
43
88
|
}
|
|
44
89
|
}
|
|
45
90
|
|
|
46
91
|
unsubscribe(): Promise<void> {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
92
|
+
if (this.listenerId) {
|
|
93
|
+
const promise =
|
|
94
|
+
this.program.provider.connection.removeAccountChangeListener(
|
|
95
|
+
this.listenerId
|
|
96
|
+
);
|
|
97
|
+
this.listenerId = undefined;
|
|
98
|
+
return promise;
|
|
99
|
+
}
|
|
50
100
|
}
|
|
51
101
|
}
|