@drift-labs/sdk 2.96.0-beta.2 → 2.96.0-beta.20

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 (110) hide show
  1. package/README.md +1 -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 -8
  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/webSocketAccountSubscriber.d.ts +1 -1
  11. package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +8 -7
  12. package/lib/accounts/webSocketDriftClientAccountSubscriber.js +24 -1
  13. package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +1 -1
  14. package/lib/config.d.ts +5 -1
  15. package/lib/config.js +9 -1
  16. package/lib/constants/perpMarkets.js +21 -0
  17. package/lib/constants/spotMarkets.js +12 -1
  18. package/lib/driftClient.d.ts +44 -9
  19. package/lib/driftClient.js +181 -61
  20. package/lib/driftClientConfig.d.ts +2 -6
  21. package/lib/events/eventSubscriber.js +9 -8
  22. package/lib/events/types.js +1 -5
  23. package/lib/idl/drift.json +169 -1
  24. package/lib/index.d.ts +1 -0
  25. package/lib/index.js +1 -0
  26. package/lib/math/margin.d.ts +16 -1
  27. package/lib/math/margin.js +67 -1
  28. package/lib/orderParams.js +8 -8
  29. package/lib/orderSubscriber/OrderSubscriber.d.ts +1 -2
  30. package/lib/orderSubscriber/OrderSubscriber.js +4 -19
  31. package/lib/orderSubscriber/types.d.ts +0 -9
  32. package/lib/tokenFaucet.js +2 -1
  33. package/lib/tx/baseTxSender.js +2 -2
  34. package/lib/tx/fastSingleTxSender.js +2 -2
  35. package/lib/tx/forwardOnlyTxSender.js +2 -2
  36. package/lib/tx/retryTxSender.js +2 -2
  37. package/lib/tx/txHandler.js +10 -7
  38. package/lib/tx/whileValidTxSender.d.ts +2 -4
  39. package/lib/tx/whileValidTxSender.js +16 -17
  40. package/lib/types.d.ts +21 -1
  41. package/lib/types.js +6 -1
  42. package/lib/user.d.ts +4 -1
  43. package/lib/user.js +13 -13
  44. package/lib/userConfig.d.ts +1 -6
  45. package/lib/userMap/userMap.js +0 -14
  46. package/lib/userMap/userMapConfig.d.ts +0 -7
  47. package/lib/userStatsConfig.d.ts +0 -6
  48. package/lib/util/TransactionConfirmationManager.d.ts +14 -0
  49. package/lib/util/TransactionConfirmationManager.js +96 -0
  50. package/package.json +4 -5
  51. package/src/accounts/pollingDriftClientAccountSubscriber.ts +41 -5
  52. package/src/accounts/types.ts +6 -9
  53. package/src/accounts/utils.ts +42 -0
  54. package/src/accounts/webSocketAccountSubscriber.ts +1 -1
  55. package/src/accounts/webSocketDriftClientAccountSubscriber.ts +43 -8
  56. package/src/accounts/webSocketProgramAccountSubscriber.ts +1 -1
  57. package/src/config.ts +15 -1
  58. package/src/constants/perpMarkets.ts +22 -0
  59. package/src/constants/spotMarkets.ts +14 -1
  60. package/src/driftClient.ts +423 -91
  61. package/src/driftClientConfig.ts +2 -7
  62. package/src/events/eventSubscriber.ts +18 -11
  63. package/src/events/types.ts +1 -5
  64. package/src/idl/drift.json +169 -1
  65. package/src/index.ts +1 -0
  66. package/src/math/margin.ts +137 -1
  67. package/src/orderParams.ts +20 -12
  68. package/src/orderSubscriber/OrderSubscriber.ts +1 -15
  69. package/src/orderSubscriber/types.ts +0 -10
  70. package/src/tokenFaucet.ts +2 -2
  71. package/src/tx/baseTxSender.ts +2 -2
  72. package/src/tx/fastSingleTxSender.ts +2 -2
  73. package/src/tx/forwardOnlyTxSender.ts +2 -2
  74. package/src/tx/retryTxSender.ts +2 -2
  75. package/src/tx/txHandler.ts +8 -2
  76. package/src/tx/whileValidTxSender.ts +23 -26
  77. package/src/types.ts +30 -1
  78. package/src/user.ts +35 -13
  79. package/src/userConfig.ts +1 -7
  80. package/src/userMap/userMap.ts +1 -17
  81. package/src/userMap/userMapConfig.ts +0 -8
  82. package/src/userStatsConfig.ts +0 -7
  83. package/src/util/TransactionConfirmationManager.ts +155 -0
  84. package/tests/ci/idl.ts +12 -3
  85. package/tests/ci/verifyConstants.ts +13 -0
  86. package/tests/tx/TransactionConfirmationManager.test.ts +286 -0
  87. package/lib/accounts/grpcAccountSubscriber.d.ts +0 -16
  88. package/lib/accounts/grpcAccountSubscriber.js +0 -155
  89. package/lib/accounts/grpcDriftClientAccountSubscriber.d.ts +0 -13
  90. package/lib/accounts/grpcDriftClientAccountSubscriber.js +0 -96
  91. package/lib/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts +0 -10
  92. package/lib/accounts/grpcInsuranceFundStakeAccountSubscriber.js +0 -30
  93. package/lib/accounts/grpcProgramAccountSubscriber.d.ts +0 -19
  94. package/lib/accounts/grpcProgramAccountSubscriber.js +0 -161
  95. package/lib/accounts/grpcUserAccountSubscriber.d.ts +0 -10
  96. package/lib/accounts/grpcUserAccountSubscriber.js +0 -28
  97. package/lib/accounts/grpcUserStatsAccountSubscriber.d.ts +0 -10
  98. package/lib/accounts/grpcUserStatsAccountSubscriber.js +0 -28
  99. package/lib/orderSubscriber/grpcSubscription.d.ts +0 -25
  100. package/lib/orderSubscriber/grpcSubscription.js +0 -68
  101. package/lib/userMap/grpcSubscription.d.ts +0 -26
  102. package/lib/userMap/grpcSubscription.js +0 -42
  103. package/src/accounts/grpcAccountSubscriber.ts +0 -158
  104. package/src/accounts/grpcDriftClientAccountSubscriber.ts +0 -196
  105. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -62
  106. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -181
  107. package/src/accounts/grpcUserAccountSubscriber.ts +0 -48
  108. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -51
  109. package/src/orderSubscriber/grpcSubscription.ts +0 -126
  110. package/src/userMap/grpcSubscription.ts +0 -83
@@ -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,23 +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';
155
- import { gprcDriftClientAccountSubscriber } from './accounts/grpcDriftClientAccountSubscriber';
165
+ import * as ed from '@noble/ed25519';
156
166
 
157
167
  type RemainingAccountParams = {
158
168
  userAccounts: UserAccount[];
@@ -204,6 +214,7 @@ export class DriftClient {
204
214
 
205
215
  receiverProgram?: Program<PythSolanaReceiver>;
206
216
  wormholeProgram?: Program<WormholeCoreBridgeSolana>;
217
+ sbOnDemandProgramdId: PublicKey;
207
218
  sbOnDemandProgram?: Program30<Idl30>;
208
219
  sbProgramFeedConfigs?: Map<string, any>;
209
220
 
@@ -219,7 +230,7 @@ export class DriftClient {
219
230
  this.connection = config.connection;
220
231
  this.wallet = config.wallet;
221
232
  this.opts = config.opts || {
222
- ...AnchorProvider.defaultOptions(),
233
+ ...DEFAULT_CONFIRMATION_OPTS,
223
234
  commitment: config?.connection?.commitment,
224
235
  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)
225
236
  };
@@ -248,6 +259,7 @@ export class DriftClient {
248
259
  config?.txHandler ??
249
260
  new TxHandler({
250
261
  connection: this.connection,
262
+ // @ts-ignore
251
263
  wallet: this.provider.wallet,
252
264
  confirmationOptions: this.opts,
253
265
  opts: {
@@ -293,19 +305,6 @@ export class DriftClient {
293
305
  type: 'polling',
294
306
  accountLoader: config.accountSubscription.accountLoader,
295
307
  };
296
- } else if (config.accountSubscription?.type === 'grpc') {
297
- this.userAccountSubscriptionConfig = {
298
- type: 'grpc',
299
- resubTimeoutMs: config.accountSubscription?.resubTimeoutMs,
300
- logResubMessages: config.accountSubscription?.logResubMessages,
301
- configs: config.accountSubscription?.configs,
302
- };
303
- this.userStatsAccountSubscriptionConfig = {
304
- type: 'grpc',
305
- resubTimeoutMs: config.accountSubscription?.resubTimeoutMs,
306
- logResubMessages: config.accountSubscription?.logResubMessages,
307
- configs: config.accountSubscription?.configs,
308
- };
309
308
  } else {
310
309
  this.userAccountSubscriptionConfig = {
311
310
  type: 'websocket',
@@ -339,6 +338,8 @@ export class DriftClient {
339
338
  );
340
339
  }
341
340
 
341
+ const delistedMarketSetting =
342
+ config.delistedMarketSetting || DelistedMarketSetting.Subscribe;
342
343
  const noMarketsAndOraclesSpecified =
343
344
  config.perpMarketIndexes === undefined &&
344
345
  config.spotMarketIndexes === undefined &&
@@ -350,20 +351,8 @@ export class DriftClient {
350
351
  config.perpMarketIndexes ?? [],
351
352
  config.spotMarketIndexes ?? [],
352
353
  config.oracleInfos ?? [],
353
- noMarketsAndOraclesSpecified
354
- );
355
- } else if (config.accountSubscription?.type === 'grpc') {
356
- this.accountSubscriber = new gprcDriftClientAccountSubscriber(
357
- config.accountSubscription.configs,
358
- this.program,
359
- config.perpMarketIndexes ?? [],
360
- config.spotMarketIndexes ?? [],
361
- config.oracleInfos ?? [],
362
354
  noMarketsAndOraclesSpecified,
363
- {
364
- resubTimeoutMs: config.accountSubscription?.resubTimeoutMs,
365
- logResubMessages: config.accountSubscription?.logResubMessages,
366
- }
355
+ delistedMarketSetting
367
356
  );
368
357
  } else {
369
358
  this.accountSubscriber = new WebSocketDriftClientAccountSubscriber(
@@ -372,6 +361,7 @@ export class DriftClient {
372
361
  config.spotMarketIndexes ?? [],
373
362
  config.oracleInfos ?? [],
374
363
  noMarketsAndOraclesSpecified,
364
+ delistedMarketSetting,
375
365
  {
376
366
  resubTimeoutMs: config.accountSubscription?.resubTimeoutMs,
377
367
  logResubMessages: config.accountSubscription?.logResubMessages,
@@ -379,7 +369,6 @@ export class DriftClient {
379
369
  config.accountSubscription?.commitment
380
370
  );
381
371
  }
382
-
383
372
  this.eventEmitter = this.accountSubscriber.eventEmitter;
384
373
 
385
374
  this.metricsEventEmitter = new EventEmitter();
@@ -396,6 +385,9 @@ export class DriftClient {
396
385
  opts: this.opts,
397
386
  txHandler: this.txHandler,
398
387
  });
388
+
389
+ this.sbOnDemandProgramdId =
390
+ configs[config.env ?? 'mainnet-beta'].SB_ON_DEMAND_PID;
399
391
  }
400
392
 
401
393
  public getUserMapKey(subAccountId: number, authority: PublicKey): string {
@@ -1934,14 +1926,13 @@ export class DriftClient {
1934
1926
  });
1935
1927
  }
1936
1928
 
1937
- public async createDepositTxn(
1929
+ public async getDepositTxnIx(
1938
1930
  amount: BN,
1939
1931
  marketIndex: number,
1940
1932
  associatedTokenAccount: PublicKey,
1941
1933
  subAccountId?: number,
1942
- reduceOnly = false,
1943
- txParams?: TxParams
1944
- ): Promise<VersionedTransaction | Transaction> {
1934
+ reduceOnly = false
1935
+ ): Promise<TransactionInstruction[]> {
1945
1936
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
1946
1937
 
1947
1938
  const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
@@ -1987,6 +1978,25 @@ export class DriftClient {
1987
1978
  );
1988
1979
  }
1989
1980
 
1981
+ return instructions;
1982
+ }
1983
+
1984
+ public async createDepositTxn(
1985
+ amount: BN,
1986
+ marketIndex: number,
1987
+ associatedTokenAccount: PublicKey,
1988
+ subAccountId?: number,
1989
+ reduceOnly = false,
1990
+ txParams?: TxParams
1991
+ ): Promise<VersionedTransaction | Transaction> {
1992
+ const instructions = await this.getDepositTxnIx(
1993
+ amount,
1994
+ marketIndex,
1995
+ associatedTokenAccount,
1996
+ subAccountId,
1997
+ reduceOnly
1998
+ );
1999
+
1990
2000
  txParams = { ...(txParams ?? this.txParams), computeUnits: 600_000 };
1991
2001
 
1992
2002
  const tx = await this.buildTransaction(instructions, txParams);
@@ -2179,7 +2189,7 @@ export class DriftClient {
2179
2189
  );
2180
2190
  }
2181
2191
 
2182
- public async createInitializeUserAccountAndDepositCollateral(
2192
+ public async createInitializeUserAccountAndDepositCollateralIxs(
2183
2193
  amount: BN,
2184
2194
  userTokenAccount: PublicKey,
2185
2195
  marketIndex = 0,
@@ -2188,9 +2198,11 @@ export class DriftClient {
2188
2198
  fromSubAccountId?: number,
2189
2199
  referrerInfo?: ReferrerInfo,
2190
2200
  donateAmount?: BN,
2191
- txParams?: TxParams,
2192
2201
  customMaxMarginRatio?: number
2193
- ): Promise<[Transaction | VersionedTransaction, PublicKey]> {
2202
+ ): Promise<{
2203
+ ixs: TransactionInstruction[];
2204
+ userAccountPublicKey: PublicKey;
2205
+ }> {
2194
2206
  const ixs = [];
2195
2207
 
2196
2208
  const [userAccountPublicKey, initializeUserAccountIx] =
@@ -2291,6 +2303,37 @@ export class DriftClient {
2291
2303
  );
2292
2304
  }
2293
2305
 
2306
+ return {
2307
+ ixs,
2308
+ userAccountPublicKey,
2309
+ };
2310
+ }
2311
+
2312
+ public async createInitializeUserAccountAndDepositCollateral(
2313
+ amount: BN,
2314
+ userTokenAccount: PublicKey,
2315
+ marketIndex = 0,
2316
+ subAccountId = 0,
2317
+ name?: string,
2318
+ fromSubAccountId?: number,
2319
+ referrerInfo?: ReferrerInfo,
2320
+ donateAmount?: BN,
2321
+ txParams?: TxParams,
2322
+ customMaxMarginRatio?: number
2323
+ ): Promise<[Transaction | VersionedTransaction, PublicKey]> {
2324
+ const { ixs, userAccountPublicKey } =
2325
+ await this.createInitializeUserAccountAndDepositCollateralIxs(
2326
+ amount,
2327
+ userTokenAccount,
2328
+ marketIndex,
2329
+ subAccountId,
2330
+ name,
2331
+ fromSubAccountId,
2332
+ referrerInfo,
2333
+ donateAmount,
2334
+ customMaxMarginRatio
2335
+ );
2336
+
2294
2337
  const tx = await this.buildTransaction(ixs, txParams);
2295
2338
 
2296
2339
  return [tx, userAccountPublicKey];
@@ -2971,6 +3014,7 @@ export class DriftClient {
2971
3014
  undefined,
2972
3015
  undefined,
2973
3016
  undefined,
3017
+ undefined,
2974
3018
  subAccountId
2975
3019
  );
2976
3020
  }
@@ -3157,15 +3201,33 @@ export class DriftClient {
3157
3201
 
3158
3202
  public async getPlacePerpOrderIx(
3159
3203
  orderParams: OptionalOrderParams,
3160
- subAccountId?: number
3204
+ subAccountId?: number,
3205
+ depositToTradeArgs?: {
3206
+ isMakingNewAccount: boolean;
3207
+ depositMarketIndex: number;
3208
+ }
3161
3209
  ): Promise<TransactionInstruction> {
3162
3210
  orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
3163
- const user = await this.getUserAccountPublicKey(subAccountId);
3211
+
3212
+ const isDepositToTradeTx = depositToTradeArgs !== undefined;
3213
+
3214
+ const user = isDepositToTradeTx
3215
+ ? getUserAccountPublicKeySync(
3216
+ this.program.programId,
3217
+ this.authority,
3218
+ subAccountId
3219
+ )
3220
+ : await this.getUserAccountPublicKey(subAccountId);
3164
3221
 
3165
3222
  const remainingAccounts = this.getRemainingAccounts({
3166
- userAccounts: [this.getUserAccount(subAccountId)],
3167
- useMarketLastSlotCache: true,
3223
+ userAccounts: depositToTradeArgs?.isMakingNewAccount
3224
+ ? []
3225
+ : [this.getUserAccount(subAccountId)],
3226
+ useMarketLastSlotCache: false,
3168
3227
  readablePerpMarketIndex: orderParams.marketIndex,
3228
+ readableSpotMarketIndexes: isDepositToTradeTx
3229
+ ? [depositToTradeArgs?.depositMarketIndex]
3230
+ : undefined,
3169
3231
  });
3170
3232
 
3171
3233
  return await this.program.instruction.placePerpOrder(orderParams, {
@@ -4912,6 +4974,7 @@ export class DriftClient {
4912
4974
  orderParams: OptionalOrderParams,
4913
4975
  makerInfo?: MakerInfo | MakerInfo[],
4914
4976
  referrerInfo?: ReferrerInfo,
4977
+ successCondition?: PlaceAndTakeOrderSuccessCondition,
4915
4978
  txParams?: TxParams,
4916
4979
  subAccountId?: number
4917
4980
  ): Promise<TransactionSignature> {
@@ -4921,6 +4984,7 @@ export class DriftClient {
4921
4984
  orderParams,
4922
4985
  makerInfo,
4923
4986
  referrerInfo,
4987
+ successCondition,
4924
4988
  subAccountId
4925
4989
  ),
4926
4990
  txParams
@@ -4968,6 +5032,7 @@ export class DriftClient {
4968
5032
  orderParams,
4969
5033
  makerInfo,
4970
5034
  referrerInfo,
5035
+ undefined,
4971
5036
  subAccountId
4972
5037
  );
4973
5038
 
@@ -5132,6 +5197,7 @@ export class DriftClient {
5132
5197
  const signedTxs = (
5133
5198
  await this.txHandler.getSignedTransactionMap(
5134
5199
  txsToSign,
5200
+ // @ts-ignore
5135
5201
  this.provider.wallet
5136
5202
  )
5137
5203
  ).signedTxMap;
@@ -5157,6 +5223,7 @@ export class DriftClient {
5157
5223
  orderParams: OptionalOrderParams,
5158
5224
  makerInfo?: MakerInfo | MakerInfo[],
5159
5225
  referrerInfo?: ReferrerInfo,
5226
+ successCondition?: PlaceAndTakeOrderSuccessCondition,
5160
5227
  subAccountId?: number
5161
5228
  ): Promise<TransactionInstruction> {
5162
5229
  orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
@@ -5213,7 +5280,7 @@ export class DriftClient {
5213
5280
 
5214
5281
  return await this.program.instruction.placeAndTakePerpOrder(
5215
5282
  orderParams,
5216
- null,
5283
+ successCondition ?? null,
5217
5284
  {
5218
5285
  accounts: {
5219
5286
  state: await this.getStatePublicKey(),
@@ -5302,6 +5369,271 @@ export class DriftClient {
5302
5369
  );
5303
5370
  }
5304
5371
 
5372
+ public encodeSwiftServerMessage(message: SwiftServerMessage): Buffer {
5373
+ const messageWithBuffer = {
5374
+ slot: message.slot,
5375
+ swiftOrderSignature: message.swiftOrderSignature,
5376
+ };
5377
+ return this.program.coder.types.encode(
5378
+ 'SwiftServerMessage',
5379
+ messageWithBuffer
5380
+ );
5381
+ }
5382
+
5383
+ public decodeSwiftServerMessage(encodedMessage: Buffer): SwiftServerMessage {
5384
+ const decodedSwiftMessage = this.program.coder.types.decode(
5385
+ 'SwiftServerMessage',
5386
+ encodedMessage
5387
+ );
5388
+ return {
5389
+ slot: decodedSwiftMessage.slot,
5390
+ swiftOrderSignature: decodedSwiftMessage.swiftSignature,
5391
+ };
5392
+ }
5393
+
5394
+ public async signSwiftServerMessage(
5395
+ message: SwiftServerMessage
5396
+ ): Promise<Buffer> {
5397
+ const swiftServerMessage = Uint8Array.from(
5398
+ this.encodeSwiftServerMessage(message)
5399
+ );
5400
+ return await this.signMessage(swiftServerMessage);
5401
+ }
5402
+
5403
+ public async signSwiftOrderParamsMessage(
5404
+ orderParamsMessage: SwiftOrderParamsMessage
5405
+ ): Promise<Buffer> {
5406
+ const takerOrderParamsMessage = Uint8Array.from(
5407
+ this.encodeSwiftOrderParamsMessage(orderParamsMessage)
5408
+ );
5409
+ return await this.signMessage(takerOrderParamsMessage);
5410
+ }
5411
+
5412
+ public encodeSwiftOrderParamsMessage(
5413
+ orderParamsMessage: SwiftOrderParamsMessage
5414
+ ): Buffer {
5415
+ return this.program.coder.types.encode(
5416
+ 'SwiftOrderParamsMessage',
5417
+ orderParamsMessage
5418
+ );
5419
+ }
5420
+
5421
+ public decodeSwiftOrderParamsMessage(
5422
+ encodedMessage: Buffer
5423
+ ): SwiftOrderParamsMessage {
5424
+ return this.program.coder.types.decode(
5425
+ 'SwiftOrderParamsMessage',
5426
+ encodedMessage
5427
+ );
5428
+ }
5429
+
5430
+ public async signMessage(
5431
+ message: Uint8Array,
5432
+ keypair: Keypair = this.wallet.payer
5433
+ ): Promise<Buffer> {
5434
+ return Buffer.from(await ed.sign(message, keypair.secretKey.slice(0, 32)));
5435
+ }
5436
+
5437
+ public async placeSwiftTakerOrder(
5438
+ swiftServerMessage: Buffer,
5439
+ swiftSignature: Buffer,
5440
+ swiftOrderParamsMessage: Buffer,
5441
+ swiftOrderParamsSignature: Buffer,
5442
+ marketIndex: number,
5443
+ takerInfo: {
5444
+ taker: PublicKey;
5445
+ takerStats: PublicKey;
5446
+ takerUserAccount: UserAccount;
5447
+ },
5448
+ txParams?: TxParams
5449
+ ): Promise<TransactionSignature> {
5450
+ const ixs = await this.getPlaceSwiftTakerPerpOrderIxs(
5451
+ swiftServerMessage,
5452
+ swiftSignature,
5453
+ swiftOrderParamsMessage,
5454
+ swiftOrderParamsSignature,
5455
+ marketIndex,
5456
+ takerInfo
5457
+ );
5458
+ const { txSig } = await this.sendTransaction(
5459
+ await this.buildTransaction(ixs, txParams),
5460
+ [],
5461
+ this.opts
5462
+ );
5463
+ return txSig;
5464
+ }
5465
+
5466
+ public async getPlaceSwiftTakerPerpOrderIxs(
5467
+ encodedSwiftServerMessage: Buffer,
5468
+ swiftSignature: Buffer,
5469
+ encodedSwiftOrderParamsMessage: Buffer,
5470
+ swiftOrderParamsSignature: Buffer,
5471
+ marketIndex: number,
5472
+ takerInfo: {
5473
+ taker: PublicKey;
5474
+ takerStats: PublicKey;
5475
+ takerUserAccount: UserAccount;
5476
+ }
5477
+ ): Promise<TransactionInstruction[]> {
5478
+ const remainingAccounts = this.getRemainingAccounts({
5479
+ userAccounts: [takerInfo.takerUserAccount],
5480
+ useMarketLastSlotCache: true,
5481
+ readablePerpMarketIndex: marketIndex,
5482
+ });
5483
+
5484
+ const swiftServerSignatureIx =
5485
+ Ed25519Program.createInstructionWithPublicKey({
5486
+ publicKey: new PublicKey(SWIFT_ID).toBytes(),
5487
+ signature: Uint8Array.from(swiftSignature),
5488
+ message: Uint8Array.from(encodedSwiftServerMessage),
5489
+ });
5490
+
5491
+ const swiftOrderParamsSignatureIx =
5492
+ Ed25519Program.createInstructionWithPublicKey({
5493
+ publicKey: takerInfo.takerUserAccount.authority.toBytes(),
5494
+ signature: Uint8Array.from(swiftOrderParamsSignature),
5495
+ message: Uint8Array.from(encodedSwiftOrderParamsMessage),
5496
+ });
5497
+
5498
+ const placeTakerSwiftPerpOrderIx =
5499
+ await this.program.instruction.placeSwiftTakerOrder(
5500
+ encodedSwiftServerMessage,
5501
+ encodedSwiftOrderParamsMessage,
5502
+ swiftSignature,
5503
+ {
5504
+ accounts: {
5505
+ state: await this.getStatePublicKey(),
5506
+ user: takerInfo.taker,
5507
+ userStats: takerInfo.takerStats,
5508
+ authority: this.wallet.publicKey,
5509
+ ixSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
5510
+ },
5511
+ remainingAccounts,
5512
+ }
5513
+ );
5514
+
5515
+ return [
5516
+ swiftServerSignatureIx,
5517
+ swiftOrderParamsSignatureIx,
5518
+ placeTakerSwiftPerpOrderIx,
5519
+ ];
5520
+ }
5521
+
5522
+ public async placeAndMakeSwiftPerpOrder(
5523
+ encodedSwiftMessage: Buffer,
5524
+ swiftSignature: Buffer,
5525
+ encodedSwiftOrderParamsMessage: Buffer,
5526
+ swiftOrderParamsSignature: Buffer,
5527
+ takerExpectedOrderId: number,
5528
+ takerInfo: {
5529
+ taker: PublicKey;
5530
+ takerStats: PublicKey;
5531
+ takerUserAccount: UserAccount;
5532
+ },
5533
+ orderParams: OptionalOrderParams,
5534
+ referrerInfo?: ReferrerInfo,
5535
+ txParams?: TxParams,
5536
+ subAccountId?: number
5537
+ ): Promise<TransactionSignature> {
5538
+ const ixs = await this.getPlaceAndMakeSwiftPerpOrderIxs(
5539
+ encodedSwiftMessage,
5540
+ swiftSignature,
5541
+ encodedSwiftOrderParamsMessage,
5542
+ swiftOrderParamsSignature,
5543
+ takerExpectedOrderId,
5544
+ takerInfo,
5545
+ orderParams,
5546
+ referrerInfo,
5547
+ subAccountId
5548
+ );
5549
+ const { txSig, slot } = await this.sendTransaction(
5550
+ await this.buildTransaction(ixs, txParams),
5551
+ [],
5552
+ this.opts
5553
+ );
5554
+
5555
+ this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
5556
+ return txSig;
5557
+ }
5558
+
5559
+ public async getPlaceAndMakeSwiftPerpOrderIxs(
5560
+ encodedSwiftMessage: Buffer,
5561
+ swiftSignature: Buffer,
5562
+ encodedSwiftOrderParamsMessage: Buffer,
5563
+ swiftOrderParamsSignature: Buffer,
5564
+ takerExpectedOrderId: number,
5565
+ takerInfo: {
5566
+ taker: PublicKey;
5567
+ takerStats: PublicKey;
5568
+ takerUserAccount: UserAccount;
5569
+ },
5570
+ orderParams: OptionalOrderParams,
5571
+ referrerInfo?: ReferrerInfo,
5572
+ subAccountId?: number
5573
+ ): Promise<TransactionInstruction[]> {
5574
+ const [
5575
+ swiftServerSignatureIx,
5576
+ swiftOrderSignatureIx,
5577
+ placeTakerSwiftPerpOrderIx,
5578
+ ] = await this.getPlaceSwiftTakerPerpOrderIxs(
5579
+ encodedSwiftMessage,
5580
+ swiftSignature,
5581
+ encodedSwiftOrderParamsMessage,
5582
+ swiftOrderParamsSignature,
5583
+ orderParams.marketIndex,
5584
+ takerInfo
5585
+ );
5586
+
5587
+ orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
5588
+ const userStatsPublicKey = this.getUserStatsAccountPublicKey();
5589
+ const user = await this.getUserAccountPublicKey(subAccountId);
5590
+
5591
+ const remainingAccounts = this.getRemainingAccounts({
5592
+ userAccounts: [
5593
+ this.getUserAccount(subAccountId),
5594
+ takerInfo.takerUserAccount,
5595
+ ],
5596
+ useMarketLastSlotCache: true,
5597
+ writablePerpMarketIndexes: [orderParams.marketIndex],
5598
+ });
5599
+
5600
+ if (referrerInfo) {
5601
+ remainingAccounts.push({
5602
+ pubkey: referrerInfo.referrer,
5603
+ isWritable: true,
5604
+ isSigner: false,
5605
+ });
5606
+ remainingAccounts.push({
5607
+ pubkey: referrerInfo.referrerStats,
5608
+ isWritable: true,
5609
+ isSigner: false,
5610
+ });
5611
+ }
5612
+
5613
+ const placeAndMakeIx = await this.program.instruction.placeAndMakePerpOrder(
5614
+ orderParams,
5615
+ takerExpectedOrderId,
5616
+ {
5617
+ accounts: {
5618
+ state: await this.getStatePublicKey(),
5619
+ user,
5620
+ userStats: userStatsPublicKey,
5621
+ taker: takerInfo.taker,
5622
+ takerStats: takerInfo.takerStats,
5623
+ authority: this.wallet.publicKey,
5624
+ },
5625
+ remainingAccounts,
5626
+ }
5627
+ );
5628
+
5629
+ return [
5630
+ swiftServerSignatureIx,
5631
+ swiftOrderSignatureIx,
5632
+ placeTakerSwiftPerpOrderIx,
5633
+ placeAndMakeIx,
5634
+ ];
5635
+ }
5636
+
5305
5637
  public async preparePlaceAndTakeSpotOrder(
5306
5638
  orderParams: OptionalOrderParams,
5307
5639
  fulfillmentConfig?: SerumV3FulfillmentConfigAccount,
@@ -5542,6 +5874,7 @@ export class DriftClient {
5542
5874
  undefined,
5543
5875
  undefined,
5544
5876
  undefined,
5877
+ undefined,
5545
5878
  subAccountId
5546
5879
  );
5547
5880
  }
@@ -7370,12 +7703,13 @@ export class DriftClient {
7370
7703
  return this.receiverProgram;
7371
7704
  }
7372
7705
 
7373
- public getSwitchboardOnDemandProgram(): Program30<Idl30> {
7706
+ public async getSwitchboardOnDemandProgram(): Promise<Program30<Idl30>> {
7707
+ const idl = (await Program30.fetchIdl(
7708
+ this.sbOnDemandProgramdId,
7709
+ this.provider
7710
+ ))!;
7374
7711
  if (this.sbOnDemandProgram === undefined) {
7375
- this.sbOnDemandProgram = new Program30(
7376
- switchboardOnDemandIdl as Idl30,
7377
- this.provider
7378
- );
7712
+ this.sbOnDemandProgram = new Program30(idl, this.provider);
7379
7713
  }
7380
7714
  return this.sbOnDemandProgram;
7381
7715
  }
@@ -7597,7 +7931,7 @@ export class DriftClient {
7597
7931
  feed: PublicKey,
7598
7932
  numSignatures = 3
7599
7933
  ): Promise<TransactionInstruction | undefined> {
7600
- const program = this.getSwitchboardOnDemandProgram();
7934
+ const program = await this.getSwitchboardOnDemandProgram();
7601
7935
  const feedAccount = new PullFeed(program, feed);
7602
7936
  if (!this.sbProgramFeedConfigs) {
7603
7937
  this.sbProgramFeedConfigs = new Map();
@@ -7609,8 +7943,6 @@ export class DriftClient {
7609
7943
 
7610
7944
  const [pullIx, _responses, success] = await feedAccount.fetchUpdateIx({
7611
7945
  numSignatures,
7612
- // @ts-ignore :: TODO someone needs to look at this
7613
- feedConfigs: this.sbProgramFeedConfigs.get(feed.toString()),
7614
7946
  });
7615
7947
  if (!success) {
7616
7948
  return undefined;