@drift-labs/sdk 2.82.0-beta.6 → 2.82.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/README.md CHANGED
@@ -19,6 +19,13 @@ npm i @drift-labs/sdk
19
19
 
20
20
  ## Getting Started
21
21
 
22
+ Documentation:
23
+
24
+ - [API docs](https://drift-labs.github.io/v2-teacher/)
25
+ - [overview docs](https://docs.drift.trade/)
26
+
27
+ The below is a light overview of using solana and drift's typescript sdk, but not as comprehensive as the [API docs](https://drift-labs.github.io/v2-teacher/).
28
+
22
29
  ### Setting up a wallet for your program
23
30
 
24
31
  ```bash
@@ -77,8 +84,10 @@ convertToNumber(new BN(10500), new BN(1000)); // = 10.5
77
84
  ### Setting up an account and making a trade
78
85
 
79
86
  ```typescript
80
- import { AnchorProvider, BN } from '@coral-xyz/anchor';
81
- import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
87
+ import * as anchor from '@coral-xyz/anchor';
88
+ import { AnchorProvider } from '@coral-xyz/anchor';
89
+ import { getAssociatedTokenAddress, TOKEN_PROGRAM_ID } from '@solana/spl-token';
90
+
82
91
  import { Connection, Keypair, PublicKey } from '@solana/web3.js';
83
92
  import {
84
93
  calculateReservePrice,
@@ -95,16 +104,17 @@ import {
95
104
  BASE_PRECISION,
96
105
  getMarketOrderParams,
97
106
  BulkAccountLoader,
98
- getMarketsAndOraclesForSubscription
107
+ BN,
108
+ calculateBidAskPrice,
109
+ getMarketsAndOraclesForSubscription,
110
+ calculateEstimatedPerpEntryPrice,
99
111
  } from '../sdk';
100
112
 
101
113
  export const getTokenAddress = (
102
114
  mintAddress: string,
103
115
  userPubKey: string
104
116
  ): Promise<PublicKey> => {
105
- return Token.getAssociatedTokenAddress(
106
- new PublicKey(`ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`),
107
- TOKEN_PROGRAM_ID,
117
+ return getAssociatedTokenAddress(
108
118
  new PublicKey(mintAddress),
109
119
  new PublicKey(userPubKey)
110
120
  );
@@ -112,49 +122,56 @@ export const getTokenAddress = (
112
122
 
113
123
  const main = async () => {
114
124
  const env = 'devnet';
125
+ // const env = 'mainnet-beta';
126
+
115
127
  // Initialize Drift SDK
116
128
  const sdkConfig = initialize({ env });
117
129
 
118
130
  // Set up the Wallet and Provider
119
- const privateKey = process.env.BOT_PRIVATE_KEY; // stored as an array string
120
- const keypair = Keypair.fromSecretKey(
121
- Uint8Array.from(JSON.parse(privateKey))
122
- );
123
- const wallet = new Wallet(keypair);
131
+ if (!process.env.ANCHOR_WALLET) {
132
+ throw new Error('ANCHOR_WALLET env var must be set.');
133
+ }
124
134
 
125
- // Set up the Connection
126
- const rpcAddress = process.env.RPC_ADDRESS; // can use: https://api.devnet.solana.com for devnet; https://api.mainnet-beta.solana.com for mainnet;
127
- const connection = new Connection(rpcAddress);
135
+ if (!process.env.ANCHOR_PROVIDER_URL) {
136
+ throw new Error('ANCHOR_PROVIDER_URL env var must be set.');
137
+ }
128
138
 
129
- // Set up the Provider
130
- const provider = new AnchorProvider(
131
- connection,
132
- wallet,
133
- AnchorProvider.defaultOptions()
139
+ const provider = anchor.AnchorProvider.local(
140
+ process.env.ANCHOR_PROVIDER_URL,
141
+ {
142
+ preflightCommitment: 'confirmed',
143
+ skipPreflight: false,
144
+ commitment: 'confirmed',
145
+ }
134
146
  );
135
-
136
147
  // Check SOL Balance
137
- const lamportsBalance = await connection.getBalance(wallet.publicKey);
138
- console.log('SOL balance:', lamportsBalance / 10 ** 9);
148
+ const lamportsBalance = await provider.connection.getBalance(
149
+ provider.wallet.publicKey
150
+ );
151
+ console.log(
152
+ provider.wallet.publicKey.toString(),
153
+ env,
154
+ 'SOL balance:',
155
+ lamportsBalance / 10 ** 9
156
+ );
139
157
 
140
158
  // Misc. other things to set up
141
159
  const usdcTokenAddress = await getTokenAddress(
142
160
  sdkConfig.USDC_MINT_ADDRESS,
143
- wallet.publicKey.toString()
161
+ provider.wallet.publicKey.toString()
144
162
  );
145
163
 
146
164
  // Set up the Drift Client
147
165
  const driftPublicKey = new PublicKey(sdkConfig.DRIFT_PROGRAM_ID);
148
166
  const bulkAccountLoader = new BulkAccountLoader(
149
- connection,
167
+ provider.connection,
150
168
  'confirmed',
151
169
  1000
152
170
  );
153
171
  const driftClient = new DriftClient({
154
- connection,
172
+ connection: provider.connection,
155
173
  wallet: provider.wallet,
156
174
  programID: driftPublicKey,
157
- ...getMarketsAndOraclesForSubscription(env),
158
175
  accountSubscription: {
159
176
  type: 'polling',
160
177
  accountLoader: bulkAccountLoader,
@@ -162,6 +179,8 @@ const main = async () => {
162
179
  });
163
180
  await driftClient.subscribe();
164
181
 
182
+ console.log('subscribed to driftClient');
183
+
165
184
  // Set up user client
166
185
  const user = new User({
167
186
  driftClient: driftClient,
@@ -176,13 +195,20 @@ const main = async () => {
176
195
  const userAccountExists = await user.exists();
177
196
 
178
197
  if (!userAccountExists) {
179
- //// Create a Clearing House account by Depositing some USDC ($10,000 in this case)
198
+ console.log(
199
+ 'initializing to',
200
+ env,
201
+ ' drift account for',
202
+ provider.wallet.publicKey.toString()
203
+ );
204
+
205
+ //// Create a Drift V2 account by Depositing some USDC ($10,000 in this case)
180
206
  const depositAmount = new BN(10000).mul(QUOTE_PRECISION);
181
207
  await driftClient.initializeUserAccountAndDepositCollateral(
182
208
  depositAmount,
183
209
  await getTokenAddress(
184
210
  usdcTokenAddress.toString(),
185
- wallet.publicKey.toString()
211
+ provider.wallet.publicKey.toString()
186
212
  )
187
213
  );
188
214
  }
@@ -194,6 +220,9 @@ const main = async () => {
194
220
  (market) => market.baseAssetSymbol === 'SOL'
195
221
  );
196
222
 
223
+ const marketIndex = solMarketInfo.marketIndex;
224
+
225
+ // Get vAMM bid and ask price
197
226
  const [bid, ask] = calculateBidAskPrice(
198
227
  driftClient.getPerpMarketAccount(marketIndex).amm,
199
228
  driftClient.getOracleDataForPerpMarket(marketIndex)
@@ -203,35 +232,26 @@ const main = async () => {
203
232
  const formattedAskPrice = convertToNumber(ask, PRICE_PRECISION);
204
233
 
205
234
  console.log(
206
- `Current amm bid and ask price are $${formattedBidPrice} and $${formattedAskPrice}`
235
+ env,
236
+ `vAMM bid: $${formattedBidPrice} and ask: $${formattedAskPrice}`
207
237
  );
208
238
 
209
- // Estimate the slippage for a $5000 LONG trade
210
239
  const solMarketAccount = driftClient.getPerpMarketAccount(
211
240
  solMarketInfo.marketIndex
212
241
  );
242
+ console.log(env, `Placing a 1 SOL-PERP LONG order`);
213
243
 
214
- const slippage = convertToNumber(
215
- calculateTradeSlippage(
216
- PositionDirection.LONG,
217
- new BN(1).mul(BASE_PRECISION),
218
- solMarketAccount,
219
- 'base',
220
- driftClient.getOracleDataForPerpMarket(solMarketInfo.marketIndex)
221
- )[0],
222
- PRICE_PRECISION
223
- );
224
-
225
- console.log(`Slippage for a 1 SOL-PERP would be $${slippage}`);
226
-
227
- await driftClient.placePerpOrder(
244
+ const txSig = await driftClient.placePerpOrder(
228
245
  getMarketOrderParams({
229
246
  baseAssetAmount: new BN(1).mul(BASE_PRECISION),
230
247
  direction: PositionDirection.LONG,
231
248
  marketIndex: solMarketAccount.marketIndex,
232
249
  })
233
250
  );
234
- console.log(`Placed a 1 SOL-PERP LONG order`);
251
+ console.log(
252
+ env,
253
+ `Placed a 1 SOL-PERP LONG order. Tranaction signature: ${txSig}`
254
+ );
235
255
  };
236
256
 
237
257
  main();
@@ -244,5 +264,3 @@ Drift Protocol v2 is licensed under [Apache 2.0](./LICENSE).
244
264
  Unless you explicitly state otherwise, any contribution intentionally submitted
245
265
  for inclusion in Drift SDK by you, as defined in the Apache-2.0 license, shall be
246
266
  licensed as above, without any additional terms or conditions.
247
-
248
-
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.82.0-beta.6
1
+ 2.82.0-beta.8
@@ -10,6 +10,7 @@ const anchor_1 = require("@coral-xyz/anchor");
10
10
  const assert_1 = __importDefault(require("assert"));
11
11
  const bs58_1 = __importDefault(require("bs58"));
12
12
  const DEFAULT_TIMEOUT = 35000;
13
+ const NOT_CONFIRMED_ERROR_CODE = -1001;
13
14
  class BaseTxSender {
14
15
  constructor({ connection, wallet, opts = anchor_1.AnchorProvider.defaultOptions(), timeout = DEFAULT_TIMEOUT, additionalConnections = new Array(), confirmationStrategy = types_1.ConfirmationStrategy.Combo, additionalTxSenderCallbacks, }) {
15
16
  this.timeoutCount = 0;
@@ -181,7 +182,7 @@ class BaseTxSender {
181
182
  }
182
183
  this.timeoutCount += 1;
183
184
  const duration = (Date.now() - start) / 1000;
184
- throw new Error(`Transaction was not confirmed in ${duration.toFixed(2)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`);
185
+ throw new types_1.TxSendError(`Transaction was not confirmed in ${duration.toFixed(2)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`, NOT_CONFIRMED_ERROR_CODE);
185
186
  }
186
187
  return response;
187
188
  }
@@ -203,7 +204,7 @@ class BaseTxSender {
203
204
  // Transaction not confirmed within 30 seconds
204
205
  this.timeoutCount += 1;
205
206
  const duration = (Date.now() - start) / 1000;
206
- throw new Error(`Transaction was not confirmed in ${duration.toFixed(2)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`);
207
+ throw new types_1.TxSendError(`Transaction was not confirmed in ${duration.toFixed(2)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`, NOT_CONFIRMED_ERROR_CODE);
207
208
  }
208
209
  async confirmTransaction(signature, commitment) {
209
210
  if (this.confirmationStrategy === types_1.ConfirmationStrategy.WebSocket ||
package/lib/tx/types.d.ts CHANGED
@@ -22,3 +22,8 @@ export interface TxSender {
22
22
  simulateTransaction(tx: VersionedTransaction): Promise<boolean>;
23
23
  getTimeoutCount(): number;
24
24
  }
25
+ export declare class TxSendError extends Error {
26
+ message: string;
27
+ code: number;
28
+ constructor(message: string, code: number);
29
+ }
package/lib/tx/types.js CHANGED
@@ -1,9 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ConfirmationStrategy = void 0;
3
+ exports.TxSendError = exports.ConfirmationStrategy = void 0;
4
4
  var ConfirmationStrategy;
5
5
  (function (ConfirmationStrategy) {
6
6
  ConfirmationStrategy["WebSocket"] = "websocket";
7
7
  ConfirmationStrategy["Polling"] = "polling";
8
8
  ConfirmationStrategy["Combo"] = "combo";
9
9
  })(ConfirmationStrategy = exports.ConfirmationStrategy || (exports.ConfirmationStrategy = {}));
10
+ class TxSendError extends Error {
11
+ constructor(message, code) {
12
+ super(message);
13
+ this.message = message;
14
+ this.code = code;
15
+ if (Error.captureStackTrace) {
16
+ Error.captureStackTrace(this, TxSendError);
17
+ }
18
+ }
19
+ }
20
+ exports.TxSendError = TxSendError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.82.0-beta.6",
3
+ "version": "2.82.0-beta.8",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -2,6 +2,7 @@ import {
2
2
  ConfirmationStrategy,
3
3
  ExtraConfirmationOptions,
4
4
  TxSender,
5
+ TxSendError,
5
6
  TxSigAndSlot,
6
7
  } from './types';
7
8
  import {
@@ -25,6 +26,7 @@ import bs58 from 'bs58';
25
26
  import { IWallet } from '../types';
26
27
 
27
28
  const DEFAULT_TIMEOUT = 35000;
29
+ const NOT_CONFIRMED_ERROR_CODE = -1001;
28
30
 
29
31
  export abstract class BaseTxSender implements TxSender {
30
32
  connection: Connection;
@@ -282,10 +284,11 @@ export abstract class BaseTxSender implements TxSender {
282
284
  }
283
285
  this.timeoutCount += 1;
284
286
  const duration = (Date.now() - start) / 1000;
285
- throw new Error(
287
+ throw new TxSendError(
286
288
  `Transaction was not confirmed in ${duration.toFixed(
287
289
  2
288
- )} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`
290
+ )} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`,
291
+ NOT_CONFIRMED_ERROR_CODE
289
292
  );
290
293
  }
291
294
 
@@ -317,10 +320,11 @@ export abstract class BaseTxSender implements TxSender {
317
320
  // Transaction not confirmed within 30 seconds
318
321
  this.timeoutCount += 1;
319
322
  const duration = (Date.now() - start) / 1000;
320
- throw new Error(
323
+ throw new TxSendError(
321
324
  `Transaction was not confirmed in ${duration.toFixed(
322
325
  2
323
- )} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`
326
+ )} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`,
327
+ NOT_CONFIRMED_ERROR_CODE
324
328
  );
325
329
  }
326
330
 
package/src/tx/types.ts CHANGED
@@ -60,3 +60,15 @@ export interface TxSender {
60
60
 
61
61
  getTimeoutCount(): number;
62
62
  }
63
+
64
+ export class TxSendError extends Error {
65
+ constructor(
66
+ public message: string,
67
+ public code: number
68
+ ) {
69
+ super(message);
70
+ if (Error.captureStackTrace) {
71
+ Error.captureStackTrace(this, TxSendError);
72
+ }
73
+ }
74
+ }