@drift-labs/sdk 0.2.0-master.32 → 0.2.0-master.34
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.js +2 -1
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +2 -2
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +8 -8
- package/lib/accounts/types.d.ts +1 -0
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +2 -2
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +7 -7
- package/lib/addresses/marketAddresses.js +1 -1
- package/lib/addresses/pda.d.ts +4 -4
- package/lib/addresses/pda.js +23 -22
- package/lib/admin.d.ts +30 -32
- package/lib/admin.js +111 -119
- package/lib/clearingHouse.d.ts +43 -34
- package/lib/clearingHouse.js +353 -193
- package/lib/clearingHouseConfig.d.ts +2 -2
- package/lib/clearingHouseUser.d.ts +26 -5
- package/lib/clearingHouseUser.js +151 -51
- package/lib/config.d.ts +2 -0
- package/lib/config.js +5 -1
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +3 -2
- package/lib/dlob/DLOB.d.ts +18 -11
- package/lib/dlob/DLOB.js +179 -107
- package/lib/dlob/DLOBNode.js +2 -10
- package/lib/dlob/NodeList.js +1 -1
- package/lib/events/eventSubscriber.d.ts +1 -0
- package/lib/events/eventSubscriber.js +11 -4
- package/lib/events/fetchLogs.d.ts +3 -1
- package/lib/events/fetchLogs.js +13 -5
- package/lib/events/pollingLogProvider.js +1 -1
- package/lib/events/types.d.ts +1 -1
- package/lib/events/webSocketLogProvider.js +1 -1
- package/lib/factory/bigNum.d.ts +5 -4
- package/lib/factory/bigNum.js +36 -6
- package/lib/idl/clearing_house.json +1540 -1246
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/math/amm.js +9 -9
- package/lib/math/exchangeStatus.d.ts +4 -0
- package/lib/math/exchangeStatus.js +18 -0
- package/lib/math/funding.js +10 -10
- package/lib/math/margin.js +6 -1
- package/lib/math/market.js +9 -9
- package/lib/math/orders.d.ts +7 -3
- package/lib/math/orders.js +39 -31
- package/lib/math/repeg.js +3 -3
- package/lib/math/spotBalance.js +3 -3
- package/lib/math/spotPosition.js +2 -2
- package/lib/serum/serumFulfillmentConfigMap.d.ts +10 -0
- package/lib/serum/serumFulfillmentConfigMap.js +17 -0
- package/lib/serum/serumSubscriber.d.ts +4 -0
- package/lib/serum/serumSubscriber.js +16 -1
- package/lib/types.d.ts +60 -75
- package/lib/types.js +2 -1
- package/lib/userMap/userMap.d.ts +17 -1
- package/lib/userMap/userMap.js +12 -0
- package/lib/userName.d.ts +1 -0
- package/lib/userName.js +3 -2
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +5 -1
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +9 -9
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +8 -8
- package/src/addresses/marketAddresses.ts +2 -2
- package/src/addresses/pda.ts +20 -20
- package/src/admin.ts +246 -221
- package/src/assert/assert.js +9 -0
- package/src/clearingHouse.ts +556 -236
- package/src/clearingHouseConfig.ts +2 -2
- package/src/clearingHouseUser.ts +237 -87
- package/src/config.ts +8 -1
- package/src/constants/numericConstants.ts +5 -1
- package/src/dlob/DLOB.ts +257 -120
- package/src/dlob/DLOBNode.ts +2 -14
- package/src/dlob/NodeList.ts +1 -1
- package/src/events/eventList.js +77 -0
- package/src/events/eventSubscriber.ts +18 -4
- package/src/events/fetchLogs.ts +20 -5
- package/src/events/pollingLogProvider.ts +1 -1
- package/src/events/types.ts +2 -1
- package/src/events/webSocketLogProvider.ts +1 -1
- package/src/examples/makeTradeExample.js +157 -0
- package/src/factory/bigNum.ts +59 -6
- package/src/idl/clearing_house.json +1540 -1246
- package/src/idl/pyth.json +98 -2
- package/src/index.ts +3 -0
- package/src/math/amm.ts +9 -9
- package/src/math/exchangeStatus.ts +31 -0
- package/src/math/funding.ts +20 -10
- package/src/math/margin.ts +7 -1
- package/src/math/market.ts +9 -9
- package/src/math/orders.ts +44 -29
- package/src/math/repeg.ts +3 -3
- package/src/math/spotBalance.ts +4 -4
- package/src/math/spotPosition.ts +2 -2
- package/src/serum/serumFulfillmentConfigMap.ts +26 -0
- package/src/serum/serumSubscriber.ts +20 -1
- package/src/token/index.js +38 -0
- package/src/tx/types.js +2 -0
- package/src/tx/utils.js +17 -0
- package/src/types.ts +65 -51
- package/src/userMap/userMap.ts +25 -1
- package/src/userName.ts +2 -1
- package/src/util/computeUnits.js +27 -0
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/tests/bn/test.ts +22 -1
- package/tests/dlob/helpers.ts +252 -81
- package/tests/dlob/test.ts +1040 -219
package/lib/index.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export * from './events/fetchLogs';
|
|
|
33
33
|
export * from './math/auction';
|
|
34
34
|
export * from './math/spotMarket';
|
|
35
35
|
export * from './math/conversion';
|
|
36
|
+
export * from './math/exchangeStatus';
|
|
36
37
|
export * from './math/funding';
|
|
37
38
|
export * from './math/market';
|
|
38
39
|
export * from './math/position';
|
|
@@ -51,9 +52,11 @@ export * from './math/utils';
|
|
|
51
52
|
export * from './config';
|
|
52
53
|
export * from './constants/numericConstants';
|
|
53
54
|
export * from './serum/serumSubscriber';
|
|
55
|
+
export * from './serum/serumFulfillmentConfigMap';
|
|
54
56
|
export * from './tx/retryTxSender';
|
|
55
57
|
export * from './util/computeUnits';
|
|
56
58
|
export * from './util/tps';
|
|
59
|
+
export * from './util/promiseTimeout';
|
|
57
60
|
export * from './math/spotBalance';
|
|
58
61
|
export * from './constants/spotMarkets';
|
|
59
62
|
export * from './clearingHouseConfig';
|
package/lib/index.js
CHANGED
|
@@ -56,6 +56,7 @@ __exportStar(require("./events/fetchLogs"), exports);
|
|
|
56
56
|
__exportStar(require("./math/auction"), exports);
|
|
57
57
|
__exportStar(require("./math/spotMarket"), exports);
|
|
58
58
|
__exportStar(require("./math/conversion"), exports);
|
|
59
|
+
__exportStar(require("./math/exchangeStatus"), exports);
|
|
59
60
|
__exportStar(require("./math/funding"), exports);
|
|
60
61
|
__exportStar(require("./math/market"), exports);
|
|
61
62
|
__exportStar(require("./math/position"), exports);
|
|
@@ -74,9 +75,11 @@ __exportStar(require("./math/utils"), exports);
|
|
|
74
75
|
__exportStar(require("./config"), exports);
|
|
75
76
|
__exportStar(require("./constants/numericConstants"), exports);
|
|
76
77
|
__exportStar(require("./serum/serumSubscriber"), exports);
|
|
78
|
+
__exportStar(require("./serum/serumFulfillmentConfigMap"), exports);
|
|
77
79
|
__exportStar(require("./tx/retryTxSender"), exports);
|
|
78
80
|
__exportStar(require("./util/computeUnits"), exports);
|
|
79
81
|
__exportStar(require("./util/tps"), exports);
|
|
82
|
+
__exportStar(require("./util/promiseTimeout"), exports);
|
|
80
83
|
__exportStar(require("./math/spotBalance"), exports);
|
|
81
84
|
__exportStar(require("./constants/spotMarkets"), exports);
|
|
82
85
|
__exportStar(require("./clearingHouseConfig"), exports);
|
package/lib/math/amm.js
CHANGED
|
@@ -62,10 +62,10 @@ function calculateNewAmm(amm, oraclePriceData) {
|
|
|
62
62
|
newAmm.sqrtK = newAmm.sqrtK.mul(pKNumer).div(pKDenom);
|
|
63
63
|
const invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
|
|
64
64
|
newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
|
|
65
|
-
const directionToClose = amm.
|
|
65
|
+
const directionToClose = amm.baseAssetAmountWithAmm.gt(numericConstants_1.ZERO)
|
|
66
66
|
? types_1.PositionDirection.SHORT
|
|
67
67
|
: types_1.PositionDirection.LONG;
|
|
68
|
-
const [newQuoteAssetReserve, _newBaseAssetReserve] = calculateAmmReservesAfterSwap(newAmm, 'base', amm.
|
|
68
|
+
const [newQuoteAssetReserve, _newBaseAssetReserve] = calculateAmmReservesAfterSwap(newAmm, 'base', amm.baseAssetAmountWithAmm.abs(), getSwapDirection('base', directionToClose));
|
|
69
69
|
newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
|
|
70
70
|
newPeg = (0, repeg_1.calculateBudgetedPeg)(newAmm, prePegCost, targetPrice);
|
|
71
71
|
prePegCost = (0, repeg_1.calculateRepegCost)(newAmm, newPeg);
|
|
@@ -84,10 +84,10 @@ function calculateUpdatedAMM(amm, oraclePriceData) {
|
|
|
84
84
|
const invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
|
|
85
85
|
newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
|
|
86
86
|
newAmm.pegMultiplier = newPeg;
|
|
87
|
-
const directionToClose = amm.
|
|
87
|
+
const directionToClose = amm.baseAssetAmountWithAmm.gt(numericConstants_1.ZERO)
|
|
88
88
|
? types_1.PositionDirection.SHORT
|
|
89
89
|
: types_1.PositionDirection.LONG;
|
|
90
|
-
const [newQuoteAssetReserve, _newBaseAssetReserve] = calculateAmmReservesAfterSwap(newAmm, 'base', amm.
|
|
90
|
+
const [newQuoteAssetReserve, _newBaseAssetReserve] = calculateAmmReservesAfterSwap(newAmm, 'base', amm.baseAssetAmountWithAmm.abs(), getSwapDirection('base', directionToClose));
|
|
91
91
|
newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
|
|
92
92
|
newAmm.totalFeeMinusDistributions =
|
|
93
93
|
newAmm.totalFeeMinusDistributions.sub(prepegCost);
|
|
@@ -278,7 +278,7 @@ function calculateSpread(amm, direction, oraclePriceData) {
|
|
|
278
278
|
const confIntervalPct = confInterval
|
|
279
279
|
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
|
|
280
280
|
.div(reservePrice);
|
|
281
|
-
const [longSpread, shortSpread] = calculateSpreadBN(amm.baseSpread, targetMarkSpreadPct, confIntervalPct, amm.maxSpread, amm.quoteAssetReserve, amm.terminalQuoteAssetReserve, amm.pegMultiplier, amm.
|
|
281
|
+
const [longSpread, shortSpread] = calculateSpreadBN(amm.baseSpread, targetMarkSpreadPct, confIntervalPct, amm.maxSpread, amm.quoteAssetReserve, amm.terminalQuoteAssetReserve, amm.pegMultiplier, amm.baseAssetAmountWithAmm, reservePrice, amm.totalFeeMinusDistributions, amm.baseAssetReserve, amm.minBaseAssetReserve, amm.maxBaseAssetReserve);
|
|
282
282
|
let spread;
|
|
283
283
|
if ((0, types_1.isVariant)(direction, 'long')) {
|
|
284
284
|
spread = longSpread;
|
|
@@ -356,10 +356,10 @@ exports.getSwapDirection = getSwapDirection;
|
|
|
356
356
|
* @returns cost : Precision PRICE_PRECISION
|
|
357
357
|
*/
|
|
358
358
|
function calculateTerminalPrice(market) {
|
|
359
|
-
const directionToClose = market.amm.
|
|
359
|
+
const directionToClose = market.amm.baseAssetAmountWithAmm.gt(numericConstants_1.ZERO)
|
|
360
360
|
? types_1.PositionDirection.SHORT
|
|
361
361
|
: types_1.PositionDirection.LONG;
|
|
362
|
-
const [newQuoteAssetReserve, newBaseAssetReserve] = calculateAmmReservesAfterSwap(market.amm, 'base', market.amm.
|
|
362
|
+
const [newQuoteAssetReserve, newBaseAssetReserve] = calculateAmmReservesAfterSwap(market.amm, 'base', market.amm.baseAssetAmountWithAmm.abs(), getSwapDirection('base', directionToClose));
|
|
363
363
|
const terminalPrice = newQuoteAssetReserve
|
|
364
364
|
.mul(numericConstants_1.PRICE_PRECISION)
|
|
365
365
|
.mul(market.amm.pegMultiplier)
|
|
@@ -409,7 +409,7 @@ function calculateQuoteAssetAmountSwapped(quoteAssetReserves, pegMultiplier, swa
|
|
|
409
409
|
}
|
|
410
410
|
exports.calculateQuoteAssetAmountSwapped = calculateQuoteAssetAmountSwapped;
|
|
411
411
|
function calculateMaxBaseAssetAmountFillable(amm, orderDirection) {
|
|
412
|
-
const maxFillSize = amm.baseAssetReserve.div(new anchor_1.BN(amm.
|
|
412
|
+
const maxFillSize = amm.baseAssetReserve.div(new anchor_1.BN(amm.maxFillReserveFraction));
|
|
413
413
|
let maxBaseAssetAmountOnSide;
|
|
414
414
|
if ((0, types_1.isVariant)(orderDirection, 'long')) {
|
|
415
415
|
maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.baseAssetReserve.sub(amm.minBaseAssetReserve));
|
|
@@ -417,6 +417,6 @@ function calculateMaxBaseAssetAmountFillable(amm, orderDirection) {
|
|
|
417
417
|
else {
|
|
418
418
|
maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.maxBaseAssetReserve.sub(amm.baseAssetReserve));
|
|
419
419
|
}
|
|
420
|
-
return (0, __1.standardizeBaseAssetAmount)(anchor_1.BN.min(maxFillSize, maxBaseAssetAmountOnSide), amm.
|
|
420
|
+
return (0, __1.standardizeBaseAssetAmount)(anchor_1.BN.min(maxFillSize, maxBaseAssetAmountOnSide), amm.orderStepSize);
|
|
421
421
|
}
|
|
422
422
|
exports.calculateMaxBaseAssetAmountFillable = calculateMaxBaseAssetAmountFillable;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { PerpMarketAccount, SpotMarketAccount, StateAccount } from '../types';
|
|
2
|
+
export declare function exchangePaused(state: StateAccount): boolean;
|
|
3
|
+
export declare function fillPaused(state: StateAccount, market: PerpMarketAccount | SpotMarketAccount): boolean;
|
|
4
|
+
export declare function ammPaused(state: StateAccount, market: PerpMarketAccount | SpotMarketAccount): boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ammPaused = exports.fillPaused = exports.exchangePaused = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
function exchangePaused(state) {
|
|
6
|
+
return (0, types_1.isVariant)(state.exchangeStatus, 'paused');
|
|
7
|
+
}
|
|
8
|
+
exports.exchangePaused = exchangePaused;
|
|
9
|
+
function fillPaused(state, market) {
|
|
10
|
+
return ((0, types_1.isOneOfVariant)(state.exchangeStatus, ['paused', 'fillPaused']) ||
|
|
11
|
+
(0, types_1.isOneOfVariant)(market.status, ['paused', 'fillPaused']));
|
|
12
|
+
}
|
|
13
|
+
exports.fillPaused = fillPaused;
|
|
14
|
+
function ammPaused(state, market) {
|
|
15
|
+
return ((0, types_1.isOneOfVariant)(state.exchangeStatus, ['paused', 'ammPaused']) ||
|
|
16
|
+
(0, types_1.isOneOfVariant)(market.status, ['paused', 'ammPaused']));
|
|
17
|
+
}
|
|
18
|
+
exports.ammPaused = ammPaused;
|
package/lib/math/funding.js
CHANGED
|
@@ -90,9 +90,9 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
90
90
|
let cappedAltEst;
|
|
91
91
|
let largerSide;
|
|
92
92
|
let smallerSide;
|
|
93
|
-
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
|
|
94
|
-
largerSide = market.baseAssetAmountLong.abs();
|
|
95
|
-
smallerSide = market.baseAssetAmountShort.abs();
|
|
93
|
+
if (market.amm.baseAssetAmountLong.gt(market.amm.baseAssetAmountShort.abs())) {
|
|
94
|
+
largerSide = market.amm.baseAssetAmountLong.abs();
|
|
95
|
+
smallerSide = market.amm.baseAssetAmountShort.abs();
|
|
96
96
|
if (twapSpread.gt(new anchor_1.BN(0))) {
|
|
97
97
|
return [
|
|
98
98
|
markTwapWithMantissa,
|
|
@@ -103,9 +103,9 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
103
103
|
];
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
107
|
-
largerSide = market.baseAssetAmountShort.abs();
|
|
108
|
-
smallerSide = market.baseAssetAmountLong.abs();
|
|
106
|
+
else if (market.amm.baseAssetAmountLong.lt(market.amm.baseAssetAmountShort.abs())) {
|
|
107
|
+
largerSide = market.amm.baseAssetAmountShort.abs();
|
|
108
|
+
smallerSide = market.amm.baseAssetAmountLong.abs();
|
|
109
109
|
if (twapSpread.lt(new anchor_1.BN(0))) {
|
|
110
110
|
return [
|
|
111
111
|
markTwapWithMantissa,
|
|
@@ -184,10 +184,10 @@ exports.calculateEstimatedFundingRate = calculateEstimatedFundingRate;
|
|
|
184
184
|
*/
|
|
185
185
|
async function calculateLongShortFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
|
|
186
186
|
const [_1, _2, _, cappedAltEst, interpEst] = await calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
|
|
187
|
-
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort)) {
|
|
187
|
+
if (market.amm.baseAssetAmountLong.gt(market.amm.baseAssetAmountShort)) {
|
|
188
188
|
return [cappedAltEst, interpEst];
|
|
189
189
|
}
|
|
190
|
-
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort)) {
|
|
190
|
+
else if (market.amm.baseAssetAmountLong.lt(market.amm.baseAssetAmountShort)) {
|
|
191
191
|
return [interpEst, cappedAltEst];
|
|
192
192
|
}
|
|
193
193
|
else {
|
|
@@ -204,10 +204,10 @@ exports.calculateLongShortFundingRate = calculateLongShortFundingRate;
|
|
|
204
204
|
*/
|
|
205
205
|
async function calculateLongShortFundingRateAndLiveTwaps(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
|
|
206
206
|
const [markTwapLive, oracleTwapLive, _2, cappedAltEst, interpEst] = await calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
|
|
207
|
-
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
|
|
207
|
+
if (market.amm.baseAssetAmountLong.gt(market.amm.baseAssetAmountShort.abs())) {
|
|
208
208
|
return [markTwapLive, oracleTwapLive, cappedAltEst, interpEst];
|
|
209
209
|
}
|
|
210
|
-
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
210
|
+
else if (market.amm.baseAssetAmountLong.lt(market.amm.baseAssetAmountShort.abs())) {
|
|
211
211
|
return [markTwapLive, oracleTwapLive, interpEst, cappedAltEst];
|
|
212
212
|
}
|
|
213
213
|
else {
|
package/lib/math/margin.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithO
|
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const anchor_1 = require("@project-serum/anchor");
|
|
7
|
+
const types_1 = require("../types");
|
|
7
8
|
const assert_1 = require("../assert/assert");
|
|
8
9
|
function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
|
|
9
10
|
imfFactor, liabilityWeight, precision) {
|
|
@@ -58,9 +59,13 @@ function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData
|
|
|
58
59
|
}
|
|
59
60
|
exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
|
|
60
61
|
function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData) {
|
|
62
|
+
let price = oraclePriceData.price;
|
|
63
|
+
if ((0, types_1.isVariant)(market.status, 'settlement')) {
|
|
64
|
+
price = market.expiryPrice;
|
|
65
|
+
}
|
|
61
66
|
return perpPosition.baseAssetAmount
|
|
62
67
|
.abs()
|
|
63
|
-
.mul(
|
|
68
|
+
.mul(price)
|
|
64
69
|
.div(numericConstants_1.AMM_RESERVE_PRECISION);
|
|
65
70
|
}
|
|
66
71
|
exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
|
package/lib/math/market.js
CHANGED
|
@@ -76,30 +76,30 @@ function calculateUnrealizedAssetWeight(market, quoteSpotMarket, unrealizedPnl,
|
|
|
76
76
|
let assetWeight;
|
|
77
77
|
switch (marginCategory) {
|
|
78
78
|
case 'Initial':
|
|
79
|
-
assetWeight = new anchor_1.BN(market.
|
|
80
|
-
if (market.
|
|
79
|
+
assetWeight = new anchor_1.BN(market.unrealizedPnlInitialAssetWeight);
|
|
80
|
+
if (market.unrealizedPnlMaxImbalance.gt(numericConstants_1.ZERO)) {
|
|
81
81
|
const netUnsettledPnl = calculateNetUserPnlImbalance(market, quoteSpotMarket, oraclePriceData);
|
|
82
|
-
if (netUnsettledPnl.gt(market.
|
|
82
|
+
if (netUnsettledPnl.gt(market.unrealizedPnlMaxImbalance)) {
|
|
83
83
|
assetWeight = assetWeight
|
|
84
|
-
.mul(market.
|
|
84
|
+
.mul(market.unrealizedPnlMaxImbalance)
|
|
85
85
|
.div(netUnsettledPnl);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unrealizedPnl, market.
|
|
88
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unrealizedPnl, market.unrealizedPnlImfFactor, assetWeight);
|
|
89
89
|
break;
|
|
90
90
|
case 'Maintenance':
|
|
91
|
-
assetWeight = new anchor_1.BN(market.
|
|
91
|
+
assetWeight = new anchor_1.BN(market.unrealizedPnlMaintenanceAssetWeight);
|
|
92
92
|
break;
|
|
93
93
|
}
|
|
94
94
|
return assetWeight;
|
|
95
95
|
}
|
|
96
96
|
exports.calculateUnrealizedAssetWeight = calculateUnrealizedAssetWeight;
|
|
97
97
|
function calculateMarketAvailablePNL(perpMarket, spotMarket) {
|
|
98
|
-
return (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.
|
|
98
|
+
return (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.scaledBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
99
99
|
}
|
|
100
100
|
exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
|
|
101
101
|
function calculateNetUserPnl(perpMarket, oraclePriceData) {
|
|
102
|
-
const netUserPositionValue = perpMarket.amm.
|
|
102
|
+
const netUserPositionValue = perpMarket.amm.baseAssetAmountWithAmm
|
|
103
103
|
.mul(oraclePriceData.price)
|
|
104
104
|
.div(numericConstants_1.BASE_PRECISION)
|
|
105
105
|
.div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
|
|
@@ -112,7 +112,7 @@ function calculateNetUserPnl(perpMarket, oraclePriceData) {
|
|
|
112
112
|
exports.calculateNetUserPnl = calculateNetUserPnl;
|
|
113
113
|
function calculateNetUserPnlImbalance(perpMarket, spotMarket, oraclePriceData) {
|
|
114
114
|
const netUserPnl = calculateNetUserPnl(perpMarket, oraclePriceData);
|
|
115
|
-
const pnlPool = (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.
|
|
115
|
+
const pnlPool = (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.scaledBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
116
116
|
const imbalance = netUserPnl.sub(pnlPool);
|
|
117
117
|
return imbalance;
|
|
118
118
|
}
|
package/lib/math/orders.d.ts
CHANGED
|
@@ -7,8 +7,12 @@ export declare function isOrderRiskIncreasing(user: ClearingHouseUser, order: Or
|
|
|
7
7
|
export declare function isOrderRiskIncreasingInSameDirection(user: ClearingHouseUser, order: Order): boolean;
|
|
8
8
|
export declare function isOrderReduceOnly(user: ClearingHouseUser, order: Order): boolean;
|
|
9
9
|
export declare function standardizeBaseAssetAmount(baseAssetAmount: BN, stepSize: BN): BN;
|
|
10
|
-
export declare function getLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number
|
|
11
|
-
export declare function
|
|
10
|
+
export declare function getLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
11
|
+
export declare function getOptionalLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number): BN | undefined;
|
|
12
|
+
export declare function hasLimitPrice(order: Order, slot: number): boolean;
|
|
13
|
+
export declare function isFillableByVAMM(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number, ts: number): boolean;
|
|
12
14
|
export declare function calculateBaseAssetAmountForAmmToFulfill(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
13
15
|
export declare function calculateBaseAssetAmountToFillUpToLimitPrice(order: Order, market: PerpMarketAccount, limitPrice: BN, oraclePriceData: OraclePriceData): BN;
|
|
14
|
-
export declare function isOrderExpired(order: Order,
|
|
16
|
+
export declare function isOrderExpired(order: Order, ts: number): boolean;
|
|
17
|
+
export declare function isMarketOrder(order: Order): boolean;
|
|
18
|
+
export declare function isLimitOrder(order: Order): boolean;
|
package/lib/math/orders.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
3
|
+
exports.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasLimitPrice = exports.getOptionalLimitPrice = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const anchor_1 = require("@project-serum/anchor");
|
|
7
7
|
const auction_1 = require("./auction");
|
|
8
|
-
const market_1 = require("./market");
|
|
9
8
|
const amm_1 = require("./amm");
|
|
10
9
|
function isOrderRiskIncreasing(user, order) {
|
|
11
10
|
if ((0, types_1.isVariant)(order.status, 'init')) {
|
|
@@ -80,10 +79,10 @@ function standardizeBaseAssetAmount(baseAssetAmount, stepSize) {
|
|
|
80
79
|
return baseAssetAmount.sub(remainder);
|
|
81
80
|
}
|
|
82
81
|
exports.standardizeBaseAssetAmount = standardizeBaseAssetAmount;
|
|
83
|
-
function getLimitPrice(order, oraclePriceData, slot
|
|
82
|
+
function getLimitPrice(order, oraclePriceData, slot) {
|
|
84
83
|
let limitPrice;
|
|
85
|
-
if (
|
|
86
|
-
limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
|
|
84
|
+
if (order.oraclePriceOffset !== 0) {
|
|
85
|
+
limitPrice = oraclePriceData.price.add(new anchor_1.BN(order.oraclePriceOffset));
|
|
87
86
|
}
|
|
88
87
|
else if ((0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket'])) {
|
|
89
88
|
if (!(0, auction_1.isAuctionComplete)(order, slot)) {
|
|
@@ -93,27 +92,13 @@ function getLimitPrice(order, oraclePriceData, slot, perpMarket) {
|
|
|
93
92
|
limitPrice = order.price;
|
|
94
93
|
}
|
|
95
94
|
else {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
limitPrice = askPrice.add(delta);
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
const bidPrice = (0, market_1.calculateBidPrice)(perpMarket, oraclePriceData);
|
|
104
|
-
const delta = bidPrice.div(new anchor_1.BN(perpMarket.amm.maxSlippageRatio));
|
|
105
|
-
limitPrice = bidPrice.sub(delta);
|
|
106
|
-
}
|
|
95
|
+
// check oracle validity?
|
|
96
|
+
const oraclePrice1Pct = oraclePriceData.price.div(new anchor_1.BN(100));
|
|
97
|
+
if ((0, types_1.isVariant)(order.direction, 'long')) {
|
|
98
|
+
limitPrice = oraclePriceData.price.add(oraclePrice1Pct);
|
|
107
99
|
}
|
|
108
100
|
else {
|
|
109
|
-
|
|
110
|
-
const oraclePrice1Pct = oraclePriceData.price.div(new anchor_1.BN(100));
|
|
111
|
-
if ((0, types_1.isVariant)(order.direction, 'long')) {
|
|
112
|
-
limitPrice = oraclePriceData.price.add(oraclePrice1Pct);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
limitPrice = oraclePriceData.price.sub(oraclePrice1Pct);
|
|
116
|
-
}
|
|
101
|
+
limitPrice = oraclePriceData.price.sub(oraclePrice1Pct);
|
|
117
102
|
}
|
|
118
103
|
}
|
|
119
104
|
}
|
|
@@ -123,10 +108,25 @@ function getLimitPrice(order, oraclePriceData, slot, perpMarket) {
|
|
|
123
108
|
return limitPrice;
|
|
124
109
|
}
|
|
125
110
|
exports.getLimitPrice = getLimitPrice;
|
|
126
|
-
function
|
|
111
|
+
function getOptionalLimitPrice(order, oraclePriceData, slot) {
|
|
112
|
+
if (hasLimitPrice(order, slot)) {
|
|
113
|
+
return getLimitPrice(order, oraclePriceData, slot);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.getOptionalLimitPrice = getOptionalLimitPrice;
|
|
120
|
+
function hasLimitPrice(order, slot) {
|
|
121
|
+
return (order.price.gt(numericConstants_1.ZERO) ||
|
|
122
|
+
order.oraclePriceOffset != 0 ||
|
|
123
|
+
!(0, auction_1.isAuctionComplete)(order, slot));
|
|
124
|
+
}
|
|
125
|
+
exports.hasLimitPrice = hasLimitPrice;
|
|
126
|
+
function isFillableByVAMM(order, market, oraclePriceData, slot, ts) {
|
|
127
127
|
return (((0, auction_1.isAuctionComplete)(order, slot) &&
|
|
128
128
|
!calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).eq(numericConstants_1.ZERO)) ||
|
|
129
|
-
isOrderExpired(order,
|
|
129
|
+
isOrderExpired(order, ts));
|
|
130
130
|
}
|
|
131
131
|
exports.isFillableByVAMM = isFillableByVAMM;
|
|
132
132
|
function calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot) {
|
|
@@ -134,7 +134,7 @@ function calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData,
|
|
|
134
134
|
order.triggered === false) {
|
|
135
135
|
return numericConstants_1.ZERO;
|
|
136
136
|
}
|
|
137
|
-
const limitPrice = getLimitPrice(order, oraclePriceData, slot
|
|
137
|
+
const limitPrice = getLimitPrice(order, oraclePriceData, slot);
|
|
138
138
|
const baseAssetAmount = calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData);
|
|
139
139
|
const maxBaseAssetAmount = (0, amm_1.calculateMaxBaseAssetAmountFillable)(market.amm, order.direction);
|
|
140
140
|
return anchor_1.BN.min(maxBaseAssetAmount, baseAssetAmount);
|
|
@@ -142,7 +142,7 @@ function calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData,
|
|
|
142
142
|
exports.calculateBaseAssetAmountForAmmToFulfill = calculateBaseAssetAmountForAmmToFulfill;
|
|
143
143
|
function calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData) {
|
|
144
144
|
const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction, oraclePriceData);
|
|
145
|
-
const baseAssetAmount = standardizeBaseAssetAmount(maxAmountToTrade, market.amm.
|
|
145
|
+
const baseAssetAmount = standardizeBaseAssetAmount(maxAmountToTrade, market.amm.orderStepSize);
|
|
146
146
|
// Check that directions are the same
|
|
147
147
|
const sameDirection = isSameDirection(direction, order.direction);
|
|
148
148
|
if (!sameDirection) {
|
|
@@ -157,12 +157,20 @@ function isSameDirection(firstDirection, secondDirection) {
|
|
|
157
157
|
return (((0, types_1.isVariant)(firstDirection, 'long') && (0, types_1.isVariant)(secondDirection, 'long')) ||
|
|
158
158
|
((0, types_1.isVariant)(firstDirection, 'short') && (0, types_1.isVariant)(secondDirection, 'short')));
|
|
159
159
|
}
|
|
160
|
-
function isOrderExpired(order,
|
|
160
|
+
function isOrderExpired(order, ts) {
|
|
161
161
|
if ((0, types_1.isOneOfVariant)(order.orderType, ['triggerMarket', 'triggerLimit']) ||
|
|
162
162
|
!(0, types_1.isVariant)(order.status, 'open') ||
|
|
163
|
-
order.
|
|
163
|
+
order.maxTs.eq(numericConstants_1.ZERO)) {
|
|
164
164
|
return false;
|
|
165
165
|
}
|
|
166
|
-
return new anchor_1.BN(
|
|
166
|
+
return new anchor_1.BN(ts).gt(order.maxTs);
|
|
167
167
|
}
|
|
168
168
|
exports.isOrderExpired = isOrderExpired;
|
|
169
|
+
function isMarketOrder(order) {
|
|
170
|
+
return (0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket']);
|
|
171
|
+
}
|
|
172
|
+
exports.isMarketOrder = isMarketOrder;
|
|
173
|
+
function isLimitOrder(order) {
|
|
174
|
+
return (0, types_1.isOneOfVariant)(order.orderType, ['limit', 'triggerLimit']);
|
|
175
|
+
}
|
|
176
|
+
exports.isLimitOrder = isLimitOrder;
|
package/lib/math/repeg.js
CHANGED
|
@@ -15,7 +15,7 @@ function calculateAdjustKCost(amm, numerator, denomenator) {
|
|
|
15
15
|
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
16
16
|
const x = amm.baseAssetReserve;
|
|
17
17
|
const y = amm.quoteAssetReserve;
|
|
18
|
-
const d = amm.
|
|
18
|
+
const d = amm.baseAssetAmountWithAmm;
|
|
19
19
|
const Q = amm.pegMultiplier;
|
|
20
20
|
const quoteScale = y.mul(d).mul(Q); //.div(AMM_RESERVE_PRECISION);
|
|
21
21
|
const p = numerator.mul(numericConstants_1.PRICE_PRECISION).div(denomenator);
|
|
@@ -101,7 +101,7 @@ function calculateBudgetedK(amm, cost) {
|
|
|
101
101
|
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
102
102
|
const x = amm.baseAssetReserve;
|
|
103
103
|
const y = amm.quoteAssetReserve;
|
|
104
|
-
const d = amm.
|
|
104
|
+
const d = amm.baseAssetAmountWithAmm;
|
|
105
105
|
const Q = amm.pegMultiplier;
|
|
106
106
|
const [numerator, denominator] = calculateBudgetedKBN(x, y, cost, Q, d);
|
|
107
107
|
return [numerator, denominator];
|
|
@@ -120,7 +120,7 @@ function calculateBudgetedPeg(amm, cost, targetPrice) {
|
|
|
120
120
|
const k = amm.sqrtK.mul(amm.sqrtK);
|
|
121
121
|
const x = amm.baseAssetReserve;
|
|
122
122
|
const y = amm.quoteAssetReserve;
|
|
123
|
-
const d = amm.
|
|
123
|
+
const d = amm.baseAssetAmountWithAmm;
|
|
124
124
|
const Q = amm.pegMultiplier;
|
|
125
125
|
const C = cost.mul(new anchor_1.BN(-1));
|
|
126
126
|
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
package/lib/math/spotBalance.js
CHANGED
|
@@ -177,12 +177,12 @@ function calculateWithdrawLimit(spotMarket, now) {
|
|
|
177
177
|
const borrowTokenTwapLive = spotMarket.borrowTokenTwap
|
|
178
178
|
.mul(sinceStart)
|
|
179
179
|
.add(marketBorrowTokenAmount.mul(sinceLast))
|
|
180
|
-
.div(sinceLast.add(
|
|
180
|
+
.div(sinceLast.add(sinceStart));
|
|
181
181
|
const depositTokenTwapLive = spotMarket.depositTokenTwap
|
|
182
182
|
.mul(sinceStart)
|
|
183
183
|
.add(marketDepositTokenAmount.mul(sinceLast))
|
|
184
|
-
.div(sinceLast.add(
|
|
185
|
-
const maxBorrowTokens = anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(borrowTokenTwapLive.div(new anchor_1.BN(5)))), marketDepositTokenAmount.sub(marketDepositTokenAmount.div(new anchor_1.BN(
|
|
184
|
+
.div(sinceLast.add(sinceStart));
|
|
185
|
+
const maxBorrowTokens = anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(borrowTokenTwapLive.div(new anchor_1.BN(5)))), marketDepositTokenAmount.sub(marketDepositTokenAmount.div(new anchor_1.BN(5)))); // between ~15-80% utilization with friction on twap
|
|
186
186
|
const minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.min(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), spotMarket.withdrawGuardThreshold), depositTokenTwapLive));
|
|
187
187
|
return {
|
|
188
188
|
borrowLimit: maxBorrowTokens.sub(marketBorrowTokenAmount),
|
package/lib/math/spotPosition.js
CHANGED
|
@@ -4,11 +4,11 @@ exports.getWorstCaseTokenAmounts = exports.isSpotPositionAvailable = void 0;
|
|
|
4
4
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
5
|
const spotBalance_1 = require("./spotBalance");
|
|
6
6
|
function isSpotPositionAvailable(position) {
|
|
7
|
-
return position.
|
|
7
|
+
return position.scaledBalance.eq(numericConstants_1.ZERO) && position.openOrders === 0;
|
|
8
8
|
}
|
|
9
9
|
exports.isSpotPositionAvailable = isSpotPositionAvailable;
|
|
10
10
|
function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, oraclePriceData) {
|
|
11
|
-
const tokenAmount = (0, spotBalance_1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.
|
|
11
|
+
const tokenAmount = (0, spotBalance_1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType), spotPosition.balanceType);
|
|
12
12
|
const tokenAmountAllBidsFill = tokenAmount.add(spotPosition.openBids);
|
|
13
13
|
const tokenAmountAllAsksFill = tokenAmount.add(spotPosition.openAsks);
|
|
14
14
|
if (tokenAmountAllAsksFill.abs().gt(tokenAmountAllBidsFill.abs())) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { SerumV3FulfillmentConfigAccount } from '../types';
|
|
3
|
+
import { ClearingHouse } from '../clearingHouse';
|
|
4
|
+
export declare class SerumFulfillmentConfigMap {
|
|
5
|
+
clearingHouse: ClearingHouse;
|
|
6
|
+
map: Map<number, SerumV3FulfillmentConfigAccount>;
|
|
7
|
+
constructor(clearingHouse: ClearingHouse);
|
|
8
|
+
add(marketIndex: number, serumMarketAddress: PublicKey): Promise<void>;
|
|
9
|
+
get(marketIndex: number): SerumV3FulfillmentConfigAccount;
|
|
10
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SerumFulfillmentConfigMap = void 0;
|
|
4
|
+
class SerumFulfillmentConfigMap {
|
|
5
|
+
constructor(clearingHouse) {
|
|
6
|
+
this.map = new Map();
|
|
7
|
+
this.clearingHouse = clearingHouse;
|
|
8
|
+
}
|
|
9
|
+
async add(marketIndex, serumMarketAddress) {
|
|
10
|
+
const account = await this.clearingHouse.getSerumV3FulfillmentConfig(serumMarketAddress);
|
|
11
|
+
this.map.set(marketIndex, account);
|
|
12
|
+
}
|
|
13
|
+
get(marketIndex) {
|
|
14
|
+
return this.map.get(marketIndex);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.SerumFulfillmentConfigMap = SerumFulfillmentConfigMap;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
1
2
|
import { Connection, PublicKey } from '@solana/web3.js';
|
|
2
3
|
import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
|
|
3
4
|
import { Market, Orderbook } from '@project-serum/serum';
|
|
4
5
|
import { SerumMarketSubscriberConfig } from './types';
|
|
6
|
+
import { BN } from '@project-serum/anchor';
|
|
5
7
|
export declare class SerumSubscriber {
|
|
6
8
|
connection: Connection;
|
|
7
9
|
programId: PublicKey;
|
|
@@ -19,5 +21,7 @@ export declare class SerumSubscriber {
|
|
|
19
21
|
lastBidsSlot: number;
|
|
20
22
|
constructor(config: SerumMarketSubscriberConfig);
|
|
21
23
|
subscribe(): Promise<void>;
|
|
24
|
+
getBestBid(): BN | undefined;
|
|
25
|
+
getBestAsk(): BN | undefined;
|
|
22
26
|
unsubscribe(): Promise<void>;
|
|
23
27
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SerumSubscriber = void 0;
|
|
4
4
|
const serum_1 = require("@project-serum/serum");
|
|
5
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
6
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
7
|
class SerumSubscriber {
|
|
6
8
|
constructor(config) {
|
|
7
9
|
this.connection = config.connection;
|
|
@@ -19,7 +21,6 @@ class SerumSubscriber {
|
|
|
19
21
|
this.asksCallbackId = this.accountLoader.addAccount(this.asksAddress, (buffer, slot) => {
|
|
20
22
|
this.lastAsksSlot = slot;
|
|
21
23
|
this.asks = serum_1.Orderbook.decode(this.market, buffer);
|
|
22
|
-
console.log(this.asks.getL2(3));
|
|
23
24
|
});
|
|
24
25
|
this.bidsAddress = this.market.bidsAddress;
|
|
25
26
|
this.bids = await this.market.loadBids(this.connection);
|
|
@@ -29,6 +30,20 @@ class SerumSubscriber {
|
|
|
29
30
|
});
|
|
30
31
|
this.subscribed = true;
|
|
31
32
|
}
|
|
33
|
+
getBestBid() {
|
|
34
|
+
const bestBid = this.bids.getL2(1)[0];
|
|
35
|
+
if (!bestBid) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
return new anchor_1.BN(bestBid[0] * numericConstants_1.PRICE_PRECISION.toNumber());
|
|
39
|
+
}
|
|
40
|
+
getBestAsk() {
|
|
41
|
+
const bestAsk = this.asks.getL2(1)[0];
|
|
42
|
+
if (!bestAsk) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
return new anchor_1.BN(bestAsk[0] * numericConstants_1.PRICE_PRECISION.toNumber());
|
|
46
|
+
}
|
|
32
47
|
async unsubscribe() {
|
|
33
48
|
if (!this.subscribed) {
|
|
34
49
|
return;
|