@drift-labs/sdk 2.108.0-beta.6 → 2.108.0-beta.8
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/browser/driftClient.d.ts +5 -5
- package/lib/browser/driftClient.js +17 -14
- package/lib/browser/index.d.ts +1 -0
- package/lib/browser/index.js +1 -0
- package/lib/browser/math/oracles.js +16 -0
- package/lib/browser/tx/txHandler.d.ts +1 -0
- package/lib/browser/tx/txHandler.js +18 -7
- package/lib/browser/tx/utils.d.ts +3 -1
- package/lib/browser/tx/utils.js +73 -1
- package/lib/node/driftClient.d.ts +5 -5
- package/lib/node/driftClient.js +17 -14
- package/lib/node/index.d.ts +1 -0
- package/lib/node/index.js +1 -0
- package/lib/node/math/oracles.js +16 -0
- package/lib/node/tx/txHandler.d.ts +1 -0
- package/lib/node/tx/txHandler.js +18 -7
- package/lib/node/tx/utils.d.ts +3 -1
- package/lib/node/tx/utils.js +73 -1
- package/package.json +1 -1
- package/src/driftClient.ts +53 -19
- package/src/index.ts +1 -0
- package/src/math/oracles.ts +28 -0
- package/src/tx/txHandler.ts +27 -8
- package/src/tx/utils.ts +115 -1
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.108.0-beta.
|
|
1
|
+
2.108.0-beta.8
|
|
@@ -389,8 +389,8 @@ export declare class DriftClient {
|
|
|
389
389
|
marketIndex?: number;
|
|
390
390
|
direction?: PositionDirection;
|
|
391
391
|
}, placeOrderParams: OrderParams[], txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
|
|
392
|
-
placeOrders(params: OrderParams[], txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
|
|
393
|
-
preparePlaceOrdersTx(params: OrderParams[], txParams?: TxParams, subAccountId?: number): Promise<{
|
|
392
|
+
placeOrders(params: OrderParams[], txParams?: TxParams, subAccountId?: number, optionalIxs?: TransactionInstruction[]): Promise<TransactionSignature>;
|
|
393
|
+
preparePlaceOrdersTx(params: OrderParams[], txParams?: TxParams, subAccountId?: number, optionalIxs?: TransactionInstruction[]): Promise<{
|
|
394
394
|
placeOrdersTx: anchor.web3.Transaction | anchor.web3.VersionedTransaction;
|
|
395
395
|
}>;
|
|
396
396
|
getPlaceOrdersIx(params: OptionalOrderParams[], subAccountId?: number): Promise<TransactionInstruction>;
|
|
@@ -520,7 +520,7 @@ export declare class DriftClient {
|
|
|
520
520
|
updateUserOpenOrdersCount(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams, fillerPublicKey?: PublicKey): Promise<TransactionSignature>;
|
|
521
521
|
getUpdateUserOpenOrdersCountIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, fillerPublicKey?: PublicKey): Promise<TransactionInstruction>;
|
|
522
522
|
placeAndTakePerpOrder(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, successCondition?: PlaceAndTakeOrderSuccessCondition, auctionDurationPercentage?: number, txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
|
|
523
|
-
preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, bracketOrdersParams?: OptionalOrderParams[], txParams?: TxParams, subAccountId?: number, cancelExistingOrders?: boolean, settlePnl?: boolean, exitEarlyIfSimFails?: boolean, auctionDurationPercentage?: number): Promise<{
|
|
523
|
+
preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, bracketOrdersParams?: OptionalOrderParams[], txParams?: TxParams, subAccountId?: number, cancelExistingOrders?: boolean, settlePnl?: boolean, exitEarlyIfSimFails?: boolean, auctionDurationPercentage?: number, optionalIxs?: TransactionInstruction[]): Promise<{
|
|
524
524
|
placeAndTakeTx: Transaction | VersionedTransaction;
|
|
525
525
|
cancelExistingOrdersTx: Transaction | VersionedTransaction;
|
|
526
526
|
settlePnlTx: Transaction | VersionedTransaction;
|
|
@@ -706,7 +706,7 @@ export declare class DriftClient {
|
|
|
706
706
|
settleeUserAccountPublicKey: PublicKey;
|
|
707
707
|
settleeUserAccount: UserAccount;
|
|
708
708
|
}[], marketIndexes: number[]): Promise<Array<TransactionInstruction>>;
|
|
709
|
-
settlePNL(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number, txParams?: TxParams): Promise<TransactionSignature>;
|
|
709
|
+
settlePNL(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number, txParams?: TxParams, optionalIxs?: TransactionInstruction[]): Promise<TransactionSignature>;
|
|
710
710
|
settlePNLIx(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number): Promise<TransactionInstruction>;
|
|
711
711
|
settleMultiplePNLs(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, txParams?: TxParams): Promise<TransactionSignature>;
|
|
712
712
|
settleMultiplePNLsMultipleTxs(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, txParams?: TxParams): Promise<TransactionSignature[]>;
|
|
@@ -896,7 +896,7 @@ export declare class DriftClient {
|
|
|
896
896
|
* @returns
|
|
897
897
|
*/
|
|
898
898
|
sendTransaction(tx: Transaction | VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
|
|
899
|
-
buildTransaction(instructions: TransactionInstruction | TransactionInstruction[], txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean, recentBlockhash?: BlockhashWithExpiryBlockHeight): Promise<Transaction | VersionedTransaction>;
|
|
899
|
+
buildTransaction(instructions: TransactionInstruction | TransactionInstruction[], txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean, recentBlockhash?: BlockhashWithExpiryBlockHeight, optionalIxs?: TransactionInstruction[]): Promise<Transaction | VersionedTransaction>;
|
|
900
900
|
buildBulkTransactions(instructions: (TransactionInstruction | TransactionInstruction[])[], txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean): Promise<(Transaction | VersionedTransaction)[]>;
|
|
901
901
|
buildTransactionsMap(instructionsMap: Record<string, TransactionInstruction | TransactionInstruction[]>, txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean): Promise<MappedRecord<Record<string, anchor.web3.TransactionInstruction | anchor.web3.TransactionInstruction[]>, anchor.web3.Transaction | anchor.web3.VersionedTransaction>>;
|
|
902
902
|
buildAndSignTransactionsMap(instructionsMap: Record<string, TransactionInstruction | TransactionInstruction[]>, txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean): Promise<{
|
|
@@ -2069,13 +2069,13 @@ class DriftClient {
|
|
|
2069
2069
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2070
2070
|
return txSig;
|
|
2071
2071
|
}
|
|
2072
|
-
async placeOrders(params, txParams, subAccountId) {
|
|
2073
|
-
const { txSig } = await this.sendTransaction((await this.preparePlaceOrdersTx(params, txParams, subAccountId))
|
|
2074
|
-
.placeOrdersTx, [], this.opts, false);
|
|
2072
|
+
async placeOrders(params, txParams, subAccountId, optionalIxs) {
|
|
2073
|
+
const { txSig } = await this.sendTransaction((await this.preparePlaceOrdersTx(params, txParams, subAccountId, optionalIxs)).placeOrdersTx, [], this.opts, false);
|
|
2075
2074
|
return txSig;
|
|
2076
2075
|
}
|
|
2077
|
-
async preparePlaceOrdersTx(params, txParams, subAccountId) {
|
|
2078
|
-
const
|
|
2076
|
+
async preparePlaceOrdersTx(params, txParams, subAccountId, optionalIxs) {
|
|
2077
|
+
const lookupTableAccount = await this.fetchMarketLookupTableAccount();
|
|
2078
|
+
const tx = await this.buildTransaction(await this.getPlaceOrdersIx(params, subAccountId), txParams, undefined, [lookupTableAccount], undefined, undefined, optionalIxs);
|
|
2079
2079
|
return {
|
|
2080
2080
|
placeOrdersTx: tx,
|
|
2081
2081
|
};
|
|
@@ -2989,7 +2989,7 @@ class DriftClient {
|
|
|
2989
2989
|
this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
|
|
2990
2990
|
return txSig;
|
|
2991
2991
|
}
|
|
2992
|
-
async preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams, makerInfo, referrerInfo, bracketOrdersParams = new Array(), txParams, subAccountId, cancelExistingOrders, settlePnl, exitEarlyIfSimFails, auctionDurationPercentage) {
|
|
2992
|
+
async preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams, makerInfo, referrerInfo, bracketOrdersParams = new Array(), txParams, subAccountId, cancelExistingOrders, settlePnl, exitEarlyIfSimFails, auctionDurationPercentage, optionalIxs) {
|
|
2993
2993
|
const placeAndTakeIxs = [];
|
|
2994
2994
|
const txsToSign = {
|
|
2995
2995
|
placeAndTakeTx: undefined,
|
|
@@ -2998,6 +2998,7 @@ class DriftClient {
|
|
|
2998
2998
|
};
|
|
2999
2999
|
// Get recent block hash so that we can re-use it for all transactions. Makes this logic run faster with fewer RPC requests
|
|
3000
3000
|
const recentBlockHash = await this.txHandler.getLatestBlockhashForTransaction();
|
|
3001
|
+
const lookupTableAccount = await this.fetchMarketLookupTableAccount();
|
|
3001
3002
|
let earlyExitFailedPlaceAndTakeSim = false;
|
|
3002
3003
|
const prepPlaceAndTakeTx = async () => {
|
|
3003
3004
|
var _a;
|
|
@@ -3014,7 +3015,7 @@ class DriftClient {
|
|
|
3014
3015
|
useSimulatedComputeUnits: false,
|
|
3015
3016
|
};
|
|
3016
3017
|
if (shouldUseSimulationComputeUnits || shouldExitIfSimulationFails) {
|
|
3017
|
-
const placeAndTakeTxToSim = (await this.buildTransaction(placeAndTakeIxs, txParams, undefined,
|
|
3018
|
+
const placeAndTakeTxToSim = (await this.buildTransaction(placeAndTakeIxs, txParams, undefined, [lookupTableAccount], true, recentBlockHash, optionalIxs));
|
|
3018
3019
|
const simulationResult = await txParamProcessor_1.TransactionParamProcessor.getTxSimComputeUnits(placeAndTakeTxToSim, this.connection, (_a = txParams.computeUnitsBufferMultiplier) !== null && _a !== void 0 ? _a : 1.2, txParams.lowerBoundCu);
|
|
3019
3020
|
if (shouldExitIfSimulationFails && !simulationResult.success) {
|
|
3020
3021
|
earlyExitFailedPlaceAndTakeSim = true;
|
|
@@ -3023,17 +3024,17 @@ class DriftClient {
|
|
|
3023
3024
|
txsToSign.placeAndTakeTx = await this.buildTransaction(placeAndTakeIxs, {
|
|
3024
3025
|
...txParamsWithoutImplicitSimulation,
|
|
3025
3026
|
computeUnits: simulationResult.computeUnits,
|
|
3026
|
-
}, undefined,
|
|
3027
|
+
}, undefined, [lookupTableAccount], undefined, recentBlockHash, optionalIxs);
|
|
3027
3028
|
}
|
|
3028
3029
|
else {
|
|
3029
|
-
txsToSign.placeAndTakeTx = await this.buildTransaction(placeAndTakeIxs, txParams, undefined,
|
|
3030
|
+
txsToSign.placeAndTakeTx = await this.buildTransaction(placeAndTakeIxs, txParams, undefined, [lookupTableAccount], undefined, recentBlockHash, optionalIxs);
|
|
3030
3031
|
}
|
|
3031
3032
|
return;
|
|
3032
3033
|
};
|
|
3033
3034
|
const prepCancelOrderTx = async () => {
|
|
3034
3035
|
if (cancelExistingOrders && (0, types_1.isVariant)(orderParams.marketType, 'perp')) {
|
|
3035
3036
|
const cancelOrdersIx = await this.getCancelOrdersIx(orderParams.marketType, orderParams.marketIndex, null, subAccountId);
|
|
3036
|
-
txsToSign.cancelExistingOrdersTx = await this.buildTransaction([cancelOrdersIx], txParams, this.txVersion,
|
|
3037
|
+
txsToSign.cancelExistingOrdersTx = await this.buildTransaction([cancelOrdersIx], txParams, this.txVersion, [lookupTableAccount], undefined, recentBlockHash, optionalIxs);
|
|
3037
3038
|
}
|
|
3038
3039
|
return;
|
|
3039
3040
|
};
|
|
@@ -3041,7 +3042,7 @@ class DriftClient {
|
|
|
3041
3042
|
if (settlePnl && (0, types_1.isVariant)(orderParams.marketType, 'perp')) {
|
|
3042
3043
|
const userAccountPublicKey = await this.getUserAccountPublicKey(subAccountId);
|
|
3043
3044
|
const settlePnlIx = await this.settlePNLIx(userAccountPublicKey, this.getUserAccount(subAccountId), orderParams.marketIndex);
|
|
3044
|
-
txsToSign.settlePnlTx = await this.buildTransaction([settlePnlIx], txParams, this.txVersion,
|
|
3045
|
+
txsToSign.settlePnlTx = await this.buildTransaction([settlePnlIx], txParams, this.txVersion, [lookupTableAccount], undefined, recentBlockHash, optionalIxs);
|
|
3045
3046
|
}
|
|
3046
3047
|
return;
|
|
3047
3048
|
};
|
|
@@ -3647,8 +3648,9 @@ class DriftClient {
|
|
|
3647
3648
|
}
|
|
3648
3649
|
return ixs;
|
|
3649
3650
|
}
|
|
3650
|
-
async settlePNL(settleeUserAccountPublicKey, settleeUserAccount, marketIndex, txParams) {
|
|
3651
|
-
const
|
|
3651
|
+
async settlePNL(settleeUserAccountPublicKey, settleeUserAccount, marketIndex, txParams, optionalIxs) {
|
|
3652
|
+
const lookupTableAccount = await this.fetchMarketLookupTableAccount();
|
|
3653
|
+
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex), txParams, undefined, [lookupTableAccount], undefined, undefined, optionalIxs), [], this.opts);
|
|
3652
3654
|
return txSig;
|
|
3653
3655
|
}
|
|
3654
3656
|
async settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex) {
|
|
@@ -4894,7 +4896,7 @@ class DriftClient {
|
|
|
4894
4896
|
return this.txSender.send(tx, additionalSigners, opts !== null && opts !== void 0 ? opts : this.opts, preSigned);
|
|
4895
4897
|
}
|
|
4896
4898
|
}
|
|
4897
|
-
async buildTransaction(instructions, txParams, txVersion, lookupTables, forceVersionedTransaction, recentBlockhash) {
|
|
4899
|
+
async buildTransaction(instructions, txParams, txVersion, lookupTables, forceVersionedTransaction, recentBlockhash, optionalIxs) {
|
|
4898
4900
|
return this.txHandler.buildTransaction({
|
|
4899
4901
|
instructions,
|
|
4900
4902
|
txVersion: txVersion !== null && txVersion !== void 0 ? txVersion : this.txVersion,
|
|
@@ -4905,6 +4907,7 @@ class DriftClient {
|
|
|
4905
4907
|
lookupTables,
|
|
4906
4908
|
forceVersionedTransaction,
|
|
4907
4909
|
recentBlockhash,
|
|
4910
|
+
optionalIxs,
|
|
4908
4911
|
});
|
|
4909
4912
|
}
|
|
4910
4913
|
async buildBulkTransactions(instructions, txParams, txVersion, lookupTables, forceVersionedTransaction) {
|
package/lib/browser/index.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ export * from './oracles/pythClient';
|
|
|
86
86
|
export * from './oracles/pythPullClient';
|
|
87
87
|
export * from './oracles/pythLazerClient';
|
|
88
88
|
export * from './oracles/switchboardOnDemandClient';
|
|
89
|
+
export * from './oracles/oracleId';
|
|
89
90
|
export * from './swift/swiftOrderSubscriber';
|
|
90
91
|
export * from './tx/fastSingleTxSender';
|
|
91
92
|
export * from './tx/retryTxSender';
|
package/lib/browser/index.js
CHANGED
|
@@ -109,6 +109,7 @@ __exportStar(require("./oracles/pythClient"), exports);
|
|
|
109
109
|
__exportStar(require("./oracles/pythPullClient"), exports);
|
|
110
110
|
__exportStar(require("./oracles/pythLazerClient"), exports);
|
|
111
111
|
__exportStar(require("./oracles/switchboardOnDemandClient"), exports);
|
|
112
|
+
__exportStar(require("./oracles/oracleId"), exports);
|
|
112
113
|
__exportStar(require("./swift/swiftOrderSubscriber"), exports);
|
|
113
114
|
__exportStar(require("./tx/fastSingleTxSender"), exports);
|
|
114
115
|
__exportStar(require("./tx/retryTxSender"), exports);
|
|
@@ -149,6 +149,22 @@ function getMultipleBetweenOracleSources(firstOracleSource, secondOracleSource)
|
|
|
149
149
|
(0, types_1.isVariant)(secondOracleSource, 'pythPull')) {
|
|
150
150
|
return { numerator: new index_1.BN(1), denominator: new index_1.BN(1000) };
|
|
151
151
|
}
|
|
152
|
+
if ((0, types_1.isVariant)(firstOracleSource, 'pythLazer') &&
|
|
153
|
+
(0, types_1.isVariant)(secondOracleSource, 'pythLazer1M')) {
|
|
154
|
+
return { numerator: new index_1.BN(1000000), denominator: new index_1.BN(1) };
|
|
155
|
+
}
|
|
156
|
+
if ((0, types_1.isVariant)(firstOracleSource, 'pythLazer') &&
|
|
157
|
+
(0, types_1.isVariant)(secondOracleSource, 'pythLazer1K')) {
|
|
158
|
+
return { numerator: new index_1.BN(1000), denominator: new index_1.BN(1) };
|
|
159
|
+
}
|
|
160
|
+
if ((0, types_1.isVariant)(firstOracleSource, 'pythLazer1M') &&
|
|
161
|
+
(0, types_1.isVariant)(secondOracleSource, 'pythLazer')) {
|
|
162
|
+
return { numerator: new index_1.BN(1), denominator: new index_1.BN(1000000) };
|
|
163
|
+
}
|
|
164
|
+
if ((0, types_1.isVariant)(firstOracleSource, 'pythLazer1K') &&
|
|
165
|
+
(0, types_1.isVariant)(secondOracleSource, 'pythLazer')) {
|
|
166
|
+
return { numerator: new index_1.BN(1), denominator: new index_1.BN(1000) };
|
|
167
|
+
}
|
|
152
168
|
return { numerator: new index_1.BN(1), denominator: new index_1.BN(1) };
|
|
153
169
|
}
|
|
154
170
|
exports.getMultipleBetweenOracleSources = getMultipleBetweenOracleSources;
|
|
@@ -277,24 +277,35 @@ class TxHandler {
|
|
|
277
277
|
*/
|
|
278
278
|
async buildTransaction(props) {
|
|
279
279
|
var _a;
|
|
280
|
-
const {
|
|
280
|
+
const { txVersion, txParams, connection: _connection, preFlightCommitment: _preFlightCommitment, fetchMarketLookupTableAccount, forceVersionedTransaction, instructions, } = props;
|
|
281
281
|
let { lookupTables } = props;
|
|
282
282
|
// # Collect and process Tx Params
|
|
283
283
|
let baseTxParams = {
|
|
284
284
|
computeUnits: txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits,
|
|
285
285
|
computeUnitsPrice: txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice,
|
|
286
286
|
};
|
|
287
|
+
const instructionsArray = Array.isArray(instructions)
|
|
288
|
+
? instructions
|
|
289
|
+
: [instructions];
|
|
290
|
+
let instructionsToUse;
|
|
291
|
+
// add optional ixs if there's room (usually oracle cranks)
|
|
292
|
+
if (props.optionalIxs && txVersion === 0) {
|
|
293
|
+
instructionsToUse = (0, utils_1.getCombinedInstructions)(instructionsArray, props.optionalIxs, txVersion === 0, lookupTables);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
instructionsToUse = instructionsArray;
|
|
297
|
+
}
|
|
287
298
|
if (txParams === null || txParams === void 0 ? void 0 : txParams.useSimulatedComputeUnits) {
|
|
288
|
-
const processedTxParams = await this.getProcessedTransactionParams(
|
|
299
|
+
const processedTxParams = await this.getProcessedTransactionParams({
|
|
300
|
+
...props,
|
|
301
|
+
instructions: instructionsToUse,
|
|
302
|
+
});
|
|
289
303
|
baseTxParams = {
|
|
290
304
|
...baseTxParams,
|
|
291
305
|
...processedTxParams,
|
|
292
306
|
};
|
|
293
307
|
}
|
|
294
|
-
const
|
|
295
|
-
? instructions
|
|
296
|
-
: [instructions];
|
|
297
|
-
const { hasSetComputeUnitLimitIx, hasSetComputeUnitPriceIx } = (0, computeUnits_1.containsComputeUnitIxs)(instructionsArray);
|
|
308
|
+
const { hasSetComputeUnitLimitIx, hasSetComputeUnitPriceIx } = (0, computeUnits_1.containsComputeUnitIxs)(instructionsToUse);
|
|
298
309
|
// # Create Tx Instructions
|
|
299
310
|
const allIx = [];
|
|
300
311
|
const computeUnits = baseTxParams === null || baseTxParams === void 0 ? void 0 : baseTxParams.computeUnits;
|
|
@@ -314,7 +325,7 @@ class TxHandler {
|
|
|
314
325
|
microLamports: computeUnitsPrice,
|
|
315
326
|
}));
|
|
316
327
|
}
|
|
317
|
-
allIx.push(...
|
|
328
|
+
allIx.push(...instructionsToUse);
|
|
318
329
|
const recentBlockhash = (_a = props === null || props === void 0 ? void 0 : props.recentBlockhash) !== null && _a !== void 0 ? _a : (await this.getLatestBlockhashForTransaction());
|
|
319
330
|
// # Create and return Transaction
|
|
320
331
|
if (txVersion === 'legacy') {
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
import { Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
1
|
+
import { AddressLookupTableAccount, Transaction, TransactionInstruction, VersionedTransaction } from '@solana/web3.js';
|
|
2
2
|
export declare const isVersionedTransaction: (tx: Transaction | VersionedTransaction) => boolean;
|
|
3
|
+
export declare const getSizeOfTransaction: (instructions: TransactionInstruction[], versionedTransaction?: boolean, addressLookupTables?: AddressLookupTableAccount[]) => number;
|
|
4
|
+
export declare const getCombinedInstructions: (baseInstructions: TransactionInstruction[], optionalInstructions?: TransactionInstruction[], versionedTransaction?: boolean, addressLookupTables?: AddressLookupTableAccount[]) => TransactionInstruction[];
|
package/lib/browser/tx/utils.js
CHANGED
|
@@ -1,10 +1,82 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isVersionedTransaction = void 0;
|
|
3
|
+
exports.getCombinedInstructions = exports.getSizeOfTransaction = exports.isVersionedTransaction = void 0;
|
|
4
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const MAX_SIZE = 1232;
|
|
5
6
|
const isVersionedTransaction = (tx) => {
|
|
6
7
|
const version = tx === null || tx === void 0 ? void 0 : tx.version;
|
|
7
8
|
const isVersionedTx = tx instanceof web3_js_1.VersionedTransaction || version !== undefined;
|
|
8
9
|
return isVersionedTx;
|
|
9
10
|
};
|
|
10
11
|
exports.isVersionedTransaction = isVersionedTransaction;
|
|
12
|
+
const getSizeOfTransaction = (instructions, versionedTransaction = true, addressLookupTables = []) => {
|
|
13
|
+
const programs = new Set();
|
|
14
|
+
const signers = new Set();
|
|
15
|
+
let accounts = new Set();
|
|
16
|
+
instructions.forEach((ix) => {
|
|
17
|
+
try {
|
|
18
|
+
if (ix.programId) {
|
|
19
|
+
programs.add(ix.programId.toBase58());
|
|
20
|
+
accounts.add(ix.programId.toBase58());
|
|
21
|
+
}
|
|
22
|
+
if (ix.keys) {
|
|
23
|
+
ix.keys.forEach((key) => {
|
|
24
|
+
if (key.isSigner) {
|
|
25
|
+
signers.add(key.pubkey.toBase58());
|
|
26
|
+
}
|
|
27
|
+
accounts.add(key.pubkey.toBase58());
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
console.log(e);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const instructionSizes = instructions
|
|
36
|
+
.map((ix) => 1 +
|
|
37
|
+
getSizeOfCompressedU16(ix.keys.length) +
|
|
38
|
+
ix.keys.length +
|
|
39
|
+
getSizeOfCompressedU16(ix.data.length) +
|
|
40
|
+
ix.data.length)
|
|
41
|
+
.reduce((a, b) => a + b, 0);
|
|
42
|
+
let numberOfAddressLookups = 0;
|
|
43
|
+
if (addressLookupTables.length > 0) {
|
|
44
|
+
const lookupTableAddresses = addressLookupTables
|
|
45
|
+
.map((addressLookupTable) => addressLookupTable.state.addresses.map((address) => address.toBase58()))
|
|
46
|
+
.flat();
|
|
47
|
+
const totalNumberOfAccounts = accounts.size;
|
|
48
|
+
accounts = new Set([...accounts].filter((account) => !lookupTableAddresses.includes(account)));
|
|
49
|
+
accounts = new Set([...accounts, ...programs, ...signers]);
|
|
50
|
+
numberOfAddressLookups = totalNumberOfAccounts - accounts.size;
|
|
51
|
+
}
|
|
52
|
+
return (getSizeOfCompressedU16(signers.size) +
|
|
53
|
+
signers.size * 64 + // array of signatures
|
|
54
|
+
3 +
|
|
55
|
+
getSizeOfCompressedU16(accounts.size) +
|
|
56
|
+
32 * accounts.size + // array of account addresses
|
|
57
|
+
32 + // recent blockhash
|
|
58
|
+
getSizeOfCompressedU16(instructions.length) +
|
|
59
|
+
instructionSizes + // array of instructions
|
|
60
|
+
(versionedTransaction ? 1 + getSizeOfCompressedU16(0) : 0) +
|
|
61
|
+
(versionedTransaction ? 32 * addressLookupTables.length : 0) +
|
|
62
|
+
(versionedTransaction && addressLookupTables.length > 0 ? 2 : 0) +
|
|
63
|
+
numberOfAddressLookups);
|
|
64
|
+
};
|
|
65
|
+
exports.getSizeOfTransaction = getSizeOfTransaction;
|
|
66
|
+
const getCombinedInstructions = (baseInstructions, optionalInstructions = [], versionedTransaction = true, addressLookupTables = []) => {
|
|
67
|
+
if (optionalInstructions.length === 0) {
|
|
68
|
+
return baseInstructions;
|
|
69
|
+
}
|
|
70
|
+
let allInstructions = [...optionalInstructions, ...baseInstructions];
|
|
71
|
+
let txSize = (0, exports.getSizeOfTransaction)(allInstructions, versionedTransaction, addressLookupTables);
|
|
72
|
+
while (txSize > MAX_SIZE &&
|
|
73
|
+
allInstructions.length > baseInstructions.length) {
|
|
74
|
+
allInstructions = allInstructions.slice(1);
|
|
75
|
+
txSize = (0, exports.getSizeOfTransaction)(allInstructions, versionedTransaction, addressLookupTables);
|
|
76
|
+
}
|
|
77
|
+
return allInstructions;
|
|
78
|
+
};
|
|
79
|
+
exports.getCombinedInstructions = getCombinedInstructions;
|
|
80
|
+
function getSizeOfCompressedU16(n) {
|
|
81
|
+
return 1 + Number(n >= 128) + Number(n >= 16384);
|
|
82
|
+
}
|
|
@@ -389,8 +389,8 @@ export declare class DriftClient {
|
|
|
389
389
|
marketIndex?: number;
|
|
390
390
|
direction?: PositionDirection;
|
|
391
391
|
}, placeOrderParams: OrderParams[], txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
|
|
392
|
-
placeOrders(params: OrderParams[], txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
|
|
393
|
-
preparePlaceOrdersTx(params: OrderParams[], txParams?: TxParams, subAccountId?: number): Promise<{
|
|
392
|
+
placeOrders(params: OrderParams[], txParams?: TxParams, subAccountId?: number, optionalIxs?: TransactionInstruction[]): Promise<TransactionSignature>;
|
|
393
|
+
preparePlaceOrdersTx(params: OrderParams[], txParams?: TxParams, subAccountId?: number, optionalIxs?: TransactionInstruction[]): Promise<{
|
|
394
394
|
placeOrdersTx: anchor.web3.Transaction | anchor.web3.VersionedTransaction;
|
|
395
395
|
}>;
|
|
396
396
|
getPlaceOrdersIx(params: OptionalOrderParams[], subAccountId?: number): Promise<TransactionInstruction>;
|
|
@@ -520,7 +520,7 @@ export declare class DriftClient {
|
|
|
520
520
|
updateUserOpenOrdersCount(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams, fillerPublicKey?: PublicKey): Promise<TransactionSignature>;
|
|
521
521
|
getUpdateUserOpenOrdersCountIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, fillerPublicKey?: PublicKey): Promise<TransactionInstruction>;
|
|
522
522
|
placeAndTakePerpOrder(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, successCondition?: PlaceAndTakeOrderSuccessCondition, auctionDurationPercentage?: number, txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
|
|
523
|
-
preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, bracketOrdersParams?: OptionalOrderParams[], txParams?: TxParams, subAccountId?: number, cancelExistingOrders?: boolean, settlePnl?: boolean, exitEarlyIfSimFails?: boolean, auctionDurationPercentage?: number): Promise<{
|
|
523
|
+
preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, bracketOrdersParams?: OptionalOrderParams[], txParams?: TxParams, subAccountId?: number, cancelExistingOrders?: boolean, settlePnl?: boolean, exitEarlyIfSimFails?: boolean, auctionDurationPercentage?: number, optionalIxs?: TransactionInstruction[]): Promise<{
|
|
524
524
|
placeAndTakeTx: Transaction | VersionedTransaction;
|
|
525
525
|
cancelExistingOrdersTx: Transaction | VersionedTransaction;
|
|
526
526
|
settlePnlTx: Transaction | VersionedTransaction;
|
|
@@ -706,7 +706,7 @@ export declare class DriftClient {
|
|
|
706
706
|
settleeUserAccountPublicKey: PublicKey;
|
|
707
707
|
settleeUserAccount: UserAccount;
|
|
708
708
|
}[], marketIndexes: number[]): Promise<Array<TransactionInstruction>>;
|
|
709
|
-
settlePNL(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number, txParams?: TxParams): Promise<TransactionSignature>;
|
|
709
|
+
settlePNL(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number, txParams?: TxParams, optionalIxs?: TransactionInstruction[]): Promise<TransactionSignature>;
|
|
710
710
|
settlePNLIx(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number): Promise<TransactionInstruction>;
|
|
711
711
|
settleMultiplePNLs(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, txParams?: TxParams): Promise<TransactionSignature>;
|
|
712
712
|
settleMultiplePNLsMultipleTxs(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, txParams?: TxParams): Promise<TransactionSignature[]>;
|
|
@@ -896,7 +896,7 @@ export declare class DriftClient {
|
|
|
896
896
|
* @returns
|
|
897
897
|
*/
|
|
898
898
|
sendTransaction(tx: Transaction | VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
|
|
899
|
-
buildTransaction(instructions: TransactionInstruction | TransactionInstruction[], txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean, recentBlockhash?: BlockhashWithExpiryBlockHeight): Promise<Transaction | VersionedTransaction>;
|
|
899
|
+
buildTransaction(instructions: TransactionInstruction | TransactionInstruction[], txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean, recentBlockhash?: BlockhashWithExpiryBlockHeight, optionalIxs?: TransactionInstruction[]): Promise<Transaction | VersionedTransaction>;
|
|
900
900
|
buildBulkTransactions(instructions: (TransactionInstruction | TransactionInstruction[])[], txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean): Promise<(Transaction | VersionedTransaction)[]>;
|
|
901
901
|
buildTransactionsMap(instructionsMap: Record<string, TransactionInstruction | TransactionInstruction[]>, txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean): Promise<MappedRecord<Record<string, anchor.web3.TransactionInstruction | anchor.web3.TransactionInstruction[]>, anchor.web3.Transaction | anchor.web3.VersionedTransaction>>;
|
|
902
902
|
buildAndSignTransactionsMap(instructionsMap: Record<string, TransactionInstruction | TransactionInstruction[]>, txParams?: TxParams, txVersion?: TransactionVersion, lookupTables?: AddressLookupTableAccount[], forceVersionedTransaction?: boolean): Promise<{
|
package/lib/node/driftClient.js
CHANGED
|
@@ -2069,13 +2069,13 @@ class DriftClient {
|
|
|
2069
2069
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2070
2070
|
return txSig;
|
|
2071
2071
|
}
|
|
2072
|
-
async placeOrders(params, txParams, subAccountId) {
|
|
2073
|
-
const { txSig } = await this.sendTransaction((await this.preparePlaceOrdersTx(params, txParams, subAccountId))
|
|
2074
|
-
.placeOrdersTx, [], this.opts, false);
|
|
2072
|
+
async placeOrders(params, txParams, subAccountId, optionalIxs) {
|
|
2073
|
+
const { txSig } = await this.sendTransaction((await this.preparePlaceOrdersTx(params, txParams, subAccountId, optionalIxs)).placeOrdersTx, [], this.opts, false);
|
|
2075
2074
|
return txSig;
|
|
2076
2075
|
}
|
|
2077
|
-
async preparePlaceOrdersTx(params, txParams, subAccountId) {
|
|
2078
|
-
const
|
|
2076
|
+
async preparePlaceOrdersTx(params, txParams, subAccountId, optionalIxs) {
|
|
2077
|
+
const lookupTableAccount = await this.fetchMarketLookupTableAccount();
|
|
2078
|
+
const tx = await this.buildTransaction(await this.getPlaceOrdersIx(params, subAccountId), txParams, undefined, [lookupTableAccount], undefined, undefined, optionalIxs);
|
|
2079
2079
|
return {
|
|
2080
2080
|
placeOrdersTx: tx,
|
|
2081
2081
|
};
|
|
@@ -2989,7 +2989,7 @@ class DriftClient {
|
|
|
2989
2989
|
this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
|
|
2990
2990
|
return txSig;
|
|
2991
2991
|
}
|
|
2992
|
-
async preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams, makerInfo, referrerInfo, bracketOrdersParams = new Array(), txParams, subAccountId, cancelExistingOrders, settlePnl, exitEarlyIfSimFails, auctionDurationPercentage) {
|
|
2992
|
+
async preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams, makerInfo, referrerInfo, bracketOrdersParams = new Array(), txParams, subAccountId, cancelExistingOrders, settlePnl, exitEarlyIfSimFails, auctionDurationPercentage, optionalIxs) {
|
|
2993
2993
|
const placeAndTakeIxs = [];
|
|
2994
2994
|
const txsToSign = {
|
|
2995
2995
|
placeAndTakeTx: undefined,
|
|
@@ -2998,6 +2998,7 @@ class DriftClient {
|
|
|
2998
2998
|
};
|
|
2999
2999
|
// Get recent block hash so that we can re-use it for all transactions. Makes this logic run faster with fewer RPC requests
|
|
3000
3000
|
const recentBlockHash = await this.txHandler.getLatestBlockhashForTransaction();
|
|
3001
|
+
const lookupTableAccount = await this.fetchMarketLookupTableAccount();
|
|
3001
3002
|
let earlyExitFailedPlaceAndTakeSim = false;
|
|
3002
3003
|
const prepPlaceAndTakeTx = async () => {
|
|
3003
3004
|
var _a;
|
|
@@ -3014,7 +3015,7 @@ class DriftClient {
|
|
|
3014
3015
|
useSimulatedComputeUnits: false,
|
|
3015
3016
|
};
|
|
3016
3017
|
if (shouldUseSimulationComputeUnits || shouldExitIfSimulationFails) {
|
|
3017
|
-
const placeAndTakeTxToSim = (await this.buildTransaction(placeAndTakeIxs, txParams, undefined,
|
|
3018
|
+
const placeAndTakeTxToSim = (await this.buildTransaction(placeAndTakeIxs, txParams, undefined, [lookupTableAccount], true, recentBlockHash, optionalIxs));
|
|
3018
3019
|
const simulationResult = await txParamProcessor_1.TransactionParamProcessor.getTxSimComputeUnits(placeAndTakeTxToSim, this.connection, (_a = txParams.computeUnitsBufferMultiplier) !== null && _a !== void 0 ? _a : 1.2, txParams.lowerBoundCu);
|
|
3019
3020
|
if (shouldExitIfSimulationFails && !simulationResult.success) {
|
|
3020
3021
|
earlyExitFailedPlaceAndTakeSim = true;
|
|
@@ -3023,17 +3024,17 @@ class DriftClient {
|
|
|
3023
3024
|
txsToSign.placeAndTakeTx = await this.buildTransaction(placeAndTakeIxs, {
|
|
3024
3025
|
...txParamsWithoutImplicitSimulation,
|
|
3025
3026
|
computeUnits: simulationResult.computeUnits,
|
|
3026
|
-
}, undefined,
|
|
3027
|
+
}, undefined, [lookupTableAccount], undefined, recentBlockHash, optionalIxs);
|
|
3027
3028
|
}
|
|
3028
3029
|
else {
|
|
3029
|
-
txsToSign.placeAndTakeTx = await this.buildTransaction(placeAndTakeIxs, txParams, undefined,
|
|
3030
|
+
txsToSign.placeAndTakeTx = await this.buildTransaction(placeAndTakeIxs, txParams, undefined, [lookupTableAccount], undefined, recentBlockHash, optionalIxs);
|
|
3030
3031
|
}
|
|
3031
3032
|
return;
|
|
3032
3033
|
};
|
|
3033
3034
|
const prepCancelOrderTx = async () => {
|
|
3034
3035
|
if (cancelExistingOrders && (0, types_1.isVariant)(orderParams.marketType, 'perp')) {
|
|
3035
3036
|
const cancelOrdersIx = await this.getCancelOrdersIx(orderParams.marketType, orderParams.marketIndex, null, subAccountId);
|
|
3036
|
-
txsToSign.cancelExistingOrdersTx = await this.buildTransaction([cancelOrdersIx], txParams, this.txVersion,
|
|
3037
|
+
txsToSign.cancelExistingOrdersTx = await this.buildTransaction([cancelOrdersIx], txParams, this.txVersion, [lookupTableAccount], undefined, recentBlockHash, optionalIxs);
|
|
3037
3038
|
}
|
|
3038
3039
|
return;
|
|
3039
3040
|
};
|
|
@@ -3041,7 +3042,7 @@ class DriftClient {
|
|
|
3041
3042
|
if (settlePnl && (0, types_1.isVariant)(orderParams.marketType, 'perp')) {
|
|
3042
3043
|
const userAccountPublicKey = await this.getUserAccountPublicKey(subAccountId);
|
|
3043
3044
|
const settlePnlIx = await this.settlePNLIx(userAccountPublicKey, this.getUserAccount(subAccountId), orderParams.marketIndex);
|
|
3044
|
-
txsToSign.settlePnlTx = await this.buildTransaction([settlePnlIx], txParams, this.txVersion,
|
|
3045
|
+
txsToSign.settlePnlTx = await this.buildTransaction([settlePnlIx], txParams, this.txVersion, [lookupTableAccount], undefined, recentBlockHash, optionalIxs);
|
|
3045
3046
|
}
|
|
3046
3047
|
return;
|
|
3047
3048
|
};
|
|
@@ -3647,8 +3648,9 @@ class DriftClient {
|
|
|
3647
3648
|
}
|
|
3648
3649
|
return ixs;
|
|
3649
3650
|
}
|
|
3650
|
-
async settlePNL(settleeUserAccountPublicKey, settleeUserAccount, marketIndex, txParams) {
|
|
3651
|
-
const
|
|
3651
|
+
async settlePNL(settleeUserAccountPublicKey, settleeUserAccount, marketIndex, txParams, optionalIxs) {
|
|
3652
|
+
const lookupTableAccount = await this.fetchMarketLookupTableAccount();
|
|
3653
|
+
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex), txParams, undefined, [lookupTableAccount], undefined, undefined, optionalIxs), [], this.opts);
|
|
3652
3654
|
return txSig;
|
|
3653
3655
|
}
|
|
3654
3656
|
async settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex) {
|
|
@@ -4894,7 +4896,7 @@ class DriftClient {
|
|
|
4894
4896
|
return this.txSender.send(tx, additionalSigners, opts !== null && opts !== void 0 ? opts : this.opts, preSigned);
|
|
4895
4897
|
}
|
|
4896
4898
|
}
|
|
4897
|
-
async buildTransaction(instructions, txParams, txVersion, lookupTables, forceVersionedTransaction, recentBlockhash) {
|
|
4899
|
+
async buildTransaction(instructions, txParams, txVersion, lookupTables, forceVersionedTransaction, recentBlockhash, optionalIxs) {
|
|
4898
4900
|
return this.txHandler.buildTransaction({
|
|
4899
4901
|
instructions,
|
|
4900
4902
|
txVersion: txVersion !== null && txVersion !== void 0 ? txVersion : this.txVersion,
|
|
@@ -4905,6 +4907,7 @@ class DriftClient {
|
|
|
4905
4907
|
lookupTables,
|
|
4906
4908
|
forceVersionedTransaction,
|
|
4907
4909
|
recentBlockhash,
|
|
4910
|
+
optionalIxs,
|
|
4908
4911
|
});
|
|
4909
4912
|
}
|
|
4910
4913
|
async buildBulkTransactions(instructions, txParams, txVersion, lookupTables, forceVersionedTransaction) {
|
package/lib/node/index.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ export * from './oracles/pythClient';
|
|
|
86
86
|
export * from './oracles/pythPullClient';
|
|
87
87
|
export * from './oracles/pythLazerClient';
|
|
88
88
|
export * from './oracles/switchboardOnDemandClient';
|
|
89
|
+
export * from './oracles/oracleId';
|
|
89
90
|
export * from './swift/swiftOrderSubscriber';
|
|
90
91
|
export * from './tx/fastSingleTxSender';
|
|
91
92
|
export * from './tx/retryTxSender';
|
package/lib/node/index.js
CHANGED
|
@@ -109,6 +109,7 @@ __exportStar(require("./oracles/pythClient"), exports);
|
|
|
109
109
|
__exportStar(require("./oracles/pythPullClient"), exports);
|
|
110
110
|
__exportStar(require("./oracles/pythLazerClient"), exports);
|
|
111
111
|
__exportStar(require("./oracles/switchboardOnDemandClient"), exports);
|
|
112
|
+
__exportStar(require("./oracles/oracleId"), exports);
|
|
112
113
|
__exportStar(require("./swift/swiftOrderSubscriber"), exports);
|
|
113
114
|
__exportStar(require("./tx/fastSingleTxSender"), exports);
|
|
114
115
|
__exportStar(require("./tx/retryTxSender"), exports);
|
package/lib/node/math/oracles.js
CHANGED
|
@@ -149,6 +149,22 @@ function getMultipleBetweenOracleSources(firstOracleSource, secondOracleSource)
|
|
|
149
149
|
(0, types_1.isVariant)(secondOracleSource, 'pythPull')) {
|
|
150
150
|
return { numerator: new index_1.BN(1), denominator: new index_1.BN(1000) };
|
|
151
151
|
}
|
|
152
|
+
if ((0, types_1.isVariant)(firstOracleSource, 'pythLazer') &&
|
|
153
|
+
(0, types_1.isVariant)(secondOracleSource, 'pythLazer1M')) {
|
|
154
|
+
return { numerator: new index_1.BN(1000000), denominator: new index_1.BN(1) };
|
|
155
|
+
}
|
|
156
|
+
if ((0, types_1.isVariant)(firstOracleSource, 'pythLazer') &&
|
|
157
|
+
(0, types_1.isVariant)(secondOracleSource, 'pythLazer1K')) {
|
|
158
|
+
return { numerator: new index_1.BN(1000), denominator: new index_1.BN(1) };
|
|
159
|
+
}
|
|
160
|
+
if ((0, types_1.isVariant)(firstOracleSource, 'pythLazer1M') &&
|
|
161
|
+
(0, types_1.isVariant)(secondOracleSource, 'pythLazer')) {
|
|
162
|
+
return { numerator: new index_1.BN(1), denominator: new index_1.BN(1000000) };
|
|
163
|
+
}
|
|
164
|
+
if ((0, types_1.isVariant)(firstOracleSource, 'pythLazer1K') &&
|
|
165
|
+
(0, types_1.isVariant)(secondOracleSource, 'pythLazer')) {
|
|
166
|
+
return { numerator: new index_1.BN(1), denominator: new index_1.BN(1000) };
|
|
167
|
+
}
|
|
152
168
|
return { numerator: new index_1.BN(1), denominator: new index_1.BN(1) };
|
|
153
169
|
}
|
|
154
170
|
exports.getMultipleBetweenOracleSources = getMultipleBetweenOracleSources;
|
package/lib/node/tx/txHandler.js
CHANGED
|
@@ -277,24 +277,35 @@ class TxHandler {
|
|
|
277
277
|
*/
|
|
278
278
|
async buildTransaction(props) {
|
|
279
279
|
var _a;
|
|
280
|
-
const {
|
|
280
|
+
const { txVersion, txParams, connection: _connection, preFlightCommitment: _preFlightCommitment, fetchMarketLookupTableAccount, forceVersionedTransaction, instructions, } = props;
|
|
281
281
|
let { lookupTables } = props;
|
|
282
282
|
// # Collect and process Tx Params
|
|
283
283
|
let baseTxParams = {
|
|
284
284
|
computeUnits: txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits,
|
|
285
285
|
computeUnitsPrice: txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice,
|
|
286
286
|
};
|
|
287
|
+
const instructionsArray = Array.isArray(instructions)
|
|
288
|
+
? instructions
|
|
289
|
+
: [instructions];
|
|
290
|
+
let instructionsToUse;
|
|
291
|
+
// add optional ixs if there's room (usually oracle cranks)
|
|
292
|
+
if (props.optionalIxs && txVersion === 0) {
|
|
293
|
+
instructionsToUse = (0, utils_1.getCombinedInstructions)(instructionsArray, props.optionalIxs, txVersion === 0, lookupTables);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
instructionsToUse = instructionsArray;
|
|
297
|
+
}
|
|
287
298
|
if (txParams === null || txParams === void 0 ? void 0 : txParams.useSimulatedComputeUnits) {
|
|
288
|
-
const processedTxParams = await this.getProcessedTransactionParams(
|
|
299
|
+
const processedTxParams = await this.getProcessedTransactionParams({
|
|
300
|
+
...props,
|
|
301
|
+
instructions: instructionsToUse,
|
|
302
|
+
});
|
|
289
303
|
baseTxParams = {
|
|
290
304
|
...baseTxParams,
|
|
291
305
|
...processedTxParams,
|
|
292
306
|
};
|
|
293
307
|
}
|
|
294
|
-
const
|
|
295
|
-
? instructions
|
|
296
|
-
: [instructions];
|
|
297
|
-
const { hasSetComputeUnitLimitIx, hasSetComputeUnitPriceIx } = (0, computeUnits_1.containsComputeUnitIxs)(instructionsArray);
|
|
308
|
+
const { hasSetComputeUnitLimitIx, hasSetComputeUnitPriceIx } = (0, computeUnits_1.containsComputeUnitIxs)(instructionsToUse);
|
|
298
309
|
// # Create Tx Instructions
|
|
299
310
|
const allIx = [];
|
|
300
311
|
const computeUnits = baseTxParams === null || baseTxParams === void 0 ? void 0 : baseTxParams.computeUnits;
|
|
@@ -314,7 +325,7 @@ class TxHandler {
|
|
|
314
325
|
microLamports: computeUnitsPrice,
|
|
315
326
|
}));
|
|
316
327
|
}
|
|
317
|
-
allIx.push(...
|
|
328
|
+
allIx.push(...instructionsToUse);
|
|
318
329
|
const recentBlockhash = (_a = props === null || props === void 0 ? void 0 : props.recentBlockhash) !== null && _a !== void 0 ? _a : (await this.getLatestBlockhashForTransaction());
|
|
319
330
|
// # Create and return Transaction
|
|
320
331
|
if (txVersion === 'legacy') {
|
package/lib/node/tx/utils.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
import { Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
1
|
+
import { AddressLookupTableAccount, Transaction, TransactionInstruction, VersionedTransaction } from '@solana/web3.js';
|
|
2
2
|
export declare const isVersionedTransaction: (tx: Transaction | VersionedTransaction) => boolean;
|
|
3
|
+
export declare const getSizeOfTransaction: (instructions: TransactionInstruction[], versionedTransaction?: boolean, addressLookupTables?: AddressLookupTableAccount[]) => number;
|
|
4
|
+
export declare const getCombinedInstructions: (baseInstructions: TransactionInstruction[], optionalInstructions?: TransactionInstruction[], versionedTransaction?: boolean, addressLookupTables?: AddressLookupTableAccount[]) => TransactionInstruction[];
|
package/lib/node/tx/utils.js
CHANGED
|
@@ -1,10 +1,82 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isVersionedTransaction = void 0;
|
|
3
|
+
exports.getCombinedInstructions = exports.getSizeOfTransaction = exports.isVersionedTransaction = void 0;
|
|
4
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const MAX_SIZE = 1232;
|
|
5
6
|
const isVersionedTransaction = (tx) => {
|
|
6
7
|
const version = tx === null || tx === void 0 ? void 0 : tx.version;
|
|
7
8
|
const isVersionedTx = tx instanceof web3_js_1.VersionedTransaction || version !== undefined;
|
|
8
9
|
return isVersionedTx;
|
|
9
10
|
};
|
|
10
11
|
exports.isVersionedTransaction = isVersionedTransaction;
|
|
12
|
+
const getSizeOfTransaction = (instructions, versionedTransaction = true, addressLookupTables = []) => {
|
|
13
|
+
const programs = new Set();
|
|
14
|
+
const signers = new Set();
|
|
15
|
+
let accounts = new Set();
|
|
16
|
+
instructions.forEach((ix) => {
|
|
17
|
+
try {
|
|
18
|
+
if (ix.programId) {
|
|
19
|
+
programs.add(ix.programId.toBase58());
|
|
20
|
+
accounts.add(ix.programId.toBase58());
|
|
21
|
+
}
|
|
22
|
+
if (ix.keys) {
|
|
23
|
+
ix.keys.forEach((key) => {
|
|
24
|
+
if (key.isSigner) {
|
|
25
|
+
signers.add(key.pubkey.toBase58());
|
|
26
|
+
}
|
|
27
|
+
accounts.add(key.pubkey.toBase58());
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
console.log(e);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const instructionSizes = instructions
|
|
36
|
+
.map((ix) => 1 +
|
|
37
|
+
getSizeOfCompressedU16(ix.keys.length) +
|
|
38
|
+
ix.keys.length +
|
|
39
|
+
getSizeOfCompressedU16(ix.data.length) +
|
|
40
|
+
ix.data.length)
|
|
41
|
+
.reduce((a, b) => a + b, 0);
|
|
42
|
+
let numberOfAddressLookups = 0;
|
|
43
|
+
if (addressLookupTables.length > 0) {
|
|
44
|
+
const lookupTableAddresses = addressLookupTables
|
|
45
|
+
.map((addressLookupTable) => addressLookupTable.state.addresses.map((address) => address.toBase58()))
|
|
46
|
+
.flat();
|
|
47
|
+
const totalNumberOfAccounts = accounts.size;
|
|
48
|
+
accounts = new Set([...accounts].filter((account) => !lookupTableAddresses.includes(account)));
|
|
49
|
+
accounts = new Set([...accounts, ...programs, ...signers]);
|
|
50
|
+
numberOfAddressLookups = totalNumberOfAccounts - accounts.size;
|
|
51
|
+
}
|
|
52
|
+
return (getSizeOfCompressedU16(signers.size) +
|
|
53
|
+
signers.size * 64 + // array of signatures
|
|
54
|
+
3 +
|
|
55
|
+
getSizeOfCompressedU16(accounts.size) +
|
|
56
|
+
32 * accounts.size + // array of account addresses
|
|
57
|
+
32 + // recent blockhash
|
|
58
|
+
getSizeOfCompressedU16(instructions.length) +
|
|
59
|
+
instructionSizes + // array of instructions
|
|
60
|
+
(versionedTransaction ? 1 + getSizeOfCompressedU16(0) : 0) +
|
|
61
|
+
(versionedTransaction ? 32 * addressLookupTables.length : 0) +
|
|
62
|
+
(versionedTransaction && addressLookupTables.length > 0 ? 2 : 0) +
|
|
63
|
+
numberOfAddressLookups);
|
|
64
|
+
};
|
|
65
|
+
exports.getSizeOfTransaction = getSizeOfTransaction;
|
|
66
|
+
const getCombinedInstructions = (baseInstructions, optionalInstructions = [], versionedTransaction = true, addressLookupTables = []) => {
|
|
67
|
+
if (optionalInstructions.length === 0) {
|
|
68
|
+
return baseInstructions;
|
|
69
|
+
}
|
|
70
|
+
let allInstructions = [...optionalInstructions, ...baseInstructions];
|
|
71
|
+
let txSize = (0, exports.getSizeOfTransaction)(allInstructions, versionedTransaction, addressLookupTables);
|
|
72
|
+
while (txSize > MAX_SIZE &&
|
|
73
|
+
allInstructions.length > baseInstructions.length) {
|
|
74
|
+
allInstructions = allInstructions.slice(1);
|
|
75
|
+
txSize = (0, exports.getSizeOfTransaction)(allInstructions, versionedTransaction, addressLookupTables);
|
|
76
|
+
}
|
|
77
|
+
return allInstructions;
|
|
78
|
+
};
|
|
79
|
+
exports.getCombinedInstructions = getCombinedInstructions;
|
|
80
|
+
function getSizeOfCompressedU16(n) {
|
|
81
|
+
return 1 + Number(n >= 128) + Number(n >= 16384);
|
|
82
|
+
}
|
package/package.json
CHANGED
package/src/driftClient.ts
CHANGED
|
@@ -3919,11 +3919,18 @@ export class DriftClient {
|
|
|
3919
3919
|
public async placeOrders(
|
|
3920
3920
|
params: OrderParams[],
|
|
3921
3921
|
txParams?: TxParams,
|
|
3922
|
-
subAccountId?: number
|
|
3922
|
+
subAccountId?: number,
|
|
3923
|
+
optionalIxs?: TransactionInstruction[]
|
|
3923
3924
|
): Promise<TransactionSignature> {
|
|
3924
3925
|
const { txSig } = await this.sendTransaction(
|
|
3925
|
-
(
|
|
3926
|
-
.
|
|
3926
|
+
(
|
|
3927
|
+
await this.preparePlaceOrdersTx(
|
|
3928
|
+
params,
|
|
3929
|
+
txParams,
|
|
3930
|
+
subAccountId,
|
|
3931
|
+
optionalIxs
|
|
3932
|
+
)
|
|
3933
|
+
).placeOrdersTx,
|
|
3927
3934
|
[],
|
|
3928
3935
|
this.opts,
|
|
3929
3936
|
false
|
|
@@ -3934,11 +3941,19 @@ export class DriftClient {
|
|
|
3934
3941
|
public async preparePlaceOrdersTx(
|
|
3935
3942
|
params: OrderParams[],
|
|
3936
3943
|
txParams?: TxParams,
|
|
3937
|
-
subAccountId?: number
|
|
3944
|
+
subAccountId?: number,
|
|
3945
|
+
optionalIxs?: TransactionInstruction[]
|
|
3938
3946
|
) {
|
|
3947
|
+
const lookupTableAccount = await this.fetchMarketLookupTableAccount();
|
|
3948
|
+
|
|
3939
3949
|
const tx = await this.buildTransaction(
|
|
3940
3950
|
await this.getPlaceOrdersIx(params, subAccountId),
|
|
3941
|
-
txParams
|
|
3951
|
+
txParams,
|
|
3952
|
+
undefined,
|
|
3953
|
+
[lookupTableAccount],
|
|
3954
|
+
undefined,
|
|
3955
|
+
undefined,
|
|
3956
|
+
optionalIxs
|
|
3942
3957
|
);
|
|
3943
3958
|
|
|
3944
3959
|
return {
|
|
@@ -5494,7 +5509,8 @@ export class DriftClient {
|
|
|
5494
5509
|
cancelExistingOrders?: boolean,
|
|
5495
5510
|
settlePnl?: boolean,
|
|
5496
5511
|
exitEarlyIfSimFails?: boolean,
|
|
5497
|
-
auctionDurationPercentage?: number
|
|
5512
|
+
auctionDurationPercentage?: number,
|
|
5513
|
+
optionalIxs?: TransactionInstruction[]
|
|
5498
5514
|
): Promise<{
|
|
5499
5515
|
placeAndTakeTx: Transaction | VersionedTransaction;
|
|
5500
5516
|
cancelExistingOrdersTx: Transaction | VersionedTransaction;
|
|
@@ -5514,6 +5530,8 @@ export class DriftClient {
|
|
|
5514
5530
|
const recentBlockHash =
|
|
5515
5531
|
await this.txHandler.getLatestBlockhashForTransaction();
|
|
5516
5532
|
|
|
5533
|
+
const lookupTableAccount = await this.fetchMarketLookupTableAccount();
|
|
5534
|
+
|
|
5517
5535
|
let earlyExitFailedPlaceAndTakeSim = false;
|
|
5518
5536
|
|
|
5519
5537
|
const prepPlaceAndTakeTx = async () => {
|
|
@@ -5550,9 +5568,10 @@ export class DriftClient {
|
|
|
5550
5568
|
placeAndTakeIxs,
|
|
5551
5569
|
txParams,
|
|
5552
5570
|
undefined,
|
|
5553
|
-
|
|
5571
|
+
[lookupTableAccount],
|
|
5554
5572
|
true,
|
|
5555
|
-
recentBlockHash
|
|
5573
|
+
recentBlockHash,
|
|
5574
|
+
optionalIxs
|
|
5556
5575
|
)) as VersionedTransaction;
|
|
5557
5576
|
|
|
5558
5577
|
const simulationResult =
|
|
@@ -5575,18 +5594,20 @@ export class DriftClient {
|
|
|
5575
5594
|
computeUnits: simulationResult.computeUnits,
|
|
5576
5595
|
},
|
|
5577
5596
|
undefined,
|
|
5597
|
+
[lookupTableAccount],
|
|
5578
5598
|
undefined,
|
|
5579
|
-
|
|
5580
|
-
|
|
5599
|
+
recentBlockHash,
|
|
5600
|
+
optionalIxs
|
|
5581
5601
|
);
|
|
5582
5602
|
} else {
|
|
5583
5603
|
txsToSign.placeAndTakeTx = await this.buildTransaction(
|
|
5584
5604
|
placeAndTakeIxs,
|
|
5585
5605
|
txParams,
|
|
5586
5606
|
undefined,
|
|
5607
|
+
[lookupTableAccount],
|
|
5587
5608
|
undefined,
|
|
5588
|
-
|
|
5589
|
-
|
|
5609
|
+
recentBlockHash,
|
|
5610
|
+
optionalIxs
|
|
5590
5611
|
);
|
|
5591
5612
|
}
|
|
5592
5613
|
|
|
@@ -5606,9 +5627,10 @@ export class DriftClient {
|
|
|
5606
5627
|
[cancelOrdersIx],
|
|
5607
5628
|
txParams,
|
|
5608
5629
|
this.txVersion,
|
|
5630
|
+
[lookupTableAccount],
|
|
5609
5631
|
undefined,
|
|
5610
|
-
|
|
5611
|
-
|
|
5632
|
+
recentBlockHash,
|
|
5633
|
+
optionalIxs
|
|
5612
5634
|
);
|
|
5613
5635
|
}
|
|
5614
5636
|
|
|
@@ -5631,9 +5653,10 @@ export class DriftClient {
|
|
|
5631
5653
|
[settlePnlIx],
|
|
5632
5654
|
txParams,
|
|
5633
5655
|
this.txVersion,
|
|
5656
|
+
[lookupTableAccount],
|
|
5634
5657
|
undefined,
|
|
5635
|
-
|
|
5636
|
-
|
|
5658
|
+
recentBlockHash,
|
|
5659
|
+
optionalIxs
|
|
5637
5660
|
);
|
|
5638
5661
|
}
|
|
5639
5662
|
return;
|
|
@@ -6818,8 +6841,11 @@ export class DriftClient {
|
|
|
6818
6841
|
settleeUserAccountPublicKey: PublicKey,
|
|
6819
6842
|
settleeUserAccount: UserAccount,
|
|
6820
6843
|
marketIndex: number,
|
|
6821
|
-
txParams?: TxParams
|
|
6844
|
+
txParams?: TxParams,
|
|
6845
|
+
optionalIxs?: TransactionInstruction[]
|
|
6822
6846
|
): Promise<TransactionSignature> {
|
|
6847
|
+
const lookupTableAccount = await this.fetchMarketLookupTableAccount();
|
|
6848
|
+
|
|
6823
6849
|
const { txSig } = await this.sendTransaction(
|
|
6824
6850
|
await this.buildTransaction(
|
|
6825
6851
|
await this.settlePNLIx(
|
|
@@ -6827,7 +6853,12 @@ export class DriftClient {
|
|
|
6827
6853
|
settleeUserAccount,
|
|
6828
6854
|
marketIndex
|
|
6829
6855
|
),
|
|
6830
|
-
txParams
|
|
6856
|
+
txParams,
|
|
6857
|
+
undefined,
|
|
6858
|
+
[lookupTableAccount],
|
|
6859
|
+
undefined,
|
|
6860
|
+
undefined,
|
|
6861
|
+
optionalIxs
|
|
6831
6862
|
),
|
|
6832
6863
|
[],
|
|
6833
6864
|
this.opts
|
|
@@ -8700,6 +8731,7 @@ export class DriftClient {
|
|
|
8700
8731
|
guardianSetIndex,
|
|
8701
8732
|
DEFAULT_WORMHOLE_PROGRAM_ID
|
|
8702
8733
|
);
|
|
8734
|
+
|
|
8703
8735
|
const trimmedVaa = trimVaaSignatures(
|
|
8704
8736
|
accumulatorUpdateData.vaa,
|
|
8705
8737
|
numSignatures
|
|
@@ -9287,7 +9319,8 @@ export class DriftClient {
|
|
|
9287
9319
|
txVersion?: TransactionVersion,
|
|
9288
9320
|
lookupTables?: AddressLookupTableAccount[],
|
|
9289
9321
|
forceVersionedTransaction?: boolean,
|
|
9290
|
-
recentBlockhash?: BlockhashWithExpiryBlockHeight
|
|
9322
|
+
recentBlockhash?: BlockhashWithExpiryBlockHeight,
|
|
9323
|
+
optionalIxs?: TransactionInstruction[]
|
|
9291
9324
|
): Promise<Transaction | VersionedTransaction> {
|
|
9292
9325
|
return this.txHandler.buildTransaction({
|
|
9293
9326
|
instructions,
|
|
@@ -9300,6 +9333,7 @@ export class DriftClient {
|
|
|
9300
9333
|
lookupTables,
|
|
9301
9334
|
forceVersionedTransaction,
|
|
9302
9335
|
recentBlockhash,
|
|
9336
|
+
optionalIxs,
|
|
9303
9337
|
});
|
|
9304
9338
|
}
|
|
9305
9339
|
|
package/src/index.ts
CHANGED
|
@@ -87,6 +87,7 @@ export * from './oracles/pythClient';
|
|
|
87
87
|
export * from './oracles/pythPullClient';
|
|
88
88
|
export * from './oracles/pythLazerClient';
|
|
89
89
|
export * from './oracles/switchboardOnDemandClient';
|
|
90
|
+
export * from './oracles/oracleId';
|
|
90
91
|
export * from './swift/swiftOrderSubscriber';
|
|
91
92
|
export * from './tx/fastSingleTxSender';
|
|
92
93
|
export * from './tx/retryTxSender';
|
package/src/math/oracles.ts
CHANGED
|
@@ -264,5 +264,33 @@ export function getMultipleBetweenOracleSources(
|
|
|
264
264
|
return { numerator: new BN(1), denominator: new BN(1000) };
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
+
if (
|
|
268
|
+
isVariant(firstOracleSource, 'pythLazer') &&
|
|
269
|
+
isVariant(secondOracleSource, 'pythLazer1M')
|
|
270
|
+
) {
|
|
271
|
+
return { numerator: new BN(1000000), denominator: new BN(1) };
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (
|
|
275
|
+
isVariant(firstOracleSource, 'pythLazer') &&
|
|
276
|
+
isVariant(secondOracleSource, 'pythLazer1K')
|
|
277
|
+
) {
|
|
278
|
+
return { numerator: new BN(1000), denominator: new BN(1) };
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (
|
|
282
|
+
isVariant(firstOracleSource, 'pythLazer1M') &&
|
|
283
|
+
isVariant(secondOracleSource, 'pythLazer')
|
|
284
|
+
) {
|
|
285
|
+
return { numerator: new BN(1), denominator: new BN(1000000) };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (
|
|
289
|
+
isVariant(firstOracleSource, 'pythLazer1K') &&
|
|
290
|
+
isVariant(secondOracleSource, 'pythLazer')
|
|
291
|
+
) {
|
|
292
|
+
return { numerator: new BN(1), denominator: new BN(1000) };
|
|
293
|
+
}
|
|
294
|
+
|
|
267
295
|
return { numerator: new BN(1), denominator: new BN(1) };
|
|
268
296
|
}
|
package/src/tx/txHandler.ts
CHANGED
|
@@ -28,7 +28,7 @@ import { containsComputeUnitIxs } from '../util/computeUnits';
|
|
|
28
28
|
import { CachedBlockhashFetcher } from './blockhashFetcher/cachedBlockhashFetcher';
|
|
29
29
|
import { BaseBlockhashFetcher } from './blockhashFetcher/baseBlockhashFetcher';
|
|
30
30
|
import { BlockhashFetcher } from './blockhashFetcher/types';
|
|
31
|
-
import { isVersionedTransaction } from './utils';
|
|
31
|
+
import { getCombinedInstructions, isVersionedTransaction } from './utils';
|
|
32
32
|
import { DEFAULT_CONFIRMATION_OPTS } from '../config';
|
|
33
33
|
|
|
34
34
|
/**
|
|
@@ -57,6 +57,7 @@ export type TxBuildingProps = {
|
|
|
57
57
|
txParams?: TxParams;
|
|
58
58
|
recentBlockhash?: BlockhashWithExpiryBlockHeight;
|
|
59
59
|
wallet?: IWallet;
|
|
60
|
+
optionalIxs?: TransactionInstruction[]; // additional instructions to add to the front of ixs if there's enough room, such as oracle cranks
|
|
60
61
|
};
|
|
61
62
|
|
|
62
63
|
export type TxHandlerConfig = {
|
|
@@ -470,13 +471,13 @@ export class TxHandler {
|
|
|
470
471
|
props: TxBuildingProps
|
|
471
472
|
): Promise<Transaction | VersionedTransaction> {
|
|
472
473
|
const {
|
|
473
|
-
instructions,
|
|
474
474
|
txVersion,
|
|
475
475
|
txParams,
|
|
476
476
|
connection: _connection,
|
|
477
477
|
preFlightCommitment: _preFlightCommitment,
|
|
478
478
|
fetchMarketLookupTableAccount,
|
|
479
479
|
forceVersionedTransaction,
|
|
480
|
+
instructions,
|
|
480
481
|
} = props;
|
|
481
482
|
|
|
482
483
|
let { lookupTables } = props;
|
|
@@ -487,8 +488,29 @@ export class TxHandler {
|
|
|
487
488
|
computeUnitsPrice: txParams?.computeUnitsPrice,
|
|
488
489
|
};
|
|
489
490
|
|
|
491
|
+
const instructionsArray = Array.isArray(instructions)
|
|
492
|
+
? instructions
|
|
493
|
+
: [instructions];
|
|
494
|
+
|
|
495
|
+
let instructionsToUse: TransactionInstruction[];
|
|
496
|
+
|
|
497
|
+
// add optional ixs if there's room (usually oracle cranks)
|
|
498
|
+
if (props.optionalIxs && txVersion === 0) {
|
|
499
|
+
instructionsToUse = getCombinedInstructions(
|
|
500
|
+
instructionsArray,
|
|
501
|
+
props.optionalIxs,
|
|
502
|
+
txVersion === 0,
|
|
503
|
+
lookupTables
|
|
504
|
+
);
|
|
505
|
+
} else {
|
|
506
|
+
instructionsToUse = instructionsArray;
|
|
507
|
+
}
|
|
508
|
+
|
|
490
509
|
if (txParams?.useSimulatedComputeUnits) {
|
|
491
|
-
const processedTxParams = await this.getProcessedTransactionParams(
|
|
510
|
+
const processedTxParams = await this.getProcessedTransactionParams({
|
|
511
|
+
...props,
|
|
512
|
+
instructions: instructionsToUse,
|
|
513
|
+
});
|
|
492
514
|
|
|
493
515
|
baseTxParams = {
|
|
494
516
|
...baseTxParams,
|
|
@@ -496,11 +518,8 @@ export class TxHandler {
|
|
|
496
518
|
};
|
|
497
519
|
}
|
|
498
520
|
|
|
499
|
-
const instructionsArray = Array.isArray(instructions)
|
|
500
|
-
? instructions
|
|
501
|
-
: [instructions];
|
|
502
521
|
const { hasSetComputeUnitLimitIx, hasSetComputeUnitPriceIx } =
|
|
503
|
-
containsComputeUnitIxs(
|
|
522
|
+
containsComputeUnitIxs(instructionsToUse);
|
|
504
523
|
|
|
505
524
|
// # Create Tx Instructions
|
|
506
525
|
const allIx = [];
|
|
@@ -529,7 +548,7 @@ export class TxHandler {
|
|
|
529
548
|
);
|
|
530
549
|
}
|
|
531
550
|
|
|
532
|
-
allIx.push(...
|
|
551
|
+
allIx.push(...instructionsToUse);
|
|
533
552
|
|
|
534
553
|
const recentBlockhash =
|
|
535
554
|
props?.recentBlockhash ?? (await this.getLatestBlockhashForTransaction());
|
package/src/tx/utils.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AddressLookupTableAccount,
|
|
3
|
+
Transaction,
|
|
4
|
+
TransactionInstruction,
|
|
5
|
+
VersionedTransaction,
|
|
6
|
+
} from '@solana/web3.js';
|
|
7
|
+
|
|
8
|
+
const MAX_SIZE = 1232;
|
|
2
9
|
|
|
3
10
|
export const isVersionedTransaction = (
|
|
4
11
|
tx: Transaction | VersionedTransaction
|
|
@@ -9,3 +16,110 @@ export const isVersionedTransaction = (
|
|
|
9
16
|
|
|
10
17
|
return isVersionedTx;
|
|
11
18
|
};
|
|
19
|
+
|
|
20
|
+
export const getSizeOfTransaction = (
|
|
21
|
+
instructions: TransactionInstruction[],
|
|
22
|
+
versionedTransaction = true,
|
|
23
|
+
addressLookupTables: AddressLookupTableAccount[] = []
|
|
24
|
+
): number => {
|
|
25
|
+
const programs = new Set<string>();
|
|
26
|
+
const signers = new Set<string>();
|
|
27
|
+
let accounts = new Set<string>();
|
|
28
|
+
|
|
29
|
+
instructions.forEach((ix) => {
|
|
30
|
+
try {
|
|
31
|
+
if (ix.programId) {
|
|
32
|
+
programs.add(ix.programId.toBase58());
|
|
33
|
+
accounts.add(ix.programId.toBase58());
|
|
34
|
+
}
|
|
35
|
+
if (ix.keys) {
|
|
36
|
+
ix.keys.forEach((key) => {
|
|
37
|
+
if (key.isSigner) {
|
|
38
|
+
signers.add(key.pubkey.toBase58());
|
|
39
|
+
}
|
|
40
|
+
accounts.add(key.pubkey.toBase58());
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
console.log(e);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const instructionSizes: number = instructions
|
|
49
|
+
.map(
|
|
50
|
+
(ix) =>
|
|
51
|
+
1 +
|
|
52
|
+
getSizeOfCompressedU16(ix.keys.length) +
|
|
53
|
+
ix.keys.length +
|
|
54
|
+
getSizeOfCompressedU16(ix.data.length) +
|
|
55
|
+
ix.data.length
|
|
56
|
+
)
|
|
57
|
+
.reduce((a, b) => a + b, 0);
|
|
58
|
+
|
|
59
|
+
let numberOfAddressLookups = 0;
|
|
60
|
+
if (addressLookupTables.length > 0) {
|
|
61
|
+
const lookupTableAddresses = addressLookupTables
|
|
62
|
+
.map((addressLookupTable) =>
|
|
63
|
+
addressLookupTable.state.addresses.map((address) => address.toBase58())
|
|
64
|
+
)
|
|
65
|
+
.flat();
|
|
66
|
+
const totalNumberOfAccounts = accounts.size;
|
|
67
|
+
accounts = new Set(
|
|
68
|
+
[...accounts].filter((account) => !lookupTableAddresses.includes(account))
|
|
69
|
+
);
|
|
70
|
+
accounts = new Set([...accounts, ...programs, ...signers]);
|
|
71
|
+
numberOfAddressLookups = totalNumberOfAccounts - accounts.size;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
getSizeOfCompressedU16(signers.size) +
|
|
76
|
+
signers.size * 64 + // array of signatures
|
|
77
|
+
3 +
|
|
78
|
+
getSizeOfCompressedU16(accounts.size) +
|
|
79
|
+
32 * accounts.size + // array of account addresses
|
|
80
|
+
32 + // recent blockhash
|
|
81
|
+
getSizeOfCompressedU16(instructions.length) +
|
|
82
|
+
instructionSizes + // array of instructions
|
|
83
|
+
(versionedTransaction ? 1 + getSizeOfCompressedU16(0) : 0) +
|
|
84
|
+
(versionedTransaction ? 32 * addressLookupTables.length : 0) +
|
|
85
|
+
(versionedTransaction && addressLookupTables.length > 0 ? 2 : 0) +
|
|
86
|
+
numberOfAddressLookups
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const getCombinedInstructions = (
|
|
91
|
+
baseInstructions: TransactionInstruction[],
|
|
92
|
+
optionalInstructions: TransactionInstruction[] = [],
|
|
93
|
+
versionedTransaction = true,
|
|
94
|
+
addressLookupTables: AddressLookupTableAccount[] = []
|
|
95
|
+
): TransactionInstruction[] => {
|
|
96
|
+
if (optionalInstructions.length === 0) {
|
|
97
|
+
return baseInstructions;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let allInstructions = [...optionalInstructions, ...baseInstructions];
|
|
101
|
+
|
|
102
|
+
let txSize = getSizeOfTransaction(
|
|
103
|
+
allInstructions,
|
|
104
|
+
versionedTransaction,
|
|
105
|
+
addressLookupTables
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
while (
|
|
109
|
+
txSize > MAX_SIZE &&
|
|
110
|
+
allInstructions.length > baseInstructions.length
|
|
111
|
+
) {
|
|
112
|
+
allInstructions = allInstructions.slice(1);
|
|
113
|
+
txSize = getSizeOfTransaction(
|
|
114
|
+
allInstructions,
|
|
115
|
+
versionedTransaction,
|
|
116
|
+
addressLookupTables
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return allInstructions;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
function getSizeOfCompressedU16(n: number) {
|
|
124
|
+
return 1 + Number(n >= 128) + Number(n >= 16384);
|
|
125
|
+
}
|