@drift-labs/sdk 2.98.0-beta.9 → 2.99.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 (69) hide show
  1. package/VERSION +1 -1
  2. package/lib/browser/accounts/pollingHighLeverageModeConfigAccountSubscriber.d.ts +29 -0
  3. package/lib/browser/accounts/pollingHighLeverageModeConfigAccountSubscriber.js +111 -0
  4. package/lib/browser/accounts/types.d.ts +14 -1
  5. package/lib/browser/accounts/webSocketHighLeverageModeConfigAccountSubscriber.d.ts +23 -0
  6. package/lib/browser/accounts/webSocketHighLeverageModeConfigAccountSubscriber.js +69 -0
  7. package/lib/browser/addresses/pda.d.ts +1 -0
  8. package/lib/browser/addresses/pda.js +8 -1
  9. package/lib/browser/constants/perpMarkets.js +11 -0
  10. package/lib/browser/constants/spotMarkets.js +2 -2
  11. package/lib/browser/driftClient.d.ts +14 -4
  12. package/lib/browser/driftClient.js +58 -16
  13. package/lib/browser/idl/drift.json +199 -8
  14. package/lib/browser/index.d.ts +4 -0
  15. package/lib/browser/index.js +4 -0
  16. package/lib/browser/jupiter/jupiterClient.d.ts +6 -0
  17. package/lib/browser/memcmp.d.ts +3 -0
  18. package/lib/browser/memcmp.js +28 -1
  19. package/lib/browser/slot/SlothashSubscriber.d.ts +26 -0
  20. package/lib/browser/slot/SlothashSubscriber.js +85 -0
  21. package/lib/browser/types.d.ts +4 -3
  22. package/lib/browser/user.js +3 -0
  23. package/lib/browser/userMap/referrerMap.d.ts +45 -0
  24. package/lib/browser/userMap/referrerMap.js +180 -0
  25. package/lib/browser/util/digest.d.ts +1 -0
  26. package/lib/browser/util/digest.js +5 -1
  27. package/lib/node/accounts/pollingHighLeverageModeConfigAccountSubscriber.d.ts +29 -0
  28. package/lib/node/accounts/pollingHighLeverageModeConfigAccountSubscriber.js +111 -0
  29. package/lib/node/accounts/types.d.ts +14 -1
  30. package/lib/node/accounts/webSocketHighLeverageModeConfigAccountSubscriber.d.ts +23 -0
  31. package/lib/node/accounts/webSocketHighLeverageModeConfigAccountSubscriber.js +69 -0
  32. package/lib/node/addresses/pda.d.ts +1 -0
  33. package/lib/node/addresses/pda.js +8 -1
  34. package/lib/node/constants/perpMarkets.js +11 -0
  35. package/lib/node/constants/spotMarkets.js +2 -2
  36. package/lib/node/driftClient.d.ts +14 -4
  37. package/lib/node/driftClient.js +58 -16
  38. package/lib/node/idl/drift.json +199 -8
  39. package/lib/node/index.d.ts +4 -0
  40. package/lib/node/index.js +4 -0
  41. package/lib/node/jupiter/jupiterClient.d.ts +6 -0
  42. package/lib/node/memcmp.d.ts +3 -0
  43. package/lib/node/memcmp.js +28 -1
  44. package/lib/node/slot/SlothashSubscriber.d.ts +26 -0
  45. package/lib/node/slot/SlothashSubscriber.js +85 -0
  46. package/lib/node/types.d.ts +4 -3
  47. package/lib/node/user.js +3 -0
  48. package/lib/node/userMap/referrerMap.d.ts +45 -0
  49. package/lib/node/userMap/referrerMap.js +180 -0
  50. package/lib/node/util/digest.d.ts +1 -0
  51. package/lib/node/util/digest.js +5 -1
  52. package/package.json +1 -1
  53. package/src/accounts/pollingHighLeverageModeConfigAccountSubscriber.ts +189 -0
  54. package/src/accounts/types.ts +25 -1
  55. package/src/accounts/webSocketHighLeverageModeConfigAccountSubscriber.ts +131 -0
  56. package/src/addresses/pda.ts +13 -0
  57. package/src/constants/perpMarkets.ts +12 -0
  58. package/src/constants/spotMarkets.ts +2 -2
  59. package/src/driftClient.ts +122 -33
  60. package/src/idl/drift.json +199 -8
  61. package/src/index.ts +4 -0
  62. package/src/jupiter/jupiterClient.ts +6 -0
  63. package/src/memcmp.ts +27 -0
  64. package/src/slot/SlothashSubscriber.ts +126 -0
  65. package/src/types.ts +4 -3
  66. package/src/user.ts +4 -0
  67. package/src/userMap/referrerMap.ts +283 -0
  68. package/src/util/digest.ts +4 -0
  69. package/tests/ci/verifyConstants.ts +16 -2
@@ -0,0 +1,131 @@
1
+ import {
2
+ DataAndSlot,
3
+ AccountSubscriber,
4
+ NotSubscribedError,
5
+ HighLeverageModeConfigAccountEvents,
6
+ HighLeverageModeConfigAccountSubscriber,
7
+ } from './types';
8
+ import { Program } from '@coral-xyz/anchor';
9
+ import StrictEventEmitter from 'strict-event-emitter-types';
10
+ import { EventEmitter } from 'events';
11
+ import { Commitment, PublicKey } from '@solana/web3.js';
12
+ import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
13
+ import { HighLeverageModeConfig } from '../types';
14
+
15
+ export class WebSocketHighLeverageModeConfigAccountSubscriber
16
+ implements HighLeverageModeConfigAccountSubscriber
17
+ {
18
+ isSubscribed: boolean;
19
+ resubTimeoutMs?: number;
20
+ commitment?: Commitment;
21
+ program: Program;
22
+ eventEmitter: StrictEventEmitter<
23
+ EventEmitter,
24
+ HighLeverageModeConfigAccountEvents
25
+ >;
26
+ highLeverageModeConfigAccountPublicKey: PublicKey;
27
+
28
+ highLeverageModeConfigDataAccountSubscriber: AccountSubscriber<HighLeverageModeConfig>;
29
+
30
+ public constructor(
31
+ program: Program,
32
+ highLeverageModeConfigAccountPublicKey: PublicKey,
33
+ resubTimeoutMs?: number,
34
+ commitment?: Commitment
35
+ ) {
36
+ this.isSubscribed = false;
37
+ this.program = program;
38
+ this.highLeverageModeConfigAccountPublicKey =
39
+ highLeverageModeConfigAccountPublicKey;
40
+ this.eventEmitter = new EventEmitter();
41
+ this.resubTimeoutMs = resubTimeoutMs;
42
+ this.commitment = commitment;
43
+ }
44
+
45
+ async subscribe(
46
+ highLeverageModeConfigAccount?: HighLeverageModeConfig
47
+ ): Promise<boolean> {
48
+ if (this.isSubscribed) {
49
+ return true;
50
+ }
51
+
52
+ this.highLeverageModeConfigDataAccountSubscriber =
53
+ new WebSocketAccountSubscriber(
54
+ 'highLeverageModeConfig',
55
+ this.program,
56
+ this.highLeverageModeConfigAccountPublicKey,
57
+ undefined,
58
+ {
59
+ resubTimeoutMs: this.resubTimeoutMs,
60
+ },
61
+ this.commitment
62
+ );
63
+
64
+ if (highLeverageModeConfigAccount) {
65
+ this.highLeverageModeConfigDataAccountSubscriber.setData(
66
+ highLeverageModeConfigAccount
67
+ );
68
+ }
69
+
70
+ await this.highLeverageModeConfigDataAccountSubscriber.subscribe(
71
+ (data: HighLeverageModeConfig) => {
72
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', data);
73
+ this.eventEmitter.emit('update');
74
+ }
75
+ );
76
+
77
+ this.eventEmitter.emit('update');
78
+ this.isSubscribed = true;
79
+ return true;
80
+ }
81
+
82
+ async fetch(): Promise<void> {
83
+ await Promise.all([
84
+ this.highLeverageModeConfigDataAccountSubscriber.fetch(),
85
+ ]);
86
+ }
87
+
88
+ async unsubscribe(): Promise<void> {
89
+ if (!this.isSubscribed) {
90
+ return;
91
+ }
92
+
93
+ await Promise.all([
94
+ this.highLeverageModeConfigDataAccountSubscriber.unsubscribe(),
95
+ ]);
96
+
97
+ this.isSubscribed = false;
98
+ }
99
+
100
+ assertIsSubscribed(): void {
101
+ if (!this.isSubscribed) {
102
+ throw new NotSubscribedError(
103
+ 'You must call `subscribe` before using this function'
104
+ );
105
+ }
106
+ }
107
+
108
+ public getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig> {
109
+ this.assertIsSubscribed();
110
+ return this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot;
111
+ }
112
+
113
+ public updateData(
114
+ highLeverageModeConfig: HighLeverageModeConfig,
115
+ slot: number
116
+ ): void {
117
+ const currentDataSlot =
118
+ this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot?.slot || 0;
119
+ if (currentDataSlot <= slot) {
120
+ this.highLeverageModeConfigDataAccountSubscriber.setData(
121
+ highLeverageModeConfig,
122
+ slot
123
+ );
124
+ this.eventEmitter.emit(
125
+ 'highLeverageModeConfigAccountUpdate',
126
+ highLeverageModeConfig
127
+ );
128
+ this.eventEmitter.emit('update');
129
+ }
130
+ }
131
+ }
@@ -85,6 +85,19 @@ export function getRFQUserAccountPublicKey(
85
85
  )[0];
86
86
  }
87
87
 
88
+ export function getSwiftUserAccountPublicKey(
89
+ programId: PublicKey,
90
+ userAccountPublicKey: PublicKey
91
+ ): PublicKey {
92
+ return PublicKey.findProgramAddressSync(
93
+ [
94
+ Buffer.from(anchor.utils.bytes.utf8.encode('SWIFT')),
95
+ userAccountPublicKey.toBuffer(),
96
+ ],
97
+ programId
98
+ )[0];
99
+ }
100
+
88
101
  export async function getPerpMarketPublicKey(
89
102
  programId: PublicKey,
90
103
  marketIndex: number
@@ -950,6 +950,18 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
950
950
  pythFeedId:
951
951
  '0x514aed52ca5294177f20187ae883cec4a018619772ddce41efcc36a6448f5d5d',
952
952
  },
953
+ {
954
+ fullName: 'MICHI',
955
+ category: ['Meme'],
956
+ symbol: 'MICHI-PERP',
957
+ baseAssetSymbol: 'MICHI',
958
+ marketIndex: 52,
959
+ oracle: new PublicKey('GHzvsMDMSiuyZoWhEAuM27MKFdN2Y4fA4wSDuSd6dLMA'),
960
+ launchTs: 1730402722000,
961
+ oracleSource: OracleSource.PYTH_PULL,
962
+ pythFeedId:
963
+ '0x63a45218d6b13ffd28ca04748615511bf70eff80a3411c97d96b8ed74a6decab',
964
+ },
953
965
  ];
954
966
 
955
967
  export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
@@ -417,13 +417,13 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
417
417
  {
418
418
  symbol: 'BNSOL',
419
419
  marketIndex: 25,
420
- oracle: new PublicKey('BAtFj4kQttZRVep3UZS2aZRDixkGYgWsbqTBVDbnSsPF'),
420
+ oracle: new PublicKey('8DmXTfhhtb9kTcpTVfb6Ygx8WhZ8wexGqcpxfn23zooe'),
421
421
  oracleSource: OracleSource.PYTH_PULL,
422
422
  mint: new PublicKey('BNso1VUJnh4zcfpZa6986Ea66P6TCp59hvtNJ8b1X85'),
423
423
  precision: LAMPORTS_PRECISION,
424
424
  precisionExp: LAMPORTS_EXP,
425
425
  pythFeedId:
426
- '0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d',
426
+ '0x55f8289be7450f1ae564dd9798e49e7d797d89adbc54fe4f8c906b1fcb94b0c3',
427
427
  },
428
428
  {
429
429
  symbol: 'MOTHER',
@@ -11,11 +11,13 @@ import bs58 from 'bs58';
11
11
  import {
12
12
  ASSOCIATED_TOKEN_PROGRAM_ID,
13
13
  createAssociatedTokenAccountInstruction,
14
+ createAssociatedTokenAccountIdempotentInstruction,
14
15
  createCloseAccountInstruction,
15
16
  createInitializeAccountInstruction,
16
17
  getAssociatedTokenAddress,
17
18
  TOKEN_2022_PROGRAM_ID,
18
19
  TOKEN_PROGRAM_ID,
20
+ getAssociatedTokenAddressSync,
19
21
  } from '@solana/spl-token';
20
22
  import {
21
23
  DriftClientMetricsEvents,
@@ -96,6 +98,7 @@ import {
96
98
  getSerumFulfillmentConfigPublicKey,
97
99
  getSerumSignerPublicKey,
98
100
  getSpotMarketPublicKey,
101
+ getSwiftUserAccountPublicKey,
99
102
  getUserAccountPublicKey,
100
103
  getUserAccountPublicKeySync,
101
104
  getUserStatsAccountPublicKey,
@@ -170,6 +173,7 @@ import { asV0Tx, PullFeed } from '@switchboard-xyz/on-demand';
170
173
  import { gprcDriftClientAccountSubscriber } from './accounts/grpcDriftClientAccountSubscriber';
171
174
  import nacl from 'tweetnacl';
172
175
  import { digest } from './util/digest';
176
+ import { Slothash } from './slot/SlothashSubscriber';
173
177
 
174
178
  type RemainingAccountParams = {
175
179
  userAccounts: UserAccount[];
@@ -361,7 +365,7 @@ export class DriftClient {
361
365
  }
362
366
 
363
367
  const delistedMarketSetting =
364
- config.delistedMarketSetting || DelistedMarketSetting.Subscribe;
368
+ config.delistedMarketSetting || DelistedMarketSetting.Unsubscribe;
365
369
  const noMarketsAndOraclesSpecified =
366
370
  config.perpMarketIndexes === undefined &&
367
371
  config.spotMarketIndexes === undefined &&
@@ -1022,6 +1026,45 @@ export class DriftClient {
1022
1026
  return [rfqUserAccountPublicKey, initializeUserAccountIx];
1023
1027
  }
1024
1028
 
1029
+ public async initializeSwiftUserOrdersAccount(
1030
+ userAccountPublicKey: PublicKey,
1031
+ txParams?: TxParams
1032
+ ): Promise<[TransactionSignature, PublicKey]> {
1033
+ const initializeIxs = [];
1034
+
1035
+ const [swiftUserAccountPublicKey, initializeUserAccountIx] =
1036
+ await this.getInitializeSwiftUserOrdersAccountInstruction(
1037
+ userAccountPublicKey
1038
+ );
1039
+ initializeIxs.push(initializeUserAccountIx);
1040
+ const tx = await this.buildTransaction(initializeIxs, txParams);
1041
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
1042
+
1043
+ return [txSig, swiftUserAccountPublicKey];
1044
+ }
1045
+
1046
+ async getInitializeSwiftUserOrdersAccountInstruction(
1047
+ userAccountPublicKey: PublicKey
1048
+ ): Promise<[PublicKey, TransactionInstruction]> {
1049
+ const swiftUserAccountPublicKey = getSwiftUserAccountPublicKey(
1050
+ this.program.programId,
1051
+ userAccountPublicKey
1052
+ );
1053
+ const initializeUserAccountIx =
1054
+ await this.program.instruction.initializeSwiftUserOrders({
1055
+ accounts: {
1056
+ swiftUserOrders: swiftUserAccountPublicKey,
1057
+ authority: this.wallet.publicKey,
1058
+ user: userAccountPublicKey,
1059
+ payer: this.wallet.publicKey,
1060
+ rent: anchor.web3.SYSVAR_RENT_PUBKEY,
1061
+ systemProgram: anchor.web3.SystemProgram.programId,
1062
+ },
1063
+ });
1064
+
1065
+ return [swiftUserAccountPublicKey, initializeUserAccountIx];
1066
+ }
1067
+
1025
1068
  async getInitializeUserInstructions(
1026
1069
  subAccountId = 0,
1027
1070
  name?: string,
@@ -5523,14 +5566,7 @@ export class DriftClient {
5523
5566
  }
5524
5567
 
5525
5568
  public encodeSwiftServerMessage(message: SwiftServerMessage): Buffer {
5526
- const messageWithBuffer = {
5527
- slot: message.slot,
5528
- swiftOrderSignature: message.swiftOrderSignature,
5529
- };
5530
- return this.program.coder.types.encode(
5531
- 'SwiftServerMessage',
5532
- messageWithBuffer
5533
- );
5569
+ return this.program.coder.types.encode('SwiftServerMessage', message);
5534
5570
  }
5535
5571
 
5536
5572
  public decodeSwiftServerMessage(encodedMessage: Buffer): SwiftServerMessage {
@@ -5539,6 +5575,7 @@ export class DriftClient {
5539
5575
  encodedMessage
5540
5576
  );
5541
5577
  return {
5578
+ uuid: decodedSwiftMessage.uuid,
5542
5579
  slot: decodedSwiftMessage.slot,
5543
5580
  swiftOrderSignature: decodedSwiftMessage.swiftSignature,
5544
5581
  };
@@ -5655,6 +5692,10 @@ export class DriftClient {
5655
5692
  state: await this.getStatePublicKey(),
5656
5693
  user: takerInfo.taker,
5657
5694
  userStats: takerInfo.takerStats,
5695
+ swiftUserOrders: getSwiftUserAccountPublicKey(
5696
+ this.program.programId,
5697
+ takerInfo.taker
5698
+ ),
5658
5699
  authority: this.wallet.publicKey,
5659
5700
  ixSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
5660
5701
  },
@@ -5674,7 +5715,7 @@ export class DriftClient {
5674
5715
  swiftSignature: Buffer,
5675
5716
  encodedSwiftOrderParamsMessage: Buffer,
5676
5717
  swiftOrderParamsSignature: Buffer,
5677
- takerExpectedOrderId: number,
5718
+ swiftOrderUuid: Uint8Array,
5678
5719
  takerInfo: {
5679
5720
  taker: PublicKey;
5680
5721
  takerStats: PublicKey;
@@ -5690,7 +5731,7 @@ export class DriftClient {
5690
5731
  swiftSignature,
5691
5732
  encodedSwiftOrderParamsMessage,
5692
5733
  swiftOrderParamsSignature,
5693
- takerExpectedOrderId,
5734
+ swiftOrderUuid,
5694
5735
  takerInfo,
5695
5736
  orderParams,
5696
5737
  referrerInfo,
@@ -5711,7 +5752,7 @@ export class DriftClient {
5711
5752
  swiftSignature: Buffer,
5712
5753
  encodedSwiftOrderParamsMessage: Buffer,
5713
5754
  swiftOrderParamsSignature: Buffer,
5714
- takerExpectedOrderId: number,
5755
+ swiftOrderUuid: Uint8Array,
5715
5756
  takerInfo: {
5716
5757
  taker: PublicKey;
5717
5758
  takerStats: PublicKey;
@@ -5760,21 +5801,26 @@ export class DriftClient {
5760
5801
  });
5761
5802
  }
5762
5803
 
5763
- const placeAndMakeIx = await this.program.instruction.placeAndMakePerpOrder(
5764
- orderParams,
5765
- takerExpectedOrderId,
5766
- {
5767
- accounts: {
5768
- state: await this.getStatePublicKey(),
5769
- user,
5770
- userStats: userStatsPublicKey,
5771
- taker: takerInfo.taker,
5772
- takerStats: takerInfo.takerStats,
5773
- authority: this.wallet.publicKey,
5774
- },
5775
- remainingAccounts,
5776
- }
5777
- );
5804
+ const placeAndMakeIx =
5805
+ await this.program.instruction.placeAndMakeSwiftPerpOrder(
5806
+ orderParams,
5807
+ swiftOrderUuid,
5808
+ {
5809
+ accounts: {
5810
+ state: await this.getStatePublicKey(),
5811
+ user,
5812
+ userStats: userStatsPublicKey,
5813
+ taker: takerInfo.taker,
5814
+ takerStats: takerInfo.takerStats,
5815
+ authority: this.wallet.publicKey,
5816
+ takerSwiftUserOrders: getSwiftUserAccountPublicKey(
5817
+ this.program.programId,
5818
+ takerInfo.taker
5819
+ ),
5820
+ },
5821
+ remainingAccounts,
5822
+ }
5823
+ );
5778
5824
 
5779
5825
  return [
5780
5826
  swiftServerSignatureIx,
@@ -7406,6 +7452,25 @@ export class DriftClient {
7406
7452
  const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
7407
7453
  const createWSOLTokenAccount =
7408
7454
  isSolMarket && collateralAccountPublicKey.equals(this.wallet.publicKey);
7455
+ const tokenProgramId = this.getTokenProgramForSpotMarket(spotMarketAccount);
7456
+
7457
+ // create associated token account because it may not exist
7458
+ const associatedTokenAccountPublicKey = getAssociatedTokenAddressSync(
7459
+ spotMarketAccount.mint,
7460
+ this.wallet.publicKey,
7461
+ true,
7462
+ tokenProgramId
7463
+ );
7464
+
7465
+ addIfStakeIxs.push(
7466
+ await createAssociatedTokenAccountIdempotentInstruction(
7467
+ this.wallet.publicKey,
7468
+ associatedTokenAccountPublicKey,
7469
+ this.wallet.publicKey,
7470
+ spotMarketAccount.mint,
7471
+ tokenProgramId
7472
+ )
7473
+ );
7409
7474
 
7410
7475
  let tokenAccount;
7411
7476
 
@@ -7556,6 +7621,7 @@ export class DriftClient {
7556
7621
  const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
7557
7622
  const createWSOLTokenAccount =
7558
7623
  isSolMarket && collateralAccountPublicKey.equals(this.wallet.publicKey);
7624
+ const tokenProgramId = this.getTokenProgramForSpotMarket(spotMarketAccount);
7559
7625
 
7560
7626
  let tokenAccount;
7561
7627
 
@@ -7577,7 +7643,8 @@ export class DriftClient {
7577
7643
  tokenAccount,
7578
7644
  this.wallet.publicKey,
7579
7645
  this.wallet.publicKey,
7580
- spotMarketAccount.mint
7646
+ spotMarketAccount.mint,
7647
+ tokenProgramId
7581
7648
  );
7582
7649
  removeIfStakeIxs.push(createTokenAccountIx);
7583
7650
  }
@@ -7816,6 +7883,13 @@ export class DriftClient {
7816
7883
  return ix;
7817
7884
  }
7818
7885
 
7886
+ /**
7887
+ * This ix will donate your funds to drift revenue pool. It does not deposit into your user account
7888
+ * @param marketIndex
7889
+ * @param amount
7890
+ * @param userTokenAccountPublicKey
7891
+ * @returns
7892
+ */
7819
7893
  public async depositIntoSpotMarketRevenuePool(
7820
7894
  marketIndex: number,
7821
7895
  amount: BN,
@@ -7889,7 +7963,15 @@ export class DriftClient {
7889
7963
  } else {
7890
7964
  marketAccount = this.getSpotMarketAccount(marketIndex);
7891
7965
  }
7892
- takerFee += (takerFee * marketAccount.feeAdjustment) / 100;
7966
+
7967
+ let takeFeeAdjustment;
7968
+ if (user && user.isHighLeverageMode()) {
7969
+ takeFeeAdjustment = 100;
7970
+ } else {
7971
+ takeFeeAdjustment = marketAccount.feeAdjustment;
7972
+ }
7973
+
7974
+ takerFee += (takerFee * takeFeeAdjustment) / 100;
7893
7975
  makerFee += (makerFee * marketAccount.feeAdjustment) / 100;
7894
7976
  }
7895
7977
 
@@ -8167,6 +8249,7 @@ export class DriftClient {
8167
8249
 
8168
8250
  public async getPostSwitchboardOnDemandUpdateAtomicIx(
8169
8251
  feed: PublicKey,
8252
+ recentSlothash?: Slothash,
8170
8253
  numSignatures = 3
8171
8254
  ): Promise<TransactionInstruction | undefined> {
8172
8255
  const program = await this.getSwitchboardOnDemandProgram();
@@ -8178,10 +8261,14 @@ export class DriftClient {
8178
8261
  const feedConfig = await feedAccount.loadConfigs();
8179
8262
  this.sbProgramFeedConfigs.set(feed.toString(), feedConfig);
8180
8263
  }
8181
-
8182
- const [pullIx, _responses, success] = await feedAccount.fetchUpdateIx({
8183
- numSignatures,
8184
- });
8264
+ const [pullIx, _responses, success] = await feedAccount.fetchUpdateIx(
8265
+ {
8266
+ numSignatures,
8267
+ },
8268
+ recentSlothash
8269
+ ? [[new BN(recentSlothash.slot), recentSlothash.hash]]
8270
+ : undefined
8271
+ );
8185
8272
  if (!success) {
8186
8273
  return undefined;
8187
8274
  }
@@ -8190,10 +8277,12 @@ export class DriftClient {
8190
8277
 
8191
8278
  public async postSwitchboardOnDemandUpdate(
8192
8279
  feed: PublicKey,
8280
+ recentSlothash?: Slothash,
8193
8281
  numSignatures = 3
8194
8282
  ): Promise<TransactionSignature> {
8195
8283
  const pullIx = await this.getPostSwitchboardOnDemandUpdateAtomicIx(
8196
8284
  feed,
8285
+ recentSlothash,
8197
8286
  numSignatures
8198
8287
  );
8199
8288
  if (!pullIx) {