@drift-labs/sdk 2.54.0-beta.0 → 2.54.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.
Files changed (52) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/pollingInsuranceFundStakeAccountSubscriber.js +0 -1
  3. package/lib/constants/perpMarkets.js +20 -0
  4. package/lib/driftClient.d.ts +8 -2
  5. package/lib/driftClient.js +95 -20
  6. package/lib/events/webSocketLogProvider.js +3 -0
  7. package/lib/idl/drift.json +7 -1
  8. package/lib/jupiter/jupiterClient.d.ts +6 -0
  9. package/lib/jupiter/jupiterClient.js +2 -2
  10. package/lib/math/funding.js +24 -1
  11. package/lib/math/oracles.js +2 -2
  12. package/lib/math/superStake.d.ts +51 -0
  13. package/lib/math/superStake.js +10 -2
  14. package/lib/priorityFee/averageOverSlotsStrategy.d.ts +0 -5
  15. package/lib/priorityFee/averageOverSlotsStrategy.js +1 -13
  16. package/lib/priorityFee/maxOverSlotsStrategy.d.ts +0 -5
  17. package/lib/priorityFee/maxOverSlotsStrategy.js +1 -13
  18. package/lib/priorityFee/priorityFeeSubscriber.d.ts +5 -4
  19. package/lib/priorityFee/priorityFeeSubscriber.js +15 -21
  20. package/lib/tx/baseTxSender.d.ts +6 -2
  21. package/lib/tx/baseTxSender.js +47 -2
  22. package/lib/tx/fastSingleTxSender.d.ts +3 -2
  23. package/lib/tx/fastSingleTxSender.js +10 -2
  24. package/lib/tx/retryTxSender.d.ts +3 -2
  25. package/lib/tx/retryTxSender.js +14 -23
  26. package/lib/tx/types.d.ts +5 -0
  27. package/lib/tx/types.js +7 -0
  28. package/lib/tx/utils.d.ts +5 -1
  29. package/lib/tx/utils.js +20 -1
  30. package/lib/userMap/userMap.js +4 -0
  31. package/package.json +1 -1
  32. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -1
  33. package/src/constants/perpMarkets.ts +20 -0
  34. package/src/driftClient.ts +197 -39
  35. package/src/events/webSocketLogProvider.ts +11 -2
  36. package/src/idl/drift.json +7 -1
  37. package/src/jupiter/jupiterClient.ts +8 -2
  38. package/src/math/funding.ts +28 -1
  39. package/src/math/oracles.ts +2 -2
  40. package/src/math/superStake.ts +60 -1
  41. package/src/priorityFee/averageOverSlotsStrategy.ts +1 -16
  42. package/src/priorityFee/maxOverSlotsStrategy.ts +1 -16
  43. package/src/priorityFee/priorityFeeSubscriber.ts +22 -26
  44. package/src/tx/baseTxSender.ts +64 -2
  45. package/src/tx/fastSingleTxSender.ts +11 -2
  46. package/src/tx/retryTxSender.ts +16 -25
  47. package/src/tx/types.ts +6 -0
  48. package/src/tx/utils.ts +32 -0
  49. package/src/userMap/userMap.ts +3 -0
  50. package/tests/amm/test.ts +275 -2
  51. package/tests/dlob/test.ts +2 -2
  52. package/tests/tx/priorityFeeStrategy.ts +2 -2
@@ -88,7 +88,7 @@ import {
88
88
  DataAndSlot,
89
89
  } from './accounts/types';
90
90
  import { TxSender, TxSigAndSlot } from './tx/types';
91
- import { wrapInTx } from './tx/utils';
91
+ import { getSignedTransactionMap, wrapInTx } from './tx/utils';
92
92
  import {
93
93
  BASE_PRECISION,
94
94
  PRICE_PRECISION,
@@ -2565,33 +2565,26 @@ export class DriftClient {
2565
2565
  txParams?: TxParams,
2566
2566
  bracketOrdersParams = new Array<OptionalOrderParams>(),
2567
2567
  referrerInfo?: ReferrerInfo,
2568
- cancelExistingOrders?: boolean
2568
+ cancelExistingOrders?: boolean,
2569
+ settlePnl?: boolean
2569
2570
  ): Promise<{
2570
2571
  txSig: TransactionSignature;
2571
2572
  signedFillTx?: Transaction;
2572
2573
  signedCancelExistingOrdersTx?: Transaction;
2574
+ signedSettlePnlTx?: Transaction;
2573
2575
  }> {
2574
2576
  const marketIndex = orderParams.marketIndex;
2575
2577
  const orderId = userAccount.nextOrderId;
2576
- const bracketOrderIxs = [];
2577
2578
 
2578
- const placePerpOrderIx = await this.getPlacePerpOrderIx(
2579
- orderParams,
2579
+ const ordersIx = await this.getPlaceOrdersIx(
2580
+ [orderParams, ...bracketOrdersParams],
2580
2581
  userAccount.subAccountId
2581
2582
  );
2582
2583
 
2583
- for (const bracketOrderParams of bracketOrdersParams) {
2584
- const placeBracketOrderIx = await this.getPlacePerpOrderIx(
2585
- bracketOrderParams,
2586
- userAccount.subAccountId
2587
- );
2588
- bracketOrderIxs.push(placeBracketOrderIx);
2589
- }
2590
-
2591
- let cancelOrdersIx: TransactionInstruction;
2592
- let cancelExistingOrdersTx: Transaction;
2584
+ /* Cancel open orders in market if requested */
2585
+ let cancelExistingOrdersTx;
2593
2586
  if (cancelExistingOrders && isVariant(orderParams.marketType, 'perp')) {
2594
- cancelOrdersIx = await this.getCancelOrdersIx(
2587
+ const cancelOrdersIx = await this.getCancelOrdersIx(
2595
2588
  orderParams.marketType,
2596
2589
  orderParams.marketIndex,
2597
2590
  null,
@@ -2606,10 +2599,27 @@ export class DriftClient {
2606
2599
  );
2607
2600
  }
2608
2601
 
2602
+ /* Settle PnL after fill if requested */
2603
+ let settlePnlTx;
2604
+ if (settlePnl && isVariant(orderParams.marketType, 'perp')) {
2605
+ const settlePnlIx = await this.settlePNLIx(
2606
+ userAccountPublicKey,
2607
+ userAccount,
2608
+ marketIndex
2609
+ );
2610
+
2611
+ //@ts-ignore
2612
+ settlePnlTx = await this.buildTransaction(
2613
+ [settlePnlIx],
2614
+ txParams,
2615
+ this.txVersion
2616
+ );
2617
+ }
2618
+
2609
2619
  // use versioned transactions if there is a lookup table account and wallet is compatible
2610
2620
  if (this.txVersion === 0) {
2611
2621
  const versionedMarketOrderTx = await this.buildTransaction(
2612
- [placePerpOrderIx].concat(bracketOrderIxs),
2622
+ ordersIx,
2613
2623
  txParams,
2614
2624
  0
2615
2625
  );
@@ -2632,17 +2642,31 @@ export class DriftClient {
2632
2642
  0
2633
2643
  );
2634
2644
 
2635
- const [
2645
+ const allPossibleTxs = [
2646
+ versionedMarketOrderTx,
2647
+ versionedFillTx,
2648
+ cancelExistingOrdersTx,
2649
+ settlePnlTx,
2650
+ ];
2651
+ const txKeys = [
2652
+ 'signedVersionedMarketOrderTx',
2653
+ 'signedVersionedFillTx',
2654
+ 'signedCancelExistingOrdersTx',
2655
+ 'signedSettlePnlTx',
2656
+ ];
2657
+
2658
+ const {
2636
2659
  signedVersionedMarketOrderTx,
2637
2660
  signedVersionedFillTx,
2638
2661
  signedCancelExistingOrdersTx,
2639
- ] = await this.provider.wallet.signAllTransactions(
2640
- [
2641
- versionedMarketOrderTx,
2642
- versionedFillTx,
2643
- cancelExistingOrdersTx,
2644
- ].filter((tx) => tx !== undefined)
2662
+ signedSettlePnlTx,
2663
+ } = await getSignedTransactionMap(
2664
+ //@ts-ignore
2665
+ this.provider.wallet,
2666
+ allPossibleTxs,
2667
+ txKeys
2645
2668
  );
2669
+
2646
2670
  const { txSig, slot } = await this.txSender.sendRawTransaction(
2647
2671
  signedVersionedMarketOrderTx.serialize(),
2648
2672
  this.opts
@@ -2655,18 +2679,16 @@ export class DriftClient {
2655
2679
  signedFillTx: signedVersionedFillTx,
2656
2680
  // @ts-ignore
2657
2681
  signedCancelExistingOrdersTx,
2682
+ // @ts-ignore
2683
+ signedSettlePnlTx,
2658
2684
  };
2659
2685
  } else {
2660
2686
  const marketOrderTx = wrapInTx(
2661
- placePerpOrderIx,
2687
+ ordersIx,
2662
2688
  txParams?.computeUnits,
2663
2689
  txParams?.computeUnitsPrice
2664
2690
  );
2665
2691
 
2666
- if (bracketOrderIxs.length > 0) {
2667
- marketOrderTx.add(...bracketOrderIxs);
2668
- }
2669
-
2670
2692
  // Apply the latest blockhash to the txs so that we can sign before sending them
2671
2693
  const currentBlockHash = (
2672
2694
  await this.connection.getLatestBlockhash('finalized')
@@ -2680,12 +2702,33 @@ export class DriftClient {
2680
2702
  cancelExistingOrdersTx.feePayer = userAccount.authority;
2681
2703
  }
2682
2704
 
2683
- const [signedMarketOrderTx, signedCancelExistingOrdersTx] =
2684
- await this.provider.wallet.signAllTransactions(
2685
- [marketOrderTx, cancelExistingOrdersTx].filter(
2686
- (tx) => tx !== undefined
2687
- )
2688
- );
2705
+ if (settlePnlTx) {
2706
+ settlePnlTx.recentBlockhash = currentBlockHash;
2707
+ settlePnlTx.feePayer = userAccount.authority;
2708
+ }
2709
+
2710
+ const allPossibleTxs = [
2711
+ marketOrderTx,
2712
+ cancelExistingOrdersTx,
2713
+ settlePnlTx,
2714
+ ];
2715
+ const txKeys = [
2716
+ 'signedMarketOrderTx',
2717
+ 'signedCancelExistingOrdersTx',
2718
+ 'signedSettlePnlTx',
2719
+ ];
2720
+
2721
+ const {
2722
+ signedMarketOrderTx,
2723
+ signedCancelExistingOrdersTx,
2724
+ signedSettlePnlTx,
2725
+ } = await getSignedTransactionMap(
2726
+ //@ts-ignore
2727
+ this.provider.wallet,
2728
+ allPossibleTxs,
2729
+ txKeys
2730
+ );
2731
+
2689
2732
  const { txSig, slot } = await this.sendTransaction(
2690
2733
  signedMarketOrderTx,
2691
2734
  [],
@@ -2694,7 +2737,14 @@ export class DriftClient {
2694
2737
  );
2695
2738
  this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
2696
2739
 
2697
- return { txSig, signedFillTx: undefined, signedCancelExistingOrdersTx };
2740
+ return {
2741
+ txSig,
2742
+ signedFillTx: undefined,
2743
+ //@ts-ignore
2744
+ signedCancelExistingOrdersTx,
2745
+ //@ts-ignore
2746
+ signedSettlePnlTx,
2747
+ };
2698
2748
  }
2699
2749
  }
2700
2750
 
@@ -3093,7 +3143,7 @@ export class DriftClient {
3093
3143
  }
3094
3144
 
3095
3145
  public async getPlaceOrdersIx(
3096
- params: OrderParams[],
3146
+ params: OptionalOrderParams[],
3097
3147
  subAccountId?: number
3098
3148
  ): Promise<TransactionInstruction> {
3099
3149
  const user = await this.getUserAccountPublicKey(subAccountId);
@@ -3118,7 +3168,9 @@ export class DriftClient {
3118
3168
  useMarketLastSlotCache: true,
3119
3169
  });
3120
3170
 
3121
- return await this.program.instruction.placeOrders(params, {
3171
+ const formattedParams = params.map((item) => getOrderParams(item));
3172
+
3173
+ return await this.program.instruction.placeOrders(formattedParams, {
3122
3174
  accounts: {
3123
3175
  state: await this.getStatePublicKey(),
3124
3176
  user,
@@ -3868,7 +3920,6 @@ export class DriftClient {
3868
3920
  slippageBps,
3869
3921
  swapMode,
3870
3922
  onlyDirectRoutes,
3871
- excludeDexes: ['Raydium CLMM'], // temp exclude to workaround bug with raydium clmm
3872
3923
  });
3873
3924
 
3874
3925
  quote = fetchedQuote;
@@ -4335,6 +4386,113 @@ export class DriftClient {
4335
4386
  return txSig;
4336
4387
  }
4337
4388
 
4389
+ public async placeAndTakePerpWithAdditionalOrders(
4390
+ orderParams: OptionalOrderParams,
4391
+ makerInfo?: MakerInfo | MakerInfo[],
4392
+ referrerInfo?: ReferrerInfo,
4393
+ bracketOrdersParams = new Array<OptionalOrderParams>(),
4394
+ txParams?: TxParams,
4395
+ subAccountId?: number,
4396
+ cancelExistingOrders?: boolean,
4397
+ settlePnl?: boolean
4398
+ ): Promise<{
4399
+ txSig: TransactionSignature;
4400
+ signedCancelExistingOrdersTx?: Transaction;
4401
+ signedSettlePnlTx?: Transaction;
4402
+ }> {
4403
+ let cancelExistingOrdersTx: Transaction;
4404
+ if (cancelExistingOrders && isVariant(orderParams.marketType, 'perp')) {
4405
+ const cancelOrdersIx = await this.getCancelOrdersIx(
4406
+ orderParams.marketType,
4407
+ orderParams.marketIndex,
4408
+ null,
4409
+ subAccountId
4410
+ );
4411
+
4412
+ //@ts-ignore
4413
+ cancelExistingOrdersTx = await this.buildTransaction(
4414
+ [cancelOrdersIx],
4415
+ txParams,
4416
+ this.txVersion
4417
+ );
4418
+ }
4419
+
4420
+ /* Settle PnL after fill if requested */
4421
+ let settlePnlTx: Transaction;
4422
+ if (settlePnl && isVariant(orderParams.marketType, 'perp')) {
4423
+ const userAccountPublicKey = await this.getUserAccountPublicKey(
4424
+ subAccountId
4425
+ );
4426
+
4427
+ const settlePnlIx = await this.settlePNLIx(
4428
+ userAccountPublicKey,
4429
+ this.getUserAccount(subAccountId),
4430
+ orderParams.marketIndex
4431
+ );
4432
+
4433
+ //@ts-ignore
4434
+ settlePnlTx = await this.buildTransaction(
4435
+ [settlePnlIx],
4436
+ txParams,
4437
+ this.txVersion
4438
+ );
4439
+ }
4440
+
4441
+ const ixs = [];
4442
+
4443
+ const placeAndTakeIx = await this.getPlaceAndTakePerpOrderIx(
4444
+ orderParams,
4445
+ makerInfo,
4446
+ referrerInfo,
4447
+ subAccountId
4448
+ );
4449
+
4450
+ ixs.push(placeAndTakeIx);
4451
+
4452
+ if (bracketOrdersParams.length > 0) {
4453
+ const bracketOrdersIx = await this.getPlaceOrdersIx(
4454
+ bracketOrdersParams,
4455
+ subAccountId
4456
+ );
4457
+ ixs.push(bracketOrdersIx);
4458
+ }
4459
+
4460
+ const placeAndTakeTx = await this.buildTransaction(ixs, txParams);
4461
+
4462
+ const allPossibleTxs = [
4463
+ placeAndTakeTx,
4464
+ cancelExistingOrdersTx,
4465
+ settlePnlTx,
4466
+ ];
4467
+ const txKeys = [
4468
+ 'signedPlaceAndTakeTx',
4469
+ 'signedCancelExistingOrdersTx',
4470
+ 'signedSettlePnlTx',
4471
+ ];
4472
+
4473
+ const {
4474
+ signedPlaceAndTakeTx,
4475
+ signedCancelExistingOrdersTx,
4476
+ signedSettlePnlTx,
4477
+ } = await getSignedTransactionMap(
4478
+ //@ts-ignore
4479
+ this.provider.wallet,
4480
+ allPossibleTxs,
4481
+ txKeys
4482
+ );
4483
+
4484
+ const { txSig, slot } = await this.sendTransaction(
4485
+ signedPlaceAndTakeTx,
4486
+ [],
4487
+ this.opts,
4488
+ true
4489
+ );
4490
+ this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
4491
+
4492
+ //@ts-ignore
4493
+ return { txSig, signedCancelExistingOrdersTx, signedSettlePnlTx };
4494
+ }
4495
+
4338
4496
  public async getPlaceAndTakePerpOrderIx(
4339
4497
  orderParams: OptionalOrderParams,
4340
4498
  makerInfo?: MakerInfo | MakerInfo[],
@@ -1,5 +1,11 @@
1
1
  import { LogProvider, logProviderCallback } from './types';
2
- import { Commitment, Connection, PublicKey } from '@solana/web3.js';
2
+ import {
3
+ Commitment,
4
+ Connection,
5
+ Context,
6
+ Logs,
7
+ PublicKey,
8
+ } from '@solana/web3.js';
3
9
  import { EventEmitter } from 'events';
4
10
 
5
11
  export class WebSocketLogProvider implements LogProvider {
@@ -45,7 +51,7 @@ export class WebSocketLogProvider implements LogProvider {
45
51
  public setSubscription(callback: logProviderCallback): void {
46
52
  this.subscriptionId = this.connection.onLogs(
47
53
  this.address,
48
- (logs, ctx) => {
54
+ (logs: Logs, ctx: Context) => {
49
55
  if (this.resubTimeoutMs && !this.isUnsubscribing) {
50
56
  this.receivingData = true;
51
57
  clearTimeout(this.timeoutId);
@@ -55,6 +61,9 @@ export class WebSocketLogProvider implements LogProvider {
55
61
  }
56
62
  this.reconnectAttempts = 0;
57
63
  }
64
+ if (logs.err !== null) {
65
+ return;
66
+ }
58
67
  callback(logs.signature, ctx.slot, logs.logs, undefined);
59
68
  },
60
69
  this.commitment
@@ -8524,7 +8524,13 @@
8524
8524
  "kind": "enum",
8525
8525
  "variants": [
8526
8526
  {
8527
- "name": "Standard"
8527
+ "name": "Standard",
8528
+ "fields": [
8529
+ {
8530
+ "name": "track_open_orders_fraction",
8531
+ "type": "bool"
8532
+ }
8533
+ ]
8528
8534
  },
8529
8535
  {
8530
8536
  "name": "Liquidation",
@@ -210,6 +210,12 @@ export interface QuoteResponse {
210
210
  * @memberof QuoteResponse
211
211
  */
212
212
  timeTaken?: number;
213
+ /**
214
+ *
215
+ * @type {string}
216
+ * @memberof QuoteResponse
217
+ */
218
+ error?: string;
213
219
  }
214
220
 
215
221
  export class JupiterClient {
@@ -279,7 +285,7 @@ export class JupiterClient {
279
285
  slippageBps = 50,
280
286
  swapMode = 'ExactIn',
281
287
  onlyDirectRoutes = false,
282
- excludeDexes = [],
288
+ excludeDexes,
283
289
  }: {
284
290
  inputMint: PublicKey;
285
291
  outputMint: PublicKey;
@@ -298,7 +304,7 @@ export class JupiterClient {
298
304
  swapMode,
299
305
  onlyDirectRoutes: onlyDirectRoutes.toString(),
300
306
  maxAccounts: maxAccounts.toString(),
301
- excludeDexes: excludeDexes.join(','),
307
+ ...(excludeDexes && { excludeDexes: excludeDexes.join(',') }),
302
308
  }).toString();
303
309
  const quote = await (await fetch(`${this.url}/v6/quote?${params}`)).json();
304
310
  return quote;
@@ -11,6 +11,7 @@ import { PerpMarketAccount, isVariant } from '../types';
11
11
  import { OraclePriceData } from '../oracles/types';
12
12
  import { calculateBidAskPrice } from './amm';
13
13
  import { calculateLiveOracleTwap } from './oracles';
14
+ import { clampBN } from './utils';
14
15
 
15
16
  function calculateLiveMarkTwap(
16
17
  market: PerpMarketAccount,
@@ -160,8 +161,15 @@ export async function calculateAllEstimatedFundingRate(
160
161
  const twapSpreadWithOffset = twapSpread.add(
161
162
  oracleTwap.abs().div(FUNDING_RATE_OFFSET_DENOMINATOR)
162
163
  );
164
+ const maxSpread = getMaxPriceDivergenceForFundingRate(market, oracleTwap);
163
165
 
164
- const twapSpreadPct = twapSpreadWithOffset
166
+ const clampedSpreadWithOffset = clampBN(
167
+ twapSpreadWithOffset,
168
+ maxSpread.mul(new BN(-1)),
169
+ maxSpread
170
+ );
171
+
172
+ const twapSpreadPct = clampedSpreadWithOffset
165
173
  .mul(PRICE_PRECISION)
166
174
  .mul(new BN(100))
167
175
  .div(oracleTwap);
@@ -234,6 +242,25 @@ export async function calculateAllEstimatedFundingRate(
234
242
  return [markTwap, oracleTwap, lowerboundEst, cappedAltEst, interpEst];
235
243
  }
236
244
 
245
+ function getMaxPriceDivergenceForFundingRate(
246
+ market: PerpMarketAccount,
247
+ oracleTwap: BN
248
+ ) {
249
+ if (isVariant(market.contractTier, 'a')) {
250
+ return oracleTwap.divn(33);
251
+ } else if (isVariant(market.contractTier, 'b')) {
252
+ return oracleTwap.divn(33);
253
+ } else if (isVariant(market.contractTier, 'c')) {
254
+ return oracleTwap.divn(20);
255
+ } else if (isVariant(market.contractTier, 'speculative')) {
256
+ return oracleTwap.divn(10);
257
+ } else if (isVariant(market.contractTier, 'isolated')) {
258
+ return oracleTwap.divn(10);
259
+ } else {
260
+ return oracleTwap.divn(10);
261
+ }
262
+ }
263
+
237
264
  /**
238
265
  *
239
266
  * @param market
@@ -47,8 +47,8 @@ export function isOracleValid(
47
47
  .div(oraclePriceData.price)
48
48
  .gt(oracleGuardRails.validity.confidenceIntervalMaxSize);
49
49
 
50
- const oracleIsStale = oraclePriceData.slot
51
- .sub(new BN(slot))
50
+ const oracleIsStale = new BN(slot)
51
+ .sub(oraclePriceData.slot)
52
52
  .gt(oracleGuardRails.validity.slotsBeforeStaleForAmm);
53
53
 
54
54
  return !(
@@ -333,6 +333,63 @@ export async function fetchJitoSolMetrics() {
333
333
  return data;
334
334
  }
335
335
 
336
+ export type MSOL_METRICS_ENDPOINT_RESPONSE = {
337
+ total_active_balance: number;
338
+ available_reserve_balance: number;
339
+ emergency_cooling_down: number;
340
+ tvl_sol: number;
341
+ msol_directed_stake_sol: number;
342
+ msol_directed_stake_msol: number;
343
+ mnde_total_supply: number;
344
+ mnde_circulating_supply: number;
345
+ validators_count: number;
346
+ stake_accounts: number;
347
+ staking_sol_cap: number;
348
+ m_sol_price: number;
349
+ avg_staking_apy: number;
350
+ msol_price_apy_14d: number;
351
+ msol_price_apy_30d: number;
352
+ msol_price_apy_90d: number;
353
+ msol_price_apy_365d: number;
354
+ reserve_pda: number;
355
+ treasury_m_sol_amount: number;
356
+ m_sol_mint_supply: number;
357
+ m_sol_supply_state: number;
358
+ liq_pool_sol: number;
359
+ liq_pool_m_sol: number;
360
+ liq_pool_value: number;
361
+ liq_pool_token_supply: number;
362
+ liq_pool_token_price: number;
363
+ liq_pool_target: number;
364
+ liq_pool_min_fee: number;
365
+ liq_pool_max_fee: number;
366
+ liq_pool_current_fee: number;
367
+ liq_pool_treasury_cut: number;
368
+ liq_pool_cap: number;
369
+ total_cooling_down: number;
370
+ last_stake_delta_epoch: number;
371
+ circulating_ticket_count: number;
372
+ circulating_ticket_balance: number;
373
+ reward_fee_bp: number;
374
+ lido_staking: number;
375
+ lido_st_sol_price: number;
376
+ lido_stsol_price_apy_14d: number;
377
+ lido_stsol_price_apy_30d: number;
378
+ lido_stsol_price_apy_90d: number;
379
+ lido_stsol_price_apy_365d: number;
380
+ stake_delta: number;
381
+ bot_balance: number;
382
+ treasury_farm_claim_mnde_balance: number;
383
+ last_3_epochs_avg_duration_hs: number;
384
+ mnde_votes_validators: number;
385
+ };
386
+
387
+ export const fetchMSolMetrics = async () => {
388
+ const res = await fetch('https://api2.marinade.finance/metrics_json');
389
+ const data: MSOL_METRICS_ENDPOINT_RESPONSE = await res.json();
390
+ return data;
391
+ };
392
+
336
393
  const getJitoSolHistoricalPriceMap = async (timestamps: number[]) => {
337
394
  try {
338
395
  const data = await fetchJitoSolMetrics();
@@ -382,7 +439,9 @@ export async function calculateSolEarned({
382
439
  const now = Date.now() / 1000;
383
440
  const timestamps: number[] = [
384
441
  now,
385
- ...depositRecords.map((r) => r.ts.toNumber()),
442
+ ...depositRecords
443
+ .filter((r) => r.marketIndex === marketIndex)
444
+ .map((r) => r.ts.toNumber()),
386
445
  ];
387
446
 
388
447
  let lstRatios = new Map<number, number>();
@@ -1,30 +1,15 @@
1
1
  import { PriorityFeeStrategy } from './types';
2
2
 
3
3
  export class AverageOverSlotsStrategy implements PriorityFeeStrategy {
4
- private lookbackSlots: number;
5
-
6
- /**
7
- * @param lookbackSlots The number of slots to look back from the max slot in the sample
8
- */
9
- constructor(lookbackSlots = 10) {
10
- this.lookbackSlots = lookbackSlots;
11
- }
12
-
13
4
  calculate(samples: { slot: number; prioritizationFee: number }[]): number {
14
5
  if (samples.length === 0) {
15
6
  return 0;
16
7
  }
17
- const stopSlot = samples[0].slot - this.lookbackSlots;
18
8
  let runningSumFees = 0;
19
- let countFees = 0;
20
9
 
21
10
  for (let i = 0; i < samples.length; i++) {
22
- if (samples[i].slot <= stopSlot) {
23
- return runningSumFees / countFees;
24
- }
25
11
  runningSumFees += samples[i].prioritizationFee;
26
- countFees++;
27
12
  }
28
- return runningSumFees / countFees;
13
+ return runningSumFees / samples.length;
29
14
  }
30
15
  }
@@ -1,30 +1,15 @@
1
1
  import { PriorityFeeStrategy } from './types';
2
2
 
3
3
  export class MaxOverSlotsStrategy implements PriorityFeeStrategy {
4
- private lookbackSlots: number;
5
-
6
- /**
7
- * @param lookbackSlots The number of slots to look back from the max slot in the sample
8
- */
9
- constructor(lookbackSlots = 10) {
10
- this.lookbackSlots = lookbackSlots;
11
- }
12
-
13
4
  calculate(samples: { slot: number; prioritizationFee: number }[]): number {
14
5
  if (samples.length === 0) {
15
6
  return 0;
16
7
  }
17
8
  // Assuming samples are sorted in descending order of slot.
18
- const stopSlot = samples[0].slot - this.lookbackSlots;
19
9
  let currMaxFee = samples[0].prioritizationFee;
20
10
 
21
11
  for (let i = 0; i < samples.length; i++) {
22
- if (samples[i].slot <= stopSlot) {
23
- return currMaxFee;
24
- }
25
- if (samples[i].prioritizationFee > currMaxFee) {
26
- currMaxFee = samples[i].prioritizationFee;
27
- }
12
+ currMaxFee = Math.max(samples[i].prioritizationFee, currMaxFee);
28
13
  }
29
14
  return currMaxFee;
30
15
  }