@drift-labs/sdk 0.2.0-master.38 → 0.2.0-master.39
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/README.md +14 -14
- package/lib/accounts/bulkUserStatsSubscription.d.ts +2 -2
- package/lib/accounts/bulkUserSubscription.d.ts +2 -2
- package/lib/accounts/{pollingClearingHouseAccountSubscriber.d.ts → pollingDriftClientAccountSubscriber.d.ts} +3 -8
- package/lib/accounts/{pollingClearingHouseAccountSubscriber.js → pollingDriftClientAccountSubscriber.js} +6 -13
- package/lib/accounts/{pollingOracleSubscriber.d.ts → pollingOracleAccountSubscriber.d.ts} +2 -2
- package/lib/accounts/{pollingOracleSubscriber.js → pollingOracleAccountSubscriber.js} +3 -3
- package/lib/accounts/types.d.ts +4 -4
- package/lib/accounts/{webSocketClearingHouseAccountSubscriber.d.ts → webSocketDriftClientAccountSubscriber.d.ts} +3 -3
- package/lib/accounts/{webSocketClearingHouseAccountSubscriber.js → webSocketDriftClientAccountSubscriber.js} +4 -4
- package/lib/addresses/pda.d.ts +3 -3
- package/lib/addresses/pda.js +10 -10
- package/lib/{admin.d.ts → adminClient.d.ts} +9 -4
- package/lib/{admin.js → adminClient.js} +62 -15
- package/lib/config.js +1 -1
- package/lib/constants/numericConstants.d.ts +3 -0
- package/lib/constants/numericConstants.js +5 -2
- package/lib/dlob/DLOB.d.ts +2 -2
- package/lib/dlob/DLOB.js +4 -4
- package/lib/{clearingHouse.d.ts → driftClient.d.ts} +20 -20
- package/lib/{clearingHouse.js → driftClient.js} +28 -28
- package/lib/{clearingHouseConfig.d.ts → driftClientConfig.d.ts} +3 -3
- package/lib/{clearingHouseConfig.js → driftClientConfig.js} +0 -0
- package/lib/examples/makeTradeExample.js +13 -13
- package/lib/idl/{clearing_house.json → drift.json} +603 -119
- package/lib/index.d.ts +10 -10
- package/lib/index.js +10 -10
- package/lib/math/orders.d.ts +4 -4
- package/lib/math/orders.js +3 -3
- package/lib/serum/serumFulfillmentConfigMap.d.ts +3 -3
- package/lib/serum/serumFulfillmentConfigMap.js +3 -3
- package/lib/types.d.ts +38 -2
- package/lib/types.js +2 -1
- package/lib/{clearingHouseUser.d.ts → user.d.ts} +16 -10
- package/lib/{clearingHouseUser.js → user.js} +53 -45
- package/lib/userConfig.d.ts +14 -0
- package/lib/{clearingHouseUserConfig.js → userConfig.js} +0 -0
- package/lib/userMap/userMap.d.ts +17 -17
- package/lib/userMap/userMap.js +15 -15
- package/lib/userMap/userStatsMap.d.ts +7 -7
- package/lib/userMap/userStatsMap.js +10 -10
- package/lib/{clearingHouseUserStats.d.ts → userStats.d.ts} +5 -5
- package/lib/{clearingHouseUserStats.js → userStats.js} +8 -8
- package/lib/userStatsConfig.d.ts +14 -0
- package/lib/{clearingHouseUserStatsConfig.js → userStatsConfig.js} +0 -0
- package/package.json +1 -1
- package/src/accounts/bulkUserStatsSubscription.ts +2 -2
- package/src/accounts/bulkUserSubscription.ts +2 -2
- package/src/accounts/{pollingClearingHouseAccountSubscriber.ts → pollingDriftClientAccountSubscriber.ts} +11 -25
- package/src/accounts/{pollingOracleSubscriber.ts → pollingOracleAccountSubscriber.ts} +2 -2
- package/src/accounts/types.ts +4 -4
- package/src/accounts/{webSocketClearingHouseAccountSubscriber.ts → webSocketDriftClientAccountSubscriber.ts} +7 -7
- package/src/addresses/pda.ts +6 -8
- package/src/{admin.ts → adminClient.ts} +125 -18
- package/src/config.ts +1 -1
- package/src/constants/numericConstants.ts +4 -0
- package/src/dlob/DLOB.ts +5 -5
- package/src/{clearingHouse.ts → driftClient.ts} +45 -47
- package/src/{clearingHouseConfig.ts → driftClientConfig.ts} +3 -3
- package/src/examples/makeTradeExample.ts +15 -17
- package/src/idl/{clearing_house.json → drift.json} +603 -119
- package/src/index.ts +10 -10
- package/src/math/orders.ts +7 -13
- package/src/serum/serumFulfillmentConfigMap.ts +5 -5
- package/src/types.ts +41 -2
- package/src/{clearingHouseUser.ts → user.ts} +59 -53
- package/src/{clearingHouseUserConfig.ts → userConfig.ts} +5 -5
- package/src/userMap/userMap.ts +29 -29
- package/src/userMap/userStatsMap.ts +21 -23
- package/src/{clearingHouseUserStats.ts → userStats.ts} +10 -10
- package/src/userStatsConfig.ts +18 -0
- package/tests/dlob/helpers.ts +55 -13
- package/lib/clearingHouseUserConfig.d.ts +0 -14
- package/lib/clearingHouseUserStatsConfig.d.ts +0 -14
- package/src/clearingHouseUserStatsConfig.ts +0 -18
package/src/index.ts
CHANGED
|
@@ -9,23 +9,23 @@ export * from './oracles/switchboardClient';
|
|
|
9
9
|
export * from './types';
|
|
10
10
|
export * from './constants/perpMarkets';
|
|
11
11
|
export * from './accounts/fetch';
|
|
12
|
-
export * from './accounts/
|
|
12
|
+
export * from './accounts/webSocketDriftClientAccountSubscriber';
|
|
13
13
|
export * from './accounts/bulkAccountLoader';
|
|
14
14
|
export * from './accounts/bulkUserSubscription';
|
|
15
15
|
export * from './accounts/bulkUserStatsSubscription';
|
|
16
|
-
export * from './accounts/
|
|
17
|
-
export * from './accounts/
|
|
16
|
+
export * from './accounts/pollingDriftClientAccountSubscriber';
|
|
17
|
+
export * from './accounts/pollingOracleAccountSubscriber';
|
|
18
18
|
export * from './accounts/pollingTokenAccountSubscriber';
|
|
19
19
|
export * from './accounts/pollingUserAccountSubscriber';
|
|
20
20
|
export * from './accounts/pollingUserStatsAccountSubscriber';
|
|
21
21
|
export * from './accounts/types';
|
|
22
22
|
export * from './addresses/pda';
|
|
23
|
-
export * from './
|
|
24
|
-
export * from './
|
|
25
|
-
export * from './
|
|
26
|
-
export * from './
|
|
27
|
-
export * from './
|
|
28
|
-
export * from './
|
|
23
|
+
export * from './adminClient';
|
|
24
|
+
export * from './user';
|
|
25
|
+
export * from './userConfig';
|
|
26
|
+
export * from './userStats';
|
|
27
|
+
export * from './userStatsConfig';
|
|
28
|
+
export * from './driftClient';
|
|
29
29
|
export * from './factory/oracleClient';
|
|
30
30
|
export * from './factory/bigNum';
|
|
31
31
|
export * from './events/types';
|
|
@@ -60,7 +60,7 @@ export * from './util/tps';
|
|
|
60
60
|
export * from './util/promiseTimeout';
|
|
61
61
|
export * from './math/spotBalance';
|
|
62
62
|
export * from './constants/spotMarkets';
|
|
63
|
-
export * from './
|
|
63
|
+
export * from './driftClientConfig';
|
|
64
64
|
export * from './dlob/DLOB';
|
|
65
65
|
export * from './dlob/DLOBNode';
|
|
66
66
|
export * from './dlob/NodeList';
|
package/src/math/orders.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { User } from '../user';
|
|
2
2
|
import {
|
|
3
3
|
isOneOfVariant,
|
|
4
4
|
isVariant,
|
|
@@ -15,16 +15,13 @@ import {
|
|
|
15
15
|
calculateMaxBaseAssetAmountToTrade,
|
|
16
16
|
} from './amm';
|
|
17
17
|
|
|
18
|
-
export function isOrderRiskIncreasing(
|
|
19
|
-
user: ClearingHouseUser,
|
|
20
|
-
order: Order
|
|
21
|
-
): boolean {
|
|
18
|
+
export function isOrderRiskIncreasing(user: User, order: Order): boolean {
|
|
22
19
|
if (isVariant(order.status, 'init')) {
|
|
23
20
|
return false;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
const position =
|
|
27
|
-
user.
|
|
24
|
+
user.getPerpPosition(order.marketIndex) ||
|
|
28
25
|
user.getEmptyPosition(order.marketIndex);
|
|
29
26
|
|
|
30
27
|
// if no position exists, it's risk increasing
|
|
@@ -57,7 +54,7 @@ export function isOrderRiskIncreasing(
|
|
|
57
54
|
}
|
|
58
55
|
|
|
59
56
|
export function isOrderRiskIncreasingInSameDirection(
|
|
60
|
-
user:
|
|
57
|
+
user: User,
|
|
61
58
|
order: Order
|
|
62
59
|
): boolean {
|
|
63
60
|
if (isVariant(order.status, 'init')) {
|
|
@@ -65,7 +62,7 @@ export function isOrderRiskIncreasingInSameDirection(
|
|
|
65
62
|
}
|
|
66
63
|
|
|
67
64
|
const position =
|
|
68
|
-
user.
|
|
65
|
+
user.getPerpPosition(order.marketIndex) ||
|
|
69
66
|
user.getEmptyPosition(order.marketIndex);
|
|
70
67
|
|
|
71
68
|
// if no position exists, it's risk increasing
|
|
@@ -89,16 +86,13 @@ export function isOrderRiskIncreasingInSameDirection(
|
|
|
89
86
|
return false;
|
|
90
87
|
}
|
|
91
88
|
|
|
92
|
-
export function isOrderReduceOnly(
|
|
93
|
-
user: ClearingHouseUser,
|
|
94
|
-
order: Order
|
|
95
|
-
): boolean {
|
|
89
|
+
export function isOrderReduceOnly(user: User, order: Order): boolean {
|
|
96
90
|
if (isVariant(order.status, 'init')) {
|
|
97
91
|
return false;
|
|
98
92
|
}
|
|
99
93
|
|
|
100
94
|
const position =
|
|
101
|
-
user.
|
|
95
|
+
user.getPerpPosition(order.marketIndex) ||
|
|
102
96
|
user.getEmptyPosition(order.marketIndex);
|
|
103
97
|
|
|
104
98
|
// if position is long and order is long
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { PublicKey } from '@solana/web3.js';
|
|
2
2
|
import { SerumV3FulfillmentConfigAccount } from '../types';
|
|
3
|
-
import {
|
|
3
|
+
import { DriftClient } from '../driftClient';
|
|
4
4
|
|
|
5
5
|
export class SerumFulfillmentConfigMap {
|
|
6
|
-
|
|
6
|
+
driftClient: DriftClient;
|
|
7
7
|
map = new Map<number, SerumV3FulfillmentConfigAccount>();
|
|
8
8
|
|
|
9
|
-
public constructor(
|
|
10
|
-
this.
|
|
9
|
+
public constructor(driftClient: DriftClient) {
|
|
10
|
+
this.driftClient = driftClient;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
public async add(
|
|
14
14
|
marketIndex: number,
|
|
15
15
|
serumMarketAddress: PublicKey
|
|
16
16
|
): Promise<void> {
|
|
17
|
-
const account = await this.
|
|
17
|
+
const account = await this.driftClient.getSerumV3FulfillmentConfig(
|
|
18
18
|
serumMarketAddress
|
|
19
19
|
);
|
|
20
20
|
this.map.set(marketIndex, account);
|
package/src/types.ts
CHANGED
|
@@ -34,7 +34,8 @@ export class ContractTier {
|
|
|
34
34
|
static readonly A = { a: {} };
|
|
35
35
|
static readonly B = { b: {} };
|
|
36
36
|
static readonly C = { c: {} };
|
|
37
|
-
static readonly
|
|
37
|
+
static readonly SPECULATIVE = { speculative: {} };
|
|
38
|
+
static readonly ISOLATED = { isolated: {} };
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
export class AssetTier {
|
|
@@ -189,6 +190,7 @@ export type DepositRecord = {
|
|
|
189
190
|
marketWithdrawBalance: BN;
|
|
190
191
|
marketCumulativeDepositInterest: BN;
|
|
191
192
|
marketCumulativeBorrowInterest: BN;
|
|
193
|
+
depositRecordId: BN;
|
|
192
194
|
transferUser?: PublicKey;
|
|
193
195
|
};
|
|
194
196
|
|
|
@@ -359,6 +361,9 @@ export type LiquidatePerpPnlForDepositRecord = {
|
|
|
359
361
|
export type PerpBankruptcyRecord = {
|
|
360
362
|
marketIndex: number;
|
|
361
363
|
pnl: BN;
|
|
364
|
+
ifPayment: BN;
|
|
365
|
+
clawbackUser: PublicKey | null;
|
|
366
|
+
clawbackUserPayment: BN | null;
|
|
362
367
|
cumulativeFundingRateDelta: BN;
|
|
363
368
|
};
|
|
364
369
|
|
|
@@ -440,6 +445,7 @@ export type StateAccount = {
|
|
|
440
445
|
export type PerpMarketAccount = {
|
|
441
446
|
status: MarketStatus;
|
|
442
447
|
contractType: ContractType;
|
|
448
|
+
contractTier: ContractTier;
|
|
443
449
|
expiryTs: BN;
|
|
444
450
|
expiryPrice: BN;
|
|
445
451
|
marketIndex: number;
|
|
@@ -451,6 +457,8 @@ export type PerpMarketAccount = {
|
|
|
451
457
|
marginRatioInitial: number;
|
|
452
458
|
marginRatioMaintenance: number;
|
|
453
459
|
nextFillRecordId: BN;
|
|
460
|
+
nextFundingRateRecordId: BN;
|
|
461
|
+
nextCurveRecordId: BN;
|
|
454
462
|
pnlPool: PoolBalance;
|
|
455
463
|
liquidatorFee: number;
|
|
456
464
|
ifLiquidationFee: number;
|
|
@@ -538,12 +546,15 @@ export type SpotMarketAccount = {
|
|
|
538
546
|
depositTokenTwap: BN;
|
|
539
547
|
borrowTokenTwap: BN;
|
|
540
548
|
utilizationTwap: BN;
|
|
549
|
+
nextDepositRecordId: BN;
|
|
541
550
|
|
|
542
551
|
orderStepSize: BN;
|
|
543
552
|
orderTickSize: BN;
|
|
544
553
|
nextFillRecordId: BN;
|
|
545
554
|
spotFeePool: PoolBalance;
|
|
546
555
|
totalSpotFee: BN;
|
|
556
|
+
|
|
557
|
+
ordersEnabled: boolean;
|
|
547
558
|
};
|
|
548
559
|
|
|
549
560
|
export type PoolBalance = {
|
|
@@ -560,6 +571,7 @@ export type AMM = {
|
|
|
560
571
|
lastMarkPriceTwap: BN;
|
|
561
572
|
lastMarkPriceTwap5min: BN;
|
|
562
573
|
lastMarkPriceTwapTs: BN;
|
|
574
|
+
lastTradeTs: BN;
|
|
563
575
|
|
|
564
576
|
oracle: PublicKey;
|
|
565
577
|
oracleSource: OracleSource;
|
|
@@ -573,7 +585,11 @@ export type AMM = {
|
|
|
573
585
|
pegMultiplier: BN;
|
|
574
586
|
cumulativeFundingRateLong: BN;
|
|
575
587
|
cumulativeFundingRateShort: BN;
|
|
576
|
-
|
|
588
|
+
last24hAvgFundingRate: BN;
|
|
589
|
+
lastFundingRateShort: BN;
|
|
590
|
+
lastFundingRateLong: BN;
|
|
591
|
+
|
|
592
|
+
totalLiquidationFee: BN;
|
|
577
593
|
totalFeeMinusDistributions: BN;
|
|
578
594
|
totalFeeWithdrawn: BN;
|
|
579
595
|
totalFee: BN;
|
|
@@ -590,11 +606,13 @@ export type AMM = {
|
|
|
590
606
|
baseAssetAmountShort: BN;
|
|
591
607
|
quoteAssetAmount: BN;
|
|
592
608
|
terminalQuoteAssetReserve: BN;
|
|
609
|
+
concentrationCoef: BN;
|
|
593
610
|
feePool: PoolBalance;
|
|
594
611
|
totalExchangeFee: BN;
|
|
595
612
|
totalMmFee: BN;
|
|
596
613
|
netRevenueSinceLastFunding: BN;
|
|
597
614
|
lastUpdateSlot: BN;
|
|
615
|
+
lastOracleNormalisedPrice: BN;
|
|
598
616
|
lastOracleValid: boolean;
|
|
599
617
|
lastBidPriceTwap: BN;
|
|
600
618
|
lastAskPriceTwap: BN;
|
|
@@ -606,9 +624,29 @@ export type AMM = {
|
|
|
606
624
|
quoteAssetAmountPerLp: BN;
|
|
607
625
|
|
|
608
626
|
ammJitIntensity: number;
|
|
627
|
+
maxOpenInterest: BN;
|
|
609
628
|
maxBaseAssetReserve: BN;
|
|
610
629
|
minBaseAssetReserve: BN;
|
|
611
630
|
cumulativeSocialLoss: BN;
|
|
631
|
+
|
|
632
|
+
quoteBreakEvenAmountLong: BN;
|
|
633
|
+
quoteBreakEvenAmountShort: BN;
|
|
634
|
+
quoteEntryAmountLong: BN;
|
|
635
|
+
quoteEntryAmountShort: BN;
|
|
636
|
+
|
|
637
|
+
markStd: BN;
|
|
638
|
+
longIntensityCount: number;
|
|
639
|
+
longIntensityVolume: BN;
|
|
640
|
+
shortIntensityCount: number;
|
|
641
|
+
shortIntensityVolume: BN;
|
|
642
|
+
volume24h: BN;
|
|
643
|
+
minOrderSize: BN;
|
|
644
|
+
maxPositionSize: BN;
|
|
645
|
+
|
|
646
|
+
bidBaseAssetReserve: BN;
|
|
647
|
+
bidQuoteAssetReserve: BN;
|
|
648
|
+
askBaseAssetReserve: BN;
|
|
649
|
+
askQuoteAssetReserve: BN;
|
|
612
650
|
};
|
|
613
651
|
|
|
614
652
|
// # User Account Types
|
|
@@ -669,6 +707,7 @@ export type UserAccount = {
|
|
|
669
707
|
settledPerpPnl: BN;
|
|
670
708
|
totalDeposits: BN;
|
|
671
709
|
totalWithdraws: BN;
|
|
710
|
+
cumulativePerpFunding: BN;
|
|
672
711
|
};
|
|
673
712
|
|
|
674
713
|
export type SpotPosition = {
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { PublicKey } from '@solana/web3.js';
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
4
|
-
import {
|
|
4
|
+
import { DriftClient } from './driftClient';
|
|
5
5
|
import {
|
|
6
6
|
isVariant,
|
|
7
7
|
MarginCategory,
|
|
8
8
|
Order,
|
|
9
9
|
UserAccount,
|
|
10
10
|
PerpPosition,
|
|
11
|
+
SpotPosition,
|
|
11
12
|
} from './types';
|
|
12
13
|
import { calculateEntryPrice } from './math/position';
|
|
13
14
|
import {
|
|
@@ -55,15 +56,15 @@ import {
|
|
|
55
56
|
calculateWorstCaseBaseAssetAmount,
|
|
56
57
|
} from './math/margin';
|
|
57
58
|
import { OraclePriceData } from './oracles/types';
|
|
58
|
-
import {
|
|
59
|
+
import { UserConfig } from './userConfig';
|
|
59
60
|
import { PollingUserAccountSubscriber } from './accounts/pollingUserAccountSubscriber';
|
|
60
61
|
import { WebSocketUserAccountSubscriber } from './accounts/webSocketUserAccountSubscriber';
|
|
61
62
|
import {
|
|
62
63
|
getWorstCaseTokenAmounts,
|
|
63
64
|
isSpotPositionAvailable,
|
|
64
65
|
} from './math/spotPosition';
|
|
65
|
-
export class
|
|
66
|
-
|
|
66
|
+
export class User {
|
|
67
|
+
driftClient: DriftClient;
|
|
67
68
|
userAccountPublicKey: PublicKey;
|
|
68
69
|
accountSubscriber: UserAccountSubscriber;
|
|
69
70
|
_isSubscribed = false;
|
|
@@ -77,18 +78,18 @@ export class ClearingHouseUser {
|
|
|
77
78
|
this._isSubscribed = val;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
public constructor(config:
|
|
81
|
-
this.
|
|
81
|
+
public constructor(config: UserConfig) {
|
|
82
|
+
this.driftClient = config.driftClient;
|
|
82
83
|
this.userAccountPublicKey = config.userAccountPublicKey;
|
|
83
84
|
if (config.accountSubscription?.type === 'polling') {
|
|
84
85
|
this.accountSubscriber = new PollingUserAccountSubscriber(
|
|
85
|
-
config.
|
|
86
|
+
config.driftClient.program,
|
|
86
87
|
config.userAccountPublicKey,
|
|
87
88
|
config.accountSubscription.accountLoader
|
|
88
89
|
);
|
|
89
90
|
} else {
|
|
90
91
|
this.accountSubscriber = new WebSocketUserAccountSubscriber(
|
|
91
|
-
config.
|
|
92
|
+
config.driftClient.program,
|
|
92
93
|
config.userAccountPublicKey
|
|
93
94
|
);
|
|
94
95
|
}
|
|
@@ -96,7 +97,7 @@ export class ClearingHouseUser {
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
/**
|
|
99
|
-
* Subscribe to
|
|
100
|
+
* Subscribe to User state accounts
|
|
100
101
|
* @returns SusbcriptionSuccess result
|
|
101
102
|
*/
|
|
102
103
|
public async subscribe(): Promise<boolean> {
|
|
@@ -125,16 +126,27 @@ export class ClearingHouseUser {
|
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
/**
|
|
128
|
-
* Gets the user's current position for a given market. If the user has no position returns undefined
|
|
129
|
+
* Gets the user's current position for a given perp market. If the user has no position returns undefined
|
|
129
130
|
* @param marketIndex
|
|
130
|
-
* @returns
|
|
131
|
+
* @returns userPerpPosition
|
|
131
132
|
*/
|
|
132
|
-
public
|
|
133
|
+
public getPerpPosition(marketIndex: number): PerpPosition | undefined {
|
|
133
134
|
return this.getUserAccount().perpPositions.find(
|
|
134
135
|
(position) => position.marketIndex === marketIndex
|
|
135
136
|
);
|
|
136
137
|
}
|
|
137
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Gets the user's current position for a given spot market. If the user has no position returns undefined
|
|
141
|
+
* @param marketIndex
|
|
142
|
+
* @returns userSpotPosition
|
|
143
|
+
*/
|
|
144
|
+
public getSpotPosition(marketIndex: number): SpotPosition | undefined {
|
|
145
|
+
return this.getUserAccount().spotPositions.find(
|
|
146
|
+
(position) => position.marketIndex === marketIndex
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
138
150
|
public getEmptyPosition(marketIndex: number): PerpPosition {
|
|
139
151
|
return {
|
|
140
152
|
baseAssetAmount: ZERO,
|
|
@@ -185,7 +197,7 @@ export class ClearingHouseUser {
|
|
|
185
197
|
|
|
186
198
|
public async exists(): Promise<boolean> {
|
|
187
199
|
const userAccountRPCResponse =
|
|
188
|
-
await this.
|
|
200
|
+
await this.driftClient.connection.getParsedAccountInfo(
|
|
189
201
|
this.userAccountPublicKey
|
|
190
202
|
);
|
|
191
203
|
return userAccountRPCResponse.value !== null;
|
|
@@ -197,7 +209,7 @@ export class ClearingHouseUser {
|
|
|
197
209
|
* @returns : open asks
|
|
198
210
|
*/
|
|
199
211
|
public getPerpBidAsks(marketIndex: number): [BN, BN] {
|
|
200
|
-
const position = this.
|
|
212
|
+
const position = this.getPerpPosition(marketIndex);
|
|
201
213
|
|
|
202
214
|
const [lpOpenBids, lpOpenAsks] = this.getLPBidAsks(marketIndex);
|
|
203
215
|
|
|
@@ -213,12 +225,12 @@ export class ClearingHouseUser {
|
|
|
213
225
|
* @returns : lp open asks
|
|
214
226
|
*/
|
|
215
227
|
public getLPBidAsks(marketIndex: number): [BN, BN] {
|
|
216
|
-
const position = this.
|
|
228
|
+
const position = this.getPerpPosition(marketIndex);
|
|
217
229
|
if (position === undefined || position.lpShares.eq(ZERO)) {
|
|
218
230
|
return [ZERO, ZERO];
|
|
219
231
|
}
|
|
220
232
|
|
|
221
|
-
const market = this.
|
|
233
|
+
const market = this.driftClient.getPerpMarketAccount(marketIndex);
|
|
222
234
|
const [marketOpenBids, marketOpenAsks] = calculateMarketOpenBidAsk(
|
|
223
235
|
market.amm.baseAssetReserve,
|
|
224
236
|
market.amm.minBaseAssetReserve,
|
|
@@ -242,16 +254,14 @@ export class ClearingHouseUser {
|
|
|
242
254
|
* @returns : pnl from settle
|
|
243
255
|
*/
|
|
244
256
|
public getSettledLPPosition(marketIndex: number): [PerpPosition, BN, BN] {
|
|
245
|
-
const _position = this.
|
|
257
|
+
const _position = this.getPerpPosition(marketIndex);
|
|
246
258
|
const position = this.getClonedPosition(_position);
|
|
247
259
|
|
|
248
260
|
if (position.lpShares.eq(ZERO)) {
|
|
249
261
|
return [position, ZERO, ZERO];
|
|
250
262
|
}
|
|
251
263
|
|
|
252
|
-
const market = this.
|
|
253
|
-
position.marketIndex
|
|
254
|
-
);
|
|
264
|
+
const market = this.driftClient.getPerpMarketAccount(position.marketIndex);
|
|
255
265
|
const nShares = position.lpShares;
|
|
256
266
|
|
|
257
267
|
const deltaBaa = market.amm.baseAssetAmountPerLp
|
|
@@ -408,13 +418,13 @@ export class ClearingHouseUser {
|
|
|
408
418
|
marketIndex?: number,
|
|
409
419
|
withWeightMarginCategory?: MarginCategory
|
|
410
420
|
): BN {
|
|
411
|
-
const quoteSpotMarket = this.
|
|
421
|
+
const quoteSpotMarket = this.driftClient.getQuoteSpotMarketAccount();
|
|
412
422
|
return this.getUserAccount()
|
|
413
423
|
.perpPositions.filter((pos) =>
|
|
414
424
|
marketIndex ? pos.marketIndex === marketIndex : true
|
|
415
425
|
)
|
|
416
426
|
.reduce((unrealizedPnl, perpPosition) => {
|
|
417
|
-
const market = this.
|
|
427
|
+
const market = this.driftClient.getPerpMarketAccount(
|
|
418
428
|
perpPosition.marketIndex
|
|
419
429
|
);
|
|
420
430
|
const oraclePriceData = this.getOracleDataForPerpMarket(
|
|
@@ -458,7 +468,7 @@ export class ClearingHouseUser {
|
|
|
458
468
|
marketIndex ? pos.marketIndex === marketIndex : true
|
|
459
469
|
)
|
|
460
470
|
.reduce((pnl, perpPosition) => {
|
|
461
|
-
const market = this.
|
|
471
|
+
const market = this.driftClient.getPerpMarketAccount(
|
|
462
472
|
perpPosition.marketIndex
|
|
463
473
|
);
|
|
464
474
|
return pnl.add(calculatePositionFundingPNL(market, perpPosition));
|
|
@@ -482,7 +492,7 @@ export class ClearingHouseUser {
|
|
|
482
492
|
}
|
|
483
493
|
|
|
484
494
|
const spotMarketAccount: SpotMarketAccount =
|
|
485
|
-
this.
|
|
495
|
+
this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
486
496
|
|
|
487
497
|
if (spotPosition.marketIndex === QUOTE_SPOT_MARKET_INDEX) {
|
|
488
498
|
if (isVariant(spotPosition.balanceType, 'borrow')) {
|
|
@@ -632,7 +642,7 @@ export class ClearingHouseUser {
|
|
|
632
642
|
|
|
633
643
|
// Todo this needs to account for whether it's based on initial or maintenance requirements
|
|
634
644
|
const spotMarketAccount: SpotMarketAccount =
|
|
635
|
-
this.
|
|
645
|
+
this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
636
646
|
|
|
637
647
|
if (spotPosition.marketIndex === QUOTE_SPOT_MARKET_INDEX) {
|
|
638
648
|
if (isVariant(spotPosition.balanceType, 'deposit')) {
|
|
@@ -757,7 +767,7 @@ export class ClearingHouseUser {
|
|
|
757
767
|
): BN {
|
|
758
768
|
return this.getUserAccount().perpPositions.reduce(
|
|
759
769
|
(totalPerpValue, perpPosition) => {
|
|
760
|
-
const market = this.
|
|
770
|
+
const market = this.driftClient.getPerpMarketAccount(
|
|
761
771
|
perpPosition.marketIndex
|
|
762
772
|
);
|
|
763
773
|
|
|
@@ -843,8 +853,8 @@ export class ClearingHouseUser {
|
|
|
843
853
|
oraclePriceData: OraclePriceData
|
|
844
854
|
): BN {
|
|
845
855
|
const userPosition =
|
|
846
|
-
this.
|
|
847
|
-
const market = this.
|
|
856
|
+
this.getPerpPosition(marketIndex) || this.getEmptyPosition(marketIndex);
|
|
857
|
+
const market = this.driftClient.getPerpMarketAccount(
|
|
848
858
|
userPosition.marketIndex
|
|
849
859
|
);
|
|
850
860
|
return calculateBaseAssetValueWithOracle(
|
|
@@ -875,9 +885,7 @@ export class ClearingHouseUser {
|
|
|
875
885
|
amountToClose?: BN,
|
|
876
886
|
useAMMClose = false
|
|
877
887
|
): [BN, BN] {
|
|
878
|
-
const market = this.
|
|
879
|
-
position.marketIndex
|
|
880
|
-
);
|
|
888
|
+
const market = this.driftClient.getPerpMarketAccount(position.marketIndex);
|
|
881
889
|
|
|
882
890
|
const entryPrice = calculateEntryPrice(position);
|
|
883
891
|
|
|
@@ -967,7 +975,7 @@ export class ClearingHouseUser {
|
|
|
967
975
|
marketIndex: number,
|
|
968
976
|
category: MarginCategory = 'Initial'
|
|
969
977
|
): BN {
|
|
970
|
-
const market = this.
|
|
978
|
+
const market = this.driftClient.getPerpMarketAccount(marketIndex);
|
|
971
979
|
|
|
972
980
|
const totalAssetValue = this.getTotalAssetValue();
|
|
973
981
|
if (totalAssetValue.eq(ZERO)) {
|
|
@@ -1018,7 +1026,7 @@ export class ClearingHouseUser {
|
|
|
1018
1026
|
let liquidationBuffer = undefined;
|
|
1019
1027
|
if (this.getUserAccount().isBeingLiquidated) {
|
|
1020
1028
|
liquidationBuffer = new BN(
|
|
1021
|
-
this.
|
|
1029
|
+
this.driftClient.getStateAccount().liquidationMarginBufferRatio
|
|
1022
1030
|
);
|
|
1023
1031
|
}
|
|
1024
1032
|
const maintenanceRequirement =
|
|
@@ -1036,7 +1044,7 @@ export class ClearingHouseUser {
|
|
|
1036
1044
|
continue;
|
|
1037
1045
|
}
|
|
1038
1046
|
|
|
1039
|
-
const market = this.
|
|
1047
|
+
const market = this.driftClient.getPerpMarketAccount(
|
|
1040
1048
|
userPosition.marketIndex
|
|
1041
1049
|
);
|
|
1042
1050
|
if (
|
|
@@ -1085,7 +1093,7 @@ export class ClearingHouseUser {
|
|
|
1085
1093
|
this.getTotalPerpPositionValueExcludingMarket(perpPosition.marketIndex);
|
|
1086
1094
|
|
|
1087
1095
|
const currentPerpPosition =
|
|
1088
|
-
this.
|
|
1096
|
+
this.getPerpPosition(perpPosition.marketIndex) ||
|
|
1089
1097
|
this.getEmptyPosition(perpPosition.marketIndex);
|
|
1090
1098
|
|
|
1091
1099
|
const currentPerpPositionBaseSize = currentPerpPosition.baseAssetAmount;
|
|
@@ -1114,7 +1122,7 @@ export class ClearingHouseUser {
|
|
|
1114
1122
|
|
|
1115
1123
|
if (proposedBaseAssetAmount.eq(ZERO)) return new BN(-1);
|
|
1116
1124
|
|
|
1117
|
-
const market = this.
|
|
1125
|
+
const market = this.driftClient.getPerpMarketAccount(
|
|
1118
1126
|
proposedPerpPosition.marketIndex
|
|
1119
1127
|
);
|
|
1120
1128
|
|
|
@@ -1132,7 +1140,7 @@ export class ClearingHouseUser {
|
|
|
1132
1140
|
this.getUserAccount().perpPositions.reduce(
|
|
1133
1141
|
(totalMarginRequirement, position) => {
|
|
1134
1142
|
if (position.marketIndex !== perpPosition.marketIndex) {
|
|
1135
|
-
const market = this.
|
|
1143
|
+
const market = this.driftClient.getPerpMarketAccount(
|
|
1136
1144
|
position.marketIndex
|
|
1137
1145
|
);
|
|
1138
1146
|
const positionValue = calculateBaseAssetValueWithOracle(
|
|
@@ -1215,7 +1223,7 @@ export class ClearingHouseUser {
|
|
|
1215
1223
|
let markPriceAfterTrade;
|
|
1216
1224
|
if (positionBaseSizeChange.eq(ZERO)) {
|
|
1217
1225
|
markPriceAfterTrade = calculateReservePrice(
|
|
1218
|
-
this.
|
|
1226
|
+
this.driftClient.getPerpMarketAccount(perpPosition.marketIndex),
|
|
1219
1227
|
this.getOracleDataForPerpMarket(perpPosition.marketIndex)
|
|
1220
1228
|
);
|
|
1221
1229
|
} else {
|
|
@@ -1225,7 +1233,7 @@ export class ClearingHouseUser {
|
|
|
1225
1233
|
markPriceAfterTrade = calculateTradeSlippage(
|
|
1226
1234
|
direction,
|
|
1227
1235
|
positionBaseSizeChange.abs(),
|
|
1228
|
-
this.
|
|
1236
|
+
this.driftClient.getPerpMarketAccount(perpPosition.marketIndex),
|
|
1229
1237
|
'base',
|
|
1230
1238
|
this.getOracleDataForPerpMarket(perpPosition.marketIndex)
|
|
1231
1239
|
)[3]; // newPrice after swap
|
|
@@ -1249,7 +1257,7 @@ export class ClearingHouseUser {
|
|
|
1249
1257
|
closeQuoteAmount: BN
|
|
1250
1258
|
): BN {
|
|
1251
1259
|
const currentPosition =
|
|
1252
|
-
this.
|
|
1260
|
+
this.getPerpPosition(positionMarketIndex) ||
|
|
1253
1261
|
this.getEmptyPosition(positionMarketIndex);
|
|
1254
1262
|
|
|
1255
1263
|
const closeBaseAmount = currentPosition.baseAssetAmount
|
|
@@ -1296,7 +1304,7 @@ export class ClearingHouseUser {
|
|
|
1296
1304
|
tradeSide: PositionDirection
|
|
1297
1305
|
): BN {
|
|
1298
1306
|
const currentPosition =
|
|
1299
|
-
this.
|
|
1307
|
+
this.getPerpPosition(targetMarketIndex) ||
|
|
1300
1308
|
this.getEmptyPosition(targetMarketIndex);
|
|
1301
1309
|
|
|
1302
1310
|
const targetSide = isVariant(tradeSide, 'short') ? 'short' : 'long';
|
|
@@ -1331,8 +1339,7 @@ export class ClearingHouseUser {
|
|
|
1331
1339
|
// current leverage is greater than max leverage - can only reduce position size
|
|
1332
1340
|
|
|
1333
1341
|
if (!targetingSameSide) {
|
|
1334
|
-
const market =
|
|
1335
|
-
this.clearingHouse.getPerpMarketAccount(targetMarketIndex);
|
|
1342
|
+
const market = this.driftClient.getPerpMarketAccount(targetMarketIndex);
|
|
1336
1343
|
const perpPositionValue = this.getPerpPositionValue(
|
|
1337
1344
|
targetMarketIndex,
|
|
1338
1345
|
oracleData
|
|
@@ -1383,7 +1390,7 @@ export class ClearingHouseUser {
|
|
|
1383
1390
|
includeOpenOrders = true
|
|
1384
1391
|
): BN {
|
|
1385
1392
|
const currentPosition =
|
|
1386
|
-
this.
|
|
1393
|
+
this.getPerpPosition(targetMarketIndex) ||
|
|
1387
1394
|
this.getEmptyPosition(targetMarketIndex);
|
|
1388
1395
|
|
|
1389
1396
|
const oracleData = this.getOracleDataForPerpMarket(targetMarketIndex);
|
|
@@ -1444,7 +1451,7 @@ export class ClearingHouseUser {
|
|
|
1444
1451
|
*/
|
|
1445
1452
|
public calculateFeeForQuoteAmount(quoteAmount: BN): BN {
|
|
1446
1453
|
const feeTier =
|
|
1447
|
-
this.
|
|
1454
|
+
this.driftClient.getStateAccount().perpFeeStructure.feeTiers[0];
|
|
1448
1455
|
return quoteAmount
|
|
1449
1456
|
.mul(new BN(feeTier.feeNumerator))
|
|
1450
1457
|
.div(new BN(feeTier.feeDenominator));
|
|
@@ -1458,7 +1465,7 @@ export class ClearingHouseUser {
|
|
|
1458
1465
|
*/
|
|
1459
1466
|
public getWithdrawalLimit(marketIndex: number, reduceOnly?: boolean): BN {
|
|
1460
1467
|
const nowTs = new BN(Math.floor(Date.now() / 1000));
|
|
1461
|
-
const spotMarket = this.
|
|
1468
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(marketIndex);
|
|
1462
1469
|
|
|
1463
1470
|
const { borrowLimit, withdrawLimit } = calculateWithdrawLimit(
|
|
1464
1471
|
spotMarket,
|
|
@@ -1485,7 +1492,7 @@ export class ClearingHouseUser {
|
|
|
1485
1492
|
const userSpotBalance = userSpotPosition
|
|
1486
1493
|
? getTokenAmount(
|
|
1487
1494
|
userSpotPosition.scaledBalance,
|
|
1488
|
-
this.
|
|
1495
|
+
this.driftClient.getSpotMarketAccount(marketIndex),
|
|
1489
1496
|
SpotBalanceType.DEPOSIT
|
|
1490
1497
|
)
|
|
1491
1498
|
: ZERO;
|
|
@@ -1536,7 +1543,7 @@ export class ClearingHouseUser {
|
|
|
1536
1543
|
includeOpenOrders?: boolean
|
|
1537
1544
|
): BN {
|
|
1538
1545
|
const currentPerpPosition =
|
|
1539
|
-
this.
|
|
1546
|
+
this.getPerpPosition(marketToIgnore) ||
|
|
1540
1547
|
this.getEmptyPosition(marketToIgnore);
|
|
1541
1548
|
|
|
1542
1549
|
const oracleData = this.getOracleDataForPerpMarket(marketToIgnore);
|
|
@@ -1558,18 +1565,17 @@ export class ClearingHouseUser {
|
|
|
1558
1565
|
|
|
1559
1566
|
private getOracleDataForPerpMarket(marketIndex: number): OraclePriceData {
|
|
1560
1567
|
const oracleKey =
|
|
1561
|
-
this.
|
|
1568
|
+
this.driftClient.getPerpMarketAccount(marketIndex).amm.oracle;
|
|
1562
1569
|
const oracleData =
|
|
1563
|
-
this.
|
|
1570
|
+
this.driftClient.getOraclePriceDataAndSlot(oracleKey).data;
|
|
1564
1571
|
|
|
1565
1572
|
return oracleData;
|
|
1566
1573
|
}
|
|
1567
1574
|
private getOracleDataForSpotMarket(marketIndex: number): OraclePriceData {
|
|
1568
|
-
const oracleKey =
|
|
1569
|
-
this.clearingHouse.getSpotMarketAccount(marketIndex).oracle;
|
|
1575
|
+
const oracleKey = this.driftClient.getSpotMarketAccount(marketIndex).oracle;
|
|
1570
1576
|
|
|
1571
1577
|
const oracleData =
|
|
1572
|
-
this.
|
|
1578
|
+
this.driftClient.getOraclePriceDataAndSlot(oracleKey).data;
|
|
1573
1579
|
|
|
1574
1580
|
return oracleData;
|
|
1575
1581
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DriftClient } from './driftClient';
|
|
2
2
|
import { PublicKey } from '@solana/web3.js';
|
|
3
3
|
import { BulkAccountLoader } from './accounts/bulkAccountLoader';
|
|
4
4
|
|
|
5
|
-
export type
|
|
6
|
-
accountSubscription?:
|
|
7
|
-
|
|
5
|
+
export type UserConfig = {
|
|
6
|
+
accountSubscription?: UserSubscriptionConfig;
|
|
7
|
+
driftClient: DriftClient;
|
|
8
8
|
userAccountPublicKey: PublicKey;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
export type
|
|
11
|
+
export type UserSubscriptionConfig =
|
|
12
12
|
| {
|
|
13
13
|
type: 'websocket';
|
|
14
14
|
}
|