@drift-labs/sdk 2.94.0-beta.2 → 2.94.0-beta.3

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 CHANGED
@@ -1 +1 @@
1
- 2.94.0-beta.2
1
+ 2.94.0-beta.3
@@ -47,7 +47,7 @@ export declare abstract class BaseTxSender implements TxSender {
47
47
  sendToAdditionalConnections(rawTx: Buffer | Uint8Array, opts: ConfirmOptions): void;
48
48
  addAdditionalConnection(newConnection: Connection): void;
49
49
  getTimeoutCount(): number;
50
- checkConfirmationResultForError(txSig: string, result: RpcResponseAndContext<SignatureResult>): Promise<void>;
50
+ checkConfirmationResultForError(txSig: string, result: SignatureResult): Promise<void>;
51
51
  reportTransactionError(txSig: string): Promise<any>;
52
52
  getTxLandRate(): number;
53
53
  private defaultLandRateToFeeFunc;
@@ -103,7 +103,7 @@ class BaseTxSender {
103
103
  }
104
104
  }
105
105
  async confirmTransactionWebSocket(signature, commitment) {
106
- var _a;
106
+ var _a, _b;
107
107
  let decodedSignature;
108
108
  try {
109
109
  decodedSignature = bs58_1.default.decode(signature);
@@ -150,11 +150,13 @@ class BaseTxSender {
150
150
  if (response === null) {
151
151
  if (this.confirmationStrategy === types_1.ConfirmationStrategy.Combo) {
152
152
  try {
153
- const rpcResponse = await this.connection.getSignatureStatus(signature);
154
- if ((_a = rpcResponse === null || rpcResponse === void 0 ? void 0 : rpcResponse.value) === null || _a === void 0 ? void 0 : _a.confirmationStatus) {
153
+ const rpcResponse = await this.connection.getSignatureStatuses([
154
+ signature,
155
+ ]);
156
+ if ((_b = (_a = rpcResponse === null || rpcResponse === void 0 ? void 0 : rpcResponse.value) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.confirmationStatus) {
155
157
  response = {
156
158
  context: rpcResponse.context,
157
- value: { err: rpcResponse.value.err },
159
+ value: { err: rpcResponse.value[0].err },
158
160
  };
159
161
  return response;
160
162
  }
@@ -176,10 +178,14 @@ class BaseTxSender {
176
178
  const start = Date.now();
177
179
  while (totalTime < this.timeout) {
178
180
  await new Promise((resolve) => setTimeout(resolve, backoffTime));
179
- const response = await this.connection.getSignatureStatus(signature);
180
- const result = response && ((_a = response.value) === null || _a === void 0 ? void 0 : _a[0]);
181
- if (result && result.confirmationStatus === commitment) {
182
- return { context: result.context, value: { err: null } };
181
+ const rpcResponse = await this.connection.getSignatureStatuses([
182
+ signature,
183
+ ]);
184
+ const signatureResult = rpcResponse && ((_a = rpcResponse.value) === null || _a === void 0 ? void 0 : _a[0]);
185
+ if (rpcResponse &&
186
+ signatureResult &&
187
+ signatureResult.confirmationStatus === commitment) {
188
+ return { context: rpcResponse.context, value: { err: null } };
183
189
  }
184
190
  totalTime += backoffTime;
185
191
  backoffTime = Math.min(backoffTime * 2, 5000);
@@ -238,7 +244,7 @@ class BaseTxSender {
238
244
  return this.timeoutCount;
239
245
  }
240
246
  async checkConfirmationResultForError(txSig, result) {
241
- if (result.value.err) {
247
+ if (result.err) {
242
248
  await this.reportTransactionError(txSig);
243
249
  }
244
250
  return;
@@ -63,14 +63,14 @@ class FastSingleTxSender extends baseTxSender_1.BaseTxSender {
63
63
  this.confirmTransaction(txid, opts.commitment).then(async (result) => {
64
64
  var _a;
65
65
  (_a = this.txSigCache) === null || _a === void 0 ? void 0 : _a.set(txid, true);
66
- await this.checkConfirmationResultForError(txid, result);
66
+ await this.checkConfirmationResultForError(txid, result.value);
67
67
  slot = result.context.slot;
68
68
  });
69
69
  }
70
70
  else {
71
71
  const result = await this.confirmTransaction(txid, opts.commitment);
72
72
  (_b = this.txSigCache) === null || _b === void 0 ? void 0 : _b.set(txid, true);
73
- await this.checkConfirmationResultForError(txid, result);
73
+ await this.checkConfirmationResultForError(txid, result.value);
74
74
  slot = result.context.slot;
75
75
  }
76
76
  }
@@ -69,7 +69,7 @@ class RetryTxSender extends baseTxSender_1.BaseTxSender {
69
69
  try {
70
70
  const result = await this.confirmTransaction(txid, opts.commitment);
71
71
  (_b = this.txSigCache) === null || _b === void 0 ? void 0 : _b.set(txid, true);
72
- await this.checkConfirmationResultForError(txid, result);
72
+ await this.checkConfirmationResultForError(txid, result.value);
73
73
  slot = result.context.slot;
74
74
  // eslint-disable-next-line no-useless-catch
75
75
  }
@@ -20,6 +20,8 @@ export declare class WhileValidTxSender extends BaseTxSender {
20
20
  lastValidBlockHeight: number;
21
21
  }>;
22
22
  blockhashCommitment: Commitment;
23
+ useBlockHeightOffset: boolean;
24
+ private checkAndSetUseBlockHeightOffset;
23
25
  constructor({ connection, wallet, opts, retrySleep, additionalConnections, additionalTxSenderCallbacks, blockhashCommitment, txHandler, trackTxLandRate, txLandRateLookbackWindowMinutes, landRateToFeeFunc, }: {
24
26
  connection: Connection;
25
27
  wallet: IWallet;
@@ -10,6 +10,25 @@ const bs58_1 = __importDefault(require("bs58"));
10
10
  const DEFAULT_RETRY = 2000;
11
11
  const VALID_BLOCK_HEIGHT_OFFSET = -150; // This is a bit of weirdness but the lastValidBlockHeight value returned from connection.getLatestBlockhash is always 300 blocks ahead of the current block, even though the transaction actually expires after 150 blocks. This accounts for that so that we can at least accuractely estimate the transaction expiry.
12
12
  class WhileValidTxSender extends baseTxSender_1.BaseTxSender {
13
+ async checkAndSetUseBlockHeightOffset() {
14
+ this.connection.getVersion().then((version) => {
15
+ const solanaCoreVersion = version['solana-core'];
16
+ if (!solanaCoreVersion)
17
+ return;
18
+ const majorVersion = solanaCoreVersion.split('.')[0];
19
+ if (!majorVersion)
20
+ return;
21
+ const parsedMajorVersion = parseInt(majorVersion);
22
+ if (isNaN(parsedMajorVersion))
23
+ return;
24
+ if (parsedMajorVersion >= 2) {
25
+ this.useBlockHeightOffset = false;
26
+ }
27
+ else {
28
+ this.useBlockHeightOffset = true;
29
+ }
30
+ });
31
+ }
13
32
  constructor({ connection, wallet, opts = { ...anchor_1.AnchorProvider.defaultOptions(), maxRetries: 0 }, retrySleep = DEFAULT_RETRY, additionalConnections = new Array(), additionalTxSenderCallbacks = [], blockhashCommitment = 'finalized', txHandler, trackTxLandRate, txLandRateLookbackWindowMinutes, landRateToFeeFunc, }) {
14
33
  super({
15
34
  connection,
@@ -24,8 +43,10 @@ class WhileValidTxSender extends baseTxSender_1.BaseTxSender {
24
43
  });
25
44
  this.timoutCount = 0;
26
45
  this.untilValid = new Map();
46
+ this.useBlockHeightOffset = true;
27
47
  this.retrySleep = retrySleep;
28
48
  this.blockhashCommitment = blockhashCommitment;
49
+ this.checkAndSetUseBlockHeightOffset();
29
50
  }
30
51
  async sleep(reference) {
31
52
  return new Promise((resolve) => {
@@ -120,11 +141,16 @@ class WhileValidTxSender extends baseTxSender_1.BaseTxSender {
120
141
  const { blockhash, lastValidBlockHeight } = this.untilValid.get(txid);
121
142
  const result = await this.connection.confirmTransaction({
122
143
  signature: txid,
123
- lastValidBlockHeight: lastValidBlockHeight + VALID_BLOCK_HEIGHT_OFFSET,
124
144
  blockhash,
125
- }, opts.commitment);
145
+ lastValidBlockHeight: this.useBlockHeightOffset
146
+ ? lastValidBlockHeight + VALID_BLOCK_HEIGHT_OFFSET
147
+ : lastValidBlockHeight,
148
+ }, opts === null || opts === void 0 ? void 0 : opts.commitment);
149
+ if (!result) {
150
+ throw new Error(`Couldn't get signature status for txid: ${txid}`);
151
+ }
126
152
  (_b = this.txSigCache) === null || _b === void 0 ? void 0 : _b.set(txid, true);
127
- await this.checkConfirmationResultForError(txid, result);
153
+ await this.checkConfirmationResultForError(txid, result.value);
128
154
  slot = result.context.slot;
129
155
  // eslint-disable-next-line no-useless-catch
130
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.94.0-beta.2",
3
+ "version": "2.94.0-beta.3",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -267,13 +267,14 @@ export abstract class BaseTxSender implements TxSender {
267
267
  if (response === null) {
268
268
  if (this.confirmationStrategy === ConfirmationStrategy.Combo) {
269
269
  try {
270
- const rpcResponse = await this.connection.getSignatureStatus(
271
- signature
272
- );
273
- if (rpcResponse?.value?.confirmationStatus) {
270
+ const rpcResponse = await this.connection.getSignatureStatuses([
271
+ signature,
272
+ ]);
273
+
274
+ if (rpcResponse?.value?.[0]?.confirmationStatus) {
274
275
  response = {
275
276
  context: rpcResponse.context,
276
- value: { err: rpcResponse.value.err },
277
+ value: { err: rpcResponse.value[0].err },
277
278
  };
278
279
  return response;
279
280
  }
@@ -305,11 +306,18 @@ export abstract class BaseTxSender implements TxSender {
305
306
  while (totalTime < this.timeout) {
306
307
  await new Promise((resolve) => setTimeout(resolve, backoffTime));
307
308
 
308
- const response = await this.connection.getSignatureStatus(signature);
309
- const result = response && response.value?.[0];
309
+ const rpcResponse = await this.connection.getSignatureStatuses([
310
+ signature,
311
+ ]);
312
+
313
+ const signatureResult = rpcResponse && rpcResponse.value?.[0];
310
314
 
311
- if (result && result.confirmationStatus === commitment) {
312
- return { context: result.context, value: { err: null } };
315
+ if (
316
+ rpcResponse &&
317
+ signatureResult &&
318
+ signatureResult.confirmationStatus === commitment
319
+ ) {
320
+ return { context: rpcResponse.context, value: { err: null } };
313
321
  }
314
322
 
315
323
  totalTime += backoffTime;
@@ -398,9 +406,9 @@ export abstract class BaseTxSender implements TxSender {
398
406
 
399
407
  public async checkConfirmationResultForError(
400
408
  txSig: string,
401
- result: RpcResponseAndContext<SignatureResult>
409
+ result: SignatureResult
402
410
  ) {
403
- if (result.value.err) {
411
+ if (result.err) {
404
412
  await this.reportTransactionError(txSig);
405
413
  }
406
414
 
@@ -118,14 +118,14 @@ export class FastSingleTxSender extends BaseTxSender {
118
118
  this.confirmTransaction(txid, opts.commitment).then(
119
119
  async (result) => {
120
120
  this.txSigCache?.set(txid, true);
121
- await this.checkConfirmationResultForError(txid, result);
121
+ await this.checkConfirmationResultForError(txid, result.value);
122
122
  slot = result.context.slot;
123
123
  }
124
124
  );
125
125
  } else {
126
126
  const result = await this.confirmTransaction(txid, opts.commitment);
127
127
  this.txSigCache?.set(txid, true);
128
- await this.checkConfirmationResultForError(txid, result);
128
+ await this.checkConfirmationResultForError(txid, result.value);
129
129
  slot = result.context.slot;
130
130
  }
131
131
  } catch (e) {
@@ -117,7 +117,7 @@ export class RetryTxSender extends BaseTxSender {
117
117
  const result = await this.confirmTransaction(txid, opts.commitment);
118
118
  this.txSigCache?.set(txid, true);
119
119
 
120
- await this.checkConfirmationResultForError(txid, result);
120
+ await this.checkConfirmationResultForError(txid, result.value);
121
121
 
122
122
  slot = result.context.slot;
123
123
  // eslint-disable-next-line no-useless-catch
@@ -35,6 +35,30 @@ export class WhileValidTxSender extends BaseTxSender {
35
35
  >();
36
36
  blockhashCommitment: Commitment;
37
37
 
38
+ useBlockHeightOffset = true;
39
+
40
+ private async checkAndSetUseBlockHeightOffset() {
41
+ this.connection.getVersion().then((version) => {
42
+ const solanaCoreVersion = version['solana-core'];
43
+
44
+ if (!solanaCoreVersion) return;
45
+
46
+ const majorVersion = solanaCoreVersion.split('.')[0];
47
+
48
+ if (!majorVersion) return;
49
+
50
+ const parsedMajorVersion = parseInt(majorVersion);
51
+
52
+ if (isNaN(parsedMajorVersion)) return;
53
+
54
+ if (parsedMajorVersion >= 2) {
55
+ this.useBlockHeightOffset = false;
56
+ } else {
57
+ this.useBlockHeightOffset = true;
58
+ }
59
+ });
60
+ }
61
+
38
62
  public constructor({
39
63
  connection,
40
64
  wallet,
@@ -73,6 +97,8 @@ export class WhileValidTxSender extends BaseTxSender {
73
97
  });
74
98
  this.retrySleep = retrySleep;
75
99
  this.blockhashCommitment = blockhashCommitment;
100
+
101
+ this.checkAndSetUseBlockHeightOffset();
76
102
  }
77
103
 
78
104
  async sleep(reference: ResolveReference): Promise<void> {
@@ -209,17 +235,25 @@ export class WhileValidTxSender extends BaseTxSender {
209
235
  let slot: number;
210
236
  try {
211
237
  const { blockhash, lastValidBlockHeight } = this.untilValid.get(txid);
238
+
212
239
  const result = await this.connection.confirmTransaction(
213
240
  {
214
241
  signature: txid,
215
- lastValidBlockHeight:
216
- lastValidBlockHeight + VALID_BLOCK_HEIGHT_OFFSET,
217
242
  blockhash,
243
+ lastValidBlockHeight: this.useBlockHeightOffset
244
+ ? lastValidBlockHeight + VALID_BLOCK_HEIGHT_OFFSET
245
+ : lastValidBlockHeight,
218
246
  },
219
- opts.commitment
247
+ opts?.commitment
220
248
  );
249
+
250
+ if (!result) {
251
+ throw new Error(`Couldn't get signature status for txid: ${txid}`);
252
+ }
253
+
221
254
  this.txSigCache?.set(txid, true);
222
- await this.checkConfirmationResultForError(txid, result);
255
+
256
+ await this.checkConfirmationResultForError(txid, result.value);
223
257
 
224
258
  slot = result.context.slot;
225
259
  // eslint-disable-next-line no-useless-catch
package/tests/ci/idl.ts CHANGED
@@ -1,7 +1,4 @@
1
- import {
2
- DriftClient,
3
- BulkAccountLoader,
4
- } from '../../src';
1
+ import { DriftClient, BulkAccountLoader } from '../../src';
5
2
  import { Connection, Keypair } from '@solana/web3.js';
6
3
  import { Wallet, Program } from '@coral-xyz/anchor';
7
4
  import dotenv from 'dotenv';
@@ -40,14 +37,19 @@ describe('Verify IDL', function () {
40
37
  });
41
38
 
42
39
  it('verify idl', async () => {
43
- const idl = await Program.fetchIdl(mainnetDriftClient.program.programId, mainnetDriftClient.provider);
40
+ const idl = await Program.fetchIdl(
41
+ mainnetDriftClient.program.programId,
42
+ mainnetDriftClient.provider
43
+ );
44
44
 
45
45
  // anchor idl init seems to strip the metadata
46
- idl["metadata"] = {"address":"dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"};
46
+ idl['metadata'] = {
47
+ address: 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH',
48
+ };
47
49
  const encodedMainnetIdl = JSON.stringify(idl);
48
50
 
49
51
  const encodedSdkIdl = JSON.stringify(driftIDL);
50
52
 
51
53
  assert(encodedSdkIdl === encodedMainnetIdl);
52
54
  });
53
- });
55
+ });
@@ -61,13 +61,14 @@ describe('Verify Constants', function () {
61
61
  },
62
62
  });
63
63
 
64
- let lutAccounts : string[];
64
+ let lutAccounts: string[];
65
65
 
66
66
  before(async () => {
67
67
  await devnetDriftClient.subscribe();
68
68
  await mainnetDriftClient.subscribe();
69
69
 
70
- const lookupTable = await mainnetDriftClient.fetchMarketLookupTableAccount();
70
+ const lookupTable =
71
+ await mainnetDriftClient.fetchMarketLookupTableAccount();
71
72
  lutAccounts = lookupTable.state.addresses.map((x) => x.toBase58());
72
73
  });
73
74
 
@@ -113,10 +114,20 @@ describe('Verify Constants', function () {
113
114
  );
114
115
 
115
116
  const lutHasMarket = lutAccounts.includes(market.pubkey.toBase58());
116
- assert(lutHasMarket, `Mainnet LUT is missing spot market ${market.marketIndex} pubkey ${market.pubkey.toBase58()}`);
117
+ assert(
118
+ lutHasMarket,
119
+ `Mainnet LUT is missing spot market ${
120
+ market.marketIndex
121
+ } pubkey ${market.pubkey.toBase58()}`
122
+ );
117
123
 
118
124
  const lutHasMarketOracle = lutAccounts.includes(market.oracle.toBase58());
119
- assert(lutHasMarketOracle, `Mainnet LUT is missing spot market ${market.marketIndex} oracle ${market.oracle.toBase58()}`);
125
+ assert(
126
+ lutHasMarketOracle,
127
+ `Mainnet LUT is missing spot market ${
128
+ market.marketIndex
129
+ } oracle ${market.oracle.toBase58()}`
130
+ );
120
131
  }
121
132
 
122
133
  const perpMarkets = mainnetDriftClient.getPerpMarketAccounts();
@@ -150,10 +161,22 @@ describe('Verify Constants', function () {
150
161
  );
151
162
 
152
163
  const lutHasMarket = lutAccounts.includes(market.pubkey.toBase58());
153
- assert(lutHasMarket, `Mainnet LUT is missing perp market ${market.marketIndex} pubkey ${market.pubkey.toBase58()}`);
164
+ assert(
165
+ lutHasMarket,
166
+ `Mainnet LUT is missing perp market ${
167
+ market.marketIndex
168
+ } pubkey ${market.pubkey.toBase58()}`
169
+ );
154
170
 
155
- const lutHasMarketOracle = lutAccounts.includes(market.amm.oracle.toBase58());
156
- assert(lutHasMarketOracle, `Mainnet LUT is missing perp market ${market.marketIndex} oracle ${market.amm.oracle.toBase58()}`);
171
+ const lutHasMarketOracle = lutAccounts.includes(
172
+ market.amm.oracle.toBase58()
173
+ );
174
+ assert(
175
+ lutHasMarketOracle,
176
+ `Mainnet LUT is missing perp market ${
177
+ market.marketIndex
178
+ } oracle ${market.amm.oracle.toBase58()}`
179
+ );
157
180
  }
158
181
  });
159
182