@drift-labs/sdk 0.1.21-master.0 → 0.1.22
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 +0 -1
- package/lib/accounts/bulkAccountLoader.js +4 -2
- package/lib/accounts/bulkUserSubscription.d.ts +0 -1
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +5 -2
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +23 -1
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +0 -1
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +3 -2
- package/lib/accounts/pollingUserAccountSubscriber.js +13 -0
- package/lib/accounts/types.d.ts +8 -3
- package/lib/accounts/utils.d.ts +0 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts +0 -1
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +5 -2
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +25 -0
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +3 -2
- package/lib/accounts/webSocketUserAccountSubscriber.js +11 -0
- package/lib/addresses.d.ts +4 -1
- package/lib/addresses.js +28 -1
- package/lib/admin.d.ts +10 -4
- package/lib/admin.js +48 -3
- package/lib/assert/assert.d.ts +0 -1
- package/lib/clearingHouse.d.ts +27 -2
- package/lib/clearingHouse.js +307 -7
- package/lib/clearingHouseUser.d.ts +16 -3
- package/lib/clearingHouseUser.js +79 -9
- package/lib/config.d.ts +0 -1
- package/lib/constants/markets.d.ts +0 -1
- package/lib/constants/markets.js +8 -0
- package/lib/constants/numericConstants.d.ts +1 -1
- package/lib/constants/numericConstants.js +2 -1
- package/lib/examples/makeTradeExample.d.ts +0 -1
- package/lib/factory/clearingHouse.d.ts +0 -1
- package/lib/factory/clearingHouseUser.d.ts +0 -1
- package/lib/idl/clearing_house.json +1077 -50
- package/lib/index.d.ts +3 -1
- package/lib/index.js +3 -0
- package/lib/math/amm.d.ts +3 -1
- package/lib/math/amm.js +121 -8
- package/lib/math/conversion.d.ts +0 -1
- package/lib/math/funding.d.ts +0 -1
- package/lib/math/insuranceFund.d.ts +0 -1
- package/lib/math/market.d.ts +2 -2
- package/lib/math/market.js +11 -1
- package/lib/math/orders.d.ts +3 -0
- package/lib/math/orders.js +32 -0
- package/lib/math/position.d.ts +4 -2
- package/lib/math/position.js +18 -4
- package/lib/math/trade.d.ts +0 -1
- package/lib/math/utils.d.ts +0 -1
- package/lib/mockUSDCFaucet.d.ts +0 -1
- package/lib/orderParams.d.ts +7 -0
- package/lib/orderParams.js +108 -0
- package/lib/orders.d.ts +6 -0
- package/lib/orders.js +136 -0
- package/lib/pythClient.d.ts +0 -1
- package/lib/token/index.d.ts +0 -1
- package/lib/tx/defaultTxSender.d.ts +0 -1
- package/lib/tx/types.d.ts +0 -1
- package/lib/tx/utils.d.ts +0 -1
- package/lib/types.d.ts +145 -2
- package/lib/types.js +36 -1
- package/lib/util/computeUnits.d.ts +0 -1
- package/lib/util/tps.d.ts +0 -1
- package/lib/wallet.d.ts +0 -1
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +3 -3
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +33 -0
- package/src/accounts/pollingUserAccountSubscriber.ts +30 -2
- package/src/accounts/types.ts +11 -2
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +47 -0
- package/src/accounts/webSocketUserAccountSubscriber.ts +29 -2
- package/src/addresses.ts +37 -0
- package/src/admin.ts +84 -6
- package/src/clearingHouse.ts +430 -5
- package/src/clearingHouseUser.ts +129 -12
- package/src/constants/markets.ts +8 -0
- package/src/constants/numericConstants.ts +1 -0
- package/src/idl/clearing_house.json +1077 -50
- package/src/index.ts +3 -0
- package/src/math/amm.ts +169 -14
- package/src/math/market.ts +28 -2
- package/src/math/orders.ts +44 -0
- package/src/math/position.ts +23 -3
- package/src/orderParams.ts +151 -0
- package/src/orders.ts +236 -0
- package/src/types.ts +129 -1
- package/tsconfig.json +0 -1
- package/lib/accounts/bulkAccountLoader.d.ts.map +0 -1
- package/lib/accounts/bulkUserSubscription.d.ts.map +0 -1
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/pollingUserAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/types.d.ts.map +0 -1
- package/lib/accounts/utils.d.ts.map +0 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts.map +0 -1
- package/lib/addresses.d.ts.map +0 -1
- package/lib/admin.d.ts.map +0 -1
- package/lib/assert/assert.d.ts.map +0 -1
- package/lib/clearingHouse.d.ts.map +0 -1
- package/lib/clearingHouseUser.d.ts.map +0 -1
- package/lib/config.d.ts.map +0 -1
- package/lib/constants/markets.d.ts.map +0 -1
- package/lib/constants/numericConstants.d.ts.map +0 -1
- package/lib/examples/makeTradeExample.d.ts.map +0 -1
- package/lib/factory/clearingHouse.d.ts.map +0 -1
- package/lib/factory/clearingHouseUser.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/math/amm.d.ts.map +0 -1
- package/lib/math/conversion.d.ts.map +0 -1
- package/lib/math/funding.d.ts.map +0 -1
- package/lib/math/insuranceFund.d.ts.map +0 -1
- package/lib/math/market.d.ts.map +0 -1
- package/lib/math/position.d.ts.map +0 -1
- package/lib/math/trade.d.ts.map +0 -1
- package/lib/math/utils.d.ts.map +0 -1
- package/lib/mockUSDCFaucet.d.ts.map +0 -1
- package/lib/pythClient.d.ts.map +0 -1
- package/lib/token/index.d.ts.map +0 -1
- package/lib/tx/defaultTxSender.d.ts.map +0 -1
- package/lib/tx/types.d.ts.map +0 -1
- package/lib/tx/utils.d.ts.map +0 -1
- package/lib/types.d.ts.map +0 -1
- package/lib/util/computeUnits.d.ts.map +0 -1
- package/lib/util/tps.d.ts.map +0 -1
- package/lib/wallet.d.ts.map +0 -1
package/src/clearingHouseUser.ts
CHANGED
|
@@ -2,8 +2,14 @@ import { PublicKey } from '@solana/web3.js';
|
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
4
4
|
import { ClearingHouse } from './clearingHouse';
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import {
|
|
6
|
+
Order,
|
|
7
|
+
UserAccount,
|
|
8
|
+
UserOrdersAccount,
|
|
9
|
+
UserPosition,
|
|
10
|
+
UserPositionsAccount,
|
|
11
|
+
} from './types';
|
|
12
|
+
import { calculateEntryPrice, isEmptyPosition } from './math/position';
|
|
7
13
|
import {
|
|
8
14
|
MARK_PRICE_PRECISION,
|
|
9
15
|
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
@@ -23,6 +29,8 @@ import {
|
|
|
23
29
|
calculatePositionFundingPNL,
|
|
24
30
|
calculatePositionPNL,
|
|
25
31
|
PositionDirection,
|
|
32
|
+
getUserOrdersAccountPublicKey,
|
|
33
|
+
calculateNewStateAfterOrder,
|
|
26
34
|
calculateTradeSlippage,
|
|
27
35
|
BN,
|
|
28
36
|
} from '.';
|
|
@@ -37,6 +45,7 @@ export class ClearingHouseUser {
|
|
|
37
45
|
authority: PublicKey;
|
|
38
46
|
accountSubscriber: UserAccountSubscriber;
|
|
39
47
|
userAccountPublicKey?: PublicKey;
|
|
48
|
+
userOrdersAccountPublicKey?: PublicKey;
|
|
40
49
|
_isSubscribed = false;
|
|
41
50
|
eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
|
|
42
51
|
|
|
@@ -111,6 +120,10 @@ export class ClearingHouseUser {
|
|
|
111
120
|
return this.accountSubscriber.getUserPositionsAccount();
|
|
112
121
|
}
|
|
113
122
|
|
|
123
|
+
public getUserOrdersAccount(): UserOrdersAccount | undefined {
|
|
124
|
+
return this.accountSubscriber.getUserOrdersAccount();
|
|
125
|
+
}
|
|
126
|
+
|
|
114
127
|
/**
|
|
115
128
|
* Gets the user's current position for a given market. If the user has no position returns undefined
|
|
116
129
|
* @param marketIndex
|
|
@@ -128,9 +141,30 @@ export class ClearingHouseUser {
|
|
|
128
141
|
lastCumulativeFundingRate: ZERO,
|
|
129
142
|
marketIndex,
|
|
130
143
|
quoteAssetAmount: ZERO,
|
|
144
|
+
openOrders: ZERO,
|
|
131
145
|
};
|
|
132
146
|
}
|
|
133
147
|
|
|
148
|
+
/**
|
|
149
|
+
* @param orderId
|
|
150
|
+
* @returns Order
|
|
151
|
+
*/
|
|
152
|
+
public getOrder(orderId: BN): Order | undefined {
|
|
153
|
+
return this.getUserOrdersAccount().orders.find((order) =>
|
|
154
|
+
order.orderId.eq(orderId)
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @param userOrderId
|
|
160
|
+
* @returns Order
|
|
161
|
+
*/
|
|
162
|
+
public getOrderByUserOrderId(userOrderId: number): Order | undefined {
|
|
163
|
+
return this.getUserOrdersAccount().orders.find(
|
|
164
|
+
(order) => order.userOrderId === userOrderId
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
134
168
|
public async getUserAccountPublicKey(): Promise<PublicKey> {
|
|
135
169
|
if (this.userAccountPublicKey) {
|
|
136
170
|
return this.userAccountPublicKey;
|
|
@@ -143,6 +177,18 @@ export class ClearingHouseUser {
|
|
|
143
177
|
return this.userAccountPublicKey;
|
|
144
178
|
}
|
|
145
179
|
|
|
180
|
+
public async getUserOrdersAccountPublicKey(): Promise<PublicKey> {
|
|
181
|
+
if (this.userOrdersAccountPublicKey) {
|
|
182
|
+
return this.userOrdersAccountPublicKey;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
this.userOrdersAccountPublicKey = await getUserOrdersAccountPublicKey(
|
|
186
|
+
this.clearingHouse.program.programId,
|
|
187
|
+
await this.getUserAccountPublicKey()
|
|
188
|
+
);
|
|
189
|
+
return this.userOrdersAccountPublicKey;
|
|
190
|
+
}
|
|
191
|
+
|
|
146
192
|
public async exists(): Promise<boolean> {
|
|
147
193
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
148
194
|
const userAccountRPCResponse =
|
|
@@ -438,6 +484,7 @@ export class ClearingHouseUser {
|
|
|
438
484
|
),
|
|
439
485
|
lastCumulativeFundingRate: new BN(0),
|
|
440
486
|
quoteAssetAmount: new BN(0),
|
|
487
|
+
openOrders: new BN(0),
|
|
441
488
|
};
|
|
442
489
|
|
|
443
490
|
const market = this.clearingHouse.getMarket(
|
|
@@ -528,14 +575,14 @@ export class ClearingHouseUser {
|
|
|
528
575
|
// solves formula for example calc below
|
|
529
576
|
|
|
530
577
|
/* example: assume BTC price is $40k (examine 10% up/down)
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
578
|
+
|
|
579
|
+
if 10k deposit and levered 10x short BTC => BTC up $400 means:
|
|
580
|
+
1. higher base_asset_value (+$4k)
|
|
581
|
+
2. lower collateral (-$4k)
|
|
582
|
+
3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
|
|
583
|
+
|
|
584
|
+
for 10x long, BTC down $400:
|
|
585
|
+
3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
|
|
539
586
|
|
|
540
587
|
const tc = this.getTotalCollateral();
|
|
541
588
|
const tpv = this.getTotalPositionValue();
|
|
@@ -566,6 +613,7 @@ export class ClearingHouseUser {
|
|
|
566
613
|
lastCumulativeFundingRate:
|
|
567
614
|
currentMarketPosition.lastCumulativeFundingRate,
|
|
568
615
|
quoteAssetAmount: new BN(0),
|
|
616
|
+
openOrders: new BN(0),
|
|
569
617
|
};
|
|
570
618
|
|
|
571
619
|
const market = this.clearingHouse.getMarket(
|
|
@@ -700,7 +748,7 @@ export class ClearingHouseUser {
|
|
|
700
748
|
* Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
|
|
701
749
|
* => current position + remaining to get to maxLeverage
|
|
702
750
|
*
|
|
703
|
-
* @param
|
|
751
|
+
* @param targetMarketIndex
|
|
704
752
|
* @param tradeSide
|
|
705
753
|
* @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
|
|
706
754
|
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
|
|
@@ -842,7 +890,6 @@ export class ClearingHouseUser {
|
|
|
842
890
|
this.getTotalPositionValueExcludingMarket(targetMarketIndex);
|
|
843
891
|
|
|
844
892
|
const totalCollateral = this.getTotalCollateral();
|
|
845
|
-
|
|
846
893
|
if (totalCollateral.gt(ZERO)) {
|
|
847
894
|
const newLeverage = currentMarketPositionAfterTrade
|
|
848
895
|
.add(totalPositionAfterTradeExcludingTargetMarket)
|
|
@@ -885,4 +932,74 @@ export class ClearingHouseUser {
|
|
|
885
932
|
|
|
886
933
|
return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
|
|
887
934
|
}
|
|
935
|
+
|
|
936
|
+
public canFillOrder(order: Order): boolean {
|
|
937
|
+
const userAccount = this.getUserAccount();
|
|
938
|
+
const userPositionsAccount = this.getUserPositionsAccount();
|
|
939
|
+
const userPosition = this.getUserPosition(order.marketIndex);
|
|
940
|
+
const market = this.clearingHouse.getMarket(order.marketIndex);
|
|
941
|
+
|
|
942
|
+
if (isEmptyPosition(userPosition)) {
|
|
943
|
+
return false;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
const newState = calculateNewStateAfterOrder(
|
|
947
|
+
userAccount,
|
|
948
|
+
userPosition,
|
|
949
|
+
market,
|
|
950
|
+
order
|
|
951
|
+
);
|
|
952
|
+
if (newState === null) {
|
|
953
|
+
return false;
|
|
954
|
+
}
|
|
955
|
+
const [userAccountAfter, userPositionAfter, marketAfter] = newState;
|
|
956
|
+
|
|
957
|
+
const totalPositionValue = userPositionsAccount.positions.reduce(
|
|
958
|
+
(positionValue, marketPosition) => {
|
|
959
|
+
let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
|
|
960
|
+
if (marketPosition.marketIndex.eq(order.marketIndex)) {
|
|
961
|
+
market = marketAfter;
|
|
962
|
+
marketPosition = userPositionAfter;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
return positionValue.add(
|
|
966
|
+
calculateBaseAssetValue(market, marketPosition)
|
|
967
|
+
);
|
|
968
|
+
},
|
|
969
|
+
ZERO
|
|
970
|
+
);
|
|
971
|
+
|
|
972
|
+
if (totalPositionValue.eq(ZERO)) {
|
|
973
|
+
return true;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
const unrealizedPnL = userPositionsAccount.positions.reduce(
|
|
977
|
+
(pnl, marketPosition) => {
|
|
978
|
+
let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
|
|
979
|
+
pnl = pnl.add(
|
|
980
|
+
calculatePositionFundingPNL(market, marketPosition).div(
|
|
981
|
+
PRICE_TO_QUOTE_PRECISION
|
|
982
|
+
)
|
|
983
|
+
);
|
|
984
|
+
|
|
985
|
+
if (marketPosition.marketIndex.eq(order.marketIndex)) {
|
|
986
|
+
market = marketAfter;
|
|
987
|
+
marketPosition = userPositionAfter;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// update
|
|
991
|
+
return pnl.add(calculatePositionPNL(market, marketPosition, false));
|
|
992
|
+
},
|
|
993
|
+
ZERO
|
|
994
|
+
);
|
|
995
|
+
const totalCollateral = userAccountAfter.collateral.add(unrealizedPnL);
|
|
996
|
+
|
|
997
|
+
const marginRatioAfter = totalCollateral
|
|
998
|
+
.mul(TEN_THOUSAND)
|
|
999
|
+
.div(totalPositionValue);
|
|
1000
|
+
|
|
1001
|
+
const marginRatioInitial =
|
|
1002
|
+
this.clearingHouse.getStateAccount().marginRatioInitial;
|
|
1003
|
+
return marginRatioAfter.gte(marginRatioInitial);
|
|
1004
|
+
}
|
|
888
1005
|
}
|
package/src/constants/markets.ts
CHANGED
|
@@ -106,6 +106,14 @@ export const Markets: Market[] = [
|
|
|
106
106
|
mainnetPythOracle: '8JPJJkmDScpcNmBRKGZuPuG2GYAveQgP3t5gFuMymwvF',
|
|
107
107
|
launchTs: 1644382122000,
|
|
108
108
|
},
|
|
109
|
+
{
|
|
110
|
+
symbol: 'LTC-PERP',
|
|
111
|
+
baseAssetSymbol: 'LTC',
|
|
112
|
+
marketIndex: new BN(12),
|
|
113
|
+
devnetPythOracle: 'BLArYBCUYhdWiY8PCUTpvFE21iaJq85dvxLk9bYMobcU',
|
|
114
|
+
mainnetPythOracle: '8RMnV1eD55iqUFJLMguPkYBkq8DCtx81XcmAja93LvRR',
|
|
115
|
+
launchTs: 1645027429000,
|
|
116
|
+
},
|
|
109
117
|
// {
|
|
110
118
|
// symbol: 'mSOL-PERP',
|
|
111
119
|
// baseAssetSymbol: 'mSOL',
|