@drift-labs/sdk 2.86.0-beta.2 → 2.86.0-beta.21

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/user.js CHANGED
@@ -14,6 +14,7 @@ const spotPosition_1 = require("./math/spotPosition");
14
14
  const oracles_1 = require("./math/oracles");
15
15
  const tiers_1 = require("./math/tiers");
16
16
  const strictOraclePrice_1 = require("./oracles/strictOraclePrice");
17
+ const fuel_1 = require("./math/fuel");
17
18
  class User {
18
19
  get isSubscribed() {
19
20
  return this._isSubscribed && this.accountSubscriber.isSubscribed;
@@ -539,6 +540,64 @@ class User {
539
540
  return pnl.add((0, _1.calculatePositionFundingPNL)(market, perpPosition));
540
541
  }, numericConstants_1.ZERO);
541
542
  }
543
+ getFuelBonus(now, includeSettled = true, includeUnsettled = true) {
544
+ const userAccount = this.getUserAccount();
545
+ const result = {
546
+ insuranceFuel: numericConstants_1.ZERO,
547
+ takerFuel: numericConstants_1.ZERO,
548
+ makerFuel: numericConstants_1.ZERO,
549
+ depositFuel: numericConstants_1.ZERO,
550
+ borrowFuel: numericConstants_1.ZERO,
551
+ positionFuel: numericConstants_1.ZERO,
552
+ };
553
+ if (includeSettled) {
554
+ const userStats = this.driftClient
555
+ .getUserStats()
556
+ .getAccount();
557
+ result.insuranceFuel = result.insuranceFuel.add(new _1.BN(userStats.fuelInsurance));
558
+ result.takerFuel = result.takerFuel.add(new _1.BN(userStats.fuelTaker));
559
+ result.makerFuel = result.makerFuel.add(new _1.BN(userStats.fuelMaker));
560
+ result.depositFuel = result.depositFuel.add(new _1.BN(userStats.fuelDeposits));
561
+ result.borrowFuel = result.borrowFuel.add(new _1.BN(userStats.fuelBorrows));
562
+ result.positionFuel = result.positionFuel.add(new _1.BN(userStats.fuelPositions));
563
+ }
564
+ if (includeUnsettled) {
565
+ const fuelBonusNumerator = _1.BN.max(now.sub(_1.BN.max(new _1.BN(userAccount.lastFuelBonusUpdateTs), numericConstants_1.FUEL_START_TS)), numericConstants_1.ZERO);
566
+ if (fuelBonusNumerator.gt(numericConstants_1.ZERO)) {
567
+ for (const spotPosition of this.getActiveSpotPositions()) {
568
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
569
+ const tokenAmount = this.getTokenAmount(spotPosition.marketIndex);
570
+ const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
571
+ const twap5min = (0, oracles_1.calculateLiveOracleTwap)(spotMarketAccount.historicalOracleData, oraclePriceData, now, numericConstants_1.FIVE_MINUTE // 5MIN
572
+ );
573
+ const strictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price, twap5min);
574
+ const signedTokenValue = (0, _1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
575
+ if (signedTokenValue.gt(numericConstants_1.ZERO)) {
576
+ result.depositFuel = result.depositFuel.add((0, fuel_1.calculateSpotFuelBonus)(spotMarketAccount, signedTokenValue, fuelBonusNumerator));
577
+ }
578
+ else {
579
+ result.borrowFuel = result.borrowFuel.add((0, fuel_1.calculateSpotFuelBonus)(spotMarketAccount, signedTokenValue, fuelBonusNumerator));
580
+ }
581
+ }
582
+ for (const perpPosition of this.getActivePerpPositions()) {
583
+ const oraclePriceData = this.getOracleDataForPerpMarket(perpPosition.marketIndex);
584
+ const perpMarketAccount = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
585
+ const baseAssetValue = this.getPerpPositionValue(perpPosition.marketIndex, oraclePriceData, false);
586
+ result.positionFuel = result.positionFuel.add((0, fuel_1.calculatePerpFuelBonus)(perpMarketAccount, baseAssetValue, fuelBonusNumerator));
587
+ }
588
+ }
589
+ const userStats = this.driftClient
590
+ .getUserStats()
591
+ .getAccount();
592
+ // todo: get real time ifStakedGovTokenAmount using ifStakeAccount
593
+ if (userStats.ifStakedGovTokenAmount.gt(numericConstants_1.ZERO)) {
594
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(numericConstants_1.GOV_SPOT_MARKET_INDEX);
595
+ const fuelBonusNumeratorUserStats = now.sub(new _1.BN(userStats.lastFuelBonusUpdateTs));
596
+ result.insuranceFuel = result.insuranceFuel.add((0, fuel_1.calculateInsuranceFuelBonus)(spotMarketAccount, userStats.ifStakedGovTokenAmount, fuelBonusNumeratorUserStats));
597
+ }
598
+ }
599
+ return result;
600
+ }
542
601
  getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, now) {
543
602
  now = now || new _1.BN(new Date().getTime() / 1000);
544
603
  let netQuoteValue = numericConstants_1.ZERO;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.86.0-beta.2",
3
+ "version": "2.86.0-beta.21",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -101,7 +101,7 @@ export class PollingDriftClientAccountSubscriber
101
101
  }
102
102
 
103
103
  await this.updateAccountsToPoll();
104
- await this.updateOraclesToPoll();
104
+ this.updateOraclesToPoll();
105
105
  await this.addToAccountLoader();
106
106
 
107
107
  let subscriptionSucceeded = false;
@@ -116,8 +116,7 @@ export class PollingDriftClientAccountSubscriber
116
116
  this.eventEmitter.emit('update');
117
117
  }
118
118
 
119
- await this.setPerpOracleMap();
120
- await this.setSpotOracleMap();
119
+ await Promise.all([this.setPerpOracleMap(), this.setSpotOracleMap()]);
121
120
 
122
121
  this.isSubscribing = false;
123
122
  this.isSubscribed = subscriptionSucceeded;
@@ -141,14 +140,18 @@ export class PollingDriftClientAccountSubscriber
141
140
  eventType: 'stateAccountUpdate',
142
141
  });
143
142
 
144
- await this.updatePerpMarketAccountsToPoll();
145
- await this.updateSpotMarketAccountsToPoll();
143
+ await Promise.all([
144
+ this.updatePerpMarketAccountsToPoll(),
145
+ this.updateSpotMarketAccountsToPoll(),
146
+ ]);
146
147
  }
147
148
 
148
149
  async updatePerpMarketAccountsToPoll(): Promise<boolean> {
149
- for (const marketIndex of this.perpMarketIndexes) {
150
- await this.addPerpMarketAccountToPoll(marketIndex);
151
- }
150
+ await Promise.all(
151
+ this.perpMarketIndexes.map((marketIndex) => {
152
+ return this.addPerpMarketAccountToPoll(marketIndex);
153
+ })
154
+ );
152
155
  return true;
153
156
  }
154
157
 
@@ -169,9 +172,11 @@ export class PollingDriftClientAccountSubscriber
169
172
  }
170
173
 
171
174
  async updateSpotMarketAccountsToPoll(): Promise<boolean> {
172
- for (const marketIndex of this.spotMarketIndexes) {
173
- await this.addSpotMarketAccountToPoll(marketIndex);
174
- }
175
+ await Promise.all(
176
+ this.spotMarketIndexes.map(async (marketIndex) => {
177
+ await this.addSpotMarketAccountToPoll(marketIndex);
178
+ })
179
+ );
175
180
 
176
181
  return true;
177
182
  }
@@ -209,16 +214,19 @@ export class PollingDriftClientAccountSubscriber
209
214
 
210
215
  return true;
211
216
  }
212
-
213
217
  async addToAccountLoader(): Promise<void> {
218
+ const accountPromises = [];
214
219
  for (const [_, accountToPoll] of this.accountsToPoll) {
215
- await this.addAccountToAccountLoader(accountToPoll);
220
+ accountPromises.push(this.addAccountToAccountLoader(accountToPoll));
216
221
  }
217
222
 
223
+ const oraclePromises = [];
218
224
  for (const [_, oracleToPoll] of this.oraclesToPoll) {
219
- await this.addOracleToAccountLoader(oracleToPoll);
225
+ oraclePromises.push(this.addOracleToAccountLoader(oracleToPoll));
220
226
  }
221
227
 
228
+ await Promise.all([...accountPromises, ...oraclePromises]);
229
+
222
230
  this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
223
231
  this.eventEmitter.emit('error', error);
224
232
  });
@@ -446,37 +454,44 @@ export class PollingDriftClientAccountSubscriber
446
454
  }
447
455
  console.log(`Pausing to find oracle ${oracle} failed`);
448
456
  }
449
-
450
457
  async setPerpOracleMap() {
451
458
  const perpMarkets = this.getMarketAccountsAndSlots();
459
+ const oraclePromises = [];
452
460
  for (const perpMarket of perpMarkets) {
453
461
  const perpMarketAccount = perpMarket.data;
454
462
  const perpMarketIndex = perpMarketAccount.marketIndex;
455
463
  const oracle = perpMarketAccount.amm.oracle;
456
464
  if (!this.oracles.has(oracle.toBase58())) {
457
- await this.addOracle({
458
- publicKey: oracle,
459
- source: perpMarketAccount.amm.oracleSource,
460
- });
465
+ oraclePromises.push(
466
+ this.addOracle({
467
+ publicKey: oracle,
468
+ source: perpMarketAccount.amm.oracleSource,
469
+ })
470
+ );
461
471
  }
462
472
  this.perpOracleMap.set(perpMarketIndex, oracle);
463
473
  }
474
+ await Promise.all(oraclePromises);
464
475
  }
465
476
 
466
477
  async setSpotOracleMap() {
467
478
  const spotMarkets = this.getSpotMarketAccountsAndSlots();
479
+ const oraclePromises = [];
468
480
  for (const spotMarket of spotMarkets) {
469
481
  const spotMarketAccount = spotMarket.data;
470
482
  const spotMarketIndex = spotMarketAccount.marketIndex;
471
483
  const oracle = spotMarketAccount.oracle;
472
484
  if (!this.oracles.has(oracle.toBase58())) {
473
- await this.addOracle({
474
- publicKey: oracle,
475
- source: spotMarketAccount.oracleSource,
476
- });
485
+ oraclePromises.push(
486
+ this.addOracle({
487
+ publicKey: oracle,
488
+ source: spotMarketAccount.oracleSource,
489
+ })
490
+ );
477
491
  }
478
492
  this.spotOracleMap.set(spotMarketIndex, oracle);
479
493
  }
494
+ await Promise.all(oraclePromises);
480
495
  }
481
496
 
482
497
  assertIsSubscribed(): void {
@@ -115,19 +115,18 @@ export class WebSocketDriftClientAccountSubscriber
115
115
  this.eventEmitter.emit('update');
116
116
  });
117
117
 
118
- // subscribe to market accounts
119
- await this.subscribeToPerpMarketAccounts();
120
-
121
- // subscribe to spot market accounts
122
- await this.subscribeToSpotMarketAccounts();
123
-
124
- // subscribe to oracles
125
- await this.subscribeToOracles();
118
+ await Promise.all([
119
+ // subscribe to market accounts
120
+ this.subscribeToPerpMarketAccounts(),
121
+ // subscribe to spot market accounts
122
+ this.subscribeToSpotMarketAccounts(),
123
+ // subscribe to oracles
124
+ this.subscribeToOracles(),
125
+ ]);
126
126
 
127
127
  this.eventEmitter.emit('update');
128
128
 
129
- await this.setPerpOracleMap();
130
- await this.setSpotOracleMap();
129
+ await Promise.all([this.setPerpOracleMap(), this.setSpotOracleMap()]);
131
130
 
132
131
  this.isSubscribing = false;
133
132
  this.isSubscribed = true;
@@ -137,9 +136,11 @@ export class WebSocketDriftClientAccountSubscriber
137
136
  }
138
137
 
139
138
  async subscribeToPerpMarketAccounts(): Promise<boolean> {
140
- for (const marketIndex of this.perpMarketIndexes) {
141
- await this.subscribeToPerpMarketAccount(marketIndex);
142
- }
139
+ await Promise.all(
140
+ this.perpMarketIndexes.map((marketIndex) =>
141
+ this.subscribeToPerpMarketAccount(marketIndex)
142
+ )
143
+ );
143
144
  return true;
144
145
  }
145
146
 
@@ -165,9 +166,11 @@ export class WebSocketDriftClientAccountSubscriber
165
166
  }
166
167
 
167
168
  async subscribeToSpotMarketAccounts(): Promise<boolean> {
168
- for (const marketIndex of this.spotMarketIndexes) {
169
- await this.subscribeToSpotMarketAccount(marketIndex);
170
- }
169
+ await Promise.all(
170
+ this.spotMarketIndexes.map((marketIndex) =>
171
+ this.subscribeToSpotMarketAccount(marketIndex)
172
+ )
173
+ );
171
174
  return true;
172
175
  }
173
176
 
@@ -193,11 +196,11 @@ export class WebSocketDriftClientAccountSubscriber
193
196
  }
194
197
 
195
198
  async subscribeToOracles(): Promise<boolean> {
196
- for (const oracleInfo of this.oracleInfos) {
197
- if (!oracleInfo.publicKey.equals(PublicKey.default)) {
198
- await this.subscribeToOracle(oracleInfo);
199
- }
200
- }
199
+ await Promise.all(
200
+ this.oracleInfos
201
+ .filter((oracleInfo) => !oracleInfo.publicKey.equals(PublicKey.default))
202
+ .map((oracleInfo) => this.subscribeToOracle(oracleInfo))
203
+ );
201
204
 
202
205
  return true;
203
206
  }
@@ -232,21 +235,27 @@ export class WebSocketDriftClientAccountSubscriber
232
235
  }
233
236
 
234
237
  async unsubscribeFromMarketAccounts(): Promise<void> {
235
- for (const accountSubscriber of this.perpMarketAccountSubscribers.values()) {
236
- await accountSubscriber.unsubscribe();
237
- }
238
+ await Promise.all(
239
+ Array.from(this.perpMarketAccountSubscribers.values()).map(
240
+ (accountSubscriber) => accountSubscriber.unsubscribe()
241
+ )
242
+ );
238
243
  }
239
244
 
240
245
  async unsubscribeFromSpotMarketAccounts(): Promise<void> {
241
- for (const accountSubscriber of this.spotMarketAccountSubscribers.values()) {
242
- await accountSubscriber.unsubscribe();
243
- }
246
+ await Promise.all(
247
+ Array.from(this.spotMarketAccountSubscribers.values()).map(
248
+ (accountSubscriber) => accountSubscriber.unsubscribe()
249
+ )
250
+ );
244
251
  }
245
252
 
246
253
  async unsubscribeFromOracles(): Promise<void> {
247
- for (const accountSubscriber of this.oracleSubscribers.values()) {
248
- await accountSubscriber.unsubscribe();
249
- }
254
+ await Promise.all(
255
+ Array.from(this.oracleSubscribers.values()).map((accountSubscriber) =>
256
+ accountSubscriber.unsubscribe()
257
+ )
258
+ );
250
259
  }
251
260
 
252
261
  public async fetch(): Promise<void> {
@@ -315,6 +324,7 @@ export class WebSocketDriftClientAccountSubscriber
315
324
 
316
325
  async setPerpOracleMap() {
317
326
  const perpMarkets = this.getMarketAccountsAndSlots();
327
+ const addOraclePromises = [];
318
328
  for (const perpMarket of perpMarkets) {
319
329
  if (!perpMarket) {
320
330
  continue;
@@ -323,17 +333,21 @@ export class WebSocketDriftClientAccountSubscriber
323
333
  const perpMarketIndex = perpMarketAccount.marketIndex;
324
334
  const oracle = perpMarketAccount.amm.oracle;
325
335
  if (!this.oracleSubscribers.has(oracle.toBase58())) {
326
- await this.addOracle({
327
- publicKey: oracle,
328
- source: perpMarket.data.amm.oracleSource,
329
- });
336
+ addOraclePromises.push(
337
+ this.addOracle({
338
+ publicKey: oracle,
339
+ source: perpMarket.data.amm.oracleSource,
340
+ })
341
+ );
330
342
  }
331
343
  this.perpOracleMap.set(perpMarketIndex, oracle);
332
344
  }
345
+ await Promise.all(addOraclePromises);
333
346
  }
334
347
 
335
348
  async setSpotOracleMap() {
336
349
  const spotMarkets = this.getSpotMarketAccountsAndSlots();
350
+ const addOraclePromises = [];
337
351
  for (const spotMarket of spotMarkets) {
338
352
  if (!spotMarket) {
339
353
  continue;
@@ -342,13 +356,16 @@ export class WebSocketDriftClientAccountSubscriber
342
356
  const spotMarketIndex = spotMarketAccount.marketIndex;
343
357
  const oracle = spotMarketAccount.oracle;
344
358
  if (!this.oracleSubscribers.has(oracle.toBase58())) {
345
- await this.addOracle({
346
- publicKey: oracle,
347
- source: spotMarketAccount.oracleSource,
348
- });
359
+ addOraclePromises.push(
360
+ this.addOracle({
361
+ publicKey: oracle,
362
+ source: spotMarketAccount.oracleSource,
363
+ })
364
+ );
349
365
  }
350
366
  this.spotOracleMap.set(spotMarketIndex, oracle);
351
367
  }
368
+ await Promise.all(addOraclePromises);
352
369
  }
353
370
 
354
371
  assertIsSubscribed(): void {
@@ -30,6 +30,7 @@ import {
30
30
  getProtocolIfSharesTransferConfigPublicKey,
31
31
  getPrelaunchOraclePublicKey,
32
32
  getPythPullOraclePublicKey,
33
+ getUserStatsAccountPublicKey,
33
34
  } from './addresses/pda';
34
35
  import { squareRootBN } from './math/utils';
35
36
  import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
@@ -3533,6 +3534,164 @@ export class AdminClient extends DriftClient {
3533
3534
  });
3534
3535
  }
3535
3536
 
3537
+ public async updateSpotMarketFuel(
3538
+ spotMarketIndex: number,
3539
+ fuelBoostDeposits?: number,
3540
+ fuelBoostBorrows?: number,
3541
+ fuelBoostTaker?: number,
3542
+ fuelBoostMaker?: number,
3543
+ fuelBoostInsurance?: number
3544
+ ): Promise<TransactionSignature> {
3545
+ const updateSpotMarketFuelIx = await this.getUpdateSpotMarketFuelIx(
3546
+ spotMarketIndex,
3547
+ fuelBoostDeposits || null,
3548
+ fuelBoostBorrows || null,
3549
+ fuelBoostTaker || null,
3550
+ fuelBoostMaker || null,
3551
+ fuelBoostInsurance || null
3552
+ );
3553
+
3554
+ const tx = await this.buildTransaction(updateSpotMarketFuelIx);
3555
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
3556
+
3557
+ return txSig;
3558
+ }
3559
+
3560
+ public async getUpdateSpotMarketFuelIx(
3561
+ spotMarketIndex: number,
3562
+ fuelBoostDeposits?: number,
3563
+ fuelBoostBorrows?: number,
3564
+ fuelBoostTaker?: number,
3565
+ fuelBoostMaker?: number,
3566
+ fuelBoostInsurance?: number
3567
+ ): Promise<TransactionInstruction> {
3568
+ const spotMarketPublicKey = await getSpotMarketPublicKey(
3569
+ this.program.programId,
3570
+ spotMarketIndex
3571
+ );
3572
+
3573
+ return await this.program.instruction.updateSpotMarketFuel(
3574
+ fuelBoostDeposits || null,
3575
+ fuelBoostBorrows || null,
3576
+ fuelBoostTaker || null,
3577
+ fuelBoostMaker || null,
3578
+ fuelBoostInsurance || null,
3579
+ {
3580
+ accounts: {
3581
+ admin: this.isSubscribed
3582
+ ? this.getStateAccount().admin
3583
+ : this.wallet.publicKey,
3584
+ state: await this.getStatePublicKey(),
3585
+ spotMarket: spotMarketPublicKey,
3586
+ },
3587
+ }
3588
+ );
3589
+ }
3590
+
3591
+ public async updatePerpMarketFuel(
3592
+ perpMarketIndex: number,
3593
+ fuelBoostTaker?: number,
3594
+ fuelBoostMaker?: number,
3595
+ fuelBoostPosition?: number
3596
+ ): Promise<TransactionSignature> {
3597
+ const updatePerpMarketFuelIx = await this.getUpdatePerpMarketFuelIx(
3598
+ perpMarketIndex,
3599
+ fuelBoostTaker || null,
3600
+ fuelBoostMaker || null,
3601
+ fuelBoostPosition || null
3602
+ );
3603
+
3604
+ const tx = await this.buildTransaction(updatePerpMarketFuelIx);
3605
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
3606
+
3607
+ return txSig;
3608
+ }
3609
+
3610
+ public async getUpdatePerpMarketFuelIx(
3611
+ perpMarketIndex: number,
3612
+ fuelBoostTaker?: number,
3613
+ fuelBoostMaker?: number,
3614
+ fuelBoostPosition?: number
3615
+ ): Promise<TransactionInstruction> {
3616
+ const perpMarketPublicKey = await getPerpMarketPublicKey(
3617
+ this.program.programId,
3618
+ perpMarketIndex
3619
+ );
3620
+
3621
+ return await this.program.instruction.updatePerpMarketFuel(
3622
+ fuelBoostTaker || null,
3623
+ fuelBoostMaker || null,
3624
+ fuelBoostPosition || null,
3625
+ {
3626
+ accounts: {
3627
+ admin: this.isSubscribed
3628
+ ? this.getStateAccount().admin
3629
+ : this.wallet.publicKey,
3630
+ state: await this.getStatePublicKey(),
3631
+ perpMarket: perpMarketPublicKey,
3632
+ },
3633
+ }
3634
+ );
3635
+ }
3636
+
3637
+ public async initUserFuel(
3638
+ user: PublicKey,
3639
+ authority: PublicKey,
3640
+ fuelBonusDeposits?: number,
3641
+ fuelBonusBorrows?: number,
3642
+ fuelBonusTaker?: number,
3643
+ fuelBonusMaker?: number,
3644
+ fuelBonusInsurance?: number
3645
+ ): Promise<TransactionSignature> {
3646
+ const updatePerpMarketFuelIx = await this.getInitUserFuelIx(
3647
+ user,
3648
+ authority,
3649
+ fuelBonusDeposits,
3650
+ fuelBonusBorrows,
3651
+ fuelBonusTaker,
3652
+ fuelBonusMaker,
3653
+ fuelBonusInsurance
3654
+ );
3655
+
3656
+ const tx = await this.buildTransaction(updatePerpMarketFuelIx);
3657
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
3658
+
3659
+ return txSig;
3660
+ }
3661
+
3662
+ public async getInitUserFuelIx(
3663
+ user: PublicKey,
3664
+ authority: PublicKey,
3665
+ fuelBonusDeposits?: number,
3666
+ fuelBonusBorrows?: number,
3667
+ fuelBonusTaker?: number,
3668
+ fuelBonusMaker?: number,
3669
+ fuelBonusInsurance?: number
3670
+ ): Promise<TransactionInstruction> {
3671
+ const userStats = await getUserStatsAccountPublicKey(
3672
+ this.program.programId,
3673
+ authority
3674
+ );
3675
+
3676
+ return await this.program.instruction.initUserFuel(
3677
+ fuelBonusDeposits || null,
3678
+ fuelBonusBorrows || null,
3679
+ fuelBonusTaker || null,
3680
+ fuelBonusMaker || null,
3681
+ fuelBonusInsurance || null,
3682
+ {
3683
+ accounts: {
3684
+ admin: this.isSubscribed
3685
+ ? this.getStateAccount().admin
3686
+ : this.wallet.publicKey,
3687
+ state: await this.getStatePublicKey(),
3688
+ user,
3689
+ userStats,
3690
+ },
3691
+ }
3692
+ );
3693
+ }
3694
+
3536
3695
  public async initializePythPullOracle(
3537
3696
  feedId: string
3538
3697
  ): Promise<TransactionSignature> {
@@ -118,6 +118,19 @@ export class BankrunContextWrapper {
118
118
  );
119
119
  await this.context.setClock(newClock);
120
120
  }
121
+
122
+ async setTimestamp(unix_timestamp: number): Promise<void> {
123
+ const currentClock = await this.context.banksClient.getClock();
124
+ const newUnixTimestamp = BigInt(unix_timestamp);
125
+ const newClock = new Clock(
126
+ currentClock.slot,
127
+ currentClock.epochStartTimestamp,
128
+ currentClock.epoch,
129
+ currentClock.leaderScheduleEpoch,
130
+ newUnixTimestamp
131
+ );
132
+ await this.context.setClock(newClock);
133
+ }
121
134
  }
122
135
 
123
136
  export class BankrunConnection {
@@ -90,6 +90,7 @@ export const ONE_HOUR = new BN(60 * 60);
90
90
  export const ONE_YEAR = new BN(31536000);
91
91
 
92
92
  export const QUOTE_SPOT_MARKET_INDEX = 0;
93
+ export const GOV_SPOT_MARKET_INDEX = 15;
93
94
 
94
95
  export const LAMPORTS_PRECISION = new BN(LAMPORTS_PER_SOL);
95
96
  export const LAMPORTS_EXP = new BN(Math.log10(LAMPORTS_PER_SOL));
@@ -105,3 +106,6 @@ export const IDLE_TIME_SLOTS = 9000;
105
106
  export const SLOT_TIME_ESTIMATE_MS = 400;
106
107
 
107
108
  export const DUST_POSITION_SIZE = QUOTE_PRECISION.divn(100); // Dust position is any position smaller than 1c
109
+
110
+ export const FUEL_WINDOW = new BN(60 * 60 * 24 * 28); // 28 days
111
+ export const FUEL_START_TS = new BN(1722384000); // unix timestamp