@drift-labs/sdk 0.1.34-master.0 → 0.1.34-master.3

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.
@@ -35,6 +35,7 @@ export declare class PollingClearingHouseAccountSubscriber implements ClearingHo
35
35
  getClearingHouseAccounts(): Promise<ClearingHouseAccounts>;
36
36
  addToAccountLoader(): Promise<void>;
37
37
  fetch(): Promise<void>;
38
+ didSubscriptionSucceed(): boolean;
38
39
  unsubscribe(): Promise<void>;
39
40
  assertIsSubscribed(): void;
40
41
  assertOptionalIsSubscribed(optionalSubscription: ClearingHouseAccountTypes): void;
@@ -42,11 +42,14 @@ class PollingClearingHouseAccountSubscriber {
42
42
  yield this.updateAccountsToPoll();
43
43
  yield this.addToAccountLoader();
44
44
  yield this.fetch();
45
- this.eventEmitter.emit('update');
45
+ const subscriptionSucceeded = this.didSubscriptionSucceed();
46
+ if (subscriptionSucceeded) {
47
+ this.eventEmitter.emit('update');
48
+ }
46
49
  this.isSubscribing = false;
47
- this.isSubscribed = true;
48
- this.subscriptionPromiseResolver(true);
49
- return true;
50
+ this.isSubscribed = subscriptionSucceeded;
51
+ this.subscriptionPromiseResolver(subscriptionSucceeded);
52
+ return subscriptionSucceeded;
50
53
  });
51
54
  }
52
55
  updateAccountsToPoll() {
@@ -177,6 +180,16 @@ class PollingClearingHouseAccountSubscriber {
177
180
  }
178
181
  });
179
182
  }
183
+ didSubscriptionSucceed() {
184
+ let success = true;
185
+ for (const [_, accountToPoll] of this.accountsToPoll) {
186
+ if (!this[accountToPoll.key]) {
187
+ success = false;
188
+ break;
189
+ }
190
+ }
191
+ return success;
192
+ }
180
193
  unsubscribe() {
181
194
  return __awaiter(this, void 0, void 0, function* () {
182
195
  if (!this.isSubscribed) {
@@ -24,6 +24,7 @@ export declare class PollingUserAccountSubscriber implements UserAccountSubscrib
24
24
  addToAccountLoader(userPublicKeys?: UserPublicKeys): Promise<void>;
25
25
  fetchIfUnloaded(): Promise<void>;
26
26
  fetch(): Promise<void>;
27
+ didSubscriptionSucceed(): boolean;
27
28
  unsubscribe(): Promise<void>;
28
29
  assertIsSubscribed(): void;
29
30
  getUserAccount(): UserAccount;
@@ -31,9 +31,12 @@ class PollingUserAccountSubscriber {
31
31
  }
32
32
  yield this.addToAccountLoader();
33
33
  yield this.fetchIfUnloaded();
34
- this.eventEmitter.emit('update');
35
- this.isSubscribed = true;
36
- return true;
34
+ const subscriptionSucceeded = this.didSubscriptionSucceed();
35
+ if (subscriptionSucceeded) {
36
+ this.eventEmitter.emit('update');
37
+ }
38
+ this.isSubscribed = subscriptionSucceeded;
39
+ return subscriptionSucceeded;
37
40
  });
38
41
  }
39
42
  addToAccountLoader(userPublicKeys) {
@@ -122,6 +125,17 @@ class PollingUserAccountSubscriber {
122
125
  }
123
126
  });
124
127
  }
128
+ didSubscriptionSucceed() {
129
+ let success = true;
130
+ for (const [_, accountToPoll] of this.accountsToPoll) {
131
+ // userOrders may not exist
132
+ if (accountToPoll.key !== 'userOrders' && !this[accountToPoll.key]) {
133
+ success = false;
134
+ break;
135
+ }
136
+ }
137
+ return success;
138
+ }
125
139
  unsubscribe() {
126
140
  return __awaiter(this, void 0, void 0, function* () {
127
141
  if (!this.isSubscribed) {
@@ -2538,7 +2538,11 @@
2538
2538
  },
2539
2539
  {
2540
2540
  "name": "totalFeePaid",
2541
- "type": "u128"
2541
+ "type": "u64"
2542
+ },
2543
+ {
2544
+ "name": "totalFeeRebate",
2545
+ "type": "u64"
2542
2546
  },
2543
2547
  {
2544
2548
  "name": "totalTokenDiscount",
@@ -3369,7 +3373,7 @@
3369
3373
  },
3370
3374
  {
3371
3375
  "name": "fee",
3372
- "type": "u128"
3376
+ "type": "i128"
3373
3377
  },
3374
3378
  {
3375
3379
  "name": "fillerReward",
@@ -3620,7 +3624,7 @@
3620
3624
  },
3621
3625
  {
3622
3626
  "name": "fee",
3623
- "type": "u128"
3627
+ "type": "i128"
3624
3628
  },
3625
3629
  {
3626
3630
  "name": "quoteAssetAmountSurplus",
@@ -3772,7 +3776,7 @@
3772
3776
  },
3773
3777
  {
3774
3778
  "name": "fee",
3775
- "type": "u128"
3779
+ "type": "i128"
3776
3780
  },
3777
3781
  {
3778
3782
  "name": "direction",
@@ -9,7 +9,7 @@ import { OraclePriceData } from '../oracles/types';
9
9
  * @param periodAdjustment
10
10
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
11
11
  */
12
- export declare function calculateAllEstimatedFundingRate(market: Market, oraclePriceData: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN, BN]>;
12
+ export declare function calculateAllEstimatedFundingRate(market: Market, oraclePriceData?: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN, BN]>;
13
13
  /**
14
14
  *
15
15
  * @param market
@@ -18,7 +18,7 @@ export declare function calculateAllEstimatedFundingRate(market: Market, oracleP
18
18
  * @param estimationMethod
19
19
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
20
20
  */
21
- export declare function calculateEstimatedFundingRate(market: Market, oraclePriceData: OraclePriceData, periodAdjustment: BN, estimationMethod: 'interpolated' | 'lowerbound' | 'capped'): Promise<BN>;
21
+ export declare function calculateEstimatedFundingRate(market: Market, oraclePriceData?: OraclePriceData, periodAdjustment?: BN, estimationMethod?: 'interpolated' | 'lowerbound' | 'capped'): Promise<BN>;
22
22
  /**
23
23
  *
24
24
  * @param market
@@ -26,7 +26,7 @@ export declare function calculateEstimatedFundingRate(market: Market, oraclePric
26
26
  * @param periodAdjustment
27
27
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
28
28
  */
29
- export declare function calculateLongShortFundingRate(market: Market, oraclePriceData: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN]>;
29
+ export declare function calculateLongShortFundingRate(market: Market, oraclePriceData?: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN]>;
30
30
  /**
31
31
  *
32
32
  * @param market
@@ -34,7 +34,7 @@ export declare function calculateLongShortFundingRate(market: Market, oraclePric
34
34
  * @param periodAdjustment
35
35
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
36
36
  */
37
- export declare function calculateLongShortFundingRateAndLiveTwaps(market: Market, oraclePriceData: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN]>;
37
+ export declare function calculateLongShortFundingRateAndLiveTwaps(market: Market, oraclePriceData?: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN]>;
38
38
  /**
39
39
  *
40
40
  * @param market
@@ -51,30 +51,34 @@ function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustm
51
51
  const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
52
52
  const oracleInvalidDuration = anchor_1.BN.max(numericConstants_1.ZERO, lastMarkPriceTwapTs.sub(lastOraclePriceTwapTs));
53
53
  const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
54
- const oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, secondsInHour.sub(timeSinceLastOracleTwapUpdate));
55
- const oraclePrice = oraclePriceData.price;
54
+ const oracleTwapTimeSinceLastUpdate = anchor_1.BN.min(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastOracleTwapUpdate)));
56
55
  let oracleTwapWithMantissa = lastOracleTwapWithMantissa;
57
- const oracleLiveVsTwap = oraclePrice
58
- .sub(lastOracleTwapWithMantissa)
59
- .abs()
60
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
61
- .mul(new anchor_1.BN(100))
62
- .div(lastOracleTwapWithMantissa);
63
- // verify pyth live input is within 10% of last twap for live update
64
- if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
65
- oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
66
- .mul(lastOracleTwapWithMantissa)
67
- .add(timeSinceLastMarkChange.mul(oraclePrice))
68
- .add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
69
- .div(timeSinceLastMarkChange
70
- .add(oracleTwapTimeSinceLastUpdate)
71
- .add(oracleInvalidDuration));
72
- }
73
- const twapSpread = lastMarkTwapWithMantissa.sub(lastOracleTwapWithMantissa);
56
+ // if passing live oracle data, improve predicted calc estimate
57
+ if (oraclePriceData) {
58
+ const oraclePrice = oraclePriceData.price;
59
+ const oracleLiveVsTwap = oraclePrice
60
+ .sub(lastOracleTwapWithMantissa)
61
+ .abs()
62
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
63
+ .mul(new anchor_1.BN(100))
64
+ .div(lastOracleTwapWithMantissa);
65
+ // verify pyth live input is within 10% of last twap for live update
66
+ if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
67
+ oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
68
+ .mul(lastOracleTwapWithMantissa)
69
+ .add(timeSinceLastMarkChange.mul(oraclePrice))
70
+ .div(timeSinceLastMarkChange.add(oracleTwapTimeSinceLastUpdate));
71
+ }
72
+ }
73
+ const shrunkLastOracleTwapwithMantissa = oracleTwapTimeSinceLastUpdate
74
+ .mul(lastOracleTwapWithMantissa)
75
+ .add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
76
+ .div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
77
+ const twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
74
78
  const twapSpreadPct = twapSpread
75
79
  .mul(numericConstants_1.MARK_PRICE_PRECISION)
76
80
  .mul(new anchor_1.BN(100))
77
- .div(oracleTwapWithMantissa);
81
+ .div(shrunkLastOracleTwapwithMantissa);
78
82
  const lowerboundEst = twapSpreadPct
79
83
  .mul(payFreq)
80
84
  .mul(anchor_1.BN.min(secondsInHour, timeSinceLastUpdate))
package/lib/types.d.ts CHANGED
@@ -333,6 +333,7 @@ export declare type UserAccount = {
333
333
  cumulativeDeposits: BN;
334
334
  positions: PublicKey;
335
335
  totalFeePaid: BN;
336
+ totalFeeRebate: BN;
336
337
  totalTokenDiscount: BN;
337
338
  totalReferralReward: BN;
338
339
  totalRefereeDiscount: BN;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.1.34-master.0",
3
+ "version": "0.1.34-master.3",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -86,13 +86,17 @@ export class PollingClearingHouseAccountSubscriber
86
86
  await this.updateAccountsToPoll();
87
87
  await this.addToAccountLoader();
88
88
  await this.fetch();
89
- this.eventEmitter.emit('update');
89
+ const subscriptionSucceeded = this.didSubscriptionSucceed();
90
+
91
+ if (subscriptionSucceeded) {
92
+ this.eventEmitter.emit('update');
93
+ }
90
94
 
91
95
  this.isSubscribing = false;
92
- this.isSubscribed = true;
93
- this.subscriptionPromiseResolver(true);
96
+ this.isSubscribed = subscriptionSucceeded;
97
+ this.subscriptionPromiseResolver(subscriptionSucceeded);
94
98
 
95
- return true;
99
+ return subscriptionSucceeded;
96
100
  }
97
101
 
98
102
  async updateAccountsToPoll(): Promise<void> {
@@ -254,6 +258,17 @@ export class PollingClearingHouseAccountSubscriber
254
258
  }
255
259
  }
256
260
 
261
+ didSubscriptionSucceed(): boolean {
262
+ let success = true;
263
+ for (const [_, accountToPoll] of this.accountsToPoll) {
264
+ if (!this[accountToPoll.key]) {
265
+ success = false;
266
+ break;
267
+ }
268
+ }
269
+ return success;
270
+ }
271
+
257
272
  public async unsubscribe(): Promise<void> {
258
273
  if (!this.isSubscribed) {
259
274
  return;
@@ -53,10 +53,15 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
53
53
 
54
54
  await this.addToAccountLoader();
55
55
  await this.fetchIfUnloaded();
56
- this.eventEmitter.emit('update');
57
56
 
58
- this.isSubscribed = true;
59
- return true;
57
+ const subscriptionSucceeded = this.didSubscriptionSucceed();
58
+
59
+ if (subscriptionSucceeded) {
60
+ this.eventEmitter.emit('update');
61
+ }
62
+
63
+ this.isSubscribed = subscriptionSucceeded;
64
+ return subscriptionSucceeded;
60
65
  }
61
66
 
62
67
  async addToAccountLoader(userPublicKeys?: UserPublicKeys): Promise<void> {
@@ -168,6 +173,18 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
168
173
  }
169
174
  }
170
175
 
176
+ didSubscriptionSucceed(): boolean {
177
+ let success = true;
178
+ for (const [_, accountToPoll] of this.accountsToPoll) {
179
+ // userOrders may not exist
180
+ if (accountToPoll.key !== 'userOrders' && !this[accountToPoll.key]) {
181
+ success = false;
182
+ break;
183
+ }
184
+ }
185
+ return success;
186
+ }
187
+
171
188
  async unsubscribe(): Promise<void> {
172
189
  if (!this.isSubscribed) {
173
190
  return;
@@ -2538,7 +2538,11 @@
2538
2538
  },
2539
2539
  {
2540
2540
  "name": "totalFeePaid",
2541
- "type": "u128"
2541
+ "type": "u64"
2542
+ },
2543
+ {
2544
+ "name": "totalFeeRebate",
2545
+ "type": "u64"
2542
2546
  },
2543
2547
  {
2544
2548
  "name": "totalTokenDiscount",
@@ -3369,7 +3373,7 @@
3369
3373
  },
3370
3374
  {
3371
3375
  "name": "fee",
3372
- "type": "u128"
3376
+ "type": "i128"
3373
3377
  },
3374
3378
  {
3375
3379
  "name": "fillerReward",
@@ -3620,7 +3624,7 @@
3620
3624
  },
3621
3625
  {
3622
3626
  "name": "fee",
3623
- "type": "u128"
3627
+ "type": "i128"
3624
3628
  },
3625
3629
  {
3626
3630
  "name": "quoteAssetAmountSurplus",
@@ -3772,7 +3776,7 @@
3772
3776
  },
3773
3777
  {
3774
3778
  "name": "fee",
3775
- "type": "u128"
3779
+ "type": "i128"
3776
3780
  },
3777
3781
  {
3778
3782
  "name": "direction",
@@ -18,7 +18,7 @@ import { OraclePriceData } from '../oracles/types';
18
18
  */
19
19
  export async function calculateAllEstimatedFundingRate(
20
20
  market: Market,
21
- oraclePriceData: OraclePriceData,
21
+ oraclePriceData?: OraclePriceData,
22
22
  periodAdjustment: BN = new BN(1)
23
23
  ): Promise<[BN, BN, BN, BN, BN]> {
24
24
  // periodAdjustment
@@ -65,40 +65,45 @@ export async function calculateAllEstimatedFundingRate(
65
65
  );
66
66
 
67
67
  const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
68
- const oracleTwapTimeSinceLastUpdate = BN.max(
68
+ const oracleTwapTimeSinceLastUpdate = BN.min(
69
69
  secondsInHour,
70
- secondsInHour.sub(timeSinceLastOracleTwapUpdate)
70
+ BN.max(ZERO, secondsInHour.sub(timeSinceLastOracleTwapUpdate))
71
71
  );
72
-
73
- const oraclePrice = oraclePriceData.price;
74
72
  let oracleTwapWithMantissa = lastOracleTwapWithMantissa;
75
73
 
76
- const oracleLiveVsTwap = oraclePrice
77
- .sub(lastOracleTwapWithMantissa)
78
- .abs()
79
- .mul(MARK_PRICE_PRECISION)
80
- .mul(new BN(100))
81
- .div(lastOracleTwapWithMantissa);
82
-
83
- // verify pyth live input is within 10% of last twap for live update
84
- if (oracleLiveVsTwap.lte(MARK_PRICE_PRECISION.mul(new BN(10)))) {
85
- oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
86
- .mul(lastOracleTwapWithMantissa)
87
- .add(timeSinceLastMarkChange.mul(oraclePrice))
88
- .add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
89
- .div(
90
- timeSinceLastMarkChange
91
- .add(oracleTwapTimeSinceLastUpdate)
92
- .add(oracleInvalidDuration)
93
- );
74
+ // if passing live oracle data, improve predicted calc estimate
75
+ if (oraclePriceData) {
76
+ const oraclePrice = oraclePriceData.price;
77
+
78
+ const oracleLiveVsTwap = oraclePrice
79
+ .sub(lastOracleTwapWithMantissa)
80
+ .abs()
81
+ .mul(MARK_PRICE_PRECISION)
82
+ .mul(new BN(100))
83
+ .div(lastOracleTwapWithMantissa);
84
+
85
+ // verify pyth live input is within 10% of last twap for live update
86
+ if (oracleLiveVsTwap.lte(MARK_PRICE_PRECISION.mul(new BN(10)))) {
87
+ oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
88
+ .mul(lastOracleTwapWithMantissa)
89
+ .add(timeSinceLastMarkChange.mul(oraclePrice))
90
+ .div(timeSinceLastMarkChange.add(oracleTwapTimeSinceLastUpdate));
91
+ }
94
92
  }
95
93
 
96
- const twapSpread = lastMarkTwapWithMantissa.sub(lastOracleTwapWithMantissa);
94
+ const shrunkLastOracleTwapwithMantissa = oracleTwapTimeSinceLastUpdate
95
+ .mul(lastOracleTwapWithMantissa)
96
+ .add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
97
+ .div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
98
+
99
+ const twapSpread = lastMarkTwapWithMantissa.sub(
100
+ shrunkLastOracleTwapwithMantissa
101
+ );
97
102
 
98
103
  const twapSpreadPct = twapSpread
99
104
  .mul(MARK_PRICE_PRECISION)
100
105
  .mul(new BN(100))
101
- .div(oracleTwapWithMantissa);
106
+ .div(shrunkLastOracleTwapwithMantissa);
102
107
 
103
108
  const lowerboundEst = twapSpreadPct
104
109
  .mul(payFreq)
@@ -197,9 +202,9 @@ export async function calculateAllEstimatedFundingRate(
197
202
  */
198
203
  export async function calculateEstimatedFundingRate(
199
204
  market: Market,
200
- oraclePriceData: OraclePriceData,
205
+ oraclePriceData?: OraclePriceData,
201
206
  periodAdjustment: BN = new BN(1),
202
- estimationMethod: 'interpolated' | 'lowerbound' | 'capped'
207
+ estimationMethod?: 'interpolated' | 'lowerbound' | 'capped'
203
208
  ): Promise<BN> {
204
209
  const [_1, _2, lowerboundEst, cappedAltEst, interpEst] =
205
210
  await calculateAllEstimatedFundingRate(
@@ -227,7 +232,7 @@ export async function calculateEstimatedFundingRate(
227
232
  */
228
233
  export async function calculateLongShortFundingRate(
229
234
  market: Market,
230
- oraclePriceData: OraclePriceData,
235
+ oraclePriceData?: OraclePriceData,
231
236
  periodAdjustment: BN = new BN(1)
232
237
  ): Promise<[BN, BN]> {
233
238
  const [_1, _2, _, cappedAltEst, interpEst] =
@@ -255,7 +260,7 @@ export async function calculateLongShortFundingRate(
255
260
  */
256
261
  export async function calculateLongShortFundingRateAndLiveTwaps(
257
262
  market: Market,
258
- oraclePriceData: OraclePriceData,
263
+ oraclePriceData?: OraclePriceData,
259
264
  periodAdjustment: BN = new BN(1)
260
265
  ): Promise<[BN, BN, BN, BN]> {
261
266
  const [markTwapLive, oracleTwapLive, _2, cappedAltEst, interpEst] =
package/src/types.ts CHANGED
@@ -332,6 +332,7 @@ export type UserAccount = {
332
332
  cumulativeDeposits: BN;
333
333
  positions: PublicKey;
334
334
  totalFeePaid: BN;
335
+ totalFeeRebate: BN;
335
336
  totalTokenDiscount: BN;
336
337
  totalReferralReward: BN;
337
338
  totalRefereeDiscount: BN;