@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/VERSION +1 -1
- package/lib/accounts/pollingDriftClientAccountSubscriber.js +24 -16
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +25 -32
- package/lib/adminClient.d.ts +6 -0
- package/lib/adminClient.js +55 -0
- package/lib/bankrun/bankrunConnection.d.ts +1 -0
- package/lib/bankrun/bankrunConnection.js +6 -0
- package/lib/constants/numericConstants.d.ts +3 -0
- package/lib/constants/numericConstants.js +4 -1
- package/lib/constants/perpMarkets.js +125 -101
- package/lib/constants/spotMarkets.js +19 -18
- package/lib/idl/drift.json +331 -4
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/fuel.d.ts +6 -0
- package/lib/math/fuel.js +55 -0
- package/lib/types.d.ts +17 -0
- package/lib/user.d.ts +8 -0
- package/lib/user.js +59 -0
- package/package.json +1 -1
- package/src/accounts/pollingDriftClientAccountSubscriber.ts +38 -23
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +55 -38
- package/src/adminClient.ts +159 -0
- package/src/bankrun/bankrunConnection.ts +13 -0
- package/src/constants/numericConstants.ts +4 -0
- package/src/constants/perpMarkets.ts +129 -101
- package/src/constants/spotMarkets.ts +20 -18
- package/src/idl/drift.json +331 -4
- package/src/index.ts +1 -0
- package/src/math/fuel.ts +70 -0
- package/src/types.ts +22 -0
- package/src/user.ts +154 -0
- package/tests/ci/verifyConstants.ts +214 -0
- package/tests/dlob/helpers.ts +30 -0
- package/tests/user/helpers.ts +1 -0
- package/tests/user/test.ts +2 -0
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
|
@@ -101,7 +101,7 @@ export class PollingDriftClientAccountSubscriber
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
await this.updateAccountsToPoll();
|
|
104
|
-
|
|
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
|
|
145
|
-
|
|
143
|
+
await Promise.all([
|
|
144
|
+
this.updatePerpMarketAccountsToPoll(),
|
|
145
|
+
this.updateSpotMarketAccountsToPoll(),
|
|
146
|
+
]);
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
async updatePerpMarketAccountsToPoll(): Promise<boolean> {
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
173
|
-
|
|
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
|
-
|
|
220
|
+
accountPromises.push(this.addAccountToAccountLoader(accountToPoll));
|
|
216
221
|
}
|
|
217
222
|
|
|
223
|
+
const oraclePromises = [];
|
|
218
224
|
for (const [_, oracleToPoll] of this.oraclesToPoll) {
|
|
219
|
-
|
|
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
|
-
|
|
458
|
-
|
|
459
|
-
|
|
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
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
141
|
-
|
|
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
|
-
|
|
169
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
-
|
|
236
|
-
|
|
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
|
-
|
|
242
|
-
|
|
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
|
-
|
|
248
|
-
|
|
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
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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 {
|
package/src/adminClient.ts
CHANGED
|
@@ -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
|