@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.
Files changed (68) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/types.d.ts +0 -3
  3. package/lib/accounts/webSocketAccountSubscriber.js +1 -1
  4. package/lib/clock/clockSubscriber.d.ts +29 -0
  5. package/lib/clock/clockSubscriber.js +74 -0
  6. package/lib/constants/perpMarkets.js +2 -2
  7. package/lib/constants/spotMarkets.js +11 -0
  8. package/lib/dlob/DLOB.js +2 -2
  9. package/lib/dlob/orderBookLevels.js +1 -0
  10. package/lib/driftClient.d.ts +11 -14
  11. package/lib/driftClient.js +157 -260
  12. package/lib/driftClientConfig.d.ts +2 -0
  13. package/lib/idl/drift.json +1 -1
  14. package/lib/index.d.ts +2 -0
  15. package/lib/index.js +2 -0
  16. package/lib/jupiter/jupiterClient.d.ts +2 -1
  17. package/lib/jupiter/jupiterClient.js +10 -6
  18. package/lib/math/exchangeStatus.d.ts +2 -2
  19. package/lib/math/orders.d.ts +1 -1
  20. package/lib/math/orders.js +2 -2
  21. package/lib/tx/baseTxSender.d.ts +8 -6
  22. package/lib/tx/baseTxSender.js +6 -49
  23. package/lib/tx/fastSingleTxSender.d.ts +6 -6
  24. package/lib/tx/fastSingleTxSender.js +3 -31
  25. package/lib/tx/forwardOnlyTxSender.d.ts +4 -2
  26. package/lib/tx/forwardOnlyTxSender.js +2 -1
  27. package/lib/tx/retryTxSender.d.ts +4 -2
  28. package/lib/tx/retryTxSender.js +2 -1
  29. package/lib/tx/txHandler.d.ts +138 -0
  30. package/lib/tx/txHandler.js +396 -0
  31. package/lib/tx/txParamProcessor.d.ts +6 -10
  32. package/lib/tx/txParamProcessor.js +13 -17
  33. package/lib/tx/types.d.ts +3 -7
  34. package/lib/tx/whileValidTxSender.d.ts +7 -6
  35. package/lib/tx/whileValidTxSender.js +7 -28
  36. package/lib/types.d.ts +24 -4
  37. package/lib/types.js +10 -1
  38. package/lib/util/chainClock.d.ts +17 -0
  39. package/lib/util/chainClock.js +29 -0
  40. package/package.json +3 -3
  41. package/src/accounts/types.ts +0 -4
  42. package/src/accounts/webSocketAccountSubscriber.ts +1 -1
  43. package/src/clock/clockSubscriber.ts +113 -0
  44. package/src/constants/perpMarkets.ts +2 -2
  45. package/src/constants/spotMarkets.ts +13 -0
  46. package/src/dlob/DLOB.ts +2 -2
  47. package/src/dlob/orderBookLevels.ts +2 -0
  48. package/src/driftClient.ts +247 -385
  49. package/src/driftClientConfig.ts +2 -0
  50. package/src/idl/drift.json +1 -1
  51. package/src/index.ts +2 -0
  52. package/src/jupiter/jupiterClient.ts +15 -6
  53. package/src/math/exchangeStatus.ts +2 -1
  54. package/src/math/orders.ts +3 -2
  55. package/src/tx/baseTxSender.ts +21 -75
  56. package/src/tx/fastSingleTxSender.ts +10 -55
  57. package/src/tx/forwardOnlyTxSender.ts +5 -1
  58. package/src/tx/retryTxSender.ts +5 -1
  59. package/src/tx/txHandler.ts +625 -0
  60. package/src/tx/txParamProcessor.ts +16 -28
  61. package/src/tx/types.ts +2 -18
  62. package/src/tx/whileValidTxSender.ts +24 -48
  63. package/src/types.ts +26 -2
  64. package/src/util/chainClock.ts +41 -0
  65. package/tests/dlob/helpers.ts +3 -0
  66. package/lib/tx/utils.d.ts +0 -6
  67. package/lib/tx/utils.js +0 -43
  68. package/src/tx/utils.ts +0 -68
@@ -10,6 +10,7 @@ import { OracleInfo } from './oracles/types';
10
10
  import { BulkAccountLoader } from './accounts/bulkAccountLoader';
11
11
  import { DriftEnv } from './config';
12
12
  import { TxSender } from './tx/types';
13
+ import { TxHandler } from './tx/txHandler';
13
14
 
14
15
  export type DriftClientConfig = {
15
16
  connection: Connection;
@@ -19,6 +20,7 @@ export type DriftClientConfig = {
19
20
  accountSubscription?: DriftClientSubscriptionConfig;
20
21
  opts?: ConfirmOptions;
21
22
  txSender?: TxSender;
23
+ txHandler?: TxHandler;
22
24
  subAccountIds?: number[];
23
25
  activeSubAccountId?: number;
24
26
  perpMarketIndexes?: number[];
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.81.0",
2
+ "version": "2.82.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
package/src/index.ts CHANGED
@@ -102,5 +102,7 @@ export * from './auctionSubscriber/types';
102
102
  export * from './memcmp';
103
103
  export * from './decode/user';
104
104
  export * from './blockhashSubscriber';
105
+ export * from './util/chainClock';
106
+ export * from './clock/clockSubscriber';
105
107
 
106
108
  export { BN, PublicKey, pyth };
@@ -219,12 +219,13 @@ export interface QuoteResponse {
219
219
  }
220
220
 
221
221
  export class JupiterClient {
222
- url = 'https://quote-api.jup.ag';
222
+ url: string;
223
223
  connection: Connection;
224
224
  lookupTableCahce = new Map<string, AddressLookupTableAccount>();
225
225
 
226
- constructor({ connection }: { connection: Connection }) {
226
+ constructor({ connection, url }: { connection: Connection; url?: string }) {
227
227
  this.connection = connection;
228
+ this.url = url ?? 'https://quote-api.jup.ag';
228
229
  }
229
230
 
230
231
  /**
@@ -261,8 +262,10 @@ export class JupiterClient {
261
262
  onlyDirectRoutes: onlyDirectRoutes.toString(),
262
263
  }).toString();
263
264
 
265
+ const apiVersionParam =
266
+ this.url === 'https://quote-api.jup.ag' ? '/v4' : '';
264
267
  const { data: routes } = await (
265
- await fetch(`${this.url}/v4/quote?${params}`)
268
+ await fetch(`${this.url}${apiVersionParam}/quote?${params}`)
266
269
  ).json();
267
270
 
268
271
  return routes;
@@ -309,8 +312,10 @@ export class JupiterClient {
309
312
  if (swapMode === 'ExactOut') {
310
313
  params.delete('maxAccounts');
311
314
  }
315
+ const apiVersionParam =
316
+ this.url === 'https://quote-api.jup.ag' ? '/v6' : '';
312
317
  const quote = await (
313
- await fetch(`${this.url}/v6/quote?${params.toString()}`)
318
+ await fetch(`${this.url}${apiVersionParam}/quote?${params.toString()}`)
314
319
  ).json();
315
320
  return quote as QuoteResponse;
316
321
  }
@@ -334,8 +339,10 @@ export class JupiterClient {
334
339
  throw new Error('Jupiter swap quote not provided. Please try again.');
335
340
  }
336
341
 
342
+ const apiVersionParam =
343
+ this.url === 'https://quote-api.jup.ag' ? '/v6' : '';
337
344
  const resp = await (
338
- await fetch(`${this.url}/v6/swap`, {
345
+ await fetch(`${this.url}${apiVersionParam}/swap`, {
339
346
  method: 'POST',
340
347
  headers: {
341
348
  'Content-Type': 'application/json',
@@ -382,8 +389,10 @@ export class JupiterClient {
382
389
  userPublicKey: PublicKey;
383
390
  slippageBps?: number;
384
391
  }): Promise<VersionedTransaction> {
392
+ const apiVersionParam =
393
+ this.url === 'https://quote-api.jup.ag' ? '/v4' : '';
385
394
  const resp = await (
386
- await fetch(`${this.url}/v4/swap`, {
395
+ await fetch(`${this.url}${apiVersionParam}/swap`, {
387
396
  method: 'POST',
388
397
  headers: {
389
398
  'Content-Type': 'application/json',
@@ -11,6 +11,7 @@ import {
11
11
  SpotOperation,
12
12
  StateAccount,
13
13
  isVariant,
14
+ InsuranceFundOperation,
14
15
  } from '../types';
15
16
  import { BN } from '@coral-xyz/anchor';
16
17
 
@@ -65,7 +66,7 @@ export function ammPaused(
65
66
 
66
67
  export function isOperationPaused(
67
68
  pausedOperations: number,
68
- operation: PerpOperation | SpotOperation
69
+ operation: PerpOperation | SpotOperation | InsuranceFundOperation
69
70
  ): boolean {
70
71
  return (pausedOperations & operation) > 0;
71
72
  }
@@ -287,7 +287,8 @@ function isSameDirection(
287
287
  export function isOrderExpired(
288
288
  order: Order,
289
289
  ts: number,
290
- enforceBuffer = false
290
+ enforceBuffer = false,
291
+ bufferSeconds = 15
291
292
  ): boolean {
292
293
  if (
293
294
  mustBeTriggered(order) ||
@@ -299,7 +300,7 @@ export function isOrderExpired(
299
300
 
300
301
  let maxTs;
301
302
  if (enforceBuffer && isLimitOrder(order)) {
302
- maxTs = order.maxTs.addn(15);
303
+ maxTs = order.maxTs.addn(bufferSeconds);
303
304
  } else {
304
305
  maxTs = order.maxTs;
305
306
  }
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  ConfirmationStrategy,
3
- ExtraConfirmationOptions,
4
3
  TxSender,
5
4
  TxSendError,
6
5
  TxSigAndSlot,
@@ -16,13 +15,11 @@ import {
16
15
  TransactionSignature,
17
16
  Connection,
18
17
  VersionedTransaction,
19
- TransactionMessage,
20
- TransactionInstruction,
21
- AddressLookupTableAccount,
22
18
  } from '@solana/web3.js';
23
19
  import { AnchorProvider } from '@coral-xyz/anchor';
24
20
  import assert from 'assert';
25
21
  import bs58 from 'bs58';
22
+ import { TxHandler } from './txHandler';
26
23
  import { IWallet } from '../types';
27
24
 
28
25
  const DEFAULT_TIMEOUT = 35000;
@@ -37,6 +34,7 @@ export abstract class BaseTxSender implements TxSender {
37
34
  timeoutCount = 0;
38
35
  confirmationStrategy: ConfirmationStrategy;
39
36
  additionalTxSenderCallbacks: ((base58EncodedTx: string) => void)[];
37
+ txHandler: TxHandler;
40
38
 
41
39
  public constructor({
42
40
  connection,
@@ -46,6 +44,7 @@ export abstract class BaseTxSender implements TxSender {
46
44
  additionalConnections = new Array<Connection>(),
47
45
  confirmationStrategy = ConfirmationStrategy.Combo,
48
46
  additionalTxSenderCallbacks,
47
+ txHandler,
49
48
  }: {
50
49
  connection: Connection;
51
50
  wallet: IWallet;
@@ -54,6 +53,7 @@ export abstract class BaseTxSender implements TxSender {
54
53
  additionalConnections?;
55
54
  confirmationStrategy?: ConfirmationStrategy;
56
55
  additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
56
+ txHandler: TxHandler;
57
57
  }) {
58
58
  this.connection = connection;
59
59
  this.wallet = wallet;
@@ -62,14 +62,14 @@ export abstract class BaseTxSender implements TxSender {
62
62
  this.additionalConnections = additionalConnections;
63
63
  this.confirmationStrategy = confirmationStrategy;
64
64
  this.additionalTxSenderCallbacks = additionalTxSenderCallbacks;
65
+ this.txHandler = txHandler;
65
66
  }
66
67
 
67
68
  async send(
68
69
  tx: Transaction,
69
70
  additionalSigners?: Array<Signer>,
70
71
  opts?: ConfirmOptions,
71
- preSigned?: boolean,
72
- extraConfirmationOptions?: ExtraConfirmationOptions
72
+ preSigned?: boolean
73
73
  ): Promise<TxSigAndSlot> {
74
74
  if (additionalSigners === undefined) {
75
75
  additionalSigners = [];
@@ -85,10 +85,6 @@ export abstract class BaseTxSender implements TxSender {
85
85
  preSigned
86
86
  );
87
87
 
88
- if (extraConfirmationOptions?.onSignedCb) {
89
- extraConfirmationOptions.onSignedCb();
90
- }
91
-
92
88
  return this.sendRawTransaction(signedTx.serialize(), opts);
93
89
  }
94
90
 
@@ -98,68 +94,23 @@ export abstract class BaseTxSender implements TxSender {
98
94
  opts: ConfirmOptions,
99
95
  preSigned?: boolean
100
96
  ): Promise<Transaction> {
101
- if (preSigned) {
102
- return tx;
103
- }
104
-
105
- tx.feePayer = this.wallet.publicKey;
106
- tx.recentBlockhash = (
107
- await this.connection.getLatestBlockhash(opts.preflightCommitment)
108
- ).blockhash;
109
-
110
- additionalSigners
111
- .filter((s): s is Signer => s !== undefined)
112
- .forEach((kp) => {
113
- tx.partialSign(kp);
114
- });
115
-
116
- const signedTx = await this.wallet.signTransaction(tx);
117
-
118
- return signedTx;
119
- }
120
-
121
- async getVersionedTransaction(
122
- ixs: TransactionInstruction[],
123
- lookupTableAccounts: AddressLookupTableAccount[],
124
- additionalSigners?: Array<Signer>,
125
- opts?: ConfirmOptions,
126
- blockhash?: string
127
- ): Promise<VersionedTransaction> {
128
- if (additionalSigners === undefined) {
129
- additionalSigners = [];
130
- }
131
- if (opts === undefined) {
132
- opts = this.opts;
133
- }
134
-
135
- let recentBlockhash = '';
136
- if (blockhash) {
137
- recentBlockhash = blockhash;
138
- } else {
139
- recentBlockhash = (
140
- await this.connection.getLatestBlockhash(opts.preflightCommitment)
141
- ).blockhash;
142
- }
143
-
144
- const message = new TransactionMessage({
145
- payerKey: this.wallet.publicKey,
146
- recentBlockhash,
147
- instructions: ixs,
148
- }).compileToV0Message(lookupTableAccounts);
149
-
150
- const tx = new VersionedTransaction(message);
151
-
152
- return tx;
97
+ return this.txHandler.prepareTx(
98
+ tx,
99
+ additionalSigners,
100
+ undefined,
101
+ opts,
102
+ preSigned
103
+ );
153
104
  }
154
105
 
155
106
  async sendVersionedTransaction(
156
107
  tx: VersionedTransaction,
157
108
  additionalSigners?: Array<Signer>,
158
109
  opts?: ConfirmOptions,
159
- preSigned?: boolean,
160
- extraConfirmationOptions?: ExtraConfirmationOptions
110
+ preSigned?: boolean
161
111
  ): Promise<TxSigAndSlot> {
162
112
  let signedTx;
113
+
163
114
  if (preSigned) {
164
115
  signedTx = tx;
165
116
  // @ts-ignore
@@ -168,17 +119,12 @@ export abstract class BaseTxSender implements TxSender {
168
119
  tx.sign((additionalSigners ?? []).concat(this.wallet.payer));
169
120
  signedTx = tx;
170
121
  } else {
171
- additionalSigners
172
- ?.filter((s): s is Signer => s !== undefined)
173
- .forEach((kp) => {
174
- tx.sign([kp]);
175
- });
176
- // @ts-ignore
177
- signedTx = await this.wallet.signTransaction(tx);
178
- }
179
-
180
- if (extraConfirmationOptions?.onSignedCb) {
181
- extraConfirmationOptions.onSignedCb();
122
+ signedTx = await this.txHandler.signVersionedTx(
123
+ tx,
124
+ additionalSigners,
125
+ undefined,
126
+ this.wallet
127
+ );
182
128
  }
183
129
 
184
130
  if (opts === undefined) {
@@ -1,19 +1,15 @@
1
1
  import { ConfirmationStrategy, TxSigAndSlot } from './types';
2
2
  import {
3
3
  ConfirmOptions,
4
- Signer,
5
- Transaction,
6
4
  TransactionSignature,
7
5
  Connection,
8
- VersionedTransaction,
9
- TransactionMessage,
10
- TransactionInstruction,
11
- AddressLookupTableAccount,
12
6
  Commitment,
7
+ BlockhashWithExpiryBlockHeight,
13
8
  } from '@solana/web3.js';
14
9
  import { AnchorProvider } from '@coral-xyz/anchor';
15
- import { IWallet } from '../types';
16
10
  import { BaseTxSender } from './baseTxSender';
11
+ import { TxHandler } from './txHandler';
12
+ import { IWallet } from '../types';
17
13
 
18
14
  const DEFAULT_TIMEOUT = 35000;
19
15
  const DEFAULT_BLOCKHASH_REFRESH = 10000;
@@ -26,7 +22,7 @@ export class FastSingleTxSender extends BaseTxSender {
26
22
  blockhashRefreshInterval: number;
27
23
  additionalConnections: Connection[];
28
24
  timoutCount = 0;
29
- recentBlockhash: string;
25
+ recentBlockhash: BlockhashWithExpiryBlockHeight;
30
26
  skipConfirmation: boolean;
31
27
  blockhashCommitment: Commitment;
32
28
  blockhashIntervalId: NodeJS.Timer;
@@ -41,6 +37,7 @@ export class FastSingleTxSender extends BaseTxSender {
41
37
  skipConfirmation = false,
42
38
  blockhashCommitment = 'finalized',
43
39
  confirmationStrategy = ConfirmationStrategy.Combo,
40
+ txHandler,
44
41
  }: {
45
42
  connection: Connection;
46
43
  wallet: IWallet;
@@ -51,6 +48,7 @@ export class FastSingleTxSender extends BaseTxSender {
51
48
  skipConfirmation?: boolean;
52
49
  blockhashCommitment?: Commitment;
53
50
  confirmationStrategy?: ConfirmationStrategy;
51
+ txHandler: TxHandler;
54
52
  }) {
55
53
  super({
56
54
  connection,
@@ -59,6 +57,7 @@ export class FastSingleTxSender extends BaseTxSender {
59
57
  timeout,
60
58
  additionalConnections,
61
59
  confirmationStrategy,
60
+ txHandler,
62
61
  });
63
62
  this.connection = connection;
64
63
  this.wallet = wallet;
@@ -75,9 +74,9 @@ export class FastSingleTxSender extends BaseTxSender {
75
74
  if (this.blockhashRefreshInterval > 0) {
76
75
  this.blockhashIntervalId = setInterval(async () => {
77
76
  try {
78
- this.recentBlockhash = (
79
- await this.connection.getLatestBlockhash(this.blockhashCommitment)
80
- ).blockhash;
77
+ this.recentBlockhash = await this.connection.getLatestBlockhash(
78
+ this.blockhashCommitment
79
+ );
81
80
  } catch (e) {
82
81
  console.error('Error in startBlockhashRefreshLoop: ', e);
83
82
  }
@@ -85,50 +84,6 @@ export class FastSingleTxSender extends BaseTxSender {
85
84
  }
86
85
  }
87
86
 
88
- async prepareTx(
89
- tx: Transaction,
90
- additionalSigners: Array<Signer>,
91
- _opts: ConfirmOptions,
92
- preSigned?: boolean
93
- ): Promise<Transaction> {
94
- return super.prepareTx(tx, additionalSigners, _opts, preSigned);
95
- }
96
-
97
- async getVersionedTransaction(
98
- ixs: TransactionInstruction[],
99
- lookupTableAccounts: AddressLookupTableAccount[],
100
- additionalSigners?: Array<Signer>,
101
- opts?: ConfirmOptions,
102
- blockhash?: string
103
- ): Promise<VersionedTransaction> {
104
- if (additionalSigners === undefined) {
105
- additionalSigners = [];
106
- }
107
- if (opts === undefined) {
108
- opts = this.opts;
109
- }
110
-
111
- let recentBlockhash = '';
112
- if (blockhash) {
113
- recentBlockhash = blockhash;
114
- } else {
115
- recentBlockhash =
116
- this.recentBlockhash ??
117
- (await this.connection.getLatestBlockhash(opts.preflightCommitment))
118
- .blockhash;
119
- }
120
-
121
- const message = new TransactionMessage({
122
- payerKey: this.wallet.publicKey,
123
- recentBlockhash,
124
- instructions: ixs,
125
- }).compileToV0Message(lookupTableAccounts);
126
-
127
- const tx = new VersionedTransaction(message);
128
-
129
- return tx;
130
- }
131
-
132
87
  async sendRawTransaction(
133
88
  rawTransaction: Buffer | Uint8Array,
134
89
  opts: ConfirmOptions
@@ -5,9 +5,10 @@ import {
5
5
  VersionedTransaction,
6
6
  } from '@solana/web3.js';
7
7
  import bs58 from 'bs58';
8
- import { IWallet } from '../types';
9
8
  import { BaseTxSender } from './baseTxSender';
10
9
  import { ConfirmationStrategy, TxSigAndSlot } from './types';
10
+ import { TxHandler } from './txHandler';
11
+ import { IWallet } from '../types';
11
12
 
12
13
  const DEFAULT_TIMEOUT = 35000;
13
14
  const DEFAULT_RETRY = 5000;
@@ -33,6 +34,7 @@ export class ForwardOnlyTxSender extends BaseTxSender {
33
34
  retrySleep = DEFAULT_RETRY,
34
35
  confirmationStrategy = ConfirmationStrategy.Combo,
35
36
  additionalTxSenderCallbacks = [],
37
+ txHandler,
36
38
  }: {
37
39
  connection: Connection;
38
40
  wallet: IWallet;
@@ -41,6 +43,7 @@ export class ForwardOnlyTxSender extends BaseTxSender {
41
43
  retrySleep?: number;
42
44
  confirmationStrategy?: ConfirmationStrategy;
43
45
  additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
46
+ txHandler: TxHandler;
44
47
  }) {
45
48
  super({
46
49
  connection,
@@ -50,6 +53,7 @@ export class ForwardOnlyTxSender extends BaseTxSender {
50
53
  additionalConnections: [],
51
54
  confirmationStrategy,
52
55
  additionalTxSenderCallbacks,
56
+ txHandler,
53
57
  });
54
58
  this.connection = connection;
55
59
  this.wallet = wallet;
@@ -1,8 +1,9 @@
1
1
  import { ConfirmationStrategy, TxSigAndSlot } from './types';
2
2
  import { ConfirmOptions, Connection } from '@solana/web3.js';
3
3
  import { AnchorProvider } from '@coral-xyz/anchor';
4
- import { IWallet } from '../types';
5
4
  import { BaseTxSender } from './baseTxSender';
5
+ import { TxHandler } from './txHandler';
6
+ import { IWallet } from '../types';
6
7
 
7
8
  const DEFAULT_TIMEOUT = 35000;
8
9
  const DEFAULT_RETRY = 2000;
@@ -29,6 +30,7 @@ export class RetryTxSender extends BaseTxSender {
29
30
  additionalConnections = new Array<Connection>(),
30
31
  confirmationStrategy = ConfirmationStrategy.Combo,
31
32
  additionalTxSenderCallbacks = [],
33
+ txHandler,
32
34
  }: {
33
35
  connection: Connection;
34
36
  wallet: IWallet;
@@ -38,6 +40,7 @@ export class RetryTxSender extends BaseTxSender {
38
40
  additionalConnections?;
39
41
  confirmationStrategy?: ConfirmationStrategy;
40
42
  additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
43
+ txHandler: TxHandler;
41
44
  }) {
42
45
  super({
43
46
  connection,
@@ -47,6 +50,7 @@ export class RetryTxSender extends BaseTxSender {
47
50
  additionalConnections,
48
51
  confirmationStrategy,
49
52
  additionalTxSenderCallbacks,
53
+ txHandler,
50
54
  });
51
55
  this.connection = connection;
52
56
  this.wallet = wallet;