@drift-labs/sdk 2.96.0-beta.8 → 2.97.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 (76) hide show
  1. package/README.md +3 -0
  2. package/VERSION +1 -1
  3. package/bun.lockb +0 -0
  4. package/lib/accounts/pollingDriftClientAccountSubscriber.d.ts +5 -3
  5. package/lib/accounts/pollingDriftClientAccountSubscriber.js +24 -1
  6. package/lib/accounts/types.d.ts +5 -0
  7. package/lib/accounts/types.js +7 -1
  8. package/lib/accounts/utils.d.ts +7 -0
  9. package/lib/accounts/utils.js +33 -1
  10. package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +5 -4
  11. package/lib/accounts/webSocketDriftClientAccountSubscriber.js +24 -1
  12. package/lib/config.d.ts +6 -1
  13. package/lib/config.js +10 -1
  14. package/lib/constants/perpMarkets.js +33 -1
  15. package/lib/constants/spotMarkets.js +10 -0
  16. package/lib/constants/txConstants.d.ts +1 -0
  17. package/lib/constants/txConstants.js +4 -0
  18. package/lib/driftClient.d.ts +45 -9
  19. package/lib/driftClient.js +191 -49
  20. package/lib/driftClientConfig.d.ts +3 -0
  21. package/lib/events/types.js +1 -5
  22. package/lib/idl/drift.json +170 -2
  23. package/lib/index.d.ts +1 -0
  24. package/lib/index.js +1 -0
  25. package/lib/math/margin.d.ts +16 -1
  26. package/lib/math/margin.js +67 -1
  27. package/lib/orderParams.js +8 -8
  28. package/lib/orderSubscriber/OrderSubscriber.js +1 -6
  29. package/lib/tokenFaucet.js +2 -1
  30. package/lib/tx/baseTxSender.d.ts +0 -1
  31. package/lib/tx/baseTxSender.js +8 -26
  32. package/lib/tx/fastSingleTxSender.js +2 -2
  33. package/lib/tx/forwardOnlyTxSender.js +2 -2
  34. package/lib/tx/reportTransactionError.d.ts +20 -0
  35. package/lib/tx/reportTransactionError.js +103 -0
  36. package/lib/tx/retryTxSender.js +2 -2
  37. package/lib/tx/txHandler.js +10 -7
  38. package/lib/tx/whileValidTxSender.d.ts +4 -5
  39. package/lib/tx/whileValidTxSender.js +16 -17
  40. package/lib/types.d.ts +22 -1
  41. package/lib/types.js +6 -1
  42. package/lib/user.d.ts +4 -1
  43. package/lib/user.js +9 -2
  44. package/lib/util/TransactionConfirmationManager.d.ts +16 -0
  45. package/lib/util/TransactionConfirmationManager.js +174 -0
  46. package/package.json +4 -3
  47. package/src/accounts/pollingDriftClientAccountSubscriber.ts +41 -5
  48. package/src/accounts/types.ts +6 -0
  49. package/src/accounts/utils.ts +42 -0
  50. package/src/accounts/webSocketDriftClientAccountSubscriber.ts +40 -5
  51. package/src/config.ts +17 -1
  52. package/src/constants/perpMarkets.ts +35 -1
  53. package/src/constants/spotMarkets.ts +11 -0
  54. package/src/constants/txConstants.ts +1 -0
  55. package/src/driftClient.ts +426 -64
  56. package/src/driftClientConfig.ts +3 -0
  57. package/src/events/types.ts +1 -5
  58. package/src/idl/drift.json +170 -2
  59. package/src/index.ts +1 -0
  60. package/src/math/margin.ts +137 -1
  61. package/src/orderParams.ts +20 -12
  62. package/src/orderSubscriber/OrderSubscriber.ts +2 -5
  63. package/src/tokenFaucet.ts +2 -2
  64. package/src/tx/baseTxSender.ts +10 -32
  65. package/src/tx/fastSingleTxSender.ts +2 -2
  66. package/src/tx/forwardOnlyTxSender.ts +2 -2
  67. package/src/tx/reportTransactionError.ts +159 -0
  68. package/src/tx/retryTxSender.ts +2 -2
  69. package/src/tx/txHandler.ts +8 -2
  70. package/src/tx/whileValidTxSender.ts +18 -27
  71. package/src/types.ts +31 -1
  72. package/src/user.ts +35 -2
  73. package/src/util/TransactionConfirmationManager.ts +292 -0
  74. package/tests/ci/idl.ts +12 -3
  75. package/tests/ci/verifyConstants.ts +13 -0
  76. package/tests/tx/TransactionConfirmationManager.test.ts +305 -0
@@ -1,3 +1,4 @@
1
+ import * as anchor from '@coral-xyz/anchor';
1
2
  import {
2
3
  AnchorProvider,
3
4
  BN,
@@ -13,61 +14,66 @@ import {
13
14
  createCloseAccountInstruction,
14
15
  createInitializeAccountInstruction,
15
16
  getAssociatedTokenAddress,
16
- TOKEN_PROGRAM_ID,
17
17
  TOKEN_2022_PROGRAM_ID,
18
+ TOKEN_PROGRAM_ID,
18
19
  } from '@solana/spl-token';
19
20
  import {
20
- StateAccount,
21
+ DriftClientMetricsEvents,
22
+ isVariant,
21
23
  IWallet,
22
- PositionDirection,
23
- UserAccount,
24
- PerpMarketAccount,
25
- OrderParams,
26
- Order,
27
- SpotMarketAccount,
28
- SpotPosition,
29
24
  MakerInfo,
30
- TakerInfo,
31
- OptionalOrderParams,
32
- OrderType,
33
- ReferrerInfo,
25
+ MappedRecord,
34
26
  MarketType,
35
- TxParams,
36
- SerumV3FulfillmentConfigAccount,
37
- isVariant,
38
- ReferrerNameAccount,
27
+ ModifyOrderParams,
28
+ ModifyOrderPolicy,
29
+ OpenbookV2FulfillmentConfigAccount,
30
+ OptionalOrderParams,
31
+ Order,
32
+ OrderParams,
39
33
  OrderTriggerCondition,
40
- SpotBalanceType,
34
+ OrderType,
35
+ PerpMarketAccount,
41
36
  PerpMarketExtendedInfo,
42
- UserStatsAccount,
43
- ModifyOrderParams,
44
37
  PhoenixV1FulfillmentConfigAccount,
45
- ModifyOrderPolicy,
46
- SwapReduceOnly,
38
+ PlaceAndTakeOrderSuccessCondition,
39
+ PositionDirection,
40
+ ReferrerInfo,
41
+ ReferrerNameAccount,
42
+ SerumV3FulfillmentConfigAccount,
47
43
  SettlePnlMode,
48
44
  SignedTxData,
49
- MappedRecord,
50
- OpenbookV2FulfillmentConfigAccount,
45
+ SpotBalanceType,
46
+ SpotMarketAccount,
47
+ SpotPosition,
48
+ StateAccount,
49
+ SwapReduceOnly,
50
+ SwiftOrderParamsMessage,
51
+ SwiftServerMessage,
52
+ TakerInfo,
53
+ TxParams,
54
+ UserAccount,
55
+ UserStatsAccount,
51
56
  } from './types';
52
- import * as anchor from '@coral-xyz/anchor';
53
57
  import driftIDL from './idl/drift.json';
54
58
 
55
59
  import {
56
- Connection,
57
- PublicKey,
58
- TransactionSignature,
59
- ConfirmOptions,
60
- Transaction,
61
- TransactionInstruction,
62
60
  AccountMeta,
61
+ AddressLookupTableAccount,
62
+ BlockhashWithExpiryBlockHeight,
63
+ ConfirmOptions,
64
+ Connection,
65
+ Ed25519Program,
63
66
  Keypair,
64
67
  LAMPORTS_PER_SOL,
68
+ PublicKey,
65
69
  Signer,
66
70
  SystemProgram,
67
- AddressLookupTableAccount,
71
+ SYSVAR_INSTRUCTIONS_PUBKEY,
72
+ Transaction,
73
+ TransactionInstruction,
74
+ TransactionSignature,
68
75
  TransactionVersion,
69
76
  VersionedTransaction,
70
- BlockhashWithExpiryBlockHeight,
71
77
  } from '@solana/web3.js';
72
78
 
73
79
  import { TokenFaucet } from './tokenFaucet';
@@ -90,19 +96,19 @@ import {
90
96
  getUserStatsAccountPublicKey,
91
97
  } from './addresses/pda';
92
98
  import {
93
- DriftClientAccountSubscriber,
94
- DriftClientAccountEvents,
95
99
  DataAndSlot,
100
+ DelistedMarketSetting,
101
+ DriftClientAccountEvents,
102
+ DriftClientAccountSubscriber,
96
103
  } from './accounts/types';
97
- import { DriftClientMetricsEvents } from './types';
98
104
  import { TxSender, TxSigAndSlot } from './tx/types';
99
105
  import {
100
106
  BASE_PRECISION,
107
+ GOV_SPOT_MARKET_INDEX,
101
108
  PRICE_PRECISION,
109
+ QUOTE_PRECISION,
102
110
  QUOTE_SPOT_MARKET_INDEX,
103
111
  ZERO,
104
- QUOTE_PRECISION,
105
- GOV_SPOT_MARKET_INDEX,
106
112
  } from './constants/numericConstants';
107
113
  import { findDirectionToClose, positionIsAvailable } from './math/position';
108
114
  import { getSignedTokenAmount, getTokenAmount } from './math/spotBalance';
@@ -114,7 +120,13 @@ import { WebSocketDriftClientAccountSubscriber } from './accounts/webSocketDrift
114
120
  import { RetryTxSender } from './tx/retryTxSender';
115
121
  import { User } from './user';
116
122
  import { UserSubscriptionConfig } from './userConfig';
117
- import { configs, DRIFT_PROGRAM_ID } from './config';
123
+ import {
124
+ configs,
125
+ DRIFT_ORACLE_RECEIVER_ID,
126
+ DEFAULT_CONFIRMATION_OPTS,
127
+ DRIFT_PROGRAM_ID,
128
+ SWIFT_ID,
129
+ } from './config';
118
130
  import { WRAPPED_SOL_MINT } from './constants/spotMarkets';
119
131
  import { UserStats } from './userStats';
120
132
  import { isSpotPositionAvailable } from './math/spotPosition';
@@ -136,22 +148,21 @@ import { TransactionParamProcessor } from './tx/txParamProcessor';
136
148
  import { isOracleValid, trimVaaSignatures } from './math/oracles';
137
149
  import { TxHandler } from './tx/txHandler';
138
150
  import {
139
- wormholeCoreBridgeIdl,
140
151
  DEFAULT_RECEIVER_PROGRAM_ID,
152
+ wormholeCoreBridgeIdl,
141
153
  } from '@pythnetwork/pyth-solana-receiver';
142
154
  import { parseAccumulatorUpdateData } from '@pythnetwork/price-service-sdk';
143
155
  import {
144
156
  DEFAULT_WORMHOLE_PROGRAM_ID,
145
157
  getGuardianSetPda,
146
158
  } from '@pythnetwork/pyth-solana-receiver/lib/address';
147
- import { DRIFT_ORACLE_RECEIVER_ID } from './config';
148
159
  import { WormholeCoreBridgeSolana } from '@pythnetwork/pyth-solana-receiver/lib/idl/wormhole_core_bridge_solana';
149
160
  import { PythSolanaReceiver } from '@pythnetwork/pyth-solana-receiver/lib/idl/pyth_solana_receiver';
150
161
  import { getFeedIdUint8Array, trimFeedId } from './util/pythPullOracleUtils';
151
162
  import { isVersionedTransaction } from './tx/utils';
152
163
  import pythSolanaReceiverIdl from './idl/pyth_solana_receiver.json';
153
164
  import { asV0Tx, PullFeed } from '@switchboard-xyz/on-demand';
154
- import switchboardOnDemandIdl from './idl/switchboard_on_demand_30.json';
165
+ import * as ed from '@noble/ed25519';
155
166
 
156
167
  type RemainingAccountParams = {
157
168
  userAccounts: UserAccount[];
@@ -170,6 +181,7 @@ export class DriftClient {
170
181
  connection: Connection;
171
182
  wallet: IWallet;
172
183
  public program: Program;
184
+ public swiftID: PublicKey;
173
185
  provider: AnchorProvider;
174
186
  opts?: ConfirmOptions;
175
187
  users = new Map<string, User>();
@@ -203,6 +215,7 @@ export class DriftClient {
203
215
 
204
216
  receiverProgram?: Program<PythSolanaReceiver>;
205
217
  wormholeProgram?: Program<WormholeCoreBridgeSolana>;
218
+ sbOnDemandProgramdId: PublicKey;
206
219
  sbOnDemandProgram?: Program30<Idl30>;
207
220
  sbProgramFeedConfigs?: Map<string, any>;
208
221
 
@@ -218,7 +231,7 @@ export class DriftClient {
218
231
  this.connection = config.connection;
219
232
  this.wallet = config.wallet;
220
233
  this.opts = config.opts || {
221
- ...AnchorProvider.defaultOptions(),
234
+ ...DEFAULT_CONFIRMATION_OPTS,
222
235
  commitment: config?.connection?.commitment,
223
236
  preflightCommitment: config?.connection?.commitment, // At the moment this ensures that our transaction simulations (which use Connection object) will use the same commitment level as our Transaction blockhashes (which use these opts)
224
237
  };
@@ -233,6 +246,7 @@ export class DriftClient {
233
246
  config.programID ?? new PublicKey(DRIFT_PROGRAM_ID),
234
247
  this.provider
235
248
  );
249
+ this.swiftID = config.swiftID ?? new PublicKey(SWIFT_ID);
236
250
 
237
251
  this.authority = config.authority ?? this.wallet.publicKey;
238
252
  this.activeSubAccountId = config.activeSubAccountId ?? 0;
@@ -247,6 +261,7 @@ export class DriftClient {
247
261
  config?.txHandler ??
248
262
  new TxHandler({
249
263
  connection: this.connection,
264
+ // @ts-ignore
250
265
  wallet: this.provider.wallet,
251
266
  confirmationOptions: this.opts,
252
267
  opts: {
@@ -325,6 +340,8 @@ export class DriftClient {
325
340
  );
326
341
  }
327
342
 
343
+ const delistedMarketSetting =
344
+ config.delistedMarketSetting || DelistedMarketSetting.Subscribe;
328
345
  const noMarketsAndOraclesSpecified =
329
346
  config.perpMarketIndexes === undefined &&
330
347
  config.spotMarketIndexes === undefined &&
@@ -336,7 +353,8 @@ export class DriftClient {
336
353
  config.perpMarketIndexes ?? [],
337
354
  config.spotMarketIndexes ?? [],
338
355
  config.oracleInfos ?? [],
339
- noMarketsAndOraclesSpecified
356
+ noMarketsAndOraclesSpecified,
357
+ delistedMarketSetting
340
358
  );
341
359
  } else {
342
360
  this.accountSubscriber = new WebSocketDriftClientAccountSubscriber(
@@ -345,6 +363,7 @@ export class DriftClient {
345
363
  config.spotMarketIndexes ?? [],
346
364
  config.oracleInfos ?? [],
347
365
  noMarketsAndOraclesSpecified,
366
+ delistedMarketSetting,
348
367
  {
349
368
  resubTimeoutMs: config.accountSubscription?.resubTimeoutMs,
350
369
  logResubMessages: config.accountSubscription?.logResubMessages,
@@ -368,6 +387,9 @@ export class DriftClient {
368
387
  opts: this.opts,
369
388
  txHandler: this.txHandler,
370
389
  });
390
+
391
+ this.sbOnDemandProgramdId =
392
+ configs[config.env ?? 'mainnet-beta'].SB_ON_DEMAND_PID;
371
393
  }
372
394
 
373
395
  public getUserMapKey(subAccountId: number, authority: PublicKey): string {
@@ -1906,14 +1928,13 @@ export class DriftClient {
1906
1928
  });
1907
1929
  }
1908
1930
 
1909
- public async createDepositTxn(
1931
+ public async getDepositTxnIx(
1910
1932
  amount: BN,
1911
1933
  marketIndex: number,
1912
1934
  associatedTokenAccount: PublicKey,
1913
1935
  subAccountId?: number,
1914
- reduceOnly = false,
1915
- txParams?: TxParams
1916
- ): Promise<VersionedTransaction | Transaction> {
1936
+ reduceOnly = false
1937
+ ): Promise<TransactionInstruction[]> {
1917
1938
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
1918
1939
 
1919
1940
  const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
@@ -1959,6 +1980,25 @@ export class DriftClient {
1959
1980
  );
1960
1981
  }
1961
1982
 
1983
+ return instructions;
1984
+ }
1985
+
1986
+ public async createDepositTxn(
1987
+ amount: BN,
1988
+ marketIndex: number,
1989
+ associatedTokenAccount: PublicKey,
1990
+ subAccountId?: number,
1991
+ reduceOnly = false,
1992
+ txParams?: TxParams
1993
+ ): Promise<VersionedTransaction | Transaction> {
1994
+ const instructions = await this.getDepositTxnIx(
1995
+ amount,
1996
+ marketIndex,
1997
+ associatedTokenAccount,
1998
+ subAccountId,
1999
+ reduceOnly
2000
+ );
2001
+
1962
2002
  txParams = { ...(txParams ?? this.txParams), computeUnits: 600_000 };
1963
2003
 
1964
2004
  const tx = await this.buildTransaction(instructions, txParams);
@@ -2151,7 +2191,7 @@ export class DriftClient {
2151
2191
  );
2152
2192
  }
2153
2193
 
2154
- public async createInitializeUserAccountAndDepositCollateral(
2194
+ public async createInitializeUserAccountAndDepositCollateralIxs(
2155
2195
  amount: BN,
2156
2196
  userTokenAccount: PublicKey,
2157
2197
  marketIndex = 0,
@@ -2160,9 +2200,11 @@ export class DriftClient {
2160
2200
  fromSubAccountId?: number,
2161
2201
  referrerInfo?: ReferrerInfo,
2162
2202
  donateAmount?: BN,
2163
- txParams?: TxParams,
2164
2203
  customMaxMarginRatio?: number
2165
- ): Promise<[Transaction | VersionedTransaction, PublicKey]> {
2204
+ ): Promise<{
2205
+ ixs: TransactionInstruction[];
2206
+ userAccountPublicKey: PublicKey;
2207
+ }> {
2166
2208
  const ixs = [];
2167
2209
 
2168
2210
  const [userAccountPublicKey, initializeUserAccountIx] =
@@ -2263,6 +2305,37 @@ export class DriftClient {
2263
2305
  );
2264
2306
  }
2265
2307
 
2308
+ return {
2309
+ ixs,
2310
+ userAccountPublicKey,
2311
+ };
2312
+ }
2313
+
2314
+ public async createInitializeUserAccountAndDepositCollateral(
2315
+ amount: BN,
2316
+ userTokenAccount: PublicKey,
2317
+ marketIndex = 0,
2318
+ subAccountId = 0,
2319
+ name?: string,
2320
+ fromSubAccountId?: number,
2321
+ referrerInfo?: ReferrerInfo,
2322
+ donateAmount?: BN,
2323
+ txParams?: TxParams,
2324
+ customMaxMarginRatio?: number
2325
+ ): Promise<[Transaction | VersionedTransaction, PublicKey]> {
2326
+ const { ixs, userAccountPublicKey } =
2327
+ await this.createInitializeUserAccountAndDepositCollateralIxs(
2328
+ amount,
2329
+ userTokenAccount,
2330
+ marketIndex,
2331
+ subAccountId,
2332
+ name,
2333
+ fromSubAccountId,
2334
+ referrerInfo,
2335
+ donateAmount,
2336
+ customMaxMarginRatio
2337
+ );
2338
+
2266
2339
  const tx = await this.buildTransaction(ixs, txParams);
2267
2340
 
2268
2341
  return [tx, userAccountPublicKey];
@@ -2943,6 +3016,7 @@ export class DriftClient {
2943
3016
  undefined,
2944
3017
  undefined,
2945
3018
  undefined,
3019
+ undefined,
2946
3020
  subAccountId
2947
3021
  );
2948
3022
  }
@@ -3129,15 +3203,33 @@ export class DriftClient {
3129
3203
 
3130
3204
  public async getPlacePerpOrderIx(
3131
3205
  orderParams: OptionalOrderParams,
3132
- subAccountId?: number
3206
+ subAccountId?: number,
3207
+ depositToTradeArgs?: {
3208
+ isMakingNewAccount: boolean;
3209
+ depositMarketIndex: number;
3210
+ }
3133
3211
  ): Promise<TransactionInstruction> {
3134
3212
  orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
3135
- const user = await this.getUserAccountPublicKey(subAccountId);
3213
+
3214
+ const isDepositToTradeTx = depositToTradeArgs !== undefined;
3215
+
3216
+ const user = isDepositToTradeTx
3217
+ ? getUserAccountPublicKeySync(
3218
+ this.program.programId,
3219
+ this.authority,
3220
+ subAccountId
3221
+ )
3222
+ : await this.getUserAccountPublicKey(subAccountId);
3136
3223
 
3137
3224
  const remainingAccounts = this.getRemainingAccounts({
3138
- userAccounts: [this.getUserAccount(subAccountId)],
3139
- useMarketLastSlotCache: true,
3225
+ userAccounts: depositToTradeArgs?.isMakingNewAccount
3226
+ ? []
3227
+ : [this.getUserAccount(subAccountId)],
3228
+ useMarketLastSlotCache: false,
3140
3229
  readablePerpMarketIndex: orderParams.marketIndex,
3230
+ readableSpotMarketIndexes: isDepositToTradeTx
3231
+ ? [depositToTradeArgs?.depositMarketIndex]
3232
+ : undefined,
3141
3233
  });
3142
3234
 
3143
3235
  return await this.program.instruction.placePerpOrder(orderParams, {
@@ -4884,6 +4976,7 @@ export class DriftClient {
4884
4976
  orderParams: OptionalOrderParams,
4885
4977
  makerInfo?: MakerInfo | MakerInfo[],
4886
4978
  referrerInfo?: ReferrerInfo,
4979
+ successCondition?: PlaceAndTakeOrderSuccessCondition,
4887
4980
  txParams?: TxParams,
4888
4981
  subAccountId?: number
4889
4982
  ): Promise<TransactionSignature> {
@@ -4893,6 +4986,7 @@ export class DriftClient {
4893
4986
  orderParams,
4894
4987
  makerInfo,
4895
4988
  referrerInfo,
4989
+ successCondition,
4896
4990
  subAccountId
4897
4991
  ),
4898
4992
  txParams
@@ -4940,6 +5034,7 @@ export class DriftClient {
4940
5034
  orderParams,
4941
5035
  makerInfo,
4942
5036
  referrerInfo,
5037
+ undefined,
4943
5038
  subAccountId
4944
5039
  );
4945
5040
 
@@ -5104,6 +5199,7 @@ export class DriftClient {
5104
5199
  const signedTxs = (
5105
5200
  await this.txHandler.getSignedTransactionMap(
5106
5201
  txsToSign,
5202
+ // @ts-ignore
5107
5203
  this.provider.wallet
5108
5204
  )
5109
5205
  ).signedTxMap;
@@ -5129,6 +5225,7 @@ export class DriftClient {
5129
5225
  orderParams: OptionalOrderParams,
5130
5226
  makerInfo?: MakerInfo | MakerInfo[],
5131
5227
  referrerInfo?: ReferrerInfo,
5228
+ successCondition?: PlaceAndTakeOrderSuccessCondition,
5132
5229
  subAccountId?: number
5133
5230
  ): Promise<TransactionInstruction> {
5134
5231
  orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
@@ -5185,7 +5282,7 @@ export class DriftClient {
5185
5282
 
5186
5283
  return await this.program.instruction.placeAndTakePerpOrder(
5187
5284
  orderParams,
5188
- null,
5285
+ successCondition ?? null,
5189
5286
  {
5190
5287
  accounts: {
5191
5288
  state: await this.getStatePublicKey(),
@@ -5274,6 +5371,271 @@ export class DriftClient {
5274
5371
  );
5275
5372
  }
5276
5373
 
5374
+ public encodeSwiftServerMessage(message: SwiftServerMessage): Buffer {
5375
+ const messageWithBuffer = {
5376
+ slot: message.slot,
5377
+ swiftOrderSignature: message.swiftOrderSignature,
5378
+ };
5379
+ return this.program.coder.types.encode(
5380
+ 'SwiftServerMessage',
5381
+ messageWithBuffer
5382
+ );
5383
+ }
5384
+
5385
+ public decodeSwiftServerMessage(encodedMessage: Buffer): SwiftServerMessage {
5386
+ const decodedSwiftMessage = this.program.coder.types.decode(
5387
+ 'SwiftServerMessage',
5388
+ encodedMessage
5389
+ );
5390
+ return {
5391
+ slot: decodedSwiftMessage.slot,
5392
+ swiftOrderSignature: decodedSwiftMessage.swiftSignature,
5393
+ };
5394
+ }
5395
+
5396
+ public async signSwiftServerMessage(
5397
+ message: SwiftServerMessage
5398
+ ): Promise<Buffer> {
5399
+ const swiftServerMessage = Uint8Array.from(
5400
+ this.encodeSwiftServerMessage(message)
5401
+ );
5402
+ return await this.signMessage(swiftServerMessage);
5403
+ }
5404
+
5405
+ public async signSwiftOrderParamsMessage(
5406
+ orderParamsMessage: SwiftOrderParamsMessage
5407
+ ): Promise<Buffer> {
5408
+ const takerOrderParamsMessage = Uint8Array.from(
5409
+ this.encodeSwiftOrderParamsMessage(orderParamsMessage)
5410
+ );
5411
+ return await this.signMessage(takerOrderParamsMessage);
5412
+ }
5413
+
5414
+ public encodeSwiftOrderParamsMessage(
5415
+ orderParamsMessage: SwiftOrderParamsMessage
5416
+ ): Buffer {
5417
+ return this.program.coder.types.encode(
5418
+ 'SwiftOrderParamsMessage',
5419
+ orderParamsMessage
5420
+ );
5421
+ }
5422
+
5423
+ public decodeSwiftOrderParamsMessage(
5424
+ encodedMessage: Buffer
5425
+ ): SwiftOrderParamsMessage {
5426
+ return this.program.coder.types.decode(
5427
+ 'SwiftOrderParamsMessage',
5428
+ encodedMessage
5429
+ );
5430
+ }
5431
+
5432
+ public async signMessage(
5433
+ message: Uint8Array,
5434
+ keypair: Keypair = this.wallet.payer
5435
+ ): Promise<Buffer> {
5436
+ return Buffer.from(await ed.sign(message, keypair.secretKey.slice(0, 32)));
5437
+ }
5438
+
5439
+ public async placeSwiftTakerOrder(
5440
+ swiftServerMessage: Buffer,
5441
+ swiftSignature: Buffer,
5442
+ swiftOrderParamsMessage: Buffer,
5443
+ swiftOrderParamsSignature: Buffer,
5444
+ marketIndex: number,
5445
+ takerInfo: {
5446
+ taker: PublicKey;
5447
+ takerStats: PublicKey;
5448
+ takerUserAccount: UserAccount;
5449
+ },
5450
+ txParams?: TxParams
5451
+ ): Promise<TransactionSignature> {
5452
+ const ixs = await this.getPlaceSwiftTakerPerpOrderIxs(
5453
+ swiftServerMessage,
5454
+ swiftSignature,
5455
+ swiftOrderParamsMessage,
5456
+ swiftOrderParamsSignature,
5457
+ marketIndex,
5458
+ takerInfo
5459
+ );
5460
+ const { txSig } = await this.sendTransaction(
5461
+ await this.buildTransaction(ixs, txParams),
5462
+ [],
5463
+ this.opts
5464
+ );
5465
+ return txSig;
5466
+ }
5467
+
5468
+ public async getPlaceSwiftTakerPerpOrderIxs(
5469
+ encodedSwiftServerMessage: Buffer,
5470
+ swiftSignature: Buffer,
5471
+ encodedSwiftOrderParamsMessage: Buffer,
5472
+ swiftOrderParamsSignature: Buffer,
5473
+ marketIndex: number,
5474
+ takerInfo: {
5475
+ taker: PublicKey;
5476
+ takerStats: PublicKey;
5477
+ takerUserAccount: UserAccount;
5478
+ }
5479
+ ): Promise<TransactionInstruction[]> {
5480
+ const remainingAccounts = this.getRemainingAccounts({
5481
+ userAccounts: [takerInfo.takerUserAccount],
5482
+ useMarketLastSlotCache: true,
5483
+ readablePerpMarketIndex: marketIndex,
5484
+ });
5485
+
5486
+ const swiftServerSignatureIx =
5487
+ Ed25519Program.createInstructionWithPublicKey({
5488
+ publicKey: new PublicKey(this.swiftID).toBytes(),
5489
+ signature: Uint8Array.from(swiftSignature),
5490
+ message: Uint8Array.from(encodedSwiftServerMessage),
5491
+ });
5492
+
5493
+ const swiftOrderParamsSignatureIx =
5494
+ Ed25519Program.createInstructionWithPublicKey({
5495
+ publicKey: takerInfo.takerUserAccount.authority.toBytes(),
5496
+ signature: Uint8Array.from(swiftOrderParamsSignature),
5497
+ message: Uint8Array.from(encodedSwiftOrderParamsMessage),
5498
+ });
5499
+
5500
+ const placeTakerSwiftPerpOrderIx =
5501
+ await this.program.instruction.placeSwiftTakerOrder(
5502
+ encodedSwiftServerMessage,
5503
+ encodedSwiftOrderParamsMessage,
5504
+ swiftSignature,
5505
+ {
5506
+ accounts: {
5507
+ state: await this.getStatePublicKey(),
5508
+ user: takerInfo.taker,
5509
+ userStats: takerInfo.takerStats,
5510
+ authority: this.wallet.publicKey,
5511
+ ixSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
5512
+ },
5513
+ remainingAccounts,
5514
+ }
5515
+ );
5516
+
5517
+ return [
5518
+ swiftServerSignatureIx,
5519
+ swiftOrderParamsSignatureIx,
5520
+ placeTakerSwiftPerpOrderIx,
5521
+ ];
5522
+ }
5523
+
5524
+ public async placeAndMakeSwiftPerpOrder(
5525
+ encodedSwiftMessage: Buffer,
5526
+ swiftSignature: Buffer,
5527
+ encodedSwiftOrderParamsMessage: Buffer,
5528
+ swiftOrderParamsSignature: Buffer,
5529
+ takerExpectedOrderId: number,
5530
+ takerInfo: {
5531
+ taker: PublicKey;
5532
+ takerStats: PublicKey;
5533
+ takerUserAccount: UserAccount;
5534
+ },
5535
+ orderParams: OptionalOrderParams,
5536
+ referrerInfo?: ReferrerInfo,
5537
+ txParams?: TxParams,
5538
+ subAccountId?: number
5539
+ ): Promise<TransactionSignature> {
5540
+ const ixs = await this.getPlaceAndMakeSwiftPerpOrderIxs(
5541
+ encodedSwiftMessage,
5542
+ swiftSignature,
5543
+ encodedSwiftOrderParamsMessage,
5544
+ swiftOrderParamsSignature,
5545
+ takerExpectedOrderId,
5546
+ takerInfo,
5547
+ orderParams,
5548
+ referrerInfo,
5549
+ subAccountId
5550
+ );
5551
+ const { txSig, slot } = await this.sendTransaction(
5552
+ await this.buildTransaction(ixs, txParams),
5553
+ [],
5554
+ this.opts
5555
+ );
5556
+
5557
+ this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
5558
+ return txSig;
5559
+ }
5560
+
5561
+ public async getPlaceAndMakeSwiftPerpOrderIxs(
5562
+ encodedSwiftMessage: Buffer,
5563
+ swiftSignature: Buffer,
5564
+ encodedSwiftOrderParamsMessage: Buffer,
5565
+ swiftOrderParamsSignature: Buffer,
5566
+ takerExpectedOrderId: number,
5567
+ takerInfo: {
5568
+ taker: PublicKey;
5569
+ takerStats: PublicKey;
5570
+ takerUserAccount: UserAccount;
5571
+ },
5572
+ orderParams: OptionalOrderParams,
5573
+ referrerInfo?: ReferrerInfo,
5574
+ subAccountId?: number
5575
+ ): Promise<TransactionInstruction[]> {
5576
+ const [
5577
+ swiftServerSignatureIx,
5578
+ swiftOrderSignatureIx,
5579
+ placeTakerSwiftPerpOrderIx,
5580
+ ] = await this.getPlaceSwiftTakerPerpOrderIxs(
5581
+ encodedSwiftMessage,
5582
+ swiftSignature,
5583
+ encodedSwiftOrderParamsMessage,
5584
+ swiftOrderParamsSignature,
5585
+ orderParams.marketIndex,
5586
+ takerInfo
5587
+ );
5588
+
5589
+ orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
5590
+ const userStatsPublicKey = this.getUserStatsAccountPublicKey();
5591
+ const user = await this.getUserAccountPublicKey(subAccountId);
5592
+
5593
+ const remainingAccounts = this.getRemainingAccounts({
5594
+ userAccounts: [
5595
+ this.getUserAccount(subAccountId),
5596
+ takerInfo.takerUserAccount,
5597
+ ],
5598
+ useMarketLastSlotCache: true,
5599
+ writablePerpMarketIndexes: [orderParams.marketIndex],
5600
+ });
5601
+
5602
+ if (referrerInfo) {
5603
+ remainingAccounts.push({
5604
+ pubkey: referrerInfo.referrer,
5605
+ isWritable: true,
5606
+ isSigner: false,
5607
+ });
5608
+ remainingAccounts.push({
5609
+ pubkey: referrerInfo.referrerStats,
5610
+ isWritable: true,
5611
+ isSigner: false,
5612
+ });
5613
+ }
5614
+
5615
+ const placeAndMakeIx = await this.program.instruction.placeAndMakePerpOrder(
5616
+ orderParams,
5617
+ takerExpectedOrderId,
5618
+ {
5619
+ accounts: {
5620
+ state: await this.getStatePublicKey(),
5621
+ user,
5622
+ userStats: userStatsPublicKey,
5623
+ taker: takerInfo.taker,
5624
+ takerStats: takerInfo.takerStats,
5625
+ authority: this.wallet.publicKey,
5626
+ },
5627
+ remainingAccounts,
5628
+ }
5629
+ );
5630
+
5631
+ return [
5632
+ swiftServerSignatureIx,
5633
+ swiftOrderSignatureIx,
5634
+ placeTakerSwiftPerpOrderIx,
5635
+ placeAndMakeIx,
5636
+ ];
5637
+ }
5638
+
5277
5639
  public async preparePlaceAndTakeSpotOrder(
5278
5640
  orderParams: OptionalOrderParams,
5279
5641
  fulfillmentConfig?: SerumV3FulfillmentConfigAccount,
@@ -5514,6 +5876,7 @@ export class DriftClient {
5514
5876
  undefined,
5515
5877
  undefined,
5516
5878
  undefined,
5879
+ undefined,
5517
5880
  subAccountId
5518
5881
  );
5519
5882
  }
@@ -7342,12 +7705,13 @@ export class DriftClient {
7342
7705
  return this.receiverProgram;
7343
7706
  }
7344
7707
 
7345
- public getSwitchboardOnDemandProgram(): Program30<Idl30> {
7708
+ public async getSwitchboardOnDemandProgram(): Promise<Program30<Idl30>> {
7709
+ const idl = (await Program30.fetchIdl(
7710
+ this.sbOnDemandProgramdId,
7711
+ this.provider
7712
+ ))!;
7346
7713
  if (this.sbOnDemandProgram === undefined) {
7347
- this.sbOnDemandProgram = new Program30(
7348
- switchboardOnDemandIdl as Idl30,
7349
- this.provider
7350
- );
7714
+ this.sbOnDemandProgram = new Program30(idl, this.provider);
7351
7715
  }
7352
7716
  return this.sbOnDemandProgram;
7353
7717
  }
@@ -7569,7 +7933,7 @@ export class DriftClient {
7569
7933
  feed: PublicKey,
7570
7934
  numSignatures = 3
7571
7935
  ): Promise<TransactionInstruction | undefined> {
7572
- const program = this.getSwitchboardOnDemandProgram();
7936
+ const program = await this.getSwitchboardOnDemandProgram();
7573
7937
  const feedAccount = new PullFeed(program, feed);
7574
7938
  if (!this.sbProgramFeedConfigs) {
7575
7939
  this.sbProgramFeedConfigs = new Map();
@@ -7581,8 +7945,6 @@ export class DriftClient {
7581
7945
 
7582
7946
  const [pullIx, _responses, success] = await feedAccount.fetchUpdateIx({
7583
7947
  numSignatures,
7584
- // @ts-ignore :: TODO someone needs to look at this
7585
- feedConfigs: this.sbProgramFeedConfigs.get(feed.toString()),
7586
7948
  });
7587
7949
  if (!success) {
7588
7950
  return undefined;