@drift-labs/sdk 2.82.0-beta.8 → 2.83.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/lib/accounts/types.d.ts +0 -3
- package/lib/accounts/webSocketAccountSubscriber.js +1 -1
- package/lib/clock/clockSubscriber.d.ts +29 -0
- package/lib/clock/clockSubscriber.js +74 -0
- package/lib/constants/perpMarkets.js +2 -2
- package/lib/constants/spotMarkets.js +11 -0
- package/lib/dlob/DLOB.js +2 -2
- package/lib/dlob/orderBookLevels.js +1 -0
- package/lib/driftClient.d.ts +11 -14
- package/lib/driftClient.js +157 -260
- package/lib/driftClientConfig.d.ts +2 -0
- package/lib/idl/drift.json +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/jupiter/jupiterClient.d.ts +2 -1
- package/lib/jupiter/jupiterClient.js +10 -6
- package/lib/math/exchangeStatus.d.ts +2 -2
- package/lib/math/orders.d.ts +1 -1
- package/lib/math/orders.js +2 -2
- package/lib/tx/baseTxSender.d.ts +8 -6
- package/lib/tx/baseTxSender.js +6 -49
- package/lib/tx/fastSingleTxSender.d.ts +6 -6
- package/lib/tx/fastSingleTxSender.js +3 -31
- package/lib/tx/forwardOnlyTxSender.d.ts +4 -2
- package/lib/tx/forwardOnlyTxSender.js +2 -1
- package/lib/tx/retryTxSender.d.ts +4 -2
- package/lib/tx/retryTxSender.js +2 -1
- package/lib/tx/txHandler.d.ts +138 -0
- package/lib/tx/txHandler.js +396 -0
- package/lib/tx/txParamProcessor.d.ts +6 -10
- package/lib/tx/txParamProcessor.js +13 -17
- package/lib/tx/types.d.ts +3 -7
- package/lib/tx/whileValidTxSender.d.ts +7 -6
- package/lib/tx/whileValidTxSender.js +7 -28
- package/lib/types.d.ts +24 -4
- package/lib/types.js +10 -1
- package/lib/util/chainClock.d.ts +17 -0
- package/lib/util/chainClock.js +29 -0
- package/package.json +3 -3
- package/src/accounts/types.ts +0 -4
- package/src/accounts/webSocketAccountSubscriber.ts +1 -1
- package/src/clock/clockSubscriber.ts +113 -0
- package/src/constants/perpMarkets.ts +2 -2
- package/src/constants/spotMarkets.ts +13 -0
- package/src/dlob/DLOB.ts +2 -2
- package/src/dlob/orderBookLevels.ts +2 -0
- package/src/driftClient.ts +247 -385
- package/src/driftClientConfig.ts +2 -0
- package/src/idl/drift.json +1 -1
- package/src/index.ts +2 -0
- package/src/jupiter/jupiterClient.ts +15 -6
- package/src/math/exchangeStatus.ts +2 -1
- package/src/math/orders.ts +3 -2
- package/src/tx/baseTxSender.ts +21 -75
- package/src/tx/fastSingleTxSender.ts +10 -55
- package/src/tx/forwardOnlyTxSender.ts +5 -1
- package/src/tx/retryTxSender.ts +5 -1
- package/src/tx/txHandler.ts +625 -0
- package/src/tx/txParamProcessor.ts +16 -28
- package/src/tx/types.ts +2 -18
- package/src/tx/whileValidTxSender.ts +24 -48
- package/src/types.ts +26 -2
- package/src/util/chainClock.ts +41 -0
- package/tests/dlob/helpers.ts +3 -0
- package/lib/tx/utils.d.ts +0 -6
- package/lib/tx/utils.js +0 -43
- package/src/tx/utils.ts +0 -68
|
@@ -7,10 +7,10 @@ exports.JupiterClient = void 0;
|
|
|
7
7
|
const web3_js_1 = require("@solana/web3.js");
|
|
8
8
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
9
9
|
class JupiterClient {
|
|
10
|
-
constructor({ connection }) {
|
|
11
|
-
this.url = 'https://quote-api.jup.ag';
|
|
10
|
+
constructor({ connection, url }) {
|
|
12
11
|
this.lookupTableCahce = new Map();
|
|
13
12
|
this.connection = connection;
|
|
13
|
+
this.url = url !== null && url !== void 0 ? url : 'https://quote-api.jup.ag';
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* ** @deprecated - use getQuote
|
|
@@ -31,7 +31,8 @@ class JupiterClient {
|
|
|
31
31
|
swapMode,
|
|
32
32
|
onlyDirectRoutes: onlyDirectRoutes.toString(),
|
|
33
33
|
}).toString();
|
|
34
|
-
const
|
|
34
|
+
const apiVersionParam = this.url === 'https://quote-api.jup.ag' ? '/v4' : '';
|
|
35
|
+
const { data: routes } = await (await (0, node_fetch_1.default)(`${this.url}${apiVersionParam}/quote?${params}`)).json();
|
|
35
36
|
return routes;
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
@@ -58,7 +59,8 @@ class JupiterClient {
|
|
|
58
59
|
if (swapMode === 'ExactOut') {
|
|
59
60
|
params.delete('maxAccounts');
|
|
60
61
|
}
|
|
61
|
-
const
|
|
62
|
+
const apiVersionParam = this.url === 'https://quote-api.jup.ag' ? '/v6' : '';
|
|
63
|
+
const quote = await (await (0, node_fetch_1.default)(`${this.url}${apiVersionParam}/quote?${params.toString()}`)).json();
|
|
62
64
|
return quote;
|
|
63
65
|
}
|
|
64
66
|
/**
|
|
@@ -72,7 +74,8 @@ class JupiterClient {
|
|
|
72
74
|
if (!quote) {
|
|
73
75
|
throw new Error('Jupiter swap quote not provided. Please try again.');
|
|
74
76
|
}
|
|
75
|
-
const
|
|
77
|
+
const apiVersionParam = this.url === 'https://quote-api.jup.ag' ? '/v6' : '';
|
|
78
|
+
const resp = await (await (0, node_fetch_1.default)(`${this.url}${apiVersionParam}/swap`, {
|
|
76
79
|
method: 'POST',
|
|
77
80
|
headers: {
|
|
78
81
|
'Content-Type': 'application/json',
|
|
@@ -103,7 +106,8 @@ class JupiterClient {
|
|
|
103
106
|
* @param slippageBps the slippage tolerance in basis points
|
|
104
107
|
*/
|
|
105
108
|
async getSwapTransaction({ route, userPublicKey, slippageBps = 50, }) {
|
|
106
|
-
const
|
|
109
|
+
const apiVersionParam = this.url === 'https://quote-api.jup.ag' ? '/v4' : '';
|
|
110
|
+
const resp = await (await (0, node_fetch_1.default)(`${this.url}${apiVersionParam}/swap`, {
|
|
107
111
|
method: 'POST',
|
|
108
112
|
headers: {
|
|
109
113
|
'Content-Type': 'application/json',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PerpMarketAccount, PerpOperation, SpotMarketAccount, SpotOperation, StateAccount } from '../types';
|
|
1
|
+
import { PerpMarketAccount, PerpOperation, SpotMarketAccount, SpotOperation, StateAccount, InsuranceFundOperation } from '../types';
|
|
2
2
|
export declare function exchangePaused(state: StateAccount): boolean;
|
|
3
3
|
export declare function fillPaused(state: StateAccount, market: PerpMarketAccount | SpotMarketAccount): boolean;
|
|
4
4
|
export declare function ammPaused(state: StateAccount, market: PerpMarketAccount | SpotMarketAccount): boolean;
|
|
5
|
-
export declare function isOperationPaused(pausedOperations: number, operation: PerpOperation | SpotOperation): boolean;
|
|
5
|
+
export declare function isOperationPaused(pausedOperations: number, operation: PerpOperation | SpotOperation | InsuranceFundOperation): boolean;
|
|
6
6
|
export declare function isAmmDrawdownPause(market: PerpMarketAccount): boolean;
|
package/lib/math/orders.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare function hasAuctionPrice(order: Order, slot: number): boolean;
|
|
|
14
14
|
export declare function isFillableByVAMM(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number, ts: number, minAuctionDuration: number): boolean;
|
|
15
15
|
export declare function calculateBaseAssetAmountForAmmToFulfill(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
16
16
|
export declare function calculateBaseAssetAmountToFillUpToLimitPrice(order: Order, amm: AMM, limitPrice: BN, oraclePriceData: OraclePriceData): BN;
|
|
17
|
-
export declare function isOrderExpired(order: Order, ts: number, enforceBuffer?: boolean): boolean;
|
|
17
|
+
export declare function isOrderExpired(order: Order, ts: number, enforceBuffer?: boolean, bufferSeconds?: number): boolean;
|
|
18
18
|
export declare function isMarketOrder(order: Order): boolean;
|
|
19
19
|
export declare function isLimitOrder(order: Order): boolean;
|
|
20
20
|
export declare function mustBeTriggered(order: Order): boolean;
|
package/lib/math/orders.js
CHANGED
|
@@ -168,7 +168,7 @@ function isSameDirection(firstDirection, secondDirection) {
|
|
|
168
168
|
return (((0, types_1.isVariant)(firstDirection, 'long') && (0, types_1.isVariant)(secondDirection, 'long')) ||
|
|
169
169
|
((0, types_1.isVariant)(firstDirection, 'short') && (0, types_1.isVariant)(secondDirection, 'short')));
|
|
170
170
|
}
|
|
171
|
-
function isOrderExpired(order, ts, enforceBuffer = false) {
|
|
171
|
+
function isOrderExpired(order, ts, enforceBuffer = false, bufferSeconds = 15) {
|
|
172
172
|
if (mustBeTriggered(order) ||
|
|
173
173
|
!(0, types_1.isVariant)(order.status, 'open') ||
|
|
174
174
|
order.maxTs.eq(numericConstants_1.ZERO)) {
|
|
@@ -176,7 +176,7 @@ function isOrderExpired(order, ts, enforceBuffer = false) {
|
|
|
176
176
|
}
|
|
177
177
|
let maxTs;
|
|
178
178
|
if (enforceBuffer && isLimitOrder(order)) {
|
|
179
|
-
maxTs = order.maxTs.addn(
|
|
179
|
+
maxTs = order.maxTs.addn(bufferSeconds);
|
|
180
180
|
}
|
|
181
181
|
else {
|
|
182
182
|
maxTs = order.maxTs;
|
package/lib/tx/baseTxSender.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { ConfirmationStrategy,
|
|
3
|
-
import { Commitment, ConfirmOptions, RpcResponseAndContext, Signer, SignatureResult, Transaction, TransactionSignature, Connection, VersionedTransaction
|
|
2
|
+
import { ConfirmationStrategy, TxSender, TxSigAndSlot } from './types';
|
|
3
|
+
import { Commitment, ConfirmOptions, RpcResponseAndContext, Signer, SignatureResult, Transaction, TransactionSignature, Connection, VersionedTransaction } from '@solana/web3.js';
|
|
4
|
+
import { TxHandler } from './txHandler';
|
|
4
5
|
import { IWallet } from '../types';
|
|
5
6
|
export declare abstract class BaseTxSender implements TxSender {
|
|
6
7
|
connection: Connection;
|
|
@@ -11,7 +12,8 @@ export declare abstract class BaseTxSender implements TxSender {
|
|
|
11
12
|
timeoutCount: number;
|
|
12
13
|
confirmationStrategy: ConfirmationStrategy;
|
|
13
14
|
additionalTxSenderCallbacks: ((base58EncodedTx: string) => void)[];
|
|
14
|
-
|
|
15
|
+
txHandler: TxHandler;
|
|
16
|
+
constructor({ connection, wallet, opts, timeout, additionalConnections, confirmationStrategy, additionalTxSenderCallbacks, txHandler, }: {
|
|
15
17
|
connection: Connection;
|
|
16
18
|
wallet: IWallet;
|
|
17
19
|
opts?: ConfirmOptions;
|
|
@@ -19,11 +21,11 @@ export declare abstract class BaseTxSender implements TxSender {
|
|
|
19
21
|
additionalConnections?: any;
|
|
20
22
|
confirmationStrategy?: ConfirmationStrategy;
|
|
21
23
|
additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
|
|
24
|
+
txHandler: TxHandler;
|
|
22
25
|
});
|
|
23
|
-
send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean
|
|
26
|
+
send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
|
|
24
27
|
prepareTx(tx: Transaction, additionalSigners: Array<Signer>, opts: ConfirmOptions, preSigned?: boolean): Promise<Transaction>;
|
|
25
|
-
|
|
26
|
-
sendVersionedTransaction(tx: VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean, extraConfirmationOptions?: ExtraConfirmationOptions): Promise<TxSigAndSlot>;
|
|
28
|
+
sendVersionedTransaction(tx: VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
|
|
27
29
|
sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
|
|
28
30
|
simulateTransaction(tx: VersionedTransaction): Promise<boolean>;
|
|
29
31
|
confirmTransactionWebSocket(signature: TransactionSignature, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult>>;
|
package/lib/tx/baseTxSender.js
CHANGED
|
@@ -5,14 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.BaseTxSender = void 0;
|
|
7
7
|
const types_1 = require("./types");
|
|
8
|
-
const web3_js_1 = require("@solana/web3.js");
|
|
9
8
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
10
9
|
const assert_1 = __importDefault(require("assert"));
|
|
11
10
|
const bs58_1 = __importDefault(require("bs58"));
|
|
12
11
|
const DEFAULT_TIMEOUT = 35000;
|
|
13
12
|
const NOT_CONFIRMED_ERROR_CODE = -1001;
|
|
14
13
|
class BaseTxSender {
|
|
15
|
-
constructor({ connection, wallet, opts = anchor_1.AnchorProvider.defaultOptions(), timeout = DEFAULT_TIMEOUT, additionalConnections = new Array(), confirmationStrategy = types_1.ConfirmationStrategy.Combo, additionalTxSenderCallbacks, }) {
|
|
14
|
+
constructor({ connection, wallet, opts = anchor_1.AnchorProvider.defaultOptions(), timeout = DEFAULT_TIMEOUT, additionalConnections = new Array(), confirmationStrategy = types_1.ConfirmationStrategy.Combo, additionalTxSenderCallbacks, txHandler, }) {
|
|
16
15
|
this.timeoutCount = 0;
|
|
17
16
|
this.connection = connection;
|
|
18
17
|
this.wallet = wallet;
|
|
@@ -21,8 +20,9 @@ class BaseTxSender {
|
|
|
21
20
|
this.additionalConnections = additionalConnections;
|
|
22
21
|
this.confirmationStrategy = confirmationStrategy;
|
|
23
22
|
this.additionalTxSenderCallbacks = additionalTxSenderCallbacks;
|
|
23
|
+
this.txHandler = txHandler;
|
|
24
24
|
}
|
|
25
|
-
async send(tx, additionalSigners, opts, preSigned
|
|
25
|
+
async send(tx, additionalSigners, opts, preSigned) {
|
|
26
26
|
if (additionalSigners === undefined) {
|
|
27
27
|
additionalSigners = [];
|
|
28
28
|
}
|
|
@@ -30,48 +30,12 @@ class BaseTxSender {
|
|
|
30
30
|
opts = this.opts;
|
|
31
31
|
}
|
|
32
32
|
const signedTx = await this.prepareTx(tx, additionalSigners, opts, preSigned);
|
|
33
|
-
if (extraConfirmationOptions === null || extraConfirmationOptions === void 0 ? void 0 : extraConfirmationOptions.onSignedCb) {
|
|
34
|
-
extraConfirmationOptions.onSignedCb();
|
|
35
|
-
}
|
|
36
33
|
return this.sendRawTransaction(signedTx.serialize(), opts);
|
|
37
34
|
}
|
|
38
35
|
async prepareTx(tx, additionalSigners, opts, preSigned) {
|
|
39
|
-
|
|
40
|
-
return tx;
|
|
41
|
-
}
|
|
42
|
-
tx.feePayer = this.wallet.publicKey;
|
|
43
|
-
tx.recentBlockhash = (await this.connection.getLatestBlockhash(opts.preflightCommitment)).blockhash;
|
|
44
|
-
additionalSigners
|
|
45
|
-
.filter((s) => s !== undefined)
|
|
46
|
-
.forEach((kp) => {
|
|
47
|
-
tx.partialSign(kp);
|
|
48
|
-
});
|
|
49
|
-
const signedTx = await this.wallet.signTransaction(tx);
|
|
50
|
-
return signedTx;
|
|
36
|
+
return this.txHandler.prepareTx(tx, additionalSigners, undefined, opts, preSigned);
|
|
51
37
|
}
|
|
52
|
-
async
|
|
53
|
-
if (additionalSigners === undefined) {
|
|
54
|
-
additionalSigners = [];
|
|
55
|
-
}
|
|
56
|
-
if (opts === undefined) {
|
|
57
|
-
opts = this.opts;
|
|
58
|
-
}
|
|
59
|
-
let recentBlockhash = '';
|
|
60
|
-
if (blockhash) {
|
|
61
|
-
recentBlockhash = blockhash;
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
recentBlockhash = (await this.connection.getLatestBlockhash(opts.preflightCommitment)).blockhash;
|
|
65
|
-
}
|
|
66
|
-
const message = new web3_js_1.TransactionMessage({
|
|
67
|
-
payerKey: this.wallet.publicKey,
|
|
68
|
-
recentBlockhash,
|
|
69
|
-
instructions: ixs,
|
|
70
|
-
}).compileToV0Message(lookupTableAccounts);
|
|
71
|
-
const tx = new web3_js_1.VersionedTransaction(message);
|
|
72
|
-
return tx;
|
|
73
|
-
}
|
|
74
|
-
async sendVersionedTransaction(tx, additionalSigners, opts, preSigned, extraConfirmationOptions) {
|
|
38
|
+
async sendVersionedTransaction(tx, additionalSigners, opts, preSigned) {
|
|
75
39
|
let signedTx;
|
|
76
40
|
if (preSigned) {
|
|
77
41
|
signedTx = tx;
|
|
@@ -83,14 +47,7 @@ class BaseTxSender {
|
|
|
83
47
|
signedTx = tx;
|
|
84
48
|
}
|
|
85
49
|
else {
|
|
86
|
-
|
|
87
|
-
tx.sign([kp]);
|
|
88
|
-
});
|
|
89
|
-
// @ts-ignore
|
|
90
|
-
signedTx = await this.wallet.signTransaction(tx);
|
|
91
|
-
}
|
|
92
|
-
if (extraConfirmationOptions === null || extraConfirmationOptions === void 0 ? void 0 : extraConfirmationOptions.onSignedCb) {
|
|
93
|
-
extraConfirmationOptions.onSignedCb();
|
|
50
|
+
signedTx = await this.txHandler.signVersionedTx(tx, additionalSigners, undefined, this.wallet);
|
|
94
51
|
}
|
|
95
52
|
if (opts === undefined) {
|
|
96
53
|
opts = this.opts;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { ConfirmationStrategy, TxSigAndSlot } from './types';
|
|
4
|
-
import { ConfirmOptions,
|
|
5
|
-
import { IWallet } from '../types';
|
|
4
|
+
import { ConfirmOptions, Connection, Commitment, BlockhashWithExpiryBlockHeight } from '@solana/web3.js';
|
|
6
5
|
import { BaseTxSender } from './baseTxSender';
|
|
6
|
+
import { TxHandler } from './txHandler';
|
|
7
|
+
import { IWallet } from '../types';
|
|
7
8
|
export declare class FastSingleTxSender extends BaseTxSender {
|
|
8
9
|
connection: Connection;
|
|
9
10
|
wallet: IWallet;
|
|
@@ -12,11 +13,11 @@ export declare class FastSingleTxSender extends BaseTxSender {
|
|
|
12
13
|
blockhashRefreshInterval: number;
|
|
13
14
|
additionalConnections: Connection[];
|
|
14
15
|
timoutCount: number;
|
|
15
|
-
recentBlockhash:
|
|
16
|
+
recentBlockhash: BlockhashWithExpiryBlockHeight;
|
|
16
17
|
skipConfirmation: boolean;
|
|
17
18
|
blockhashCommitment: Commitment;
|
|
18
19
|
blockhashIntervalId: NodeJS.Timer;
|
|
19
|
-
constructor({ connection, wallet, opts, timeout, blockhashRefreshInterval, additionalConnections, skipConfirmation, blockhashCommitment, confirmationStrategy, }: {
|
|
20
|
+
constructor({ connection, wallet, opts, timeout, blockhashRefreshInterval, additionalConnections, skipConfirmation, blockhashCommitment, confirmationStrategy, txHandler, }: {
|
|
20
21
|
connection: Connection;
|
|
21
22
|
wallet: IWallet;
|
|
22
23
|
opts?: ConfirmOptions;
|
|
@@ -26,9 +27,8 @@ export declare class FastSingleTxSender extends BaseTxSender {
|
|
|
26
27
|
skipConfirmation?: boolean;
|
|
27
28
|
blockhashCommitment?: Commitment;
|
|
28
29
|
confirmationStrategy?: ConfirmationStrategy;
|
|
30
|
+
txHandler: TxHandler;
|
|
29
31
|
});
|
|
30
32
|
startBlockhashRefreshLoop(): void;
|
|
31
|
-
prepareTx(tx: Transaction, additionalSigners: Array<Signer>, _opts: ConfirmOptions, preSigned?: boolean): Promise<Transaction>;
|
|
32
|
-
getVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions, blockhash?: string): Promise<VersionedTransaction>;
|
|
33
33
|
sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
|
|
34
34
|
}
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FastSingleTxSender = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
|
-
const web3_js_1 = require("@solana/web3.js");
|
|
6
5
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
7
6
|
const baseTxSender_1 = require("./baseTxSender");
|
|
8
7
|
const DEFAULT_TIMEOUT = 35000;
|
|
9
8
|
const DEFAULT_BLOCKHASH_REFRESH = 10000;
|
|
10
9
|
class FastSingleTxSender extends baseTxSender_1.BaseTxSender {
|
|
11
|
-
constructor({ connection, wallet, opts = { ...anchor_1.AnchorProvider.defaultOptions(), maxRetries: 0 }, timeout = DEFAULT_TIMEOUT, blockhashRefreshInterval = DEFAULT_BLOCKHASH_REFRESH, additionalConnections = new Array(), skipConfirmation = false, blockhashCommitment = 'finalized', confirmationStrategy = types_1.ConfirmationStrategy.Combo, }) {
|
|
10
|
+
constructor({ connection, wallet, opts = { ...anchor_1.AnchorProvider.defaultOptions(), maxRetries: 0 }, timeout = DEFAULT_TIMEOUT, blockhashRefreshInterval = DEFAULT_BLOCKHASH_REFRESH, additionalConnections = new Array(), skipConfirmation = false, blockhashCommitment = 'finalized', confirmationStrategy = types_1.ConfirmationStrategy.Combo, txHandler, }) {
|
|
12
11
|
super({
|
|
13
12
|
connection,
|
|
14
13
|
wallet,
|
|
@@ -16,6 +15,7 @@ class FastSingleTxSender extends baseTxSender_1.BaseTxSender {
|
|
|
16
15
|
timeout,
|
|
17
16
|
additionalConnections,
|
|
18
17
|
confirmationStrategy,
|
|
18
|
+
txHandler,
|
|
19
19
|
});
|
|
20
20
|
this.timoutCount = 0;
|
|
21
21
|
this.connection = connection;
|
|
@@ -32,7 +32,7 @@ class FastSingleTxSender extends baseTxSender_1.BaseTxSender {
|
|
|
32
32
|
if (this.blockhashRefreshInterval > 0) {
|
|
33
33
|
this.blockhashIntervalId = setInterval(async () => {
|
|
34
34
|
try {
|
|
35
|
-
this.recentBlockhash =
|
|
35
|
+
this.recentBlockhash = await this.connection.getLatestBlockhash(this.blockhashCommitment);
|
|
36
36
|
}
|
|
37
37
|
catch (e) {
|
|
38
38
|
console.error('Error in startBlockhashRefreshLoop: ', e);
|
|
@@ -40,34 +40,6 @@ class FastSingleTxSender extends baseTxSender_1.BaseTxSender {
|
|
|
40
40
|
}, this.blockhashRefreshInterval);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
async prepareTx(tx, additionalSigners, _opts, preSigned) {
|
|
44
|
-
return super.prepareTx(tx, additionalSigners, _opts, preSigned);
|
|
45
|
-
}
|
|
46
|
-
async getVersionedTransaction(ixs, lookupTableAccounts, additionalSigners, opts, blockhash) {
|
|
47
|
-
var _a;
|
|
48
|
-
if (additionalSigners === undefined) {
|
|
49
|
-
additionalSigners = [];
|
|
50
|
-
}
|
|
51
|
-
if (opts === undefined) {
|
|
52
|
-
opts = this.opts;
|
|
53
|
-
}
|
|
54
|
-
let recentBlockhash = '';
|
|
55
|
-
if (blockhash) {
|
|
56
|
-
recentBlockhash = blockhash;
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
recentBlockhash =
|
|
60
|
-
(_a = this.recentBlockhash) !== null && _a !== void 0 ? _a : (await this.connection.getLatestBlockhash(opts.preflightCommitment))
|
|
61
|
-
.blockhash;
|
|
62
|
-
}
|
|
63
|
-
const message = new web3_js_1.TransactionMessage({
|
|
64
|
-
payerKey: this.wallet.publicKey,
|
|
65
|
-
recentBlockhash,
|
|
66
|
-
instructions: ixs,
|
|
67
|
-
}).compileToV0Message(lookupTableAccounts);
|
|
68
|
-
const tx = new web3_js_1.VersionedTransaction(message);
|
|
69
|
-
return tx;
|
|
70
|
-
}
|
|
71
43
|
async sendRawTransaction(rawTransaction, opts) {
|
|
72
44
|
let txid;
|
|
73
45
|
try {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { ConfirmOptions, Connection } from '@solana/web3.js';
|
|
3
|
-
import { IWallet } from '../types';
|
|
4
3
|
import { BaseTxSender } from './baseTxSender';
|
|
5
4
|
import { ConfirmationStrategy, TxSigAndSlot } from './types';
|
|
5
|
+
import { TxHandler } from './txHandler';
|
|
6
|
+
import { IWallet } from '../types';
|
|
6
7
|
type ResolveReference = {
|
|
7
8
|
resolve?: () => void;
|
|
8
9
|
};
|
|
@@ -14,7 +15,7 @@ export declare class ForwardOnlyTxSender extends BaseTxSender {
|
|
|
14
15
|
retrySleep: number;
|
|
15
16
|
additionalConnections: Connection[];
|
|
16
17
|
timoutCount: number;
|
|
17
|
-
constructor({ connection, wallet, opts, timeout, retrySleep, confirmationStrategy, additionalTxSenderCallbacks, }: {
|
|
18
|
+
constructor({ connection, wallet, opts, timeout, retrySleep, confirmationStrategy, additionalTxSenderCallbacks, txHandler, }: {
|
|
18
19
|
connection: Connection;
|
|
19
20
|
wallet: IWallet;
|
|
20
21
|
opts?: ConfirmOptions;
|
|
@@ -22,6 +23,7 @@ export declare class ForwardOnlyTxSender extends BaseTxSender {
|
|
|
22
23
|
retrySleep?: number;
|
|
23
24
|
confirmationStrategy?: ConfirmationStrategy;
|
|
24
25
|
additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
|
|
26
|
+
txHandler: TxHandler;
|
|
25
27
|
});
|
|
26
28
|
sleep(reference: ResolveReference): Promise<void>;
|
|
27
29
|
sendToAdditionalConnections(rawTx: Buffer | Uint8Array, _opts: ConfirmOptions): void;
|
|
@@ -12,7 +12,7 @@ const types_1 = require("./types");
|
|
|
12
12
|
const DEFAULT_TIMEOUT = 35000;
|
|
13
13
|
const DEFAULT_RETRY = 5000;
|
|
14
14
|
class ForwardOnlyTxSender extends baseTxSender_1.BaseTxSender {
|
|
15
|
-
constructor({ connection, wallet, opts = { ...anchor_1.AnchorProvider.defaultOptions(), maxRetries: 0 }, timeout = DEFAULT_TIMEOUT, retrySleep = DEFAULT_RETRY, confirmationStrategy = types_1.ConfirmationStrategy.Combo, additionalTxSenderCallbacks = [], }) {
|
|
15
|
+
constructor({ connection, wallet, opts = { ...anchor_1.AnchorProvider.defaultOptions(), maxRetries: 0 }, timeout = DEFAULT_TIMEOUT, retrySleep = DEFAULT_RETRY, confirmationStrategy = types_1.ConfirmationStrategy.Combo, additionalTxSenderCallbacks = [], txHandler, }) {
|
|
16
16
|
super({
|
|
17
17
|
connection,
|
|
18
18
|
wallet,
|
|
@@ -21,6 +21,7 @@ class ForwardOnlyTxSender extends baseTxSender_1.BaseTxSender {
|
|
|
21
21
|
additionalConnections: [],
|
|
22
22
|
confirmationStrategy,
|
|
23
23
|
additionalTxSenderCallbacks,
|
|
24
|
+
txHandler,
|
|
24
25
|
});
|
|
25
26
|
this.timoutCount = 0;
|
|
26
27
|
this.connection = connection;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { ConfirmationStrategy, TxSigAndSlot } from './types';
|
|
3
3
|
import { ConfirmOptions, Connection } from '@solana/web3.js';
|
|
4
|
-
import { IWallet } from '../types';
|
|
5
4
|
import { BaseTxSender } from './baseTxSender';
|
|
5
|
+
import { TxHandler } from './txHandler';
|
|
6
|
+
import { IWallet } from '../types';
|
|
6
7
|
type ResolveReference = {
|
|
7
8
|
resolve?: () => void;
|
|
8
9
|
};
|
|
@@ -14,7 +15,7 @@ export declare class RetryTxSender extends BaseTxSender {
|
|
|
14
15
|
retrySleep: number;
|
|
15
16
|
additionalConnections: Connection[];
|
|
16
17
|
timoutCount: number;
|
|
17
|
-
constructor({ connection, wallet, opts, timeout, retrySleep, additionalConnections, confirmationStrategy, additionalTxSenderCallbacks, }: {
|
|
18
|
+
constructor({ connection, wallet, opts, timeout, retrySleep, additionalConnections, confirmationStrategy, additionalTxSenderCallbacks, txHandler, }: {
|
|
18
19
|
connection: Connection;
|
|
19
20
|
wallet: IWallet;
|
|
20
21
|
opts?: ConfirmOptions;
|
|
@@ -23,6 +24,7 @@ export declare class RetryTxSender extends BaseTxSender {
|
|
|
23
24
|
additionalConnections?: any;
|
|
24
25
|
confirmationStrategy?: ConfirmationStrategy;
|
|
25
26
|
additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
|
|
27
|
+
txHandler: TxHandler;
|
|
26
28
|
});
|
|
27
29
|
sleep(reference: ResolveReference): Promise<void>;
|
|
28
30
|
sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
|
package/lib/tx/retryTxSender.js
CHANGED
|
@@ -7,7 +7,7 @@ const baseTxSender_1 = require("./baseTxSender");
|
|
|
7
7
|
const DEFAULT_TIMEOUT = 35000;
|
|
8
8
|
const DEFAULT_RETRY = 2000;
|
|
9
9
|
class RetryTxSender extends baseTxSender_1.BaseTxSender {
|
|
10
|
-
constructor({ connection, wallet, opts = { ...anchor_1.AnchorProvider.defaultOptions(), maxRetries: 0 }, timeout = DEFAULT_TIMEOUT, retrySleep = DEFAULT_RETRY, additionalConnections = new Array(), confirmationStrategy = types_1.ConfirmationStrategy.Combo, additionalTxSenderCallbacks = [], }) {
|
|
10
|
+
constructor({ connection, wallet, opts = { ...anchor_1.AnchorProvider.defaultOptions(), maxRetries: 0 }, timeout = DEFAULT_TIMEOUT, retrySleep = DEFAULT_RETRY, additionalConnections = new Array(), confirmationStrategy = types_1.ConfirmationStrategy.Combo, additionalTxSenderCallbacks = [], txHandler, }) {
|
|
11
11
|
super({
|
|
12
12
|
connection,
|
|
13
13
|
wallet,
|
|
@@ -16,6 +16,7 @@ class RetryTxSender extends baseTxSender_1.BaseTxSender {
|
|
|
16
16
|
additionalConnections,
|
|
17
17
|
confirmationStrategy,
|
|
18
18
|
additionalTxSenderCallbacks,
|
|
19
|
+
txHandler,
|
|
19
20
|
});
|
|
20
21
|
this.timoutCount = 0;
|
|
21
22
|
this.connection = connection;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { AddressLookupTableAccount, BlockhashWithExpiryBlockHeight, Commitment, ConfirmOptions, Connection, Signer, Transaction, TransactionInstruction, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
|
|
2
|
+
import { DriftClientMetricsEvents, IWallet, TxParams } from '../types';
|
|
3
|
+
export declare const COMPUTE_UNITS_DEFAULT = 200000;
|
|
4
|
+
export type TxBuildingProps = {
|
|
5
|
+
instructions: TransactionInstruction | TransactionInstruction[];
|
|
6
|
+
txVersion: TransactionVersion;
|
|
7
|
+
connection: Connection;
|
|
8
|
+
preFlightCommitment: Commitment;
|
|
9
|
+
fetchMarketLookupTableAccount: () => Promise<AddressLookupTableAccount>;
|
|
10
|
+
lookupTables?: AddressLookupTableAccount[];
|
|
11
|
+
forceVersionedTransaction?: boolean;
|
|
12
|
+
txParams?: TxParams;
|
|
13
|
+
recentBlockHash?: BlockhashWithExpiryBlockHeight;
|
|
14
|
+
wallet?: IWallet;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* This class is responsible for creating and signing transactions.
|
|
18
|
+
*/
|
|
19
|
+
export declare class TxHandler {
|
|
20
|
+
private blockHashToLastValidBlockHeightLookup;
|
|
21
|
+
private returnBlockHeightsWithSignedTxCallbackData;
|
|
22
|
+
private connection;
|
|
23
|
+
private wallet;
|
|
24
|
+
private confirmationOptions;
|
|
25
|
+
private onSignedCb?;
|
|
26
|
+
constructor(props: {
|
|
27
|
+
connection: Connection;
|
|
28
|
+
wallet: IWallet;
|
|
29
|
+
confirmationOptions: ConfirmOptions;
|
|
30
|
+
opts?: {
|
|
31
|
+
returnBlockHeightsWithSignedTxCallbackData?: boolean;
|
|
32
|
+
onSignedCb?: (txSigs: DriftClientMetricsEvents['txSigned']) => void;
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
private addHashAndExpiryToLookup;
|
|
36
|
+
private getProps;
|
|
37
|
+
updateWallet(wallet: IWallet): void;
|
|
38
|
+
/**
|
|
39
|
+
* Created this to prevent non-finalized blockhashes being used when building transactions. We want to always use finalized because otherwise it's easy to get the BlockHashNotFound error (RPC uses finalized to validate a transaction). Using an older blockhash when building transactions should never really be a problem right now.
|
|
40
|
+
*
|
|
41
|
+
* https://www.helius.dev/blog/how-to-deal-with-blockhash-errors-on-solana#why-do-blockhash-errors-occur
|
|
42
|
+
*
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
getLatestBlockhashForTransaction(): Promise<Readonly<{
|
|
46
|
+
blockhash: string;
|
|
47
|
+
lastValidBlockHeight: number;
|
|
48
|
+
}>>;
|
|
49
|
+
/**
|
|
50
|
+
* Applies recent blockhash and signs a given transaction
|
|
51
|
+
* @param tx
|
|
52
|
+
* @param additionalSigners
|
|
53
|
+
* @param wallet
|
|
54
|
+
* @param confirmationOpts
|
|
55
|
+
* @param preSigned
|
|
56
|
+
* @param recentBlockhash
|
|
57
|
+
* @returns
|
|
58
|
+
*/
|
|
59
|
+
prepareTx(tx: Transaction, additionalSigners: Array<Signer>, wallet?: IWallet, confirmationOpts?: ConfirmOptions, preSigned?: boolean, recentBlockhash?: BlockhashWithExpiryBlockHeight): Promise<Transaction>;
|
|
60
|
+
private isVersionedTransaction;
|
|
61
|
+
private getTxSigFromSignedTx;
|
|
62
|
+
private getBlockhashFromSignedTx;
|
|
63
|
+
private signTx;
|
|
64
|
+
signVersionedTx(tx: VersionedTransaction, additionalSigners: Array<Signer>, recentBlockHash?: BlockhashWithExpiryBlockHeight, wallet?: IWallet): Promise<VersionedTransaction>;
|
|
65
|
+
private handleSignedTxData;
|
|
66
|
+
/**
|
|
67
|
+
* Gets transaction params with extra processing applied, like using the simulated compute units or using a dynamically calculated compute unit price.
|
|
68
|
+
* @param txBuildingProps
|
|
69
|
+
* @returns
|
|
70
|
+
*/
|
|
71
|
+
private getProcessedTransactionParams;
|
|
72
|
+
private _generateVersionedTransaction;
|
|
73
|
+
generateLegacyVersionedTransaction(recentBlockhash: BlockhashWithExpiryBlockHeight, ixs: TransactionInstruction[], wallet?: IWallet): VersionedTransaction;
|
|
74
|
+
generateVersionedTransaction(recentBlockhash: BlockhashWithExpiryBlockHeight, ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], wallet?: IWallet): VersionedTransaction;
|
|
75
|
+
generateLegacyTransaction(ixs: TransactionInstruction[]): Transaction;
|
|
76
|
+
/**
|
|
77
|
+
* Accepts multiple instructions and builds a transaction for each. Prevents needing to spam RPC with requests for the same blockhash.
|
|
78
|
+
* @param props
|
|
79
|
+
* @returns
|
|
80
|
+
*/
|
|
81
|
+
buildBulkTransactions(props: Omit<TxBuildingProps, 'instructions'> & {
|
|
82
|
+
instructions: (TransactionInstruction | TransactionInstruction[])[];
|
|
83
|
+
}): Promise<(Transaction | VersionedTransaction)[]>;
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @param instructions
|
|
87
|
+
* @param txParams
|
|
88
|
+
* @param txVersion
|
|
89
|
+
* @param lookupTables
|
|
90
|
+
* @param forceVersionedTransaction Return a VersionedTransaction instance even if the version of the transaction is Legacy
|
|
91
|
+
* @returns
|
|
92
|
+
*/
|
|
93
|
+
buildTransaction(props: TxBuildingProps): Promise<Transaction | VersionedTransaction>;
|
|
94
|
+
wrapInTx(instruction: TransactionInstruction, computeUnits?: number, computeUnitsPrice?: number): Transaction;
|
|
95
|
+
/**
|
|
96
|
+
* Build a map of transactions from an array of instructions for multiple transactions.
|
|
97
|
+
* @param txsToSign
|
|
98
|
+
* @param keys
|
|
99
|
+
* @param wallet
|
|
100
|
+
* @param commitment
|
|
101
|
+
* @returns
|
|
102
|
+
*/
|
|
103
|
+
buildTransactionMap(txsToSign: (Transaction | undefined)[], keys: string[], wallet?: IWallet, commitment?: Commitment, recentBlockHash?: BlockhashWithExpiryBlockHeight): Promise<{
|
|
104
|
+
[key: string]: Transaction | VersionedTransaction;
|
|
105
|
+
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Get a map of signed and prepared transactions from an array of legacy transactions
|
|
108
|
+
* @param txsToSign
|
|
109
|
+
* @param keys
|
|
110
|
+
* @param wallet
|
|
111
|
+
* @param commitment
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
114
|
+
getPreparedAndSignedLegacyTransactionMap(txsToSign: (Transaction | undefined)[], keys: string[], wallet?: IWallet, commitment?: Commitment, recentBlockHash?: BlockhashWithExpiryBlockHeight): Promise<{
|
|
115
|
+
[key: string]: Transaction | VersionedTransaction;
|
|
116
|
+
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Get a map of signed transactions from an array of transactions to sign.
|
|
119
|
+
* @param txsToSign
|
|
120
|
+
* @param keys
|
|
121
|
+
* @param wallet
|
|
122
|
+
* @returns
|
|
123
|
+
*/
|
|
124
|
+
getSignedTransactionMap(txsToSign: (Transaction | VersionedTransaction | undefined)[], keys: string[], wallet?: IWallet): Promise<{
|
|
125
|
+
[key: string]: Transaction | VersionedTransaction | undefined;
|
|
126
|
+
}>;
|
|
127
|
+
/**
|
|
128
|
+
* Builds and signs transactions from a given array of instructions for multiple transactions.
|
|
129
|
+
* @param props
|
|
130
|
+
* @returns
|
|
131
|
+
*/
|
|
132
|
+
buildAndSignTransactionMap(props: Omit<TxBuildingProps, 'instructions'> & {
|
|
133
|
+
keys: string[];
|
|
134
|
+
instructions: (TransactionInstruction | TransactionInstruction[])[];
|
|
135
|
+
}): Promise<{
|
|
136
|
+
[key: string]: Transaction | VersionedTransaction;
|
|
137
|
+
}>;
|
|
138
|
+
}
|