@drift-labs/sdk 2.95.0-beta.14 → 2.95.0-beta.16
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.d.ts +1 -3
- package/lib/accounts/pollingDriftClientAccountSubscriber.js +4 -14
- package/lib/accounts/types.d.ts +1 -1
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +1 -3
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +4 -14
- package/lib/driftClient.js +1 -1
- package/lib/math/spotBalance.d.ts +3 -3
- package/lib/math/spotBalance.js +7 -7
- package/package.json +1 -1
- package/src/accounts/pollingDriftClientAccountSubscriber.ts +5 -17
- package/src/accounts/types.ts +1 -1
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +5 -17
- package/src/driftClient.ts +1 -3
- package/src/math/spotBalance.ts +13 -7
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.95.0-beta.
|
|
1
|
+
2.95.0-beta.16
|
|
@@ -24,10 +24,8 @@ export declare class PollingDriftClientAccountSubscriber implements DriftClientA
|
|
|
24
24
|
state?: DataAndSlot<StateAccount>;
|
|
25
25
|
perpMarket: Map<number, DataAndSlot<PerpMarketAccount>>;
|
|
26
26
|
perpOracleMap: Map<number, PublicKey>;
|
|
27
|
-
perpOracleStringMap: Map<number, string>;
|
|
28
27
|
spotMarket: Map<number, DataAndSlot<SpotMarketAccount>>;
|
|
29
28
|
spotOracleMap: Map<number, PublicKey>;
|
|
30
|
-
spotOracleStringMap: Map<number, string>;
|
|
31
29
|
oracles: Map<string, DataAndSlot<OraclePriceData>>;
|
|
32
30
|
user?: DataAndSlot<UserAccount>;
|
|
33
31
|
private isSubscribing;
|
|
@@ -60,7 +58,7 @@ export declare class PollingDriftClientAccountSubscriber implements DriftClientA
|
|
|
60
58
|
getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
|
|
61
59
|
getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
|
|
62
60
|
getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
|
|
63
|
-
getOraclePriceDataAndSlot(oraclePublicKey: PublicKey
|
|
61
|
+
getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
|
|
64
62
|
getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
|
|
65
63
|
getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
|
|
66
64
|
updateAccountLoaderPollingFrequency(pollingFrequency: number): void;
|
|
@@ -9,7 +9,6 @@ const web3_js_1 = require("@solana/web3.js");
|
|
|
9
9
|
const oracleClientCache_1 = require("../oracles/oracleClientCache");
|
|
10
10
|
const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
|
|
11
11
|
const config_1 = require("../config");
|
|
12
|
-
const ORACLE_DEFAULT_KEY = web3_js_1.PublicKey.default.toBase58();
|
|
13
12
|
class PollingDriftClientAccountSubscriber {
|
|
14
13
|
constructor(program, accountLoader, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles) {
|
|
15
14
|
this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
|
|
@@ -17,10 +16,8 @@ class PollingDriftClientAccountSubscriber {
|
|
|
17
16
|
this.oraclesToPoll = new Map();
|
|
18
17
|
this.perpMarket = new Map();
|
|
19
18
|
this.perpOracleMap = new Map();
|
|
20
|
-
this.perpOracleStringMap = new Map();
|
|
21
19
|
this.spotMarket = new Map();
|
|
22
20
|
this.spotOracleMap = new Map();
|
|
23
|
-
this.spotOracleStringMap = new Map();
|
|
24
21
|
this.oracles = new Map();
|
|
25
22
|
this.isSubscribing = false;
|
|
26
23
|
this.isSubscribed = false;
|
|
@@ -303,7 +300,6 @@ class PollingDriftClientAccountSubscriber {
|
|
|
303
300
|
}));
|
|
304
301
|
}
|
|
305
302
|
this.perpOracleMap.set(perpMarketIndex, oracle);
|
|
306
|
-
this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
|
|
307
303
|
}
|
|
308
304
|
await Promise.all(oraclePromises);
|
|
309
305
|
}
|
|
@@ -321,7 +317,6 @@ class PollingDriftClientAccountSubscriber {
|
|
|
321
317
|
}));
|
|
322
318
|
}
|
|
323
319
|
this.spotOracleMap.set(spotMarketIndex, oracle);
|
|
324
|
-
this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
|
|
325
320
|
}
|
|
326
321
|
await Promise.all(oraclePromises);
|
|
327
322
|
}
|
|
@@ -348,21 +343,17 @@ class PollingDriftClientAccountSubscriber {
|
|
|
348
343
|
}
|
|
349
344
|
getOraclePriceDataAndSlot(oraclePublicKey) {
|
|
350
345
|
this.assertIsSubscribed();
|
|
351
|
-
|
|
352
|
-
? oraclePublicKey
|
|
353
|
-
: oraclePublicKey.toBase58();
|
|
354
|
-
if (oracleString === ORACLE_DEFAULT_KEY) {
|
|
346
|
+
if (oraclePublicKey.equals(web3_js_1.PublicKey.default)) {
|
|
355
347
|
return {
|
|
356
348
|
data: quoteAssetOracleClient_1.QUOTE_ORACLE_PRICE_DATA,
|
|
357
349
|
slot: 0,
|
|
358
350
|
};
|
|
359
351
|
}
|
|
360
|
-
return this.oracles.get(
|
|
352
|
+
return this.oracles.get(oraclePublicKey.toString());
|
|
361
353
|
}
|
|
362
354
|
getOraclePriceDataAndSlotForPerpMarket(marketIndex) {
|
|
363
355
|
const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
|
|
364
356
|
const oracle = this.perpOracleMap.get(marketIndex);
|
|
365
|
-
const oracleString = this.perpOracleStringMap.get(marketIndex);
|
|
366
357
|
if (!perpMarketAccount || !oracle) {
|
|
367
358
|
return undefined;
|
|
368
359
|
}
|
|
@@ -370,12 +361,11 @@ class PollingDriftClientAccountSubscriber {
|
|
|
370
361
|
// If the oracle has changed, we need to update the oracle map in background
|
|
371
362
|
this.setPerpOracleMap();
|
|
372
363
|
}
|
|
373
|
-
return this.getOraclePriceDataAndSlot(
|
|
364
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
374
365
|
}
|
|
375
366
|
getOraclePriceDataAndSlotForSpotMarket(marketIndex) {
|
|
376
367
|
const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
|
|
377
368
|
const oracle = this.spotOracleMap.get(marketIndex);
|
|
378
|
-
const oracleString = this.spotOracleStringMap.get(marketIndex);
|
|
379
369
|
if (!spotMarketAccount || !oracle) {
|
|
380
370
|
return undefined;
|
|
381
371
|
}
|
|
@@ -383,7 +373,7 @@ class PollingDriftClientAccountSubscriber {
|
|
|
383
373
|
// If the oracle has changed, we need to update the oracle map in background
|
|
384
374
|
this.setSpotOracleMap();
|
|
385
375
|
}
|
|
386
|
-
return this.getOraclePriceDataAndSlot(
|
|
376
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
387
377
|
}
|
|
388
378
|
updateAccountLoaderPollingFrequency(pollingFrequency) {
|
|
389
379
|
this.accountLoader.updatePollingFrequency(pollingFrequency);
|
package/lib/accounts/types.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export interface DriftClientAccountSubscriber {
|
|
|
45
45
|
getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
|
|
46
46
|
getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
|
|
47
47
|
getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
|
|
48
|
-
getOraclePriceDataAndSlot(oraclePublicKey: PublicKey
|
|
48
|
+
getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
|
|
49
49
|
getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
|
|
50
50
|
getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
|
|
51
51
|
updateAccountLoaderPollingFrequency?: (pollingFrequency: number) => void;
|
|
@@ -22,10 +22,8 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
|
|
|
22
22
|
stateAccountSubscriber?: AccountSubscriber<StateAccount>;
|
|
23
23
|
perpMarketAccountSubscribers: Map<number, AccountSubscriber<PerpMarketAccount>>;
|
|
24
24
|
perpOracleMap: Map<number, PublicKey>;
|
|
25
|
-
perpOracleStringMap: Map<number, string>;
|
|
26
25
|
spotMarketAccountSubscribers: Map<number, AccountSubscriber<SpotMarketAccount>>;
|
|
27
26
|
spotOracleMap: Map<number, PublicKey>;
|
|
28
|
-
spotOracleStringMap: Map<number, string>;
|
|
29
27
|
oracleSubscribers: Map<string, AccountSubscriber<OraclePriceData>>;
|
|
30
28
|
initialPerpMarketAccountData: Map<number, PerpMarketAccount>;
|
|
31
29
|
initialSpotMarketAccountData: Map<number, SpotMarketAccount>;
|
|
@@ -59,7 +57,7 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
|
|
|
59
57
|
getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
|
|
60
58
|
getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
|
|
61
59
|
getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
|
|
62
|
-
getOraclePriceDataAndSlot(oraclePublicKey: PublicKey
|
|
60
|
+
getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
|
|
63
61
|
getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
|
|
64
62
|
getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
|
|
65
63
|
}
|
|
@@ -9,16 +9,13 @@ const web3_js_1 = require("@solana/web3.js");
|
|
|
9
9
|
const oracleClientCache_1 = require("../oracles/oracleClientCache");
|
|
10
10
|
const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
|
|
11
11
|
const config_1 = require("../config");
|
|
12
|
-
const ORACLE_DEFAULT_KEY = web3_js_1.PublicKey.default.toBase58();
|
|
13
12
|
class WebSocketDriftClientAccountSubscriber {
|
|
14
13
|
constructor(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, resubOpts, commitment) {
|
|
15
14
|
this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
|
|
16
15
|
this.perpMarketAccountSubscribers = new Map();
|
|
17
16
|
this.perpOracleMap = new Map();
|
|
18
|
-
this.perpOracleStringMap = new Map();
|
|
19
17
|
this.spotMarketAccountSubscribers = new Map();
|
|
20
18
|
this.spotOracleMap = new Map();
|
|
21
|
-
this.spotOracleStringMap = new Map();
|
|
22
19
|
this.oracleSubscribers = new Map();
|
|
23
20
|
this.isSubscribing = false;
|
|
24
21
|
this.isSubscribed = false;
|
|
@@ -227,7 +224,6 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
227
224
|
}));
|
|
228
225
|
}
|
|
229
226
|
this.perpOracleMap.set(perpMarketIndex, oracle);
|
|
230
|
-
this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
|
|
231
227
|
}
|
|
232
228
|
await Promise.all(addOraclePromises);
|
|
233
229
|
}
|
|
@@ -248,7 +244,6 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
248
244
|
}));
|
|
249
245
|
}
|
|
250
246
|
this.spotOracleMap.set(spotMarketIndex, oracle);
|
|
251
|
-
this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
|
|
252
247
|
}
|
|
253
248
|
await Promise.all(addOraclePromises);
|
|
254
249
|
}
|
|
@@ -277,21 +272,17 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
277
272
|
}
|
|
278
273
|
getOraclePriceDataAndSlot(oraclePublicKey) {
|
|
279
274
|
this.assertIsSubscribed();
|
|
280
|
-
|
|
281
|
-
? oraclePublicKey
|
|
282
|
-
: oraclePublicKey.toBase58();
|
|
283
|
-
if (oracleString === ORACLE_DEFAULT_KEY) {
|
|
275
|
+
if (oraclePublicKey.equals(web3_js_1.PublicKey.default)) {
|
|
284
276
|
return {
|
|
285
277
|
data: quoteAssetOracleClient_1.QUOTE_ORACLE_PRICE_DATA,
|
|
286
278
|
slot: 0,
|
|
287
279
|
};
|
|
288
280
|
}
|
|
289
|
-
return this.oracleSubscribers.get(
|
|
281
|
+
return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
|
|
290
282
|
}
|
|
291
283
|
getOraclePriceDataAndSlotForPerpMarket(marketIndex) {
|
|
292
284
|
const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
|
|
293
285
|
const oracle = this.perpOracleMap.get(marketIndex);
|
|
294
|
-
const oracleString = this.perpOracleStringMap.get(marketIndex);
|
|
295
286
|
if (!perpMarketAccount || !oracle) {
|
|
296
287
|
return undefined;
|
|
297
288
|
}
|
|
@@ -299,12 +290,11 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
299
290
|
// If the oracle has changed, we need to update the oracle map in background
|
|
300
291
|
this.setPerpOracleMap();
|
|
301
292
|
}
|
|
302
|
-
return this.getOraclePriceDataAndSlot(
|
|
293
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
303
294
|
}
|
|
304
295
|
getOraclePriceDataAndSlotForSpotMarket(marketIndex) {
|
|
305
296
|
const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
|
|
306
297
|
const oracle = this.spotOracleMap.get(marketIndex);
|
|
307
|
-
const oracleString = this.spotOracleStringMap.get(marketIndex);
|
|
308
298
|
if (!spotMarketAccount || !oracle) {
|
|
309
299
|
return undefined;
|
|
310
300
|
}
|
|
@@ -312,7 +302,7 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
312
302
|
// If the oracle has changed, we need to update the oracle map in background
|
|
313
303
|
this.setSpotOracleMap();
|
|
314
304
|
}
|
|
315
|
-
return this.getOraclePriceDataAndSlot(
|
|
305
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
316
306
|
}
|
|
317
307
|
}
|
|
318
308
|
exports.WebSocketDriftClientAccountSubscriber = WebSocketDriftClientAccountSubscriber;
|
package/lib/driftClient.js
CHANGED
|
@@ -309,7 +309,7 @@ class DriftClient {
|
|
|
309
309
|
return this.accountSubscriber.getSpotMarketAccountAndSlot(numericConstants_1.QUOTE_SPOT_MARKET_INDEX).data;
|
|
310
310
|
}
|
|
311
311
|
getOraclePriceDataAndSlot(oraclePublicKey) {
|
|
312
|
-
return this.accountSubscriber.getOraclePriceDataAndSlot(oraclePublicKey
|
|
312
|
+
return this.accountSubscriber.getOraclePriceDataAndSlot(oraclePublicKey);
|
|
313
313
|
}
|
|
314
314
|
async getSerumV3FulfillmentConfig(serumMarket) {
|
|
315
315
|
const address = await (0, pda_1.getSerumFulfillmentConfigPublicKey)(this.program.programId, serumMarket);
|
|
@@ -62,9 +62,9 @@ export declare function calculateSpotMarketBorrowCapacity(spotMarketAccount: Spo
|
|
|
62
62
|
totalCapacity: BN;
|
|
63
63
|
remainingCapacity: BN;
|
|
64
64
|
};
|
|
65
|
-
export declare function calculateInterestRate(bank: SpotMarketAccount, delta?: BN): BN;
|
|
66
|
-
export declare function calculateDepositRate(bank: SpotMarketAccount, delta?: BN): BN;
|
|
67
|
-
export declare function calculateBorrowRate(bank: SpotMarketAccount, delta?: BN): BN;
|
|
65
|
+
export declare function calculateInterestRate(bank: SpotMarketAccount, delta?: BN, currentUtilization?: BN): BN;
|
|
66
|
+
export declare function calculateDepositRate(bank: SpotMarketAccount, delta?: BN, currentUtilization?: BN): BN;
|
|
67
|
+
export declare function calculateBorrowRate(bank: SpotMarketAccount, delta?: BN, currentUtilization?: BN): BN;
|
|
68
68
|
export declare function calculateInterestAccumulated(bank: SpotMarketAccount, now: BN): {
|
|
69
69
|
borrowInterest: BN;
|
|
70
70
|
depositInterest: BN;
|
package/lib/math/spotBalance.js
CHANGED
|
@@ -246,8 +246,8 @@ function calculateSpotMarketBorrowCapacity(spotMarketAccount, targetBorrowRate)
|
|
|
246
246
|
return { totalCapacity, remainingCapacity };
|
|
247
247
|
}
|
|
248
248
|
exports.calculateSpotMarketBorrowCapacity = calculateSpotMarketBorrowCapacity;
|
|
249
|
-
function calculateInterestRate(bank, delta = numericConstants_1.ZERO) {
|
|
250
|
-
const utilization = calculateUtilization(bank, delta);
|
|
249
|
+
function calculateInterestRate(bank, delta = numericConstants_1.ZERO, currentUtilization = null) {
|
|
250
|
+
const utilization = currentUtilization || calculateUtilization(bank, delta);
|
|
251
251
|
let interestRate;
|
|
252
252
|
if (utilization.gt(new anchor_1.BN(bank.optimalUtilization))) {
|
|
253
253
|
const surplusUtilization = utilization.sub(new anchor_1.BN(bank.optimalUtilization));
|
|
@@ -269,11 +269,11 @@ function calculateInterestRate(bank, delta = numericConstants_1.ZERO) {
|
|
|
269
269
|
return anchor_1.BN.max(interestRate, new anchor_1.BN(bank.minBorrowRate).mul(numericConstants_2.PERCENTAGE_PRECISION.divn(200)));
|
|
270
270
|
}
|
|
271
271
|
exports.calculateInterestRate = calculateInterestRate;
|
|
272
|
-
function calculateDepositRate(bank, delta = numericConstants_1.ZERO) {
|
|
272
|
+
function calculateDepositRate(bank, delta = numericConstants_1.ZERO, currentUtilization = null) {
|
|
273
273
|
// positive delta => adding to deposit
|
|
274
274
|
// negative delta => adding to borrow
|
|
275
|
-
const utilization = calculateUtilization(bank, delta);
|
|
276
|
-
const borrowRate = calculateBorrowRate(bank, delta);
|
|
275
|
+
const utilization = currentUtilization || calculateUtilization(bank, delta);
|
|
276
|
+
const borrowRate = calculateBorrowRate(bank, delta, utilization);
|
|
277
277
|
const depositRate = borrowRate
|
|
278
278
|
.mul(numericConstants_2.PERCENTAGE_PRECISION.sub(new anchor_1.BN(bank.insuranceFund.totalFactor)))
|
|
279
279
|
.mul(utilization)
|
|
@@ -282,8 +282,8 @@ function calculateDepositRate(bank, delta = numericConstants_1.ZERO) {
|
|
|
282
282
|
return depositRate;
|
|
283
283
|
}
|
|
284
284
|
exports.calculateDepositRate = calculateDepositRate;
|
|
285
|
-
function calculateBorrowRate(bank, delta = numericConstants_1.ZERO) {
|
|
286
|
-
return calculateInterestRate(bank, delta);
|
|
285
|
+
function calculateBorrowRate(bank, delta = numericConstants_1.ZERO, currentUtilization = null) {
|
|
286
|
+
return calculateInterestRate(bank, delta, currentUtilization);
|
|
287
287
|
}
|
|
288
288
|
exports.calculateBorrowRate = calculateBorrowRate;
|
|
289
289
|
function calculateInterestAccumulated(bank, now) {
|
package/package.json
CHANGED
|
@@ -28,8 +28,6 @@ import { OracleClientCache } from '../oracles/oracleClientCache';
|
|
|
28
28
|
import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
|
|
29
29
|
import { findAllMarketAndOracles } from '../config';
|
|
30
30
|
|
|
31
|
-
const ORACLE_DEFAULT_KEY = PublicKey.default.toBase58();
|
|
32
|
-
|
|
33
31
|
export class PollingDriftClientAccountSubscriber
|
|
34
32
|
implements DriftClientAccountSubscriber
|
|
35
33
|
{
|
|
@@ -52,10 +50,8 @@ export class PollingDriftClientAccountSubscriber
|
|
|
52
50
|
state?: DataAndSlot<StateAccount>;
|
|
53
51
|
perpMarket = new Map<number, DataAndSlot<PerpMarketAccount>>();
|
|
54
52
|
perpOracleMap = new Map<number, PublicKey>();
|
|
55
|
-
perpOracleStringMap = new Map<number, string>();
|
|
56
53
|
spotMarket = new Map<number, DataAndSlot<SpotMarketAccount>>();
|
|
57
54
|
spotOracleMap = new Map<number, PublicKey>();
|
|
58
|
-
spotOracleStringMap = new Map<number, string>();
|
|
59
55
|
oracles = new Map<string, DataAndSlot<OraclePriceData>>();
|
|
60
56
|
user?: DataAndSlot<UserAccount>;
|
|
61
57
|
|
|
@@ -474,7 +470,6 @@ export class PollingDriftClientAccountSubscriber
|
|
|
474
470
|
);
|
|
475
471
|
}
|
|
476
472
|
this.perpOracleMap.set(perpMarketIndex, oracle);
|
|
477
|
-
this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
|
|
478
473
|
}
|
|
479
474
|
await Promise.all(oraclePromises);
|
|
480
475
|
}
|
|
@@ -495,7 +490,6 @@ export class PollingDriftClientAccountSubscriber
|
|
|
495
490
|
);
|
|
496
491
|
}
|
|
497
492
|
this.spotOracleMap.set(spotMarketIndex, oracle);
|
|
498
|
-
this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
|
|
499
493
|
}
|
|
500
494
|
await Promise.all(oraclePromises);
|
|
501
495
|
}
|
|
@@ -534,21 +528,17 @@ export class PollingDriftClientAccountSubscriber
|
|
|
534
528
|
}
|
|
535
529
|
|
|
536
530
|
public getOraclePriceDataAndSlot(
|
|
537
|
-
oraclePublicKey: PublicKey
|
|
531
|
+
oraclePublicKey: PublicKey
|
|
538
532
|
): DataAndSlot<OraclePriceData> | undefined {
|
|
539
533
|
this.assertIsSubscribed();
|
|
540
|
-
|
|
541
|
-
typeof oraclePublicKey === 'string'
|
|
542
|
-
? oraclePublicKey
|
|
543
|
-
: oraclePublicKey.toBase58();
|
|
544
|
-
if (oracleString === ORACLE_DEFAULT_KEY) {
|
|
534
|
+
if (oraclePublicKey.equals(PublicKey.default)) {
|
|
545
535
|
return {
|
|
546
536
|
data: QUOTE_ORACLE_PRICE_DATA,
|
|
547
537
|
slot: 0,
|
|
548
538
|
};
|
|
549
539
|
}
|
|
550
540
|
|
|
551
|
-
return this.oracles.get(
|
|
541
|
+
return this.oracles.get(oraclePublicKey.toString());
|
|
552
542
|
}
|
|
553
543
|
|
|
554
544
|
public getOraclePriceDataAndSlotForPerpMarket(
|
|
@@ -556,7 +546,6 @@ export class PollingDriftClientAccountSubscriber
|
|
|
556
546
|
): DataAndSlot<OraclePriceData> | undefined {
|
|
557
547
|
const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
|
|
558
548
|
const oracle = this.perpOracleMap.get(marketIndex);
|
|
559
|
-
const oracleString = this.perpOracleStringMap.get(marketIndex);
|
|
560
549
|
|
|
561
550
|
if (!perpMarketAccount || !oracle) {
|
|
562
551
|
return undefined;
|
|
@@ -567,7 +556,7 @@ export class PollingDriftClientAccountSubscriber
|
|
|
567
556
|
this.setPerpOracleMap();
|
|
568
557
|
}
|
|
569
558
|
|
|
570
|
-
return this.getOraclePriceDataAndSlot(
|
|
559
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
571
560
|
}
|
|
572
561
|
|
|
573
562
|
public getOraclePriceDataAndSlotForSpotMarket(
|
|
@@ -575,7 +564,6 @@ export class PollingDriftClientAccountSubscriber
|
|
|
575
564
|
): DataAndSlot<OraclePriceData> | undefined {
|
|
576
565
|
const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
|
|
577
566
|
const oracle = this.spotOracleMap.get(marketIndex);
|
|
578
|
-
const oracleString = this.spotOracleStringMap.get(marketIndex);
|
|
579
567
|
if (!spotMarketAccount || !oracle) {
|
|
580
568
|
return undefined;
|
|
581
569
|
}
|
|
@@ -585,7 +573,7 @@ export class PollingDriftClientAccountSubscriber
|
|
|
585
573
|
this.setSpotOracleMap();
|
|
586
574
|
}
|
|
587
575
|
|
|
588
|
-
return this.getOraclePriceDataAndSlot(
|
|
576
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
589
577
|
}
|
|
590
578
|
|
|
591
579
|
public updateAccountLoaderPollingFrequency(pollingFrequency: number): void {
|
package/src/accounts/types.ts
CHANGED
|
@@ -72,7 +72,7 @@ export interface DriftClientAccountSubscriber {
|
|
|
72
72
|
): DataAndSlot<SpotMarketAccount> | undefined;
|
|
73
73
|
getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
|
|
74
74
|
getOraclePriceDataAndSlot(
|
|
75
|
-
oraclePublicKey: PublicKey
|
|
75
|
+
oraclePublicKey: PublicKey
|
|
76
76
|
): DataAndSlot<OraclePriceData> | undefined;
|
|
77
77
|
getOraclePriceDataAndSlotForPerpMarket(
|
|
78
78
|
marketIndex: number
|
|
@@ -24,8 +24,6 @@ import * as Buffer from 'buffer';
|
|
|
24
24
|
import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
|
|
25
25
|
import { findAllMarketAndOracles } from '../config';
|
|
26
26
|
|
|
27
|
-
const ORACLE_DEFAULT_KEY = PublicKey.default.toBase58();
|
|
28
|
-
|
|
29
27
|
export class WebSocketDriftClientAccountSubscriber
|
|
30
28
|
implements DriftClientAccountSubscriber
|
|
31
29
|
{
|
|
@@ -47,13 +45,11 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
47
45
|
AccountSubscriber<PerpMarketAccount>
|
|
48
46
|
>();
|
|
49
47
|
perpOracleMap = new Map<number, PublicKey>();
|
|
50
|
-
perpOracleStringMap = new Map<number, string>();
|
|
51
48
|
spotMarketAccountSubscribers = new Map<
|
|
52
49
|
number,
|
|
53
50
|
AccountSubscriber<SpotMarketAccount>
|
|
54
51
|
>();
|
|
55
52
|
spotOracleMap = new Map<number, PublicKey>();
|
|
56
|
-
spotOracleStringMap = new Map<number, string>();
|
|
57
53
|
oracleSubscribers = new Map<string, AccountSubscriber<OraclePriceData>>();
|
|
58
54
|
|
|
59
55
|
initialPerpMarketAccountData: Map<number, PerpMarketAccount>;
|
|
@@ -436,7 +432,6 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
436
432
|
);
|
|
437
433
|
}
|
|
438
434
|
this.perpOracleMap.set(perpMarketIndex, oracle);
|
|
439
|
-
this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
|
|
440
435
|
}
|
|
441
436
|
await Promise.all(addOraclePromises);
|
|
442
437
|
}
|
|
@@ -460,7 +455,6 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
460
455
|
);
|
|
461
456
|
}
|
|
462
457
|
this.spotOracleMap.set(spotMarketIndex, oracle);
|
|
463
|
-
this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
|
|
464
458
|
}
|
|
465
459
|
await Promise.all(addOraclePromises);
|
|
466
460
|
}
|
|
@@ -505,20 +499,16 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
505
499
|
}
|
|
506
500
|
|
|
507
501
|
public getOraclePriceDataAndSlot(
|
|
508
|
-
oraclePublicKey: PublicKey
|
|
502
|
+
oraclePublicKey: PublicKey
|
|
509
503
|
): DataAndSlot<OraclePriceData> | undefined {
|
|
510
504
|
this.assertIsSubscribed();
|
|
511
|
-
|
|
512
|
-
typeof oraclePublicKey === 'string'
|
|
513
|
-
? oraclePublicKey
|
|
514
|
-
: oraclePublicKey.toBase58();
|
|
515
|
-
if (oracleString === ORACLE_DEFAULT_KEY) {
|
|
505
|
+
if (oraclePublicKey.equals(PublicKey.default)) {
|
|
516
506
|
return {
|
|
517
507
|
data: QUOTE_ORACLE_PRICE_DATA,
|
|
518
508
|
slot: 0,
|
|
519
509
|
};
|
|
520
510
|
}
|
|
521
|
-
return this.oracleSubscribers.get(
|
|
511
|
+
return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
|
|
522
512
|
}
|
|
523
513
|
|
|
524
514
|
public getOraclePriceDataAndSlotForPerpMarket(
|
|
@@ -526,7 +516,6 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
526
516
|
): DataAndSlot<OraclePriceData> | undefined {
|
|
527
517
|
const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
|
|
528
518
|
const oracle = this.perpOracleMap.get(marketIndex);
|
|
529
|
-
const oracleString = this.perpOracleStringMap.get(marketIndex);
|
|
530
519
|
if (!perpMarketAccount || !oracle) {
|
|
531
520
|
return undefined;
|
|
532
521
|
}
|
|
@@ -536,7 +525,7 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
536
525
|
this.setPerpOracleMap();
|
|
537
526
|
}
|
|
538
527
|
|
|
539
|
-
return this.getOraclePriceDataAndSlot(
|
|
528
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
540
529
|
}
|
|
541
530
|
|
|
542
531
|
public getOraclePriceDataAndSlotForSpotMarket(
|
|
@@ -544,7 +533,6 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
544
533
|
): DataAndSlot<OraclePriceData> | undefined {
|
|
545
534
|
const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
|
|
546
535
|
const oracle = this.spotOracleMap.get(marketIndex);
|
|
547
|
-
const oracleString = this.spotOracleStringMap.get(marketIndex);
|
|
548
536
|
if (!spotMarketAccount || !oracle) {
|
|
549
537
|
return undefined;
|
|
550
538
|
}
|
|
@@ -554,6 +542,6 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
554
542
|
this.setSpotOracleMap();
|
|
555
543
|
}
|
|
556
544
|
|
|
557
|
-
return this.getOraclePriceDataAndSlot(
|
|
545
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
558
546
|
}
|
|
559
547
|
}
|
package/src/driftClient.ts
CHANGED
|
@@ -538,9 +538,7 @@ export class DriftClient {
|
|
|
538
538
|
public getOraclePriceDataAndSlot(
|
|
539
539
|
oraclePublicKey: PublicKey
|
|
540
540
|
): DataAndSlot<OraclePriceData> | undefined {
|
|
541
|
-
return this.accountSubscriber.getOraclePriceDataAndSlot(
|
|
542
|
-
oraclePublicKey.toBase58()
|
|
543
|
-
);
|
|
541
|
+
return this.accountSubscriber.getOraclePriceDataAndSlot(oraclePublicKey);
|
|
544
542
|
}
|
|
545
543
|
|
|
546
544
|
public async getSerumV3FulfillmentConfig(
|
package/src/math/spotBalance.ts
CHANGED
|
@@ -379,9 +379,10 @@ export function calculateSpotMarketBorrowCapacity(
|
|
|
379
379
|
|
|
380
380
|
export function calculateInterestRate(
|
|
381
381
|
bank: SpotMarketAccount,
|
|
382
|
-
delta = ZERO
|
|
382
|
+
delta = ZERO,
|
|
383
|
+
currentUtilization: BN = null
|
|
383
384
|
): BN {
|
|
384
|
-
const utilization = calculateUtilization(bank, delta);
|
|
385
|
+
const utilization = currentUtilization || calculateUtilization(bank, delta);
|
|
385
386
|
let interestRate: BN;
|
|
386
387
|
if (utilization.gt(new BN(bank.optimalUtilization))) {
|
|
387
388
|
const surplusUtilization = utilization.sub(new BN(bank.optimalUtilization));
|
|
@@ -414,13 +415,14 @@ export function calculateInterestRate(
|
|
|
414
415
|
|
|
415
416
|
export function calculateDepositRate(
|
|
416
417
|
bank: SpotMarketAccount,
|
|
417
|
-
delta = ZERO
|
|
418
|
+
delta = ZERO,
|
|
419
|
+
currentUtilization: BN = null
|
|
418
420
|
): BN {
|
|
419
421
|
// positive delta => adding to deposit
|
|
420
422
|
// negative delta => adding to borrow
|
|
421
423
|
|
|
422
|
-
const utilization = calculateUtilization(bank, delta);
|
|
423
|
-
const borrowRate = calculateBorrowRate(bank, delta);
|
|
424
|
+
const utilization = currentUtilization || calculateUtilization(bank, delta);
|
|
425
|
+
const borrowRate = calculateBorrowRate(bank, delta, utilization);
|
|
424
426
|
const depositRate = borrowRate
|
|
425
427
|
.mul(PERCENTAGE_PRECISION.sub(new BN(bank.insuranceFund.totalFactor)))
|
|
426
428
|
.mul(utilization)
|
|
@@ -429,8 +431,12 @@ export function calculateDepositRate(
|
|
|
429
431
|
return depositRate;
|
|
430
432
|
}
|
|
431
433
|
|
|
432
|
-
export function calculateBorrowRate(
|
|
433
|
-
|
|
434
|
+
export function calculateBorrowRate(
|
|
435
|
+
bank: SpotMarketAccount,
|
|
436
|
+
delta = ZERO,
|
|
437
|
+
currentUtilization: BN = null
|
|
438
|
+
): BN {
|
|
439
|
+
return calculateInterestRate(bank, delta, currentUtilization);
|
|
434
440
|
}
|
|
435
441
|
|
|
436
442
|
export function calculateInterestAccumulated(
|