@drift-labs/sdk 2.38.1-beta.9 → 2.39.1-beta.1
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/driftClient.d.ts +22 -2
- package/lib/driftClient.js +95 -13
- package/lib/idl/drift.json +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/spotBalance.js +1 -1
- package/lib/tx/priorityFeeCalculator.d.ts +44 -0
- package/lib/tx/priorityFeeCalculator.js +85 -0
- package/lib/user.js +2 -2
- package/package.json +1 -1
- package/src/driftClient.ts +171 -13
- package/src/idl/drift.json +1 -1
- package/src/index.ts +1 -0
- package/src/math/spotBalance.ts +1 -1
- package/src/tx/priorityFeeCalculator.ts +117 -0
- package/src/user.ts +2 -2
- package/tests/tx/priorityFeeCalculator.ts +77 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.39.1-beta.1
|
package/lib/driftClient.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { DriftClientConfig } from './driftClientConfig';
|
|
|
13
13
|
import { User } from './user';
|
|
14
14
|
import { UserSubscriptionConfig } from './userConfig';
|
|
15
15
|
import { UserStats } from './userStats';
|
|
16
|
-
import { JupiterClient, Route, SwapMode } from './jupiter/jupiterClient';
|
|
16
|
+
import { JupiterClient, QuoteResponse, Route, SwapMode } from './jupiter/jupiterClient';
|
|
17
17
|
import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
18
18
|
type RemainingAccountParams = {
|
|
19
19
|
userAccounts: UserAccount[];
|
|
@@ -319,7 +319,7 @@ export declare class DriftClient {
|
|
|
319
319
|
* @param reduceOnly specify if In or Out token on the drift account must reduceOnly, checked at end of swap
|
|
320
320
|
* @param txParams
|
|
321
321
|
*/
|
|
322
|
-
swap({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, route, reduceOnly, txParams, }: {
|
|
322
|
+
swap({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, route, reduceOnly, txParams, v6, }: {
|
|
323
323
|
jupiterClient: JupiterClient;
|
|
324
324
|
outMarketIndex: number;
|
|
325
325
|
inMarketIndex: number;
|
|
@@ -331,6 +331,9 @@ export declare class DriftClient {
|
|
|
331
331
|
route?: Route;
|
|
332
332
|
reduceOnly?: SwapReduceOnly;
|
|
333
333
|
txParams?: TxParams;
|
|
334
|
+
v6?: {
|
|
335
|
+
quote?: QuoteResponse;
|
|
336
|
+
};
|
|
334
337
|
}): Promise<TransactionSignature>;
|
|
335
338
|
getJupiterSwapIx({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, route, reduceOnly, userAccountPublicKey, }: {
|
|
336
339
|
jupiterClient: JupiterClient;
|
|
@@ -349,6 +352,23 @@ export declare class DriftClient {
|
|
|
349
352
|
ixs: TransactionInstruction[];
|
|
350
353
|
lookupTables: AddressLookupTableAccount[];
|
|
351
354
|
}>;
|
|
355
|
+
getJupiterSwapIxV6({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, quote, reduceOnly, userAccountPublicKey, }: {
|
|
356
|
+
jupiterClient: JupiterClient;
|
|
357
|
+
outMarketIndex: number;
|
|
358
|
+
inMarketIndex: number;
|
|
359
|
+
outAssociatedTokenAccount?: PublicKey;
|
|
360
|
+
inAssociatedTokenAccount?: PublicKey;
|
|
361
|
+
amount: BN;
|
|
362
|
+
slippageBps?: number;
|
|
363
|
+
swapMode?: SwapMode;
|
|
364
|
+
onlyDirectRoutes?: boolean;
|
|
365
|
+
quote?: QuoteResponse;
|
|
366
|
+
reduceOnly?: SwapReduceOnly;
|
|
367
|
+
userAccountPublicKey?: PublicKey;
|
|
368
|
+
}): Promise<{
|
|
369
|
+
ixs: TransactionInstruction[];
|
|
370
|
+
lookupTables: AddressLookupTableAccount[];
|
|
371
|
+
}>;
|
|
352
372
|
/**
|
|
353
373
|
* Get the drift begin_swap and end_swap instructions
|
|
354
374
|
*
|
package/lib/driftClient.js
CHANGED
|
@@ -1975,19 +1975,41 @@ class DriftClient {
|
|
|
1975
1975
|
* @param reduceOnly specify if In or Out token on the drift account must reduceOnly, checked at end of swap
|
|
1976
1976
|
* @param txParams
|
|
1977
1977
|
*/
|
|
1978
|
-
async swap({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, route, reduceOnly, txParams, }) {
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1978
|
+
async swap({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, route, reduceOnly, txParams, v6, }) {
|
|
1979
|
+
let ixs;
|
|
1980
|
+
let lookupTables;
|
|
1981
|
+
if (v6) {
|
|
1982
|
+
const res = await this.getJupiterSwapIxV6({
|
|
1983
|
+
jupiterClient,
|
|
1984
|
+
outMarketIndex,
|
|
1985
|
+
inMarketIndex,
|
|
1986
|
+
outAssociatedTokenAccount,
|
|
1987
|
+
inAssociatedTokenAccount,
|
|
1988
|
+
amount,
|
|
1989
|
+
slippageBps,
|
|
1990
|
+
swapMode,
|
|
1991
|
+
quote: v6.quote,
|
|
1992
|
+
reduceOnly,
|
|
1993
|
+
});
|
|
1994
|
+
ixs = res.ixs;
|
|
1995
|
+
lookupTables = res.lookupTables;
|
|
1996
|
+
}
|
|
1997
|
+
else {
|
|
1998
|
+
const res = await this.getJupiterSwapIx({
|
|
1999
|
+
jupiterClient,
|
|
2000
|
+
outMarketIndex,
|
|
2001
|
+
inMarketIndex,
|
|
2002
|
+
outAssociatedTokenAccount,
|
|
2003
|
+
inAssociatedTokenAccount,
|
|
2004
|
+
amount,
|
|
2005
|
+
slippageBps,
|
|
2006
|
+
swapMode,
|
|
2007
|
+
route,
|
|
2008
|
+
reduceOnly,
|
|
2009
|
+
});
|
|
2010
|
+
ixs = res.ixs;
|
|
2011
|
+
lookupTables = res.lookupTables;
|
|
2012
|
+
}
|
|
1991
2013
|
const tx = (await this.buildTransaction(ixs, txParams, 0, lookupTables));
|
|
1992
2014
|
const { txSig, slot } = await this.sendTransaction(tx);
|
|
1993
2015
|
this.spotMarketLastSlotCache.set(outMarketIndex, slot);
|
|
@@ -2056,6 +2078,65 @@ class DriftClient {
|
|
|
2056
2078
|
];
|
|
2057
2079
|
return { ixs, lookupTables };
|
|
2058
2080
|
}
|
|
2081
|
+
async getJupiterSwapIxV6({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, quote, reduceOnly, userAccountPublicKey, }) {
|
|
2082
|
+
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
2083
|
+
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
2084
|
+
if (!quote) {
|
|
2085
|
+
const fetchedQuote = await jupiterClient.getQuote({
|
|
2086
|
+
inputMint: inMarket.mint,
|
|
2087
|
+
outputMint: outMarket.mint,
|
|
2088
|
+
amount,
|
|
2089
|
+
slippageBps,
|
|
2090
|
+
swapMode,
|
|
2091
|
+
onlyDirectRoutes,
|
|
2092
|
+
});
|
|
2093
|
+
quote = fetchedQuote;
|
|
2094
|
+
}
|
|
2095
|
+
const transaction = await jupiterClient.getSwap({
|
|
2096
|
+
quote,
|
|
2097
|
+
userPublicKey: this.provider.wallet.publicKey,
|
|
2098
|
+
slippageBps,
|
|
2099
|
+
});
|
|
2100
|
+
const { transactionMessage, lookupTables } = await jupiterClient.getTransactionMessageAndLookupTables({
|
|
2101
|
+
transaction,
|
|
2102
|
+
});
|
|
2103
|
+
const jupiterInstructions = jupiterClient.getJupiterInstructions({
|
|
2104
|
+
transactionMessage,
|
|
2105
|
+
inputMint: inMarket.mint,
|
|
2106
|
+
outputMint: outMarket.mint,
|
|
2107
|
+
});
|
|
2108
|
+
const preInstructions = [];
|
|
2109
|
+
if (!outAssociatedTokenAccount) {
|
|
2110
|
+
outAssociatedTokenAccount = await this.getAssociatedTokenAccount(outMarket.marketIndex, false);
|
|
2111
|
+
const accountInfo = await this.connection.getAccountInfo(outAssociatedTokenAccount);
|
|
2112
|
+
if (!accountInfo) {
|
|
2113
|
+
preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(outAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, outMarket.mint));
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
if (!inAssociatedTokenAccount) {
|
|
2117
|
+
inAssociatedTokenAccount = await this.getAssociatedTokenAccount(inMarket.marketIndex, false);
|
|
2118
|
+
const accountInfo = await this.connection.getAccountInfo(inAssociatedTokenAccount);
|
|
2119
|
+
if (!accountInfo) {
|
|
2120
|
+
preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(inAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, inMarket.mint));
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
2124
|
+
outMarketIndex,
|
|
2125
|
+
inMarketIndex,
|
|
2126
|
+
amountIn: amount,
|
|
2127
|
+
inTokenAccount: inAssociatedTokenAccount,
|
|
2128
|
+
outTokenAccount: outAssociatedTokenAccount,
|
|
2129
|
+
reduceOnly,
|
|
2130
|
+
userAccountPublicKey,
|
|
2131
|
+
});
|
|
2132
|
+
const ixs = [
|
|
2133
|
+
...preInstructions,
|
|
2134
|
+
beginSwapIx,
|
|
2135
|
+
...jupiterInstructions,
|
|
2136
|
+
endSwapIx,
|
|
2137
|
+
];
|
|
2138
|
+
return { ixs, lookupTables };
|
|
2139
|
+
}
|
|
2059
2140
|
/**
|
|
2060
2141
|
* Get the drift begin_swap and end_swap instructions
|
|
2061
2142
|
*
|
|
@@ -2077,6 +2158,7 @@ class DriftClient {
|
|
|
2077
2158
|
const remainingAccounts = this.getRemainingAccounts({
|
|
2078
2159
|
userAccounts,
|
|
2079
2160
|
writableSpotMarketIndexes: [outMarketIndex, inMarketIndex],
|
|
2161
|
+
readableSpotMarketIndexes: [numericConstants_1.QUOTE_SPOT_MARKET_INDEX],
|
|
2080
2162
|
});
|
|
2081
2163
|
const outSpotMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
2082
2164
|
const inSpotMarket = this.getSpotMarketAccount(inMarketIndex);
|
package/lib/idl/drift.json
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -65,6 +65,7 @@ export * from './priorityFee/priorityFeeSubscriber';
|
|
|
65
65
|
export * from './phoenix/phoenixFulfillmentConfigMap';
|
|
66
66
|
export * from './tx/fastSingleTxSender';
|
|
67
67
|
export * from './tx/retryTxSender';
|
|
68
|
+
export * from './tx/priorityFeeCalculator';
|
|
68
69
|
export * from './tx/types';
|
|
69
70
|
export * from './util/computeUnits';
|
|
70
71
|
export * from './util/tps';
|
package/lib/index.js
CHANGED
|
@@ -88,6 +88,7 @@ __exportStar(require("./priorityFee/priorityFeeSubscriber"), exports);
|
|
|
88
88
|
__exportStar(require("./phoenix/phoenixFulfillmentConfigMap"), exports);
|
|
89
89
|
__exportStar(require("./tx/fastSingleTxSender"), exports);
|
|
90
90
|
__exportStar(require("./tx/retryTxSender"), exports);
|
|
91
|
+
__exportStar(require("./tx/priorityFeeCalculator"), exports);
|
|
91
92
|
__exportStar(require("./tx/types"), exports);
|
|
92
93
|
__exportStar(require("./util/computeUnits"), exports);
|
|
93
94
|
__exportStar(require("./util/tps"), exports);
|
package/lib/math/spotBalance.js
CHANGED
|
@@ -167,7 +167,7 @@ function calculateLiabilityWeight(size, spotMarket, marginCategory) {
|
|
|
167
167
|
liabilityWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.maintenanceLiabilityWeight), numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
168
168
|
break;
|
|
169
169
|
default:
|
|
170
|
-
liabilityWeight = spotMarket.initialLiabilityWeight;
|
|
170
|
+
liabilityWeight = new anchor_1.BN(spotMarket.initialLiabilityWeight);
|
|
171
171
|
break;
|
|
172
172
|
}
|
|
173
173
|
return liabilityWeight;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { TransactionInstruction } from '@solana/web3.js';
|
|
2
|
+
/**
|
|
3
|
+
* This class determines whether a priority fee needs to be included in a transaction based on
|
|
4
|
+
* a recent history of timed out transactions.
|
|
5
|
+
*/
|
|
6
|
+
export declare class PriorityFeeCalculator {
|
|
7
|
+
lastTxTimeoutCount: number;
|
|
8
|
+
priorityFeeTriggered: boolean;
|
|
9
|
+
lastTxTimeoutCountTriggered: number;
|
|
10
|
+
priorityFeeLatchDurationMs: number;
|
|
11
|
+
/**
|
|
12
|
+
* Constructor for the PriorityFeeCalculator class.
|
|
13
|
+
* @param currentTimeMs - The current time in milliseconds.
|
|
14
|
+
* @param priorityFeeLatchDurationMs - The duration for how long to stay in triggered state before resetting. Default value is 10 seconds.
|
|
15
|
+
*/
|
|
16
|
+
constructor(currentTimeMs: number, priorityFeeLatchDurationMs?: number);
|
|
17
|
+
/**
|
|
18
|
+
* Update the priority fee state based on the current time and the current timeout count.
|
|
19
|
+
* @param currentTimeMs current time in milliseconds
|
|
20
|
+
* @returns true if priority fee should be included in the next transaction
|
|
21
|
+
*/
|
|
22
|
+
updatePriorityFee(currentTimeMs: number, txTimeoutCount: number): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* This method returns a transaction instruction list that sets the compute limit on the ComputeBudget program.
|
|
25
|
+
* @param computeUnitLimit - The maximum number of compute units that can be used by the transaction.
|
|
26
|
+
* @returns An array of transaction instructions.
|
|
27
|
+
*/
|
|
28
|
+
generateComputeBudgetIxs(computeUnitLimit: number): Array<TransactionInstruction>;
|
|
29
|
+
/**
|
|
30
|
+
* Calculates the compute unit price to use based on the desired additional fee to pay and the compute unit limit.
|
|
31
|
+
* @param computeUnitLimit desired CU to use
|
|
32
|
+
* @param additionalFeeMicroLamports desired additional fee to pay, in micro lamports
|
|
33
|
+
* @returns the compute unit price to use, in micro lamports
|
|
34
|
+
*/
|
|
35
|
+
calculateComputeUnitPrice(computeUnitLimit: number, additionalFeeMicroLamports: number): number;
|
|
36
|
+
/**
|
|
37
|
+
* This method generates a list of transaction instructions for the ComputeBudget program, and includes a priority fee if it's required
|
|
38
|
+
* @param computeUnitLimit - The maximum number of compute units that can be used by the transaction.
|
|
39
|
+
* @param usePriorityFee - A boolean indicating whether to include a priority fee in the transaction, this should be from `this.updatePriorityFee()` or `this.priorityFeeTriggered()`.
|
|
40
|
+
* @param additionalFeeMicroLamports - The additional fee to be paid, in micro lamports, the actual price will be calculated.
|
|
41
|
+
* @returns An array of transaction instructions.
|
|
42
|
+
*/
|
|
43
|
+
generateComputeBudgetWithPriorityFeeIx(computeUnitLimit: number, usePriorityFee: boolean, additionalFeeMicroLamports: number): Array<TransactionInstruction>;
|
|
44
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PriorityFeeCalculator = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
/**
|
|
6
|
+
* This class determines whether a priority fee needs to be included in a transaction based on
|
|
7
|
+
* a recent history of timed out transactions.
|
|
8
|
+
*/
|
|
9
|
+
class PriorityFeeCalculator {
|
|
10
|
+
/**
|
|
11
|
+
* Constructor for the PriorityFeeCalculator class.
|
|
12
|
+
* @param currentTimeMs - The current time in milliseconds.
|
|
13
|
+
* @param priorityFeeLatchDurationMs - The duration for how long to stay in triggered state before resetting. Default value is 10 seconds.
|
|
14
|
+
*/
|
|
15
|
+
constructor(currentTimeMs, priorityFeeLatchDurationMs = 10 * 1000) {
|
|
16
|
+
this.lastTxTimeoutCount = 0;
|
|
17
|
+
this.priorityFeeTriggered = false;
|
|
18
|
+
this.lastTxTimeoutCountTriggered = currentTimeMs;
|
|
19
|
+
this.priorityFeeLatchDurationMs = priorityFeeLatchDurationMs;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Update the priority fee state based on the current time and the current timeout count.
|
|
23
|
+
* @param currentTimeMs current time in milliseconds
|
|
24
|
+
* @returns true if priority fee should be included in the next transaction
|
|
25
|
+
*/
|
|
26
|
+
updatePriorityFee(currentTimeMs, txTimeoutCount) {
|
|
27
|
+
let triggerPriorityFee = false;
|
|
28
|
+
if (txTimeoutCount > this.lastTxTimeoutCount) {
|
|
29
|
+
this.lastTxTimeoutCount = txTimeoutCount;
|
|
30
|
+
this.lastTxTimeoutCountTriggered = currentTimeMs;
|
|
31
|
+
triggerPriorityFee = true;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
if (!this.priorityFeeTriggered) {
|
|
35
|
+
triggerPriorityFee = false;
|
|
36
|
+
}
|
|
37
|
+
else if (currentTimeMs - this.lastTxTimeoutCountTriggered <
|
|
38
|
+
this.priorityFeeLatchDurationMs) {
|
|
39
|
+
triggerPriorityFee = true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
this.priorityFeeTriggered = triggerPriorityFee;
|
|
43
|
+
return triggerPriorityFee;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* This method returns a transaction instruction list that sets the compute limit on the ComputeBudget program.
|
|
47
|
+
* @param computeUnitLimit - The maximum number of compute units that can be used by the transaction.
|
|
48
|
+
* @returns An array of transaction instructions.
|
|
49
|
+
*/
|
|
50
|
+
generateComputeBudgetIxs(computeUnitLimit) {
|
|
51
|
+
const ixs = [
|
|
52
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
53
|
+
units: computeUnitLimit,
|
|
54
|
+
}),
|
|
55
|
+
];
|
|
56
|
+
return ixs;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Calculates the compute unit price to use based on the desired additional fee to pay and the compute unit limit.
|
|
60
|
+
* @param computeUnitLimit desired CU to use
|
|
61
|
+
* @param additionalFeeMicroLamports desired additional fee to pay, in micro lamports
|
|
62
|
+
* @returns the compute unit price to use, in micro lamports
|
|
63
|
+
*/
|
|
64
|
+
calculateComputeUnitPrice(computeUnitLimit, additionalFeeMicroLamports) {
|
|
65
|
+
return additionalFeeMicroLamports / computeUnitLimit;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* This method generates a list of transaction instructions for the ComputeBudget program, and includes a priority fee if it's required
|
|
69
|
+
* @param computeUnitLimit - The maximum number of compute units that can be used by the transaction.
|
|
70
|
+
* @param usePriorityFee - A boolean indicating whether to include a priority fee in the transaction, this should be from `this.updatePriorityFee()` or `this.priorityFeeTriggered()`.
|
|
71
|
+
* @param additionalFeeMicroLamports - The additional fee to be paid, in micro lamports, the actual price will be calculated.
|
|
72
|
+
* @returns An array of transaction instructions.
|
|
73
|
+
*/
|
|
74
|
+
generateComputeBudgetWithPriorityFeeIx(computeUnitLimit, usePriorityFee, additionalFeeMicroLamports) {
|
|
75
|
+
const ixs = this.generateComputeBudgetIxs(computeUnitLimit);
|
|
76
|
+
if (usePriorityFee) {
|
|
77
|
+
const computeUnitPrice = this.calculateComputeUnitPrice(computeUnitLimit, additionalFeeMicroLamports);
|
|
78
|
+
ixs.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
|
|
79
|
+
microLamports: computeUnitPrice,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
return ixs;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.PriorityFeeCalculator = PriorityFeeCalculator;
|
package/lib/user.js
CHANGED
|
@@ -577,7 +577,7 @@ class User {
|
|
|
577
577
|
continue;
|
|
578
578
|
}
|
|
579
579
|
}
|
|
580
|
-
const { tokenAmount: worstCaseTokenAmount, ordersValue: worstCaseQuoteTokenAmount, } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory);
|
|
580
|
+
const { tokenAmount: worstCaseTokenAmount, ordersValue: worstCaseQuoteTokenAmount, } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory !== null && marginCategory !== void 0 ? marginCategory : 'Initial');
|
|
581
581
|
if (worstCaseTokenAmount.gt(numericConstants_1.ZERO) && countForBase) {
|
|
582
582
|
const baseAssetValue = this.getSpotAssetValue(worstCaseTokenAmount, strictOraclePrice, spotMarketAccount, marginCategory);
|
|
583
583
|
totalAssetValue = totalAssetValue.add(baseAssetValue);
|
|
@@ -1834,7 +1834,7 @@ class User {
|
|
|
1834
1834
|
const spotMarketAccount = this.driftClient.getQuoteSpotMarketAccount();
|
|
1835
1835
|
const oraclePriceData = this.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
|
|
1836
1836
|
const baseAssetValue = (0, _1.getTokenValue)(netQuoteValue, spotMarketAccount.decimals, oraclePriceData);
|
|
1837
|
-
const { weight, weightedTokenValue } = (0, spotPosition_1.calculateWeightedTokenValue)(netQuoteValue, baseAssetValue, oraclePriceData, spotMarketAccount, marginCategory);
|
|
1837
|
+
const { weight, weightedTokenValue } = (0, spotPosition_1.calculateWeightedTokenValue)(netQuoteValue, baseAssetValue, oraclePriceData.price, spotMarketAccount, marginCategory);
|
|
1838
1838
|
if (netQuoteValue.lt(numericConstants_1.ZERO)) {
|
|
1839
1839
|
healthComponents.borrows.push({
|
|
1840
1840
|
marketIndex: spotMarketAccount.marketIndex,
|
package/package.json
CHANGED
package/src/driftClient.ts
CHANGED
|
@@ -113,7 +113,12 @@ import { isSpotPositionAvailable } from './math/spotPosition';
|
|
|
113
113
|
import { calculateMarketMaxAvailableInsurance } from './math/market';
|
|
114
114
|
import { fetchUserStatsAccount } from './accounts/fetch';
|
|
115
115
|
import { castNumberToSpotPrecision } from './math/spotMarket';
|
|
116
|
-
import {
|
|
116
|
+
import {
|
|
117
|
+
JupiterClient,
|
|
118
|
+
QuoteResponse,
|
|
119
|
+
Route,
|
|
120
|
+
SwapMode,
|
|
121
|
+
} from './jupiter/jupiterClient';
|
|
117
122
|
import { getNonIdleUserFilter } from './memcmp';
|
|
118
123
|
import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
119
124
|
import { getMarinadeDepositIx, getMarinadeFinanceProgram } from './marinade';
|
|
@@ -3418,6 +3423,7 @@ export class DriftClient {
|
|
|
3418
3423
|
route,
|
|
3419
3424
|
reduceOnly,
|
|
3420
3425
|
txParams,
|
|
3426
|
+
v6,
|
|
3421
3427
|
}: {
|
|
3422
3428
|
jupiterClient: JupiterClient;
|
|
3423
3429
|
outMarketIndex: number;
|
|
@@ -3430,19 +3436,44 @@ export class DriftClient {
|
|
|
3430
3436
|
route?: Route;
|
|
3431
3437
|
reduceOnly?: SwapReduceOnly;
|
|
3432
3438
|
txParams?: TxParams;
|
|
3439
|
+
v6?: {
|
|
3440
|
+
quote?: QuoteResponse;
|
|
3441
|
+
};
|
|
3433
3442
|
}): Promise<TransactionSignature> {
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3443
|
+
let ixs: anchor.web3.TransactionInstruction[];
|
|
3444
|
+
let lookupTables: anchor.web3.AddressLookupTableAccount[];
|
|
3445
|
+
|
|
3446
|
+
if (v6) {
|
|
3447
|
+
const res = await this.getJupiterSwapIxV6({
|
|
3448
|
+
jupiterClient,
|
|
3449
|
+
outMarketIndex,
|
|
3450
|
+
inMarketIndex,
|
|
3451
|
+
outAssociatedTokenAccount,
|
|
3452
|
+
inAssociatedTokenAccount,
|
|
3453
|
+
amount,
|
|
3454
|
+
slippageBps,
|
|
3455
|
+
swapMode,
|
|
3456
|
+
quote: v6.quote,
|
|
3457
|
+
reduceOnly,
|
|
3458
|
+
});
|
|
3459
|
+
ixs = res.ixs;
|
|
3460
|
+
lookupTables = res.lookupTables;
|
|
3461
|
+
} else {
|
|
3462
|
+
const res = await this.getJupiterSwapIx({
|
|
3463
|
+
jupiterClient,
|
|
3464
|
+
outMarketIndex,
|
|
3465
|
+
inMarketIndex,
|
|
3466
|
+
outAssociatedTokenAccount,
|
|
3467
|
+
inAssociatedTokenAccount,
|
|
3468
|
+
amount,
|
|
3469
|
+
slippageBps,
|
|
3470
|
+
swapMode,
|
|
3471
|
+
route,
|
|
3472
|
+
reduceOnly,
|
|
3473
|
+
});
|
|
3474
|
+
ixs = res.ixs;
|
|
3475
|
+
lookupTables = res.lookupTables;
|
|
3476
|
+
}
|
|
3446
3477
|
|
|
3447
3478
|
const tx = (await this.buildTransaction(
|
|
3448
3479
|
ixs,
|
|
@@ -3588,6 +3619,132 @@ export class DriftClient {
|
|
|
3588
3619
|
return { ixs, lookupTables };
|
|
3589
3620
|
}
|
|
3590
3621
|
|
|
3622
|
+
public async getJupiterSwapIxV6({
|
|
3623
|
+
jupiterClient,
|
|
3624
|
+
outMarketIndex,
|
|
3625
|
+
inMarketIndex,
|
|
3626
|
+
outAssociatedTokenAccount,
|
|
3627
|
+
inAssociatedTokenAccount,
|
|
3628
|
+
amount,
|
|
3629
|
+
slippageBps,
|
|
3630
|
+
swapMode,
|
|
3631
|
+
onlyDirectRoutes,
|
|
3632
|
+
quote,
|
|
3633
|
+
reduceOnly,
|
|
3634
|
+
userAccountPublicKey,
|
|
3635
|
+
}: {
|
|
3636
|
+
jupiterClient: JupiterClient;
|
|
3637
|
+
outMarketIndex: number;
|
|
3638
|
+
inMarketIndex: number;
|
|
3639
|
+
outAssociatedTokenAccount?: PublicKey;
|
|
3640
|
+
inAssociatedTokenAccount?: PublicKey;
|
|
3641
|
+
amount: BN;
|
|
3642
|
+
slippageBps?: number;
|
|
3643
|
+
swapMode?: SwapMode;
|
|
3644
|
+
onlyDirectRoutes?: boolean;
|
|
3645
|
+
quote?: QuoteResponse;
|
|
3646
|
+
reduceOnly?: SwapReduceOnly;
|
|
3647
|
+
userAccountPublicKey?: PublicKey;
|
|
3648
|
+
}): Promise<{
|
|
3649
|
+
ixs: TransactionInstruction[];
|
|
3650
|
+
lookupTables: AddressLookupTableAccount[];
|
|
3651
|
+
}> {
|
|
3652
|
+
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
3653
|
+
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
3654
|
+
|
|
3655
|
+
if (!quote) {
|
|
3656
|
+
const fetchedQuote = await jupiterClient.getQuote({
|
|
3657
|
+
inputMint: inMarket.mint,
|
|
3658
|
+
outputMint: outMarket.mint,
|
|
3659
|
+
amount,
|
|
3660
|
+
slippageBps,
|
|
3661
|
+
swapMode,
|
|
3662
|
+
onlyDirectRoutes,
|
|
3663
|
+
});
|
|
3664
|
+
|
|
3665
|
+
quote = fetchedQuote;
|
|
3666
|
+
}
|
|
3667
|
+
|
|
3668
|
+
const transaction = await jupiterClient.getSwap({
|
|
3669
|
+
quote,
|
|
3670
|
+
userPublicKey: this.provider.wallet.publicKey,
|
|
3671
|
+
slippageBps,
|
|
3672
|
+
});
|
|
3673
|
+
|
|
3674
|
+
const { transactionMessage, lookupTables } =
|
|
3675
|
+
await jupiterClient.getTransactionMessageAndLookupTables({
|
|
3676
|
+
transaction,
|
|
3677
|
+
});
|
|
3678
|
+
|
|
3679
|
+
const jupiterInstructions = jupiterClient.getJupiterInstructions({
|
|
3680
|
+
transactionMessage,
|
|
3681
|
+
inputMint: inMarket.mint,
|
|
3682
|
+
outputMint: outMarket.mint,
|
|
3683
|
+
});
|
|
3684
|
+
|
|
3685
|
+
const preInstructions = [];
|
|
3686
|
+
if (!outAssociatedTokenAccount) {
|
|
3687
|
+
outAssociatedTokenAccount = await this.getAssociatedTokenAccount(
|
|
3688
|
+
outMarket.marketIndex,
|
|
3689
|
+
false
|
|
3690
|
+
);
|
|
3691
|
+
|
|
3692
|
+
const accountInfo = await this.connection.getAccountInfo(
|
|
3693
|
+
outAssociatedTokenAccount
|
|
3694
|
+
);
|
|
3695
|
+
if (!accountInfo) {
|
|
3696
|
+
preInstructions.push(
|
|
3697
|
+
this.createAssociatedTokenAccountIdempotentInstruction(
|
|
3698
|
+
outAssociatedTokenAccount,
|
|
3699
|
+
this.provider.wallet.publicKey,
|
|
3700
|
+
this.provider.wallet.publicKey,
|
|
3701
|
+
outMarket.mint
|
|
3702
|
+
)
|
|
3703
|
+
);
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3707
|
+
if (!inAssociatedTokenAccount) {
|
|
3708
|
+
inAssociatedTokenAccount = await this.getAssociatedTokenAccount(
|
|
3709
|
+
inMarket.marketIndex,
|
|
3710
|
+
false
|
|
3711
|
+
);
|
|
3712
|
+
|
|
3713
|
+
const accountInfo = await this.connection.getAccountInfo(
|
|
3714
|
+
inAssociatedTokenAccount
|
|
3715
|
+
);
|
|
3716
|
+
if (!accountInfo) {
|
|
3717
|
+
preInstructions.push(
|
|
3718
|
+
this.createAssociatedTokenAccountIdempotentInstruction(
|
|
3719
|
+
inAssociatedTokenAccount,
|
|
3720
|
+
this.provider.wallet.publicKey,
|
|
3721
|
+
this.provider.wallet.publicKey,
|
|
3722
|
+
inMarket.mint
|
|
3723
|
+
)
|
|
3724
|
+
);
|
|
3725
|
+
}
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
3729
|
+
outMarketIndex,
|
|
3730
|
+
inMarketIndex,
|
|
3731
|
+
amountIn: amount,
|
|
3732
|
+
inTokenAccount: inAssociatedTokenAccount,
|
|
3733
|
+
outTokenAccount: outAssociatedTokenAccount,
|
|
3734
|
+
reduceOnly,
|
|
3735
|
+
userAccountPublicKey,
|
|
3736
|
+
});
|
|
3737
|
+
|
|
3738
|
+
const ixs = [
|
|
3739
|
+
...preInstructions,
|
|
3740
|
+
beginSwapIx,
|
|
3741
|
+
...jupiterInstructions,
|
|
3742
|
+
endSwapIx,
|
|
3743
|
+
];
|
|
3744
|
+
|
|
3745
|
+
return { ixs, lookupTables };
|
|
3746
|
+
}
|
|
3747
|
+
|
|
3591
3748
|
/**
|
|
3592
3749
|
* Get the drift begin_swap and end_swap instructions
|
|
3593
3750
|
*
|
|
@@ -3632,6 +3789,7 @@ export class DriftClient {
|
|
|
3632
3789
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3633
3790
|
userAccounts,
|
|
3634
3791
|
writableSpotMarketIndexes: [outMarketIndex, inMarketIndex],
|
|
3792
|
+
readableSpotMarketIndexes: [QUOTE_SPOT_MARKET_INDEX],
|
|
3635
3793
|
});
|
|
3636
3794
|
|
|
3637
3795
|
const outSpotMarket = this.getSpotMarketAccount(outMarketIndex);
|
package/src/idl/drift.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -66,6 +66,7 @@ export * from './priorityFee/priorityFeeSubscriber';
|
|
|
66
66
|
export * from './phoenix/phoenixFulfillmentConfigMap';
|
|
67
67
|
export * from './tx/fastSingleTxSender';
|
|
68
68
|
export * from './tx/retryTxSender';
|
|
69
|
+
export * from './tx/priorityFeeCalculator';
|
|
69
70
|
export * from './tx/types';
|
|
70
71
|
export * from './util/computeUnits';
|
|
71
72
|
export * from './util/tps';
|
package/src/math/spotBalance.ts
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { ComputeBudgetProgram, TransactionInstruction } from '@solana/web3.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This class determines whether a priority fee needs to be included in a transaction based on
|
|
5
|
+
* a recent history of timed out transactions.
|
|
6
|
+
*/
|
|
7
|
+
export class PriorityFeeCalculator {
|
|
8
|
+
lastTxTimeoutCount: number;
|
|
9
|
+
priorityFeeTriggered: boolean;
|
|
10
|
+
lastTxTimeoutCountTriggered: number;
|
|
11
|
+
priorityFeeLatchDurationMs: number; // how long to stay in triggered state before resetting
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Constructor for the PriorityFeeCalculator class.
|
|
15
|
+
* @param currentTimeMs - The current time in milliseconds.
|
|
16
|
+
* @param priorityFeeLatchDurationMs - The duration for how long to stay in triggered state before resetting. Default value is 10 seconds.
|
|
17
|
+
*/
|
|
18
|
+
constructor(
|
|
19
|
+
currentTimeMs: number,
|
|
20
|
+
priorityFeeLatchDurationMs: number = 10 * 1000
|
|
21
|
+
) {
|
|
22
|
+
this.lastTxTimeoutCount = 0;
|
|
23
|
+
this.priorityFeeTriggered = false;
|
|
24
|
+
this.lastTxTimeoutCountTriggered = currentTimeMs;
|
|
25
|
+
this.priorityFeeLatchDurationMs = priorityFeeLatchDurationMs;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Update the priority fee state based on the current time and the current timeout count.
|
|
30
|
+
* @param currentTimeMs current time in milliseconds
|
|
31
|
+
* @returns true if priority fee should be included in the next transaction
|
|
32
|
+
*/
|
|
33
|
+
public updatePriorityFee(
|
|
34
|
+
currentTimeMs: number,
|
|
35
|
+
txTimeoutCount: number
|
|
36
|
+
): boolean {
|
|
37
|
+
let triggerPriorityFee = false;
|
|
38
|
+
|
|
39
|
+
if (txTimeoutCount > this.lastTxTimeoutCount) {
|
|
40
|
+
this.lastTxTimeoutCount = txTimeoutCount;
|
|
41
|
+
this.lastTxTimeoutCountTriggered = currentTimeMs;
|
|
42
|
+
triggerPriorityFee = true;
|
|
43
|
+
} else {
|
|
44
|
+
if (!this.priorityFeeTriggered) {
|
|
45
|
+
triggerPriorityFee = false;
|
|
46
|
+
} else if (
|
|
47
|
+
currentTimeMs - this.lastTxTimeoutCountTriggered <
|
|
48
|
+
this.priorityFeeLatchDurationMs
|
|
49
|
+
) {
|
|
50
|
+
triggerPriorityFee = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.priorityFeeTriggered = triggerPriorityFee;
|
|
55
|
+
|
|
56
|
+
return triggerPriorityFee;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* This method returns a transaction instruction list that sets the compute limit on the ComputeBudget program.
|
|
61
|
+
* @param computeUnitLimit - The maximum number of compute units that can be used by the transaction.
|
|
62
|
+
* @returns An array of transaction instructions.
|
|
63
|
+
*/
|
|
64
|
+
public generateComputeBudgetIxs(
|
|
65
|
+
computeUnitLimit: number
|
|
66
|
+
): Array<TransactionInstruction> {
|
|
67
|
+
const ixs = [
|
|
68
|
+
ComputeBudgetProgram.setComputeUnitLimit({
|
|
69
|
+
units: computeUnitLimit,
|
|
70
|
+
}),
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
return ixs;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Calculates the compute unit price to use based on the desired additional fee to pay and the compute unit limit.
|
|
78
|
+
* @param computeUnitLimit desired CU to use
|
|
79
|
+
* @param additionalFeeMicroLamports desired additional fee to pay, in micro lamports
|
|
80
|
+
* @returns the compute unit price to use, in micro lamports
|
|
81
|
+
*/
|
|
82
|
+
public calculateComputeUnitPrice(
|
|
83
|
+
computeUnitLimit: number,
|
|
84
|
+
additionalFeeMicroLamports: number
|
|
85
|
+
): number {
|
|
86
|
+
return additionalFeeMicroLamports / computeUnitLimit;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* This method generates a list of transaction instructions for the ComputeBudget program, and includes a priority fee if it's required
|
|
91
|
+
* @param computeUnitLimit - The maximum number of compute units that can be used by the transaction.
|
|
92
|
+
* @param usePriorityFee - A boolean indicating whether to include a priority fee in the transaction, this should be from `this.updatePriorityFee()` or `this.priorityFeeTriggered()`.
|
|
93
|
+
* @param additionalFeeMicroLamports - The additional fee to be paid, in micro lamports, the actual price will be calculated.
|
|
94
|
+
* @returns An array of transaction instructions.
|
|
95
|
+
*/
|
|
96
|
+
public generateComputeBudgetWithPriorityFeeIx(
|
|
97
|
+
computeUnitLimit: number,
|
|
98
|
+
usePriorityFee: boolean,
|
|
99
|
+
additionalFeeMicroLamports: number
|
|
100
|
+
): Array<TransactionInstruction> {
|
|
101
|
+
const ixs = this.generateComputeBudgetIxs(computeUnitLimit);
|
|
102
|
+
|
|
103
|
+
if (usePriorityFee) {
|
|
104
|
+
const computeUnitPrice = this.calculateComputeUnitPrice(
|
|
105
|
+
computeUnitLimit,
|
|
106
|
+
additionalFeeMicroLamports
|
|
107
|
+
);
|
|
108
|
+
ixs.push(
|
|
109
|
+
ComputeBudgetProgram.setComputeUnitPrice({
|
|
110
|
+
microLamports: computeUnitPrice,
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return ixs;
|
|
116
|
+
}
|
|
117
|
+
}
|
package/src/user.ts
CHANGED
|
@@ -967,7 +967,7 @@ export class User {
|
|
|
967
967
|
spotPosition,
|
|
968
968
|
spotMarketAccount,
|
|
969
969
|
strictOraclePrice,
|
|
970
|
-
marginCategory
|
|
970
|
+
marginCategory ?? 'Initial'
|
|
971
971
|
);
|
|
972
972
|
|
|
973
973
|
if (worstCaseTokenAmount.gt(ZERO) && countForBase) {
|
|
@@ -3320,7 +3320,7 @@ export class User {
|
|
|
3320
3320
|
const { weight, weightedTokenValue } = calculateWeightedTokenValue(
|
|
3321
3321
|
netQuoteValue,
|
|
3322
3322
|
baseAssetValue,
|
|
3323
|
-
oraclePriceData,
|
|
3323
|
+
oraclePriceData.price,
|
|
3324
3324
|
spotMarketAccount,
|
|
3325
3325
|
marginCategory
|
|
3326
3326
|
);
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { PriorityFeeCalculator } from '../../src/tx/priorityFeeCalculator';
|
|
3
|
+
|
|
4
|
+
describe('PriorityFeeCalculator', () => {
|
|
5
|
+
let priorityFeeCalculator: PriorityFeeCalculator;
|
|
6
|
+
|
|
7
|
+
const startTime = 1000000;
|
|
8
|
+
const latch_duration = 10_000;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
priorityFeeCalculator = new PriorityFeeCalculator(
|
|
12
|
+
startTime,
|
|
13
|
+
latch_duration
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should trigger priority fee when timeout count increases', () => {
|
|
18
|
+
const timeoutCount = 1;
|
|
19
|
+
expect(priorityFeeCalculator.updatePriorityFee(startTime, timeoutCount)).to
|
|
20
|
+
.be.true;
|
|
21
|
+
expect(
|
|
22
|
+
priorityFeeCalculator.updatePriorityFee(
|
|
23
|
+
startTime + latch_duration,
|
|
24
|
+
timeoutCount + 1
|
|
25
|
+
)
|
|
26
|
+
).to.be.true;
|
|
27
|
+
expect(
|
|
28
|
+
priorityFeeCalculator.updatePriorityFee(
|
|
29
|
+
startTime + latch_duration,
|
|
30
|
+
timeoutCount + 2
|
|
31
|
+
)
|
|
32
|
+
).to.be.true;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should trigger priority fee when timeout count increases, and stay latched until latch duration', () => {
|
|
36
|
+
const timeoutCount = 1;
|
|
37
|
+
expect(priorityFeeCalculator.updatePriorityFee(startTime, timeoutCount)).to
|
|
38
|
+
.be.true;
|
|
39
|
+
expect(
|
|
40
|
+
priorityFeeCalculator.updatePriorityFee(
|
|
41
|
+
startTime + latch_duration / 2,
|
|
42
|
+
timeoutCount
|
|
43
|
+
)
|
|
44
|
+
).to.be.true;
|
|
45
|
+
expect(
|
|
46
|
+
priorityFeeCalculator.updatePriorityFee(
|
|
47
|
+
startTime + latch_duration - 1,
|
|
48
|
+
timeoutCount
|
|
49
|
+
)
|
|
50
|
+
).to.be.true;
|
|
51
|
+
expect(
|
|
52
|
+
priorityFeeCalculator.updatePriorityFee(
|
|
53
|
+
startTime + latch_duration * 2,
|
|
54
|
+
timeoutCount
|
|
55
|
+
)
|
|
56
|
+
).to.be.false;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should not trigger priority fee when timeout count does not increase', () => {
|
|
60
|
+
const timeoutCount = 0;
|
|
61
|
+
expect(priorityFeeCalculator.updatePriorityFee(startTime, timeoutCount)).to
|
|
62
|
+
.be.false;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should correctly calculate compute unit price', () => {
|
|
66
|
+
const computeUnitLimit = 1_000_000;
|
|
67
|
+
const additionalFeeMicroLamports = 1_000_000_000; // 1000 lamports
|
|
68
|
+
const actualComputeUnitPrice =
|
|
69
|
+
priorityFeeCalculator.calculateComputeUnitPrice(
|
|
70
|
+
computeUnitLimit,
|
|
71
|
+
additionalFeeMicroLamports
|
|
72
|
+
);
|
|
73
|
+
expect(actualComputeUnitPrice * computeUnitLimit).to.equal(
|
|
74
|
+
additionalFeeMicroLamports
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
});
|