@drift-labs/sdk 2.16.0-beta.3 → 2.16.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/lib/config.d.ts CHANGED
@@ -10,6 +10,7 @@ declare type DriftConfig = {
10
10
  V2_ALPHA_TICKET_MINT_ADDRESS: string;
11
11
  PERP_MARKETS: PerpMarketConfig[];
12
12
  SPOT_MARKETS: SpotMarketConfig[];
13
+ MARKET_LOOKUP_TABLE: string;
13
14
  };
14
15
  export declare type DriftEnv = 'devnet' | 'mainnet-beta';
15
16
  export declare const configs: {
package/lib/config.js CHANGED
@@ -13,6 +13,7 @@ exports.configs = {
13
13
  V2_ALPHA_TICKET_MINT_ADDRESS: 'DeEiGWfCMP9psnLGkxGrBBMEAW5Jv8bBGMN8DCtFRCyB',
14
14
  PERP_MARKETS: perpMarkets_1.DevnetPerpMarkets,
15
15
  SPOT_MARKETS: spotMarkets_1.DevnetSpotMarkets,
16
+ MARKET_LOOKUP_TABLE: 'FaMS3U4uBojvGn5FSDEPimddcXsCfwkKsFgMVVnDdxGb',
16
17
  },
17
18
  'mainnet-beta': {
18
19
  ENV: 'mainnet-beta',
@@ -23,6 +24,7 @@ exports.configs = {
23
24
  V2_ALPHA_TICKET_MINT_ADDRESS: 'Cmvhycb6LQvvzaShGw4iDHRLzeSSryioAsU98DSSkMNa',
24
25
  PERP_MARKETS: perpMarkets_1.MainnetPerpMarkets,
25
26
  SPOT_MARKETS: spotMarkets_1.MainnetSpotMarkets,
27
+ MARKET_LOOKUP_TABLE: 'D9cnvzswDikQDf53k4HpQ3KJ9y1Fv3HGGDFYMXnK5T6c',
26
28
  },
27
29
  };
28
30
  let currentConfig = exports.configs.devnet;
@@ -3,7 +3,7 @@
3
3
  import { AnchorProvider, BN, Program } from '@project-serum/anchor';
4
4
  import { StateAccount, IWallet, PositionDirection, UserAccount, PerpMarketAccount, OrderParams, Order, SpotMarketAccount, SpotPosition, MakerInfo, TakerInfo, OptionalOrderParams, OrderType, ReferrerInfo, MarketType, TxParams, SerumV3FulfillmentConfigAccount } from './types';
5
5
  import * as anchor from '@project-serum/anchor';
6
- import { Connection, PublicKey, TransactionSignature, ConfirmOptions, Transaction, TransactionInstruction, AccountMeta, Signer } from '@solana/web3.js';
6
+ import { Connection, PublicKey, TransactionSignature, ConfirmOptions, Transaction, TransactionInstruction, AccountMeta, Signer, AddressLookupTableAccount } from '@solana/web3.js';
7
7
  import { TokenFaucet } from './tokenFaucet';
8
8
  import { EventEmitter } from 'events';
9
9
  import StrictEventEmitter from 'strict-event-emitter-types';
@@ -43,6 +43,7 @@ export declare class DriftClient {
43
43
  perpMarketLastSlotCache: Map<number, number>;
44
44
  spotMarketLastSlotCache: Map<number, number>;
45
45
  authority: PublicKey;
46
+ marketLookupTable: PublicKey;
46
47
  get isSubscribed(): boolean;
47
48
  set isSubscribed(val: boolean);
48
49
  constructor(config: DriftClientConfig);
@@ -82,6 +83,7 @@ export declare class DriftClient {
82
83
  getQuoteSpotMarketAccount(): SpotMarketAccount;
83
84
  getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
84
85
  getSerumV3FulfillmentConfig(serumMarket: PublicKey): Promise<SerumV3FulfillmentConfigAccount>;
86
+ fetchMarketLookupTableAccount(): Promise<AddressLookupTableAccount>;
85
87
  /**
86
88
  * Update the wallet to use for drift transactions and linked user account
87
89
  * @param newWallet
@@ -93,6 +93,10 @@ class DriftClient {
93
93
  : envSpotMarketIndexes;
94
94
  oracleInfos = oracleInfos ? oracleInfos : envOracleInfos;
95
95
  }
96
+ this.marketLookupTable = config.marketLookupTable;
97
+ if (config.env && !this.marketLookupTable) {
98
+ this.marketLookupTable = new web3_js_1.PublicKey(config_1.configs[config.env].MARKET_LOOKUP_TABLE);
99
+ }
96
100
  if (((_e = config.accountSubscription) === null || _e === void 0 ? void 0 : _e.type) === 'polling') {
97
101
  this.accountSubscriber = new pollingDriftClientAccountSubscriber_1.PollingDriftClientAccountSubscriber(this.program, config.accountSubscription.accountLoader, perpMarketIndexes !== null && perpMarketIndexes !== void 0 ? perpMarketIndexes : [], spotMarketIndexes !== null && spotMarketIndexes !== void 0 ? spotMarketIndexes : [], oracleInfos !== null && oracleInfos !== void 0 ? oracleInfos : []);
98
102
  }
@@ -231,6 +235,13 @@ class DriftClient {
231
235
  const address = await pda_1.getSerumFulfillmentConfigPublicKey(this.program.programId, serumMarket);
232
236
  return (await this.program.account.serumV3FulfillmentConfig.fetch(address));
233
237
  }
238
+ async fetchMarketLookupTableAccount() {
239
+ if (!this.marketLookupTable) {
240
+ throw Error('Market lookup table address not set');
241
+ }
242
+ return (await this.connection.getAddressLookupTable(this.marketLookupTable))
243
+ .value;
244
+ }
234
245
  /**
235
246
  * Update the wallet to use for drift transactions and linked user account
236
247
  * @param newWallet
@@ -14,6 +14,7 @@ export declare type DriftClientConfig = {
14
14
  activeSubAccountId?: number;
15
15
  perpMarketIndexes?: number[];
16
16
  spotMarketIndexes?: number[];
17
+ marketLookupTable?: PublicKey;
17
18
  oracleInfos?: OracleInfo[];
18
19
  env?: DriftEnv;
19
20
  userStats?: boolean;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.16.0-beta.3",
2
+ "version": "2.16.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { TxSender, TxSigAndSlot } from './types';
3
- import { Commitment, ConfirmOptions, RpcResponseAndContext, Signer, SignatureResult, Transaction, TransactionSignature, Connection } from '@solana/web3.js';
3
+ import { Commitment, ConfirmOptions, RpcResponseAndContext, Signer, SignatureResult, Transaction, TransactionSignature, Connection, TransactionInstruction, AddressLookupTableAccount } from '@solana/web3.js';
4
4
  import { AnchorProvider } from '@project-serum/anchor';
5
5
  declare type ResolveReference = {
6
6
  resolve?: () => void;
@@ -13,11 +13,13 @@ export declare class RetryTxSender implements TxSender {
13
13
  constructor(provider: AnchorProvider, timeout?: number, retrySleep?: number, additionalConnections?: Connection[]);
14
14
  send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
15
15
  prepareTx(tx: Transaction, additionalSigners: Array<Signer>, opts: ConfirmOptions): Promise<Transaction>;
16
+ sendVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
17
+ sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
16
18
  confirmTransaction(signature: TransactionSignature, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult>>;
17
19
  getTimestamp(): number;
18
20
  sleep(reference: ResolveReference): Promise<void>;
19
21
  promiseTimeout<T>(promises: Promise<T>[], timeoutMs: number): Promise<T | null>;
20
- sendToAdditionalConnections(rawTx: Buffer, opts: ConfirmOptions): void;
22
+ sendToAdditionalConnections(rawTx: Buffer | Uint8Array, opts: ConfirmOptions): void;
21
23
  addAdditionalConnection(newConnection: Connection): void;
22
24
  }
23
25
  export {};
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.RetryTxSender = void 0;
7
+ const web3_js_1 = require("@solana/web3.js");
7
8
  const assert_1 = __importDefault(require("assert"));
8
9
  const bs58_1 = __importDefault(require("bs58"));
9
10
  const DEFAULT_TIMEOUT = 35000;
@@ -25,7 +26,37 @@ class RetryTxSender {
25
26
  const signedTx = preSigned
26
27
  ? tx
27
28
  : await this.prepareTx(tx, additionalSigners, opts);
28
- const rawTransaction = signedTx.serialize();
29
+ return this.sendRawTransaction(signedTx.serialize(), opts);
30
+ }
31
+ async prepareTx(tx, additionalSigners, opts) {
32
+ tx.feePayer = this.provider.wallet.publicKey;
33
+ tx.recentBlockhash = (await this.provider.connection.getRecentBlockhash(opts.preflightCommitment)).blockhash;
34
+ const signedTx = await this.provider.wallet.signTransaction(tx);
35
+ additionalSigners
36
+ .filter((s) => s !== undefined)
37
+ .forEach((kp) => {
38
+ signedTx.partialSign(kp);
39
+ });
40
+ return signedTx;
41
+ }
42
+ async sendVersionedTransaction(ixs, lookupTableAccounts, additionalSigners, opts) {
43
+ if (additionalSigners === undefined) {
44
+ additionalSigners = [];
45
+ }
46
+ if (opts === undefined) {
47
+ opts = this.provider.opts;
48
+ }
49
+ const message = new web3_js_1.TransactionMessage({
50
+ payerKey: this.provider.wallet.publicKey,
51
+ recentBlockhash: (await this.provider.connection.getRecentBlockhash(opts.preflightCommitment)).blockhash,
52
+ instructions: ixs,
53
+ }).compileToV0Message(lookupTableAccounts);
54
+ const tx = new web3_js_1.VersionedTransaction(message);
55
+ // @ts-ignore
56
+ tx.sign(additionalSigners.concat(this.provider.wallet.payer));
57
+ return this.sendRawTransaction(tx.serialize(), opts);
58
+ }
59
+ async sendRawTransaction(rawTransaction, opts) {
29
60
  const startTime = this.getTimestamp();
30
61
  let txid;
31
62
  try {
@@ -74,17 +105,6 @@ class RetryTxSender {
74
105
  }
75
106
  return { txSig: txid, slot };
76
107
  }
77
- async prepareTx(tx, additionalSigners, opts) {
78
- tx.feePayer = this.provider.wallet.publicKey;
79
- tx.recentBlockhash = (await this.provider.connection.getRecentBlockhash(opts.preflightCommitment)).blockhash;
80
- const signedTx = await this.provider.wallet.signTransaction(tx);
81
- additionalSigners
82
- .filter((s) => s !== undefined)
83
- .forEach((kp) => {
84
- signedTx.partialSign(kp);
85
- });
86
- return signedTx;
87
- }
88
108
  async confirmTransaction(signature, commitment) {
89
109
  let decodedSignature;
90
110
  try {
package/lib/tx/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Provider } from '@project-serum/anchor';
2
- import { ConfirmOptions, Signer, Transaction, TransactionSignature } from '@solana/web3.js';
2
+ import { AddressLookupTableAccount, ConfirmOptions, Signer, Transaction, TransactionInstruction, TransactionSignature } from '@solana/web3.js';
3
3
  export declare type TxSigAndSlot = {
4
4
  txSig: TransactionSignature;
5
5
  slot: number;
@@ -7,4 +7,5 @@ export declare type TxSigAndSlot = {
7
7
  export interface TxSender {
8
8
  provider: Provider;
9
9
  send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
10
+ sendVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.16.0-beta.3",
3
+ "version": "2.16.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
package/src/config.ts CHANGED
@@ -21,6 +21,7 @@ type DriftConfig = {
21
21
  V2_ALPHA_TICKET_MINT_ADDRESS: string;
22
22
  PERP_MARKETS: PerpMarketConfig[];
23
23
  SPOT_MARKETS: SpotMarketConfig[];
24
+ MARKET_LOOKUP_TABLE: string;
24
25
  };
25
26
 
26
27
  export type DriftEnv = 'devnet' | 'mainnet-beta';
@@ -36,6 +37,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
36
37
  'DeEiGWfCMP9psnLGkxGrBBMEAW5Jv8bBGMN8DCtFRCyB',
37
38
  PERP_MARKETS: DevnetPerpMarkets,
38
39
  SPOT_MARKETS: DevnetSpotMarkets,
40
+ MARKET_LOOKUP_TABLE: 'FaMS3U4uBojvGn5FSDEPimddcXsCfwkKsFgMVVnDdxGb',
39
41
  },
40
42
  'mainnet-beta': {
41
43
  ENV: 'mainnet-beta',
@@ -47,6 +49,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
47
49
  'Cmvhycb6LQvvzaShGw4iDHRLzeSSryioAsU98DSSkMNa',
48
50
  PERP_MARKETS: MainnetPerpMarkets,
49
51
  SPOT_MARKETS: MainnetSpotMarkets,
52
+ MARKET_LOOKUP_TABLE: 'D9cnvzswDikQDf53k4HpQ3KJ9y1Fv3HGGDFYMXnK5T6c',
50
53
  },
51
54
  };
52
55
 
@@ -42,6 +42,7 @@ import {
42
42
  Signer,
43
43
  SystemProgram,
44
44
  ComputeBudgetProgram,
45
+ AddressLookupTableAccount,
45
46
  } from '@solana/web3.js';
46
47
 
47
48
  import { TokenFaucet } from './tokenFaucet';
@@ -77,7 +78,7 @@ import { WebSocketDriftClientAccountSubscriber } from './accounts/webSocketDrift
77
78
  import { RetryTxSender } from './tx/retryTxSender';
78
79
  import { User } from './user';
79
80
  import { UserSubscriptionConfig } from './userConfig';
80
- import { getMarketsAndOraclesForSubscription } from './config';
81
+ import { configs, getMarketsAndOraclesForSubscription } from './config';
81
82
  import { WRAPPED_SOL_MINT } from './constants/spotMarkets';
82
83
  import { UserStats } from './userStats';
83
84
  import { isSpotPositionAvailable } from './math/spotPosition';
@@ -112,6 +113,7 @@ export class DriftClient {
112
113
  perpMarketLastSlotCache = new Map<number, number>();
113
114
  spotMarketLastSlotCache = new Map<number, number>();
114
115
  authority: PublicKey;
116
+ marketLookupTable: PublicKey;
115
117
 
116
118
  public get isSubscribed() {
117
119
  return this._isSubscribed && this.accountSubscriber.isSubscribed;
@@ -178,6 +180,13 @@ export class DriftClient {
178
180
  oracleInfos = oracleInfos ? oracleInfos : envOracleInfos;
179
181
  }
180
182
 
183
+ this.marketLookupTable = config.marketLookupTable;
184
+ if (config.env && !this.marketLookupTable) {
185
+ this.marketLookupTable = new PublicKey(
186
+ configs[config.env].MARKET_LOOKUP_TABLE
187
+ );
188
+ }
189
+
181
190
  if (config.accountSubscription?.type === 'polling') {
182
191
  this.accountSubscriber = new PollingDriftClientAccountSubscriber(
183
192
  this.program,
@@ -387,6 +396,15 @@ export class DriftClient {
387
396
  )) as SerumV3FulfillmentConfigAccount;
388
397
  }
389
398
 
399
+ public async fetchMarketLookupTableAccount(): Promise<AddressLookupTableAccount> {
400
+ if (!this.marketLookupTable) {
401
+ throw Error('Market lookup table address not set');
402
+ }
403
+
404
+ return (await this.connection.getAddressLookupTable(this.marketLookupTable))
405
+ .value;
406
+ }
407
+
390
408
  /**
391
409
  * Update the wallet to use for drift transactions and linked user account
392
410
  * @param newWallet
@@ -15,6 +15,7 @@ export type DriftClientConfig = {
15
15
  activeSubAccountId?: number;
16
16
  perpMarketIndexes?: number[];
17
17
  spotMarketIndexes?: number[];
18
+ marketLookupTable?: PublicKey;
18
19
  oracleInfos?: OracleInfo[];
19
20
  env?: DriftEnv;
20
21
  userStats?: boolean;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.16.0-beta.3",
2
+ "version": "2.16.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -9,6 +9,10 @@ import {
9
9
  Transaction,
10
10
  TransactionSignature,
11
11
  Connection,
12
+ VersionedTransaction,
13
+ TransactionMessage,
14
+ TransactionInstruction,
15
+ AddressLookupTableAccount,
12
16
  } from '@solana/web3.js';
13
17
  import { AnchorProvider } from '@project-serum/anchor';
14
18
  import assert from 'assert';
@@ -56,7 +60,65 @@ export class RetryTxSender implements TxSender {
56
60
  ? tx
57
61
  : await this.prepareTx(tx, additionalSigners, opts);
58
62
 
59
- const rawTransaction = signedTx.serialize();
63
+ return this.sendRawTransaction(signedTx.serialize(), opts);
64
+ }
65
+
66
+ async prepareTx(
67
+ tx: Transaction,
68
+ additionalSigners: Array<Signer>,
69
+ opts: ConfirmOptions
70
+ ): Promise<Transaction> {
71
+ tx.feePayer = this.provider.wallet.publicKey;
72
+ tx.recentBlockhash = (
73
+ await this.provider.connection.getRecentBlockhash(
74
+ opts.preflightCommitment
75
+ )
76
+ ).blockhash;
77
+
78
+ const signedTx = await this.provider.wallet.signTransaction(tx);
79
+ additionalSigners
80
+ .filter((s): s is Signer => s !== undefined)
81
+ .forEach((kp) => {
82
+ signedTx.partialSign(kp);
83
+ });
84
+
85
+ return signedTx;
86
+ }
87
+
88
+ async sendVersionedTransaction(
89
+ ixs: TransactionInstruction[],
90
+ lookupTableAccounts: AddressLookupTableAccount[],
91
+ additionalSigners?: Array<Signer>,
92
+ opts?: ConfirmOptions
93
+ ): Promise<TxSigAndSlot> {
94
+ if (additionalSigners === undefined) {
95
+ additionalSigners = [];
96
+ }
97
+ if (opts === undefined) {
98
+ opts = this.provider.opts;
99
+ }
100
+
101
+ const message = new TransactionMessage({
102
+ payerKey: this.provider.wallet.publicKey,
103
+ recentBlockhash: (
104
+ await this.provider.connection.getRecentBlockhash(
105
+ opts.preflightCommitment
106
+ )
107
+ ).blockhash,
108
+ instructions: ixs,
109
+ }).compileToV0Message(lookupTableAccounts);
110
+
111
+ const tx = new VersionedTransaction(message);
112
+ // @ts-ignore
113
+ tx.sign(additionalSigners.concat(this.provider.wallet.payer));
114
+
115
+ return this.sendRawTransaction(tx.serialize(), opts);
116
+ }
117
+
118
+ async sendRawTransaction(
119
+ rawTransaction: Buffer | Uint8Array,
120
+ opts: ConfirmOptions
121
+ ): Promise<TxSigAndSlot> {
60
122
  const startTime = this.getTimestamp();
61
123
 
62
124
  let txid: TransactionSignature;
@@ -111,28 +173,6 @@ export class RetryTxSender implements TxSender {
111
173
  return { txSig: txid, slot };
112
174
  }
113
175
 
114
- async prepareTx(
115
- tx: Transaction,
116
- additionalSigners: Array<Signer>,
117
- opts: ConfirmOptions
118
- ): Promise<Transaction> {
119
- tx.feePayer = this.provider.wallet.publicKey;
120
- tx.recentBlockhash = (
121
- await this.provider.connection.getRecentBlockhash(
122
- opts.preflightCommitment
123
- )
124
- ).blockhash;
125
-
126
- const signedTx = await this.provider.wallet.signTransaction(tx);
127
- additionalSigners
128
- .filter((s): s is Signer => s !== undefined)
129
- .forEach((kp) => {
130
- signedTx.partialSign(kp);
131
- });
132
-
133
- return signedTx;
134
- }
135
-
136
176
  async confirmTransaction(
137
177
  signature: TransactionSignature,
138
178
  commitment?: Commitment
@@ -229,7 +269,10 @@ export class RetryTxSender implements TxSender {
229
269
  );
230
270
  }
231
271
 
232
- sendToAdditionalConnections(rawTx: Buffer, opts: ConfirmOptions): void {
272
+ sendToAdditionalConnections(
273
+ rawTx: Buffer | Uint8Array,
274
+ opts: ConfirmOptions
275
+ ): void {
233
276
  this.additionalConnections.map((connection) => {
234
277
  connection.sendRawTransaction(rawTx, opts).catch((e) => {
235
278
  console.error(
package/src/tx/types.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { Provider } from '@project-serum/anchor';
2
2
  import {
3
+ AddressLookupTableAccount,
3
4
  ConfirmOptions,
4
5
  Signer,
5
6
  Transaction,
7
+ TransactionInstruction,
6
8
  TransactionSignature,
7
9
  } from '@solana/web3.js';
8
10
 
@@ -20,4 +22,11 @@ export interface TxSender {
20
22
  opts?: ConfirmOptions,
21
23
  preSigned?: boolean
22
24
  ): Promise<TxSigAndSlot>;
25
+
26
+ sendVersionedTransaction(
27
+ ixs: TransactionInstruction[],
28
+ lookupTableAccounts: AddressLookupTableAccount[],
29
+ additionalSigners?: Array<Signer>,
30
+ opts?: ConfirmOptions
31
+ ): Promise<TxSigAndSlot>;
23
32
  }
package/src/tx/types.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
package/src/tx/utils.js DELETED
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.wrapInTx = void 0;
4
- const web3_js_1 = require("@solana/web3.js");
5
- const COMPUTE_UNITS_DEFAULT = 200000;
6
- function wrapInTx(instruction, computeUnits = 600000 // TODO, requires less code change
7
- ) {
8
- const tx = new web3_js_1.Transaction();
9
- if (computeUnits != COMPUTE_UNITS_DEFAULT) {
10
- tx.add(web3_js_1.ComputeBudgetProgram.requestUnits({
11
- units: computeUnits,
12
- additionalFee: 0,
13
- }));
14
- }
15
- return tx.add(instruction);
16
- }
17
- exports.wrapInTx = wrapInTx;