@drift-labs/sdk 2.86.0-beta.0 → 2.86.0-beta.10
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/VERSION +1 -1
- package/lib/accounts/pollingDriftClientAccountSubscriber.js +24 -16
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +25 -32
- package/lib/adminClient.d.ts +4 -0
- package/lib/adminClient.js +36 -0
- package/lib/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +3 -1
- package/lib/constants/perpMarkets.js +32 -0
- package/lib/constants/spotMarkets.js +12 -1
- package/lib/idl/drift.json +246 -4
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/fuel.d.ts +5 -0
- package/lib/math/fuel.js +45 -0
- package/lib/types.d.ts +14 -0
- package/lib/user.d.ts +7 -0
- package/lib/user.js +48 -0
- package/package.json +4 -1
- package/src/accounts/pollingDriftClientAccountSubscriber.ts +38 -23
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +55 -38
- package/src/adminClient.ts +96 -0
- package/src/constants/numericConstants.ts +3 -0
- package/src/constants/perpMarkets.ts +34 -0
- package/src/constants/spotMarkets.ts +14 -1
- package/src/idl/drift.json +246 -4
- package/src/index.ts +1 -0
- package/src/math/fuel.ts +56 -0
- package/src/types.ts +19 -0
- package/src/user.ts +120 -0
package/src/math/fuel.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { BN } from '@coral-xyz/anchor';
|
|
2
|
+
import { SpotMarketAccount, PerpMarketAccount } from '..';
|
|
3
|
+
import {
|
|
4
|
+
QUOTE_PRECISION,
|
|
5
|
+
ZERO,
|
|
6
|
+
FUEL_WINDOW,
|
|
7
|
+
} from '../constants/numericConstants';
|
|
8
|
+
|
|
9
|
+
export function calculateSpotFuelBonus(
|
|
10
|
+
spotMarket: SpotMarketAccount,
|
|
11
|
+
signedTokenValue: BN,
|
|
12
|
+
fuelBonusNumerator: BN
|
|
13
|
+
): BN {
|
|
14
|
+
let result: BN;
|
|
15
|
+
|
|
16
|
+
if (signedTokenValue.abs().lt(new BN(1))) {
|
|
17
|
+
result = ZERO;
|
|
18
|
+
} else if (signedTokenValue.gt(new BN(0))) {
|
|
19
|
+
result = signedTokenValue
|
|
20
|
+
.abs()
|
|
21
|
+
.mul(fuelBonusNumerator)
|
|
22
|
+
.mul(new BN(spotMarket.fuelBoostDeposits))
|
|
23
|
+
.div(FUEL_WINDOW)
|
|
24
|
+
.div(QUOTE_PRECISION.div(new BN(10)));
|
|
25
|
+
} else {
|
|
26
|
+
result = signedTokenValue
|
|
27
|
+
.abs()
|
|
28
|
+
.mul(fuelBonusNumerator)
|
|
29
|
+
.mul(new BN(spotMarket.fuelBoostBorrows))
|
|
30
|
+
.div(FUEL_WINDOW)
|
|
31
|
+
.div(QUOTE_PRECISION.div(new BN(10)));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function calculatePerpFuelBonus(
|
|
38
|
+
perpMarket: PerpMarketAccount,
|
|
39
|
+
baseAssetValue: BN,
|
|
40
|
+
fuelBonusNumerator: BN
|
|
41
|
+
): BN {
|
|
42
|
+
let result: BN;
|
|
43
|
+
|
|
44
|
+
if (baseAssetValue.abs().lte(QUOTE_PRECISION)) {
|
|
45
|
+
result = new BN(0);
|
|
46
|
+
} else {
|
|
47
|
+
result = baseAssetValue
|
|
48
|
+
.abs()
|
|
49
|
+
.mul(fuelBonusNumerator)
|
|
50
|
+
.mul(new BN(perpMarket.fuelBoostPosition))
|
|
51
|
+
.div(FUEL_WINDOW)
|
|
52
|
+
.div(QUOTE_PRECISION.div(new BN(10)));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return result;
|
|
56
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -636,6 +636,10 @@ export type PerpMarketAccount = {
|
|
|
636
636
|
quoteSpotMarketIndex: number;
|
|
637
637
|
feeAdjustment: number;
|
|
638
638
|
pausedOperations: number;
|
|
639
|
+
|
|
640
|
+
fuelBoostPosition: number;
|
|
641
|
+
fuelBoostMaker: number;
|
|
642
|
+
fuelBoostTaker: number;
|
|
639
643
|
};
|
|
640
644
|
|
|
641
645
|
export type HistoricalOracleData = {
|
|
@@ -734,6 +738,11 @@ export type SpotMarketAccount = {
|
|
|
734
738
|
|
|
735
739
|
maxTokenBorrowsFraction: number;
|
|
736
740
|
minBorrowRate: number;
|
|
741
|
+
|
|
742
|
+
fuelBoostDeposits: number;
|
|
743
|
+
fuelBoostBorrows: number;
|
|
744
|
+
fuelBoostMaker: number;
|
|
745
|
+
fuelBoostTaker: number;
|
|
737
746
|
};
|
|
738
747
|
|
|
739
748
|
export type PoolBalance = {
|
|
@@ -876,6 +885,14 @@ export type UserStatsAccount = {
|
|
|
876
885
|
isReferrer: boolean;
|
|
877
886
|
authority: PublicKey;
|
|
878
887
|
ifStakedQuoteAssetAmount: BN;
|
|
888
|
+
|
|
889
|
+
fuelDeposits: number;
|
|
890
|
+
fuelBorrows: number;
|
|
891
|
+
fuelPositions: number;
|
|
892
|
+
fuelTaker: number;
|
|
893
|
+
fuelMaker: number;
|
|
894
|
+
|
|
895
|
+
ifStakedGovTokenAmount: BN;
|
|
879
896
|
};
|
|
880
897
|
|
|
881
898
|
export type UserAccount = {
|
|
@@ -905,6 +922,8 @@ export type UserAccount = {
|
|
|
905
922
|
hasOpenOrder: boolean;
|
|
906
923
|
openAuctions: number;
|
|
907
924
|
hasOpenAuction: boolean;
|
|
925
|
+
|
|
926
|
+
lastFuelBonusUpdateTs: BN;
|
|
908
927
|
};
|
|
909
928
|
|
|
910
929
|
export type SpotPosition = {
|
package/src/user.ts
CHANGED
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
TEN_THOUSAND,
|
|
36
36
|
TWO,
|
|
37
37
|
ZERO,
|
|
38
|
+
FUEL_START_TS,
|
|
38
39
|
} from './constants/numericConstants';
|
|
39
40
|
import {
|
|
40
41
|
DataAndSlot,
|
|
@@ -88,6 +89,8 @@ import { calculateLiveOracleTwap } from './math/oracles';
|
|
|
88
89
|
import { getPerpMarketTierNumber, getSpotMarketTierNumber } from './math/tiers';
|
|
89
90
|
import { StrictOraclePrice } from './oracles/strictOraclePrice';
|
|
90
91
|
|
|
92
|
+
import { calculateSpotFuelBonus, calculatePerpFuelBonus } from './math/fuel';
|
|
93
|
+
|
|
91
94
|
export class User {
|
|
92
95
|
driftClient: DriftClient;
|
|
93
96
|
userAccountPublicKey: PublicKey;
|
|
@@ -873,6 +876,123 @@ export class User {
|
|
|
873
876
|
}, ZERO);
|
|
874
877
|
}
|
|
875
878
|
|
|
879
|
+
public getFuelBonus(
|
|
880
|
+
now: BN,
|
|
881
|
+
includeSettled = true,
|
|
882
|
+
includeUnsettled = true
|
|
883
|
+
): {
|
|
884
|
+
depositFuel;
|
|
885
|
+
borrowFuel;
|
|
886
|
+
positionFuel;
|
|
887
|
+
takerFuel;
|
|
888
|
+
makerFuel;
|
|
889
|
+
} {
|
|
890
|
+
const userAccount: UserAccount = this.getUserAccount();
|
|
891
|
+
|
|
892
|
+
const result = {
|
|
893
|
+
takerFuel: ZERO,
|
|
894
|
+
makerFuel: ZERO,
|
|
895
|
+
depositFuel: ZERO,
|
|
896
|
+
borrowFuel: ZERO,
|
|
897
|
+
positionFuel: ZERO,
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
if (includeSettled) {
|
|
901
|
+
const userStats: UserStatsAccount = this.driftClient
|
|
902
|
+
.getUserStats()
|
|
903
|
+
.getAccount();
|
|
904
|
+
result.takerFuel = result.takerFuel.add(new BN(userStats.fuelTaker));
|
|
905
|
+
result.makerFuel = result.makerFuel.add(new BN(userStats.fuelMaker));
|
|
906
|
+
result.depositFuel = result.depositFuel.add(
|
|
907
|
+
new BN(userStats.fuelDeposits)
|
|
908
|
+
);
|
|
909
|
+
result.borrowFuel = result.borrowFuel.add(new BN(userStats.fuelBorrows));
|
|
910
|
+
result.positionFuel = result.positionFuel.add(
|
|
911
|
+
new BN(userStats.fuelPositions)
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
if (includeUnsettled) {
|
|
916
|
+
const fuelBonusNumerator = BN.max(
|
|
917
|
+
now.sub(BN.max(userAccount.lastFuelBonusUpdateTs, FUEL_START_TS)),
|
|
918
|
+
ZERO
|
|
919
|
+
);
|
|
920
|
+
|
|
921
|
+
if (fuelBonusNumerator.gt(ZERO)) {
|
|
922
|
+
for (const spotPosition of this.getActiveSpotPositions()) {
|
|
923
|
+
const spotMarketAccount: SpotMarketAccount =
|
|
924
|
+
this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
925
|
+
|
|
926
|
+
const tokenAmount = this.getTokenAmount(spotPosition.marketIndex);
|
|
927
|
+
const oraclePriceData = this.getOracleDataForSpotMarket(
|
|
928
|
+
spotPosition.marketIndex
|
|
929
|
+
);
|
|
930
|
+
|
|
931
|
+
const twap5min = calculateLiveOracleTwap(
|
|
932
|
+
spotMarketAccount.historicalOracleData,
|
|
933
|
+
oraclePriceData,
|
|
934
|
+
now,
|
|
935
|
+
FIVE_MINUTE // 5MIN
|
|
936
|
+
);
|
|
937
|
+
const strictOraclePrice = new StrictOraclePrice(
|
|
938
|
+
oraclePriceData.price,
|
|
939
|
+
twap5min
|
|
940
|
+
);
|
|
941
|
+
|
|
942
|
+
const signedTokenValue = getStrictTokenValue(
|
|
943
|
+
tokenAmount,
|
|
944
|
+
spotMarketAccount.decimals,
|
|
945
|
+
strictOraclePrice
|
|
946
|
+
);
|
|
947
|
+
|
|
948
|
+
if (signedTokenValue.gt(ZERO)) {
|
|
949
|
+
result.depositFuel = result.depositFuel.add(
|
|
950
|
+
calculateSpotFuelBonus(
|
|
951
|
+
spotMarketAccount,
|
|
952
|
+
signedTokenValue,
|
|
953
|
+
fuelBonusNumerator
|
|
954
|
+
)
|
|
955
|
+
);
|
|
956
|
+
} else {
|
|
957
|
+
result.borrowFuel = result.borrowFuel.add(
|
|
958
|
+
calculateSpotFuelBonus(
|
|
959
|
+
spotMarketAccount,
|
|
960
|
+
signedTokenValue,
|
|
961
|
+
fuelBonusNumerator
|
|
962
|
+
)
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
for (const perpPosition of this.getActivePerpPositions()) {
|
|
968
|
+
const oraclePriceData = this.getOracleDataForPerpMarket(
|
|
969
|
+
perpPosition.marketIndex
|
|
970
|
+
);
|
|
971
|
+
|
|
972
|
+
const perpMarketAccount = this.driftClient.getPerpMarketAccount(
|
|
973
|
+
perpPosition.marketIndex
|
|
974
|
+
);
|
|
975
|
+
|
|
976
|
+
const baseAssetValue = this.getPerpPositionValue(
|
|
977
|
+
perpPosition.marketIndex,
|
|
978
|
+
oraclePriceData,
|
|
979
|
+
false
|
|
980
|
+
);
|
|
981
|
+
|
|
982
|
+
result.positionFuel = result.positionFuel.add(
|
|
983
|
+
calculatePerpFuelBonus(
|
|
984
|
+
perpMarketAccount,
|
|
985
|
+
baseAssetValue,
|
|
986
|
+
fuelBonusNumerator
|
|
987
|
+
)
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
return result;
|
|
994
|
+
}
|
|
995
|
+
|
|
876
996
|
public getSpotMarketAssetAndLiabilityValue(
|
|
877
997
|
marketIndex?: number,
|
|
878
998
|
marginCategory?: MarginCategory,
|