@drift-labs/sdk 2.77.0-beta.0 → 2.77.0-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 +13 -3
- package/lib/driftClient.js +102 -31
- package/lib/idl/drift.json +1 -1
- package/lib/priorityFee/driftPriorityFeeMethod.d.ts +1 -1
- package/lib/priorityFee/driftPriorityFeeMethod.js +2 -2
- package/lib/priorityFee/priorityFeeSubscriber.d.ts +2 -3
- package/lib/priorityFee/priorityFeeSubscriber.js +6 -14
- package/lib/priorityFee/types.d.ts +3 -2
- package/lib/tx/txParamProcessor.d.ts +28 -0
- package/lib/tx/txParamProcessor.js +71 -0
- package/lib/tx/whileValidTxSender.js +2 -1
- package/lib/types.d.ts +6 -1
- package/lib/user.js +8 -2
- package/package.json +1 -1
- package/src/driftClient.ts +154 -39
- package/src/idl/drift.json +1 -1
- package/src/priorityFee/driftPriorityFeeMethod.ts +5 -3
- package/src/priorityFee/priorityFeeSubscriber.ts +8 -16
- package/src/priorityFee/types.ts +6 -2
- package/src/tx/txParamProcessor.ts +126 -0
- package/src/tx/whileValidTxSender.ts +2 -1
- package/src/types.ts +8 -1
- package/src/user.ts +7 -2
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.77.0-beta.
|
|
1
|
+
2.77.0-beta.1
|
package/lib/driftClient.d.ts
CHANGED
|
@@ -112,7 +112,8 @@ export declare class DriftClient {
|
|
|
112
112
|
* Adds and subscribes to users based on params set by the constructor or by updateWallet.
|
|
113
113
|
*/
|
|
114
114
|
addAndSubscribeToUsers(): Promise<boolean>;
|
|
115
|
-
|
|
115
|
+
private getProcessedTransactionParams;
|
|
116
|
+
initializeUserAccount(subAccountId?: number, name?: string, referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<[TransactionSignature, PublicKey]>;
|
|
116
117
|
getInitializeUserInstructions(subAccountId?: number, name?: string, referrerInfo?: ReferrerInfo): Promise<[PublicKey, TransactionInstruction]>;
|
|
117
118
|
getInitializeUserStatsIx(): Promise<TransactionInstruction>;
|
|
118
119
|
getNextSubAccountId(): Promise<number>;
|
|
@@ -249,7 +250,7 @@ export declare class DriftClient {
|
|
|
249
250
|
* @returns
|
|
250
251
|
*/
|
|
251
252
|
initializeUserAccountAndDepositCollateral(amount: BN, userTokenAccount: PublicKey, marketIndex?: number, subAccountId?: number, name?: string, fromSubAccountId?: number, referrerInfo?: ReferrerInfo, donateAmount?: BN, txParams?: TxParams, customMaxMarginRatio?: number): Promise<[TransactionSignature, PublicKey]>;
|
|
252
|
-
initializeUserAccountForDevnet(subAccountId: number, name: string, marketIndex: number, tokenFaucet: TokenFaucet, amount: BN, referrerInfo?: ReferrerInfo): Promise<[TransactionSignature, PublicKey]>;
|
|
253
|
+
initializeUserAccountForDevnet(subAccountId: number, name: string, marketIndex: number, tokenFaucet: TokenFaucet, amount: BN, referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<[TransactionSignature, PublicKey]>;
|
|
253
254
|
/**
|
|
254
255
|
* Withdraws from a user account. If deposit doesn't already exist, creates a borrow
|
|
255
256
|
* @param amount
|
|
@@ -661,6 +662,15 @@ export declare class DriftClient {
|
|
|
661
662
|
} | undefined;
|
|
662
663
|
private handleSignedTransaction;
|
|
663
664
|
sendTransaction(tx: Transaction | VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
|
|
664
|
-
|
|
665
|
+
/**
|
|
666
|
+
*
|
|
667
|
+
* @param instructions
|
|
668
|
+
* @param txParams
|
|
669
|
+
* @param txVersion
|
|
670
|
+
* @param lookupTables
|
|
671
|
+
* @param forceVersionedTransaction Return a VersionedTransaction instance even if the version of the transaction is Legacy
|
|
672
|
+
* @returns
|
|
673
|
+
*/
|
|
674
|
+
buildTransaction(instructions: TransactionInstruction | TransactionInstruction[], txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean): Promise<Transaction | VersionedTransaction>;
|
|
665
675
|
}
|
|
666
676
|
export {};
|
package/lib/driftClient.js
CHANGED
|
@@ -56,6 +56,7 @@ const memcmp_1 = require("./memcmp");
|
|
|
56
56
|
const marinade_1 = require("./marinade");
|
|
57
57
|
const orderParams_1 = require("./orderParams");
|
|
58
58
|
const utils_2 = require("./math/utils");
|
|
59
|
+
const txParamProcessor_1 = require("./tx/txParamProcessor");
|
|
59
60
|
/**
|
|
60
61
|
* # DriftClient
|
|
61
62
|
* This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
|
|
@@ -437,7 +438,23 @@ class DriftClient {
|
|
|
437
438
|
}
|
|
438
439
|
return result;
|
|
439
440
|
}
|
|
440
|
-
async
|
|
441
|
+
async getProcessedTransactionParams(txParams, txParamProcessingParams) {
|
|
442
|
+
const tx = await txParamProcessor_1.TransactionProcessor.process({
|
|
443
|
+
txProps: {
|
|
444
|
+
instructions: txParams.instructions,
|
|
445
|
+
txParams: txParams.txParams,
|
|
446
|
+
txVersion: txParams.txVersion,
|
|
447
|
+
lookupTables: txParams.lookupTables,
|
|
448
|
+
},
|
|
449
|
+
txBuilder: (updatedTxParams) => this.buildTransaction(updatedTxParams.instructions, updatedTxParams === null || updatedTxParams === void 0 ? void 0 : updatedTxParams.txParams, updatedTxParams.txVersion, updatedTxParams.lookupTables, true),
|
|
450
|
+
processConfig: txParamProcessingParams,
|
|
451
|
+
processParams: {
|
|
452
|
+
connection: this.connection,
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
return tx;
|
|
456
|
+
}
|
|
457
|
+
async initializeUserAccount(subAccountId = 0, name, referrerInfo, txParams) {
|
|
441
458
|
const initializeIxs = [];
|
|
442
459
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
|
|
443
460
|
if (subAccountId === 0) {
|
|
@@ -446,7 +463,7 @@ class DriftClient {
|
|
|
446
463
|
}
|
|
447
464
|
}
|
|
448
465
|
initializeIxs.push(initializeUserAccountIx);
|
|
449
|
-
const tx = await this.buildTransaction(initializeIxs);
|
|
466
|
+
const tx = await this.buildTransaction(initializeIxs, txParams);
|
|
450
467
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
451
468
|
await this.addUser(subAccountId);
|
|
452
469
|
return [txSig, userAccountPublicKey];
|
|
@@ -1147,21 +1164,11 @@ class DriftClient {
|
|
|
1147
1164
|
* @returns
|
|
1148
1165
|
*/
|
|
1149
1166
|
async initializeUserAccountAndDepositCollateral(amount, userTokenAccount, marketIndex = 0, subAccountId = 0, name, fromSubAccountId, referrerInfo, donateAmount, txParams, customMaxMarginRatio) {
|
|
1150
|
-
var _a;
|
|
1151
1167
|
const ixs = [];
|
|
1152
1168
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
|
|
1153
1169
|
const additionalSigners = [];
|
|
1154
1170
|
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
1155
1171
|
const isSolMarket = spotMarket.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
1156
|
-
let params = {
|
|
1157
|
-
computeUnits: (_a = txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits) !== null && _a !== void 0 ? _a : 600000,
|
|
1158
|
-
};
|
|
1159
|
-
if (txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice) {
|
|
1160
|
-
params = {
|
|
1161
|
-
...params,
|
|
1162
|
-
computeUnitsPrice: txParams.computeUnitsPrice,
|
|
1163
|
-
};
|
|
1164
|
-
}
|
|
1165
1172
|
const authority = this.wallet.publicKey;
|
|
1166
1173
|
const isFromSubaccount = fromSubAccountId !== null &&
|
|
1167
1174
|
fromSubAccountId !== undefined &&
|
|
@@ -1203,13 +1210,13 @@ class DriftClient {
|
|
|
1203
1210
|
if (createWSOLTokenAccount) {
|
|
1204
1211
|
ixs.push((0, spl_token_1.createCloseAccountInstruction)(wsolTokenAccount, authority, authority, []));
|
|
1205
1212
|
}
|
|
1206
|
-
const tx = await this.buildTransaction(ixs,
|
|
1213
|
+
const tx = await this.buildTransaction(ixs, txParams);
|
|
1207
1214
|
const { txSig, slot } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
1208
1215
|
this.spotMarketLastSlotCache.set(marketIndex, slot);
|
|
1209
1216
|
await this.addUser(subAccountId);
|
|
1210
1217
|
return [txSig, userAccountPublicKey];
|
|
1211
1218
|
}
|
|
1212
|
-
async initializeUserAccountForDevnet(subAccountId = 0, name = userName_1.DEFAULT_USER_NAME, marketIndex, tokenFaucet, amount, referrerInfo) {
|
|
1219
|
+
async initializeUserAccountForDevnet(subAccountId = 0, name = userName_1.DEFAULT_USER_NAME, marketIndex, tokenFaucet, amount, referrerInfo, txParams) {
|
|
1213
1220
|
const ixs = [];
|
|
1214
1221
|
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
|
|
1215
1222
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
|
|
@@ -1221,7 +1228,7 @@ class DriftClient {
|
|
|
1221
1228
|
}
|
|
1222
1229
|
}
|
|
1223
1230
|
ixs.push(initializeUserAccountIx, depositCollateralIx);
|
|
1224
|
-
const tx = await this.buildTransaction(ixs);
|
|
1231
|
+
const tx = await this.buildTransaction(ixs, txParams);
|
|
1225
1232
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1226
1233
|
await this.addUser(subAccountId);
|
|
1227
1234
|
return [txSig, userAccountPublicKey];
|
|
@@ -1258,10 +1265,7 @@ class DriftClient {
|
|
|
1258
1265
|
if (createWSOLTokenAccount) {
|
|
1259
1266
|
withdrawIxs.push((0, spl_token_1.createCloseAccountInstruction)(associatedTokenAddress, authority, authority, []));
|
|
1260
1267
|
}
|
|
1261
|
-
const tx = await this.buildTransaction(withdrawIxs,
|
|
1262
|
-
...(txParams !== null && txParams !== void 0 ? txParams : this.txParams),
|
|
1263
|
-
computeUnits: 1400000,
|
|
1264
|
-
});
|
|
1268
|
+
const tx = await this.buildTransaction(withdrawIxs, txParams !== null && txParams !== void 0 ? txParams : this.txParams);
|
|
1265
1269
|
const { txSig, slot } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
1266
1270
|
this.spotMarketLastSlotCache.set(marketIndex, slot);
|
|
1267
1271
|
return txSig;
|
|
@@ -2512,12 +2516,26 @@ class DriftClient {
|
|
|
2512
2516
|
const bracketOrdersIx = await this.getPlaceOrdersIx(bracketOrdersParams, subAccountId);
|
|
2513
2517
|
ixs.push(bracketOrdersIx);
|
|
2514
2518
|
}
|
|
2515
|
-
const
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2519
|
+
const shouldUseSimulationComputeUnits = txParams === null || txParams === void 0 ? void 0 : txParams.useSimulatedComputeUnits;
|
|
2520
|
+
const shouldExitIfSimulationFails = simulateFirst;
|
|
2521
|
+
const txParamsWithoutImplicitSimulation = {
|
|
2522
|
+
...txParams,
|
|
2523
|
+
useSimulationComputeUnits: false,
|
|
2524
|
+
};
|
|
2525
|
+
let placeAndTakeTx = await this.buildTransaction(ixs, txParamsWithoutImplicitSimulation);
|
|
2526
|
+
if (shouldUseSimulationComputeUnits || shouldExitIfSimulationFails) {
|
|
2527
|
+
const simulationResult = await txParamProcessor_1.TransactionProcessor.getTxSimComputeUnits(
|
|
2528
|
+
// @ts-ignore :: TODO - TEST WITH LEGACY TRANSACTION
|
|
2529
|
+
placeAndTakeTx, this.connection);
|
|
2530
|
+
if (shouldExitIfSimulationFails && !simulationResult.success) {
|
|
2520
2531
|
return;
|
|
2532
|
+
}
|
|
2533
|
+
if (shouldUseSimulationComputeUnits) {
|
|
2534
|
+
placeAndTakeTx = await this.buildTransaction(ixs, {
|
|
2535
|
+
...txParamsWithoutImplicitSimulation,
|
|
2536
|
+
computeUnits: simulationResult.computeUnits,
|
|
2537
|
+
});
|
|
2538
|
+
}
|
|
2521
2539
|
}
|
|
2522
2540
|
let cancelExistingOrdersTx;
|
|
2523
2541
|
if (cancelExistingOrders && (0, types_1.isVariant)(orderParams.marketType, 'perp')) {
|
|
@@ -3506,23 +3524,63 @@ class DriftClient {
|
|
|
3506
3524
|
onSignedCb: this.handleSignedTransaction.bind(this),
|
|
3507
3525
|
}
|
|
3508
3526
|
: undefined;
|
|
3509
|
-
|
|
3527
|
+
const version = tx === null || tx === void 0 ? void 0 : tx.version;
|
|
3528
|
+
const isVersionedTx = tx instanceof web3_js_1.VersionedTransaction || version !== undefined;
|
|
3529
|
+
if (isVersionedTx) {
|
|
3510
3530
|
return this.txSender.sendVersionedTransaction(tx, additionalSigners, opts, preSigned, extraConfirmationOptions);
|
|
3511
3531
|
}
|
|
3512
3532
|
else {
|
|
3513
3533
|
return this.txSender.send(tx, additionalSigners, opts, preSigned, extraConfirmationOptions);
|
|
3514
3534
|
}
|
|
3515
3535
|
}
|
|
3516
|
-
|
|
3536
|
+
/**
|
|
3537
|
+
*
|
|
3538
|
+
* @param instructions
|
|
3539
|
+
* @param txParams
|
|
3540
|
+
* @param txVersion
|
|
3541
|
+
* @param lookupTables
|
|
3542
|
+
* @param forceVersionedTransaction Return a VersionedTransaction instance even if the version of the transaction is Legacy
|
|
3543
|
+
* @returns
|
|
3544
|
+
*/
|
|
3545
|
+
async buildTransaction(instructions, txParams, txVersion, lookupTables, forceVersionedTransaction) {
|
|
3517
3546
|
var _a, _b;
|
|
3547
|
+
txVersion = txVersion !== null && txVersion !== void 0 ? txVersion : this.txVersion;
|
|
3548
|
+
// # Collect and process Tx Params
|
|
3549
|
+
let baseTxParams = {
|
|
3550
|
+
computeUnits: (_a = txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits) !== null && _a !== void 0 ? _a : this.txParams.computeUnits,
|
|
3551
|
+
computeUnitsPrice: (_b = txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice) !== null && _b !== void 0 ? _b : this.txParams.computeUnitsPrice,
|
|
3552
|
+
};
|
|
3553
|
+
if (txParams === null || txParams === void 0 ? void 0 : txParams.useSimulatedComputeUnits) {
|
|
3554
|
+
const splitTxParams = {
|
|
3555
|
+
baseTxParams: {
|
|
3556
|
+
computeUnits: txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits,
|
|
3557
|
+
computeUnitsPrice: txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice,
|
|
3558
|
+
},
|
|
3559
|
+
txParamProcessingParams: {
|
|
3560
|
+
useSimulatedComputeUnits: txParams === null || txParams === void 0 ? void 0 : txParams.useSimulatedComputeUnits,
|
|
3561
|
+
computeUnitsBufferMultiplier: txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsBufferMultiplier,
|
|
3562
|
+
},
|
|
3563
|
+
};
|
|
3564
|
+
const processedTxParams = await this.getProcessedTransactionParams({
|
|
3565
|
+
instructions,
|
|
3566
|
+
txParams: splitTxParams.baseTxParams,
|
|
3567
|
+
txVersion,
|
|
3568
|
+
lookupTables,
|
|
3569
|
+
}, splitTxParams.txParamProcessingParams);
|
|
3570
|
+
baseTxParams = {
|
|
3571
|
+
...baseTxParams,
|
|
3572
|
+
...processedTxParams,
|
|
3573
|
+
};
|
|
3574
|
+
}
|
|
3575
|
+
// # Create Tx Instructions
|
|
3518
3576
|
const allIx = [];
|
|
3519
|
-
const computeUnits =
|
|
3577
|
+
const computeUnits = baseTxParams === null || baseTxParams === void 0 ? void 0 : baseTxParams.computeUnits;
|
|
3520
3578
|
if (computeUnits !== 200000) {
|
|
3521
3579
|
allIx.push(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
3522
3580
|
units: computeUnits,
|
|
3523
3581
|
}));
|
|
3524
3582
|
}
|
|
3525
|
-
const computeUnitsPrice =
|
|
3583
|
+
const computeUnitsPrice = baseTxParams === null || baseTxParams === void 0 ? void 0 : baseTxParams.computeUnitsPrice;
|
|
3526
3584
|
if (computeUnitsPrice !== 0) {
|
|
3527
3585
|
allIx.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
|
|
3528
3586
|
microLamports: computeUnitsPrice,
|
|
@@ -3534,9 +3592,22 @@ class DriftClient {
|
|
|
3534
3592
|
else {
|
|
3535
3593
|
allIx.push(instructions);
|
|
3536
3594
|
}
|
|
3537
|
-
|
|
3595
|
+
const latestBlockHashAndContext = await this.connection.getLatestBlockhashAndContext({
|
|
3596
|
+
commitment: this.opts.preflightCommitment,
|
|
3597
|
+
});
|
|
3598
|
+
// # Create and return Transaction
|
|
3538
3599
|
if (txVersion === 'legacy') {
|
|
3539
|
-
|
|
3600
|
+
if (forceVersionedTransaction) {
|
|
3601
|
+
const message = new web3_js_1.TransactionMessage({
|
|
3602
|
+
payerKey: this.provider.wallet.publicKey,
|
|
3603
|
+
recentBlockhash: latestBlockHashAndContext.value.blockhash,
|
|
3604
|
+
instructions: allIx,
|
|
3605
|
+
}).compileToLegacyMessage();
|
|
3606
|
+
return new web3_js_1.VersionedTransaction(message);
|
|
3607
|
+
}
|
|
3608
|
+
else {
|
|
3609
|
+
return new web3_js_1.Transaction().add(...allIx);
|
|
3610
|
+
}
|
|
3540
3611
|
}
|
|
3541
3612
|
else {
|
|
3542
3613
|
const marketLookupTable = await this.fetchMarketLookupTableAccount();
|
|
@@ -3545,7 +3616,7 @@ class DriftClient {
|
|
|
3545
3616
|
: [marketLookupTable];
|
|
3546
3617
|
const message = new web3_js_1.TransactionMessage({
|
|
3547
3618
|
payerKey: this.provider.wallet.publicKey,
|
|
3548
|
-
recentBlockhash:
|
|
3619
|
+
recentBlockhash: latestBlockHashAndContext.value.blockhash,
|
|
3549
3620
|
instructions: allIx,
|
|
3550
3621
|
}).compileToV0Message(lookupTables);
|
|
3551
3622
|
return new web3_js_1.VersionedTransaction(message);
|
package/lib/idl/drift.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { HeliusPriorityFeeLevels } from './heliusPriorityFeeMethod';
|
|
2
2
|
export type DriftPriorityFeeResponse = HeliusPriorityFeeLevels[];
|
|
3
|
-
export declare function fetchDriftPriorityFee(url: string,
|
|
3
|
+
export declare function fetchDriftPriorityFee(url: string, marketTypes: string[], marketIndexs: number[]): Promise<DriftPriorityFeeResponse>;
|
|
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.fetchDriftPriorityFee = void 0;
|
|
7
7
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
8
|
-
async function fetchDriftPriorityFee(url,
|
|
9
|
-
const response = await (0, node_fetch_1.default)(`${url}?marketType=${
|
|
8
|
+
async function fetchDriftPriorityFee(url, marketTypes, marketIndexs) {
|
|
9
|
+
const response = await (0, node_fetch_1.default)(`${url}/batchPriorityFees?marketType=${marketTypes.join(',')}&marketIndex=${marketIndexs.join(',')}`);
|
|
10
10
|
return await response.json();
|
|
11
11
|
}
|
|
12
12
|
exports.fetchDriftPriorityFee = fetchDriftPriorityFee;
|
|
@@ -3,7 +3,6 @@ import { PriorityFeeMethod, PriorityFeeStrategy, PriorityFeeSubscriberConfig } f
|
|
|
3
3
|
import { AverageOverSlotsStrategy } from './averageOverSlotsStrategy';
|
|
4
4
|
import { MaxOverSlotsStrategy } from './maxOverSlotsStrategy';
|
|
5
5
|
import { HeliusPriorityFeeLevels, HeliusPriorityLevel } from './heliusPriorityFeeMethod';
|
|
6
|
-
import { MarketType } from '..';
|
|
7
6
|
export type DriftMarketInfo = {
|
|
8
7
|
marketType: string;
|
|
9
8
|
marketIndex: number;
|
|
@@ -12,7 +11,7 @@ export declare class PriorityFeeSubscriber {
|
|
|
12
11
|
connection: Connection;
|
|
13
12
|
frequencyMs: number;
|
|
14
13
|
addresses: string[];
|
|
15
|
-
|
|
14
|
+
driftMarkets?: DriftMarketInfo[];
|
|
16
15
|
customStrategy?: PriorityFeeStrategy;
|
|
17
16
|
averageStrategy: AverageOverSlotsStrategy;
|
|
18
17
|
maxStrategy: MaxOverSlotsStrategy;
|
|
@@ -46,5 +45,5 @@ export declare class PriorityFeeSubscriber {
|
|
|
46
45
|
load(): Promise<void>;
|
|
47
46
|
unsubscribe(): Promise<void>;
|
|
48
47
|
updateAddresses(addresses: PublicKey[]): void;
|
|
49
|
-
updateMarketTypeAndIndex(
|
|
48
|
+
updateMarketTypeAndIndex(driftMarkets: DriftMarketInfo[]): void;
|
|
50
49
|
}
|
|
@@ -7,7 +7,6 @@ const maxOverSlotsStrategy_1 = require("./maxOverSlotsStrategy");
|
|
|
7
7
|
const solanaPriorityFeeMethod_1 = require("./solanaPriorityFeeMethod");
|
|
8
8
|
const heliusPriorityFeeMethod_1 = require("./heliusPriorityFeeMethod");
|
|
9
9
|
const driftPriorityFeeMethod_1 = require("./driftPriorityFeeMethod");
|
|
10
|
-
const __1 = require("..");
|
|
11
10
|
class PriorityFeeSubscriber {
|
|
12
11
|
constructor(config) {
|
|
13
12
|
var _a, _b;
|
|
@@ -24,7 +23,7 @@ class PriorityFeeSubscriber {
|
|
|
24
23
|
this.addresses = config.addresses
|
|
25
24
|
? config.addresses.map((address) => address.toBase58())
|
|
26
25
|
: [];
|
|
27
|
-
this.
|
|
26
|
+
this.driftMarkets = config.driftMarkets;
|
|
28
27
|
if (config.customStrategy) {
|
|
29
28
|
this.customStrategy = config.customStrategy;
|
|
30
29
|
}
|
|
@@ -91,22 +90,15 @@ class PriorityFeeSubscriber {
|
|
|
91
90
|
}
|
|
92
91
|
}
|
|
93
92
|
async loadForDrift() {
|
|
94
|
-
if (!this.
|
|
93
|
+
if (!this.driftMarkets) {
|
|
95
94
|
return;
|
|
96
95
|
}
|
|
97
|
-
const sample = await (0, driftPriorityFeeMethod_1.fetchDriftPriorityFee)(this.driftPriorityFeeEndpoint, this.
|
|
96
|
+
const sample = await (0, driftPriorityFeeMethod_1.fetchDriftPriorityFee)(this.driftPriorityFeeEndpoint, this.driftMarkets.map((m) => m.marketType), this.driftMarkets.map((m) => m.marketIndex));
|
|
98
97
|
if (sample.length > 0) {
|
|
99
98
|
this.lastAvgStrategyResult = sample[heliusPriorityFeeMethod_1.HeliusPriorityLevel.MEDIUM];
|
|
100
99
|
this.lastMaxStrategyResult = sample[heliusPriorityFeeMethod_1.HeliusPriorityLevel.UNSAFE_MAX];
|
|
101
100
|
if (this.customStrategy) {
|
|
102
|
-
|
|
103
|
-
this.lastCustomStrategyResult = this.customStrategy.calculate({
|
|
104
|
-
jsonrpc: '',
|
|
105
|
-
result: {
|
|
106
|
-
priorityFeeLevels: sample[0],
|
|
107
|
-
},
|
|
108
|
-
id: '',
|
|
109
|
-
});
|
|
101
|
+
this.lastCustomStrategyResult = this.customStrategy.calculate(sample);
|
|
110
102
|
}
|
|
111
103
|
}
|
|
112
104
|
}
|
|
@@ -186,8 +178,8 @@ class PriorityFeeSubscriber {
|
|
|
186
178
|
updateAddresses(addresses) {
|
|
187
179
|
this.addresses = addresses.map((k) => k.toBase58());
|
|
188
180
|
}
|
|
189
|
-
updateMarketTypeAndIndex(
|
|
190
|
-
this.
|
|
181
|
+
updateMarketTypeAndIndex(driftMarkets) {
|
|
182
|
+
this.driftMarkets = driftMarkets;
|
|
191
183
|
}
|
|
192
184
|
}
|
|
193
185
|
exports.PriorityFeeSubscriber = PriorityFeeSubscriber;
|
|
@@ -2,8 +2,9 @@ import { Connection, PublicKey } from '@solana/web3.js';
|
|
|
2
2
|
import { SolanaPriorityFeeResponse } from './solanaPriorityFeeMethod';
|
|
3
3
|
import { HeliusPriorityFeeResponse } from './heliusPriorityFeeMethod';
|
|
4
4
|
import { DriftMarketInfo } from './priorityFeeSubscriber';
|
|
5
|
+
import { DriftPriorityFeeResponse } from './driftPriorityFeeMethod';
|
|
5
6
|
export interface PriorityFeeStrategy {
|
|
6
|
-
calculate(samples: SolanaPriorityFeeResponse[] | HeliusPriorityFeeResponse): number;
|
|
7
|
+
calculate(samples: SolanaPriorityFeeResponse[] | HeliusPriorityFeeResponse | DriftPriorityFeeResponse): number;
|
|
7
8
|
}
|
|
8
9
|
export declare enum PriorityFeeMethod {
|
|
9
10
|
SOLANA = "solana",
|
|
@@ -14,7 +15,7 @@ export type PriorityFeeSubscriberConfig = {
|
|
|
14
15
|
connection?: Connection;
|
|
15
16
|
frequencyMs: number;
|
|
16
17
|
addresses?: PublicKey[];
|
|
17
|
-
|
|
18
|
+
driftMarkets?: DriftMarketInfo[];
|
|
18
19
|
customStrategy?: PriorityFeeStrategy;
|
|
19
20
|
priorityFeeMethod?: PriorityFeeMethod;
|
|
20
21
|
slotsToCheck?: number;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { AddressLookupTableAccount, Connection, TransactionInstruction, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
|
|
2
|
+
import { BaseTxParams, ProcessingTxParams } from '..';
|
|
3
|
+
type TransactionProps = {
|
|
4
|
+
instructions: TransactionInstruction | TransactionInstruction[];
|
|
5
|
+
txParams?: BaseTxParams;
|
|
6
|
+
txVersion?: TransactionVersion;
|
|
7
|
+
lookupTables?: AddressLookupTableAccount[];
|
|
8
|
+
forceVersionedTransaction?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* This class is responsible for running through a "processing" pipeline for a base transaction, to adjust the standard transaction parameters based on a given configuration.
|
|
12
|
+
*/
|
|
13
|
+
export declare class TransactionProcessor {
|
|
14
|
+
private static getComputeUnitsFromSim;
|
|
15
|
+
static getTxSimComputeUnits(tx: VersionedTransaction, connection: Connection): Promise<{
|
|
16
|
+
success: boolean;
|
|
17
|
+
computeUnits: number;
|
|
18
|
+
}>;
|
|
19
|
+
static process(props: {
|
|
20
|
+
txProps: TransactionProps;
|
|
21
|
+
txBuilder: (baseTransactionProps: TransactionProps) => Promise<VersionedTransaction>;
|
|
22
|
+
processConfig: ProcessingTxParams;
|
|
23
|
+
processParams: {
|
|
24
|
+
connection: Connection;
|
|
25
|
+
};
|
|
26
|
+
}): Promise<BaseTxParams>;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TransactionProcessor = void 0;
|
|
4
|
+
const COMPUTE_UNIT_BUFFER_FACTOR = 1.2;
|
|
5
|
+
const TEST_SIMS_ALWAYS_FAIL = false;
|
|
6
|
+
/**
|
|
7
|
+
* This class is responsible for running through a "processing" pipeline for a base transaction, to adjust the standard transaction parameters based on a given configuration.
|
|
8
|
+
*/
|
|
9
|
+
class TransactionProcessor {
|
|
10
|
+
static async getComputeUnitsFromSim(txSim) {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
if ((_a = txSim === null || txSim === void 0 ? void 0 : txSim.value) === null || _a === void 0 ? void 0 : _a.unitsConsumed) {
|
|
13
|
+
return (_b = txSim === null || txSim === void 0 ? void 0 : txSim.value) === null || _b === void 0 ? void 0 : _b.unitsConsumed;
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
static async getTxSimComputeUnits(tx, connection) {
|
|
18
|
+
var _a, _b, _c;
|
|
19
|
+
try {
|
|
20
|
+
if (TEST_SIMS_ALWAYS_FAIL)
|
|
21
|
+
throw new Error('Test Error::SIMS_ALWAYS_FAIL');
|
|
22
|
+
const simTxResult = await connection.simulateTransaction(tx, {
|
|
23
|
+
replaceRecentBlockhash: true, // This is important to ensure that the blockhash is not too new.. Otherwise we will very often receive a "blockHashNotFound" error
|
|
24
|
+
});
|
|
25
|
+
if ((_a = simTxResult === null || simTxResult === void 0 ? void 0 : simTxResult.value) === null || _a === void 0 ? void 0 : _a.err) {
|
|
26
|
+
throw new Error((_c = (_b = simTxResult === null || simTxResult === void 0 ? void 0 : simTxResult.value) === null || _b === void 0 ? void 0 : _b.err) === null || _c === void 0 ? void 0 : _c.toString());
|
|
27
|
+
}
|
|
28
|
+
const computeUnits = await this.getComputeUnitsFromSim(simTxResult);
|
|
29
|
+
return {
|
|
30
|
+
success: true,
|
|
31
|
+
computeUnits: computeUnits,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
console.warn(`Failed to get Simulated Compute Units for txParamProcessor`, e);
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
computeUnits: undefined,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
static async process(props) {
|
|
43
|
+
var _a;
|
|
44
|
+
// # Exit early if no process config is provided
|
|
45
|
+
if (!props.processConfig || Object.keys(props.processConfig).length === 0) {
|
|
46
|
+
return props.txProps.txParams;
|
|
47
|
+
}
|
|
48
|
+
// # Setup
|
|
49
|
+
const { txProps: txProps, txBuilder: txBuilder, processConfig, processParams: processProps, } = props;
|
|
50
|
+
const baseTransaction = await txBuilder(txProps);
|
|
51
|
+
const finalTxProps = {
|
|
52
|
+
...txProps,
|
|
53
|
+
};
|
|
54
|
+
// # Run Processes
|
|
55
|
+
if (processConfig.useSimulatedComputeUnits) {
|
|
56
|
+
const txSimComputeUnitsResult = await this.getTxSimComputeUnits(baseTransaction, processProps.connection);
|
|
57
|
+
if (txSimComputeUnitsResult.success) {
|
|
58
|
+
const bufferedComputeUnits = txSimComputeUnitsResult.computeUnits *
|
|
59
|
+
((_a = processConfig === null || processConfig === void 0 ? void 0 : processConfig.computeUnitsBufferMultiplier) !== null && _a !== void 0 ? _a : COMPUTE_UNIT_BUFFER_FACTOR);
|
|
60
|
+
// Adjust the transaction based on the simulated compute units
|
|
61
|
+
finalTxProps.txParams = {
|
|
62
|
+
...txProps.txParams,
|
|
63
|
+
computeUnits: bufferedComputeUnits,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// # Return Final Tx Params
|
|
68
|
+
return finalTxProps.txParams;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.TransactionProcessor = TransactionProcessor;
|
|
@@ -59,18 +59,19 @@ class WhileValidTxSender extends baseTxSender_1.BaseTxSender {
|
|
|
59
59
|
}
|
|
60
60
|
async sendVersionedTransaction(tx, additionalSigners, opts, preSigned, extraConfirmationOptions) {
|
|
61
61
|
const latestBlockhash = await this.connection.getLatestBlockhash();
|
|
62
|
-
tx.message.recentBlockhash = latestBlockhash.blockhash;
|
|
63
62
|
let signedTx;
|
|
64
63
|
if (preSigned) {
|
|
65
64
|
signedTx = tx;
|
|
66
65
|
// @ts-ignore
|
|
67
66
|
}
|
|
68
67
|
else if (this.wallet.payer) {
|
|
68
|
+
tx.message.recentBlockhash = latestBlockhash.blockhash;
|
|
69
69
|
// @ts-ignore
|
|
70
70
|
tx.sign((additionalSigners !== null && additionalSigners !== void 0 ? additionalSigners : []).concat(this.wallet.payer));
|
|
71
71
|
signedTx = tx;
|
|
72
72
|
}
|
|
73
73
|
else {
|
|
74
|
+
tx.message.recentBlockhash = latestBlockhash.blockhash;
|
|
74
75
|
additionalSigners === null || additionalSigners === void 0 ? void 0 : additionalSigners.filter((s) => s !== undefined).forEach((kp) => {
|
|
75
76
|
tx.sign([kp]);
|
|
76
77
|
});
|
package/lib/types.d.ts
CHANGED
|
@@ -1038,10 +1038,15 @@ export type ReferrerInfo = {
|
|
|
1038
1038
|
referrer: PublicKey;
|
|
1039
1039
|
referrerStats: PublicKey;
|
|
1040
1040
|
};
|
|
1041
|
-
export type
|
|
1041
|
+
export type BaseTxParams = {
|
|
1042
1042
|
computeUnits?: number;
|
|
1043
1043
|
computeUnitsPrice?: number;
|
|
1044
1044
|
};
|
|
1045
|
+
export type ProcessingTxParams = {
|
|
1046
|
+
useSimulatedComputeUnits?: boolean;
|
|
1047
|
+
computeUnitsBufferMultiplier?: number;
|
|
1048
|
+
};
|
|
1049
|
+
export type TxParams = BaseTxParams & ProcessingTxParams;
|
|
1045
1050
|
export declare class SwapReduceOnly {
|
|
1046
1051
|
static readonly In: {
|
|
1047
1052
|
in: {};
|
package/lib/user.js
CHANGED
|
@@ -1690,8 +1690,14 @@ class User {
|
|
|
1690
1690
|
const feeTier = this.getUserFeeTier(marketType);
|
|
1691
1691
|
let takerFee = feeTier.feeNumerator / feeTier.feeDenominator;
|
|
1692
1692
|
let makerFee = feeTier.makerRebateNumerator / feeTier.makerRebateDenominator;
|
|
1693
|
-
if (marketIndex !== undefined
|
|
1694
|
-
|
|
1693
|
+
if (marketIndex !== undefined) {
|
|
1694
|
+
let marketAccount = null;
|
|
1695
|
+
if ((0, types_1.isVariant)(marketType, 'perp')) {
|
|
1696
|
+
marketAccount = this.driftClient.getPerpMarketAccount(marketIndex);
|
|
1697
|
+
}
|
|
1698
|
+
else {
|
|
1699
|
+
marketAccount = this.driftClient.getSpotMarketAccount(marketIndex);
|
|
1700
|
+
}
|
|
1695
1701
|
takerFee += (takerFee * marketAccount.feeAdjustment) / 100;
|
|
1696
1702
|
makerFee += (makerFee * marketAccount.feeAdjustment) / 100;
|
|
1697
1703
|
}
|
package/package.json
CHANGED
package/src/driftClient.ts
CHANGED
|
@@ -42,6 +42,8 @@ import {
|
|
|
42
42
|
PhoenixV1FulfillmentConfigAccount,
|
|
43
43
|
ModifyOrderPolicy,
|
|
44
44
|
SwapReduceOnly,
|
|
45
|
+
BaseTxParams,
|
|
46
|
+
ProcessingTxParams,
|
|
45
47
|
} from './types';
|
|
46
48
|
import * as anchor from '@coral-xyz/anchor';
|
|
47
49
|
import driftIDL from './idl/drift.json';
|
|
@@ -125,6 +127,7 @@ import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
|
125
127
|
import { getMarinadeDepositIx, getMarinadeFinanceProgram } from './marinade';
|
|
126
128
|
import { getOrderParams } from './orderParams';
|
|
127
129
|
import { numberToSafeBN } from './math/utils';
|
|
130
|
+
import { TransactionProcessor as TransactionParamProcessor } from './tx/txParamProcessor';
|
|
128
131
|
|
|
129
132
|
type RemainingAccountParams = {
|
|
130
133
|
userAccounts: UserAccount[];
|
|
@@ -734,10 +737,44 @@ export class DriftClient {
|
|
|
734
737
|
return result;
|
|
735
738
|
}
|
|
736
739
|
|
|
740
|
+
private async getProcessedTransactionParams(
|
|
741
|
+
txParams: {
|
|
742
|
+
instructions: TransactionInstruction | TransactionInstruction[];
|
|
743
|
+
txParams?: BaseTxParams;
|
|
744
|
+
txVersion?: TransactionVersion;
|
|
745
|
+
lookupTables?: AddressLookupTableAccount[];
|
|
746
|
+
},
|
|
747
|
+
txParamProcessingParams: ProcessingTxParams
|
|
748
|
+
): Promise<BaseTxParams> {
|
|
749
|
+
const tx = await TransactionParamProcessor.process({
|
|
750
|
+
txProps: {
|
|
751
|
+
instructions: txParams.instructions,
|
|
752
|
+
txParams: txParams.txParams,
|
|
753
|
+
txVersion: txParams.txVersion,
|
|
754
|
+
lookupTables: txParams.lookupTables,
|
|
755
|
+
},
|
|
756
|
+
txBuilder: (updatedTxParams) =>
|
|
757
|
+
this.buildTransaction(
|
|
758
|
+
updatedTxParams.instructions,
|
|
759
|
+
updatedTxParams?.txParams,
|
|
760
|
+
updatedTxParams.txVersion,
|
|
761
|
+
updatedTxParams.lookupTables,
|
|
762
|
+
true
|
|
763
|
+
) as Promise<VersionedTransaction>,
|
|
764
|
+
processConfig: txParamProcessingParams,
|
|
765
|
+
processParams: {
|
|
766
|
+
connection: this.connection,
|
|
767
|
+
},
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
return tx;
|
|
771
|
+
}
|
|
772
|
+
|
|
737
773
|
public async initializeUserAccount(
|
|
738
774
|
subAccountId = 0,
|
|
739
775
|
name?: string,
|
|
740
|
-
referrerInfo?: ReferrerInfo
|
|
776
|
+
referrerInfo?: ReferrerInfo,
|
|
777
|
+
txParams?: TxParams
|
|
741
778
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
742
779
|
const initializeIxs = [];
|
|
743
780
|
|
|
@@ -757,7 +794,7 @@ export class DriftClient {
|
|
|
757
794
|
}
|
|
758
795
|
|
|
759
796
|
initializeIxs.push(initializeUserAccountIx);
|
|
760
|
-
const tx = await this.buildTransaction(initializeIxs);
|
|
797
|
+
const tx = await this.buildTransaction(initializeIxs, txParams);
|
|
761
798
|
|
|
762
799
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
763
800
|
|
|
@@ -1992,17 +2029,6 @@ export class DriftClient {
|
|
|
1992
2029
|
|
|
1993
2030
|
const isSolMarket = spotMarket.mint.equals(WRAPPED_SOL_MINT);
|
|
1994
2031
|
|
|
1995
|
-
let params: TxParams = {
|
|
1996
|
-
computeUnits: txParams?.computeUnits ?? 600_000,
|
|
1997
|
-
};
|
|
1998
|
-
|
|
1999
|
-
if (txParams?.computeUnitsPrice) {
|
|
2000
|
-
params = {
|
|
2001
|
-
...params,
|
|
2002
|
-
computeUnitsPrice: txParams.computeUnitsPrice,
|
|
2003
|
-
};
|
|
2004
|
-
}
|
|
2005
|
-
|
|
2006
2032
|
const authority = this.wallet.publicKey;
|
|
2007
2033
|
|
|
2008
2034
|
const isFromSubaccount =
|
|
@@ -2090,7 +2116,7 @@ export class DriftClient {
|
|
|
2090
2116
|
);
|
|
2091
2117
|
}
|
|
2092
2118
|
|
|
2093
|
-
const tx = await this.buildTransaction(ixs,
|
|
2119
|
+
const tx = await this.buildTransaction(ixs, txParams);
|
|
2094
2120
|
|
|
2095
2121
|
const { txSig, slot } = await this.sendTransaction(
|
|
2096
2122
|
tx,
|
|
@@ -2110,7 +2136,8 @@ export class DriftClient {
|
|
|
2110
2136
|
marketIndex: number,
|
|
2111
2137
|
tokenFaucet: TokenFaucet,
|
|
2112
2138
|
amount: BN,
|
|
2113
|
-
referrerInfo?: ReferrerInfo
|
|
2139
|
+
referrerInfo?: ReferrerInfo,
|
|
2140
|
+
txParams?: TxParams
|
|
2114
2141
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
2115
2142
|
const ixs = [];
|
|
2116
2143
|
|
|
@@ -2147,7 +2174,7 @@ export class DriftClient {
|
|
|
2147
2174
|
}
|
|
2148
2175
|
ixs.push(initializeUserAccountIx, depositCollateralIx);
|
|
2149
2176
|
|
|
2150
|
-
const tx = await this.buildTransaction(ixs);
|
|
2177
|
+
const tx = await this.buildTransaction(ixs, txParams);
|
|
2151
2178
|
|
|
2152
2179
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2153
2180
|
|
|
@@ -2231,10 +2258,11 @@ export class DriftClient {
|
|
|
2231
2258
|
);
|
|
2232
2259
|
}
|
|
2233
2260
|
|
|
2234
|
-
const tx = await this.buildTransaction(
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2261
|
+
const tx = await this.buildTransaction(
|
|
2262
|
+
withdrawIxs,
|
|
2263
|
+
txParams ?? this.txParams
|
|
2264
|
+
);
|
|
2265
|
+
|
|
2238
2266
|
const { txSig, slot } = await this.sendTransaction(
|
|
2239
2267
|
tx,
|
|
2240
2268
|
additionalSigners,
|
|
@@ -4535,15 +4563,37 @@ export class DriftClient {
|
|
|
4535
4563
|
ixs.push(bracketOrdersIx);
|
|
4536
4564
|
}
|
|
4537
4565
|
|
|
4538
|
-
const
|
|
4566
|
+
const shouldUseSimulationComputeUnits = txParams?.useSimulatedComputeUnits;
|
|
4567
|
+
const shouldExitIfSimulationFails = simulateFirst;
|
|
4568
|
+
|
|
4569
|
+
const txParamsWithoutImplicitSimulation = {
|
|
4570
|
+
...txParams,
|
|
4571
|
+
useSimulationComputeUnits: false,
|
|
4572
|
+
};
|
|
4573
|
+
|
|
4574
|
+
let placeAndTakeTx = await this.buildTransaction(
|
|
4539
4575
|
ixs,
|
|
4540
|
-
|
|
4541
|
-
)
|
|
4576
|
+
txParamsWithoutImplicitSimulation
|
|
4577
|
+
);
|
|
4578
|
+
|
|
4579
|
+
if (shouldUseSimulationComputeUnits || shouldExitIfSimulationFails) {
|
|
4580
|
+
const simulationResult =
|
|
4581
|
+
await TransactionParamProcessor.getTxSimComputeUnits(
|
|
4582
|
+
// @ts-ignore :: TODO - TEST WITH LEGACY TRANSACTION
|
|
4583
|
+
placeAndTakeTx,
|
|
4584
|
+
this.connection
|
|
4585
|
+
);
|
|
4542
4586
|
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4587
|
+
if (shouldExitIfSimulationFails && !simulationResult.success) {
|
|
4588
|
+
return;
|
|
4589
|
+
}
|
|
4590
|
+
|
|
4591
|
+
if (shouldUseSimulationComputeUnits) {
|
|
4592
|
+
placeAndTakeTx = await this.buildTransaction(ixs, {
|
|
4593
|
+
...txParamsWithoutImplicitSimulation,
|
|
4594
|
+
computeUnits: simulationResult.computeUnits,
|
|
4595
|
+
});
|
|
4596
|
+
}
|
|
4547
4597
|
}
|
|
4548
4598
|
|
|
4549
4599
|
let cancelExistingOrdersTx: Transaction;
|
|
@@ -6504,7 +6554,11 @@ export class DriftClient {
|
|
|
6504
6554
|
}
|
|
6505
6555
|
: undefined;
|
|
6506
6556
|
|
|
6507
|
-
|
|
6557
|
+
const version = (tx as VersionedTransaction)?.version;
|
|
6558
|
+
const isVersionedTx =
|
|
6559
|
+
tx instanceof VersionedTransaction || version !== undefined;
|
|
6560
|
+
|
|
6561
|
+
if (isVersionedTx) {
|
|
6508
6562
|
return this.txSender.sendVersionedTransaction(
|
|
6509
6563
|
tx as VersionedTransaction,
|
|
6510
6564
|
additionalSigners,
|
|
@@ -6523,14 +6577,65 @@ export class DriftClient {
|
|
|
6523
6577
|
}
|
|
6524
6578
|
}
|
|
6525
6579
|
|
|
6580
|
+
/**
|
|
6581
|
+
*
|
|
6582
|
+
* @param instructions
|
|
6583
|
+
* @param txParams
|
|
6584
|
+
* @param txVersion
|
|
6585
|
+
* @param lookupTables
|
|
6586
|
+
* @param forceVersionedTransaction Return a VersionedTransaction instance even if the version of the transaction is Legacy
|
|
6587
|
+
* @returns
|
|
6588
|
+
*/
|
|
6526
6589
|
async buildTransaction(
|
|
6527
6590
|
instructions: TransactionInstruction | TransactionInstruction[],
|
|
6528
6591
|
txParams?: TxParams,
|
|
6529
6592
|
txVersion?: TransactionVersion,
|
|
6530
|
-
lookupTables?: AddressLookupTableAccount[]
|
|
6593
|
+
lookupTables?: AddressLookupTableAccount[],
|
|
6594
|
+
forceVersionedTransaction?: boolean
|
|
6531
6595
|
): Promise<Transaction | VersionedTransaction> {
|
|
6596
|
+
txVersion = txVersion ?? this.txVersion;
|
|
6597
|
+
|
|
6598
|
+
// # Collect and process Tx Params
|
|
6599
|
+
let baseTxParams: BaseTxParams = {
|
|
6600
|
+
computeUnits: txParams?.computeUnits ?? this.txParams.computeUnits,
|
|
6601
|
+
computeUnitsPrice:
|
|
6602
|
+
txParams?.computeUnitsPrice ?? this.txParams.computeUnitsPrice,
|
|
6603
|
+
};
|
|
6604
|
+
|
|
6605
|
+
if (txParams?.useSimulatedComputeUnits) {
|
|
6606
|
+
const splitTxParams: {
|
|
6607
|
+
baseTxParams: BaseTxParams;
|
|
6608
|
+
txParamProcessingParams: ProcessingTxParams;
|
|
6609
|
+
} = {
|
|
6610
|
+
baseTxParams: {
|
|
6611
|
+
computeUnits: txParams?.computeUnits,
|
|
6612
|
+
computeUnitsPrice: txParams?.computeUnitsPrice,
|
|
6613
|
+
},
|
|
6614
|
+
txParamProcessingParams: {
|
|
6615
|
+
useSimulatedComputeUnits: txParams?.useSimulatedComputeUnits,
|
|
6616
|
+
computeUnitsBufferMultiplier: txParams?.computeUnitsBufferMultiplier,
|
|
6617
|
+
},
|
|
6618
|
+
};
|
|
6619
|
+
|
|
6620
|
+
const processedTxParams = await this.getProcessedTransactionParams(
|
|
6621
|
+
{
|
|
6622
|
+
instructions,
|
|
6623
|
+
txParams: splitTxParams.baseTxParams,
|
|
6624
|
+
txVersion,
|
|
6625
|
+
lookupTables,
|
|
6626
|
+
},
|
|
6627
|
+
splitTxParams.txParamProcessingParams
|
|
6628
|
+
);
|
|
6629
|
+
|
|
6630
|
+
baseTxParams = {
|
|
6631
|
+
...baseTxParams,
|
|
6632
|
+
...processedTxParams,
|
|
6633
|
+
};
|
|
6634
|
+
}
|
|
6635
|
+
|
|
6636
|
+
// # Create Tx Instructions
|
|
6532
6637
|
const allIx = [];
|
|
6533
|
-
const computeUnits =
|
|
6638
|
+
const computeUnits = baseTxParams?.computeUnits;
|
|
6534
6639
|
if (computeUnits !== 200_000) {
|
|
6535
6640
|
allIx.push(
|
|
6536
6641
|
ComputeBudgetProgram.setComputeUnitLimit({
|
|
@@ -6538,8 +6643,7 @@ export class DriftClient {
|
|
|
6538
6643
|
})
|
|
6539
6644
|
);
|
|
6540
6645
|
}
|
|
6541
|
-
const computeUnitsPrice =
|
|
6542
|
-
txParams?.computeUnitsPrice ?? this.txParams.computeUnitsPrice;
|
|
6646
|
+
const computeUnitsPrice = baseTxParams?.computeUnitsPrice;
|
|
6543
6647
|
if (computeUnitsPrice !== 0) {
|
|
6544
6648
|
allIx.push(
|
|
6545
6649
|
ComputeBudgetProgram.setComputeUnitPrice({
|
|
@@ -6554,9 +6658,24 @@ export class DriftClient {
|
|
|
6554
6658
|
allIx.push(instructions);
|
|
6555
6659
|
}
|
|
6556
6660
|
|
|
6557
|
-
|
|
6661
|
+
const latestBlockHashAndContext =
|
|
6662
|
+
await this.connection.getLatestBlockhashAndContext({
|
|
6663
|
+
commitment: this.opts.preflightCommitment,
|
|
6664
|
+
});
|
|
6665
|
+
|
|
6666
|
+
// # Create and return Transaction
|
|
6558
6667
|
if (txVersion === 'legacy') {
|
|
6559
|
-
|
|
6668
|
+
if (forceVersionedTransaction) {
|
|
6669
|
+
const message = new TransactionMessage({
|
|
6670
|
+
payerKey: this.provider.wallet.publicKey,
|
|
6671
|
+
recentBlockhash: latestBlockHashAndContext.value.blockhash,
|
|
6672
|
+
instructions: allIx,
|
|
6673
|
+
}).compileToLegacyMessage();
|
|
6674
|
+
|
|
6675
|
+
return new VersionedTransaction(message);
|
|
6676
|
+
} else {
|
|
6677
|
+
return new Transaction().add(...allIx);
|
|
6678
|
+
}
|
|
6560
6679
|
} else {
|
|
6561
6680
|
const marketLookupTable = await this.fetchMarketLookupTableAccount();
|
|
6562
6681
|
lookupTables = lookupTables
|
|
@@ -6564,11 +6683,7 @@ export class DriftClient {
|
|
|
6564
6683
|
: [marketLookupTable];
|
|
6565
6684
|
const message = new TransactionMessage({
|
|
6566
6685
|
payerKey: this.provider.wallet.publicKey,
|
|
6567
|
-
recentBlockhash:
|
|
6568
|
-
await this.provider.connection.getRecentBlockhash(
|
|
6569
|
-
this.opts.preflightCommitment
|
|
6570
|
-
)
|
|
6571
|
-
).blockhash,
|
|
6686
|
+
recentBlockhash: latestBlockHashAndContext.value.blockhash,
|
|
6572
6687
|
instructions: allIx,
|
|
6573
6688
|
}).compileToV0Message(lookupTables);
|
|
6574
6689
|
|
package/src/idl/drift.json
CHANGED
|
@@ -5,11 +5,13 @@ export type DriftPriorityFeeResponse = HeliusPriorityFeeLevels[];
|
|
|
5
5
|
|
|
6
6
|
export async function fetchDriftPriorityFee(
|
|
7
7
|
url: string,
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
marketTypes: string[],
|
|
9
|
+
marketIndexs: number[]
|
|
10
10
|
): Promise<DriftPriorityFeeResponse> {
|
|
11
11
|
const response = await fetch(
|
|
12
|
-
`${url}?marketType=${
|
|
12
|
+
`${url}/batchPriorityFees?marketType=${marketTypes.join(
|
|
13
|
+
','
|
|
14
|
+
)}&marketIndex=${marketIndexs.join(',')}`
|
|
13
15
|
);
|
|
14
16
|
return await response.json();
|
|
15
17
|
}
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
fetchHeliusPriorityFee,
|
|
14
14
|
} from './heliusPriorityFeeMethod';
|
|
15
15
|
import { fetchDriftPriorityFee } from './driftPriorityFeeMethod';
|
|
16
|
-
import { getVariant, MarketType } from '..';
|
|
17
16
|
|
|
18
17
|
export type DriftMarketInfo = {
|
|
19
18
|
marketType: string;
|
|
@@ -24,7 +23,7 @@ export class PriorityFeeSubscriber {
|
|
|
24
23
|
connection: Connection;
|
|
25
24
|
frequencyMs: number;
|
|
26
25
|
addresses: string[];
|
|
27
|
-
|
|
26
|
+
driftMarkets?: DriftMarketInfo[];
|
|
28
27
|
customStrategy?: PriorityFeeStrategy;
|
|
29
28
|
averageStrategy = new AverageOverSlotsStrategy();
|
|
30
29
|
maxStrategy = new MaxOverSlotsStrategy();
|
|
@@ -51,7 +50,7 @@ export class PriorityFeeSubscriber {
|
|
|
51
50
|
this.addresses = config.addresses
|
|
52
51
|
? config.addresses.map((address) => address.toBase58())
|
|
53
52
|
: [];
|
|
54
|
-
this.
|
|
53
|
+
this.driftMarkets = config.driftMarkets;
|
|
55
54
|
|
|
56
55
|
if (config.customStrategy) {
|
|
57
56
|
this.customStrategy = config.customStrategy;
|
|
@@ -137,26 +136,19 @@ export class PriorityFeeSubscriber {
|
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
private async loadForDrift(): Promise<void> {
|
|
140
|
-
if (!this.
|
|
139
|
+
if (!this.driftMarkets) {
|
|
141
140
|
return;
|
|
142
141
|
}
|
|
143
142
|
const sample = await fetchDriftPriorityFee(
|
|
144
143
|
this.driftPriorityFeeEndpoint!,
|
|
145
|
-
this.
|
|
146
|
-
this.
|
|
144
|
+
this.driftMarkets.map((m) => m.marketType),
|
|
145
|
+
this.driftMarkets.map((m) => m.marketIndex)
|
|
147
146
|
);
|
|
148
147
|
if (sample.length > 0) {
|
|
149
148
|
this.lastAvgStrategyResult = sample[HeliusPriorityLevel.MEDIUM];
|
|
150
149
|
this.lastMaxStrategyResult = sample[HeliusPriorityLevel.UNSAFE_MAX];
|
|
151
150
|
if (this.customStrategy) {
|
|
152
|
-
|
|
153
|
-
this.lastCustomStrategyResult = this.customStrategy.calculate({
|
|
154
|
-
jsonrpc: '',
|
|
155
|
-
result: {
|
|
156
|
-
priorityFeeLevels: sample[0],
|
|
157
|
-
},
|
|
158
|
-
id: '',
|
|
159
|
-
});
|
|
151
|
+
this.lastCustomStrategyResult = this.customStrategy.calculate(sample);
|
|
160
152
|
}
|
|
161
153
|
}
|
|
162
154
|
}
|
|
@@ -251,7 +243,7 @@ export class PriorityFeeSubscriber {
|
|
|
251
243
|
this.addresses = addresses.map((k) => k.toBase58());
|
|
252
244
|
}
|
|
253
245
|
|
|
254
|
-
public updateMarketTypeAndIndex(
|
|
255
|
-
this.
|
|
246
|
+
public updateMarketTypeAndIndex(driftMarkets: DriftMarketInfo[]) {
|
|
247
|
+
this.driftMarkets = driftMarkets;
|
|
256
248
|
}
|
|
257
249
|
}
|
package/src/priorityFee/types.ts
CHANGED
|
@@ -2,12 +2,16 @@ import { Connection, PublicKey } from '@solana/web3.js';
|
|
|
2
2
|
import { SolanaPriorityFeeResponse } from './solanaPriorityFeeMethod';
|
|
3
3
|
import { HeliusPriorityFeeResponse } from './heliusPriorityFeeMethod';
|
|
4
4
|
import { DriftMarketInfo } from './priorityFeeSubscriber';
|
|
5
|
+
import { DriftPriorityFeeResponse } from './driftPriorityFeeMethod';
|
|
5
6
|
|
|
6
7
|
export interface PriorityFeeStrategy {
|
|
7
8
|
// calculate the priority fee for a given set of samples.
|
|
8
9
|
// expect samples to be sorted in descending order (by slot)
|
|
9
10
|
calculate(
|
|
10
|
-
samples:
|
|
11
|
+
samples:
|
|
12
|
+
| SolanaPriorityFeeResponse[]
|
|
13
|
+
| HeliusPriorityFeeResponse
|
|
14
|
+
| DriftPriorityFeeResponse
|
|
11
15
|
): number;
|
|
12
16
|
}
|
|
13
17
|
|
|
@@ -25,7 +29,7 @@ export type PriorityFeeSubscriberConfig = {
|
|
|
25
29
|
/// addresses you plan to write lock, used to determine priority fees
|
|
26
30
|
addresses?: PublicKey[];
|
|
27
31
|
/// drift market type and index, optionally provide at initialization time if using priorityFeeMethod.DRIFT
|
|
28
|
-
|
|
32
|
+
driftMarkets?: DriftMarketInfo[];
|
|
29
33
|
/// custom strategy to calculate priority fees, defaults to AVERAGE
|
|
30
34
|
customStrategy?: PriorityFeeStrategy;
|
|
31
35
|
/// method for fetching priority fee samples
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AddressLookupTableAccount,
|
|
3
|
+
Connection,
|
|
4
|
+
RpcResponseAndContext,
|
|
5
|
+
SimulatedTransactionResponse,
|
|
6
|
+
TransactionInstruction,
|
|
7
|
+
TransactionVersion,
|
|
8
|
+
VersionedTransaction,
|
|
9
|
+
} from '@solana/web3.js';
|
|
10
|
+
import { BaseTxParams, ProcessingTxParams } from '..';
|
|
11
|
+
|
|
12
|
+
const COMPUTE_UNIT_BUFFER_FACTOR = 1.2;
|
|
13
|
+
|
|
14
|
+
const TEST_SIMS_ALWAYS_FAIL = false;
|
|
15
|
+
|
|
16
|
+
type TransactionProps = {
|
|
17
|
+
instructions: TransactionInstruction | TransactionInstruction[];
|
|
18
|
+
txParams?: BaseTxParams;
|
|
19
|
+
txVersion?: TransactionVersion;
|
|
20
|
+
lookupTables?: AddressLookupTableAccount[];
|
|
21
|
+
forceVersionedTransaction?: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* This class is responsible for running through a "processing" pipeline for a base transaction, to adjust the standard transaction parameters based on a given configuration.
|
|
26
|
+
*/
|
|
27
|
+
export class TransactionProcessor {
|
|
28
|
+
private static async getComputeUnitsFromSim(
|
|
29
|
+
txSim: RpcResponseAndContext<SimulatedTransactionResponse>
|
|
30
|
+
) {
|
|
31
|
+
if (txSim?.value?.unitsConsumed) {
|
|
32
|
+
return txSim?.value?.unitsConsumed;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public static async getTxSimComputeUnits(
|
|
39
|
+
tx: VersionedTransaction,
|
|
40
|
+
connection: Connection
|
|
41
|
+
): Promise<{ success: boolean; computeUnits: number }> {
|
|
42
|
+
try {
|
|
43
|
+
if (TEST_SIMS_ALWAYS_FAIL)
|
|
44
|
+
throw new Error('Test Error::SIMS_ALWAYS_FAIL');
|
|
45
|
+
|
|
46
|
+
const simTxResult = await connection.simulateTransaction(tx, {
|
|
47
|
+
replaceRecentBlockhash: true, // This is important to ensure that the blockhash is not too new.. Otherwise we will very often receive a "blockHashNotFound" error
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (simTxResult?.value?.err) {
|
|
51
|
+
throw new Error(simTxResult?.value?.err?.toString());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const computeUnits = await this.getComputeUnitsFromSim(simTxResult);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
success: true,
|
|
58
|
+
computeUnits: computeUnits,
|
|
59
|
+
};
|
|
60
|
+
} catch (e) {
|
|
61
|
+
console.warn(
|
|
62
|
+
`Failed to get Simulated Compute Units for txParamProcessor`,
|
|
63
|
+
e
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
computeUnits: undefined,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static async process(props: {
|
|
74
|
+
txProps: TransactionProps;
|
|
75
|
+
txBuilder: (
|
|
76
|
+
baseTransactionProps: TransactionProps
|
|
77
|
+
) => Promise<VersionedTransaction>;
|
|
78
|
+
processConfig: ProcessingTxParams;
|
|
79
|
+
processParams: {
|
|
80
|
+
connection: Connection;
|
|
81
|
+
};
|
|
82
|
+
}): Promise<BaseTxParams> {
|
|
83
|
+
// # Exit early if no process config is provided
|
|
84
|
+
if (!props.processConfig || Object.keys(props.processConfig).length === 0) {
|
|
85
|
+
return props.txProps.txParams;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// # Setup
|
|
89
|
+
const {
|
|
90
|
+
txProps: txProps,
|
|
91
|
+
txBuilder: txBuilder,
|
|
92
|
+
processConfig,
|
|
93
|
+
processParams: processProps,
|
|
94
|
+
} = props;
|
|
95
|
+
|
|
96
|
+
const baseTransaction = await txBuilder(txProps);
|
|
97
|
+
|
|
98
|
+
const finalTxProps = {
|
|
99
|
+
...txProps,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// # Run Processes
|
|
103
|
+
if (processConfig.useSimulatedComputeUnits) {
|
|
104
|
+
const txSimComputeUnitsResult = await this.getTxSimComputeUnits(
|
|
105
|
+
baseTransaction,
|
|
106
|
+
processProps.connection
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
if (txSimComputeUnitsResult.success) {
|
|
110
|
+
const bufferedComputeUnits =
|
|
111
|
+
txSimComputeUnitsResult.computeUnits *
|
|
112
|
+
(processConfig?.computeUnitsBufferMultiplier ??
|
|
113
|
+
COMPUTE_UNIT_BUFFER_FACTOR);
|
|
114
|
+
|
|
115
|
+
// Adjust the transaction based on the simulated compute units
|
|
116
|
+
finalTxProps.txParams = {
|
|
117
|
+
...txProps.txParams,
|
|
118
|
+
computeUnits: bufferedComputeUnits,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// # Return Final Tx Params
|
|
124
|
+
return finalTxProps.txParams;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -124,17 +124,18 @@ export class WhileValidTxSender extends BaseTxSender {
|
|
|
124
124
|
extraConfirmationOptions?: ExtraConfirmationOptions
|
|
125
125
|
): Promise<TxSigAndSlot> {
|
|
126
126
|
const latestBlockhash = await this.connection.getLatestBlockhash();
|
|
127
|
-
tx.message.recentBlockhash = latestBlockhash.blockhash;
|
|
128
127
|
|
|
129
128
|
let signedTx;
|
|
130
129
|
if (preSigned) {
|
|
131
130
|
signedTx = tx;
|
|
132
131
|
// @ts-ignore
|
|
133
132
|
} else if (this.wallet.payer) {
|
|
133
|
+
tx.message.recentBlockhash = latestBlockhash.blockhash;
|
|
134
134
|
// @ts-ignore
|
|
135
135
|
tx.sign((additionalSigners ?? []).concat(this.wallet.payer));
|
|
136
136
|
signedTx = tx;
|
|
137
137
|
} else {
|
|
138
|
+
tx.message.recentBlockhash = latestBlockhash.blockhash;
|
|
138
139
|
additionalSigners
|
|
139
140
|
?.filter((s): s is Signer => s !== undefined)
|
|
140
141
|
.forEach((kp) => {
|
package/src/types.ts
CHANGED
|
@@ -999,11 +999,18 @@ export type ReferrerInfo = {
|
|
|
999
999
|
referrerStats: PublicKey;
|
|
1000
1000
|
};
|
|
1001
1001
|
|
|
1002
|
-
export type
|
|
1002
|
+
export type BaseTxParams = {
|
|
1003
1003
|
computeUnits?: number;
|
|
1004
1004
|
computeUnitsPrice?: number;
|
|
1005
1005
|
};
|
|
1006
1006
|
|
|
1007
|
+
export type ProcessingTxParams = {
|
|
1008
|
+
useSimulatedComputeUnits?: boolean;
|
|
1009
|
+
computeUnitsBufferMultiplier?: number;
|
|
1010
|
+
};
|
|
1011
|
+
|
|
1012
|
+
export type TxParams = BaseTxParams & ProcessingTxParams;
|
|
1013
|
+
|
|
1007
1014
|
export class SwapReduceOnly {
|
|
1008
1015
|
static readonly In = { in: {} };
|
|
1009
1016
|
static readonly Out = { out: {} };
|
package/src/user.ts
CHANGED
|
@@ -3123,8 +3123,13 @@ export class User {
|
|
|
3123
3123
|
let makerFee =
|
|
3124
3124
|
feeTier.makerRebateNumerator / feeTier.makerRebateDenominator;
|
|
3125
3125
|
|
|
3126
|
-
if (marketIndex !== undefined
|
|
3127
|
-
|
|
3126
|
+
if (marketIndex !== undefined) {
|
|
3127
|
+
let marketAccount = null;
|
|
3128
|
+
if (isVariant(marketType, 'perp')) {
|
|
3129
|
+
marketAccount = this.driftClient.getPerpMarketAccount(marketIndex);
|
|
3130
|
+
} else {
|
|
3131
|
+
marketAccount = this.driftClient.getSpotMarketAccount(marketIndex);
|
|
3132
|
+
}
|
|
3128
3133
|
takerFee += (takerFee * marketAccount.feeAdjustment) / 100;
|
|
3129
3134
|
makerFee += (makerFee * marketAccount.feeAdjustment) / 100;
|
|
3130
3135
|
}
|