@drift-labs/sdk 2.112.0-beta.0 → 2.112.0-beta.10

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 (53) hide show
  1. package/VERSION +1 -1
  2. package/lib/browser/decode/user.js +4 -1
  3. package/lib/browser/dlob/DLOB.js +18 -2
  4. package/lib/browser/driftClient.d.ts +8 -6
  5. package/lib/browser/driftClient.js +30 -23
  6. package/lib/browser/fastlane/fastlaneOrderSubscriber.d.ts +5 -0
  7. package/lib/browser/fastlane/grpcSignedMsgUserAccountSubscriber.d.ts +22 -0
  8. package/lib/browser/fastlane/grpcSignedMsgUserAccountSubscriber.js +57 -0
  9. package/lib/browser/fastlane/index.d.ts +3 -0
  10. package/lib/browser/fastlane/index.js +19 -0
  11. package/lib/browser/fastlane/signedMsgUserAccountSubscriber.d.ts +43 -0
  12. package/lib/browser/fastlane/signedMsgUserAccountSubscriber.js +116 -0
  13. package/lib/browser/idl/drift.json +9 -1
  14. package/lib/browser/index.d.ts +1 -0
  15. package/lib/browser/index.js +1 -0
  16. package/lib/browser/math/orders.d.ts +1 -0
  17. package/lib/browser/math/orders.js +6 -1
  18. package/lib/browser/memcmp.d.ts +1 -0
  19. package/lib/browser/memcmp.js +10 -1
  20. package/lib/browser/types.d.ts +17 -1
  21. package/lib/node/decode/user.js +4 -1
  22. package/lib/node/dlob/DLOB.js +18 -2
  23. package/lib/node/driftClient.d.ts +8 -6
  24. package/lib/node/driftClient.js +30 -23
  25. package/lib/node/fastlane/fastlaneOrderSubscriber.d.ts +5 -0
  26. package/lib/node/fastlane/grpcSignedMsgUserAccountSubscriber.d.ts +22 -0
  27. package/lib/node/fastlane/grpcSignedMsgUserAccountSubscriber.js +57 -0
  28. package/lib/node/fastlane/index.d.ts +3 -0
  29. package/lib/node/fastlane/index.js +19 -0
  30. package/lib/node/fastlane/signedMsgUserAccountSubscriber.d.ts +43 -0
  31. package/lib/node/fastlane/signedMsgUserAccountSubscriber.js +116 -0
  32. package/lib/node/idl/drift.json +9 -1
  33. package/lib/node/index.d.ts +1 -0
  34. package/lib/node/index.js +1 -0
  35. package/lib/node/math/orders.d.ts +1 -0
  36. package/lib/node/math/orders.js +6 -1
  37. package/lib/node/memcmp.d.ts +1 -0
  38. package/lib/node/memcmp.js +10 -1
  39. package/lib/node/types.d.ts +17 -1
  40. package/package.json +2 -2
  41. package/src/decode/user.ts +4 -1
  42. package/src/dlob/DLOB.ts +23 -6
  43. package/src/driftClient.ts +32 -19
  44. package/src/fastlane/fastlaneOrderSubscriber.ts +5 -0
  45. package/src/fastlane/grpcSignedMsgUserAccountSubscriber.ts +95 -0
  46. package/src/fastlane/index.ts +3 -0
  47. package/src/fastlane/signedMsgUserAccountSubscriber.ts +234 -0
  48. package/src/idl/drift.json +9 -1
  49. package/src/index.ts +1 -0
  50. package/src/math/orders.ts +5 -0
  51. package/src/memcmp.ts +11 -0
  52. package/src/types.ts +23 -0
  53. package/tests/user/helpers.ts +1 -0
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.112.0-beta.0
1
+ 2.112.0-beta.10
@@ -230,7 +230,9 @@ function decodeUser(buffer) {
230
230
  offset += 1;
231
231
  const postedSlotTail = buffer.readUint8(offset);
232
232
  offset += 1;
233
- offset += 2; // padding
233
+ const bitFlags = buffer.readUint8(offset);
234
+ offset += 1;
235
+ offset += 1; // padding
234
236
  orders.push({
235
237
  slot,
236
238
  price,
@@ -256,6 +258,7 @@ function decodeUser(buffer) {
256
258
  immediateOrCancel,
257
259
  triggerCondition,
258
260
  auctionDuration,
261
+ bitFlags,
259
262
  postedSlotTail,
260
263
  });
261
264
  }
@@ -402,7 +402,16 @@ class DLOB {
402
402
  const newTakerOrder = { ...takerOrder };
403
403
  newTakerOrder.baseAssetAmountFilled =
404
404
  takerOrder.baseAssetAmountFilled.add(baseFilled);
405
- this.getListForOnChainOrder(newTakerOrder, slot, takerNode.isProtectedMaker).update(newTakerOrder, takerNode.userAccount);
405
+ if (takerNode.isSignedMsg) {
406
+ const marketTypeStr = (0, __1.getVariant)(marketType);
407
+ const orderList = (0, __1.isVariant)(takerOrder.direction, 'long')
408
+ ? this.orderLists.get(marketTypeStr).get(marketIndex).signedMsg.bid
409
+ : this.orderLists.get(marketTypeStr).get(marketIndex).signedMsg.ask;
410
+ orderList.update(newTakerOrder, takerNode.userAccount);
411
+ }
412
+ else {
413
+ this.getListForOnChainOrder(newTakerOrder, slot, takerNode.isProtectedMaker).update(newTakerOrder, takerNode.userAccount);
414
+ }
406
415
  if (newTakerOrder.baseAssetAmountFilled.eq(takerOrder.baseAssetAmount)) {
407
416
  break;
408
417
  }
@@ -478,7 +487,14 @@ class DLOB {
478
487
  }
479
488
  for (const askGenerator of askGenerators) {
480
489
  for (const ask of askGenerator) {
481
- if ((0, __1.isOrderExpired)(ask.order, ts, true, 25)) {
490
+ if (ask.isSignedMsg &&
491
+ slot.gt(ask.order.slot.addn(ask.order.auctionDuration))) {
492
+ this.orderLists
493
+ .get(marketTypeStr)
494
+ .get(marketIndex)
495
+ .signedMsg.ask.remove(ask.order, ask.userAccount);
496
+ }
497
+ else if ((0, __1.isOrderExpired)(ask.order, ts, true, 25)) {
482
498
  nodesToFill.push({
483
499
  node: ask,
484
500
  makerNodes: [],
@@ -5,7 +5,7 @@
5
5
  import * as anchor from '@coral-xyz/anchor';
6
6
  import { AnchorProvider, BN, Program, ProgramAccount } from '@coral-xyz/anchor';
7
7
  import { Idl as Idl30, Program as Program30 } from '@coral-xyz/anchor-30';
8
- import { DriftClientMetricsEvents, HighLeverageModeConfig, IWallet, MakerInfo, MappedRecord, MarketType, ModifyOrderPolicy, OpenbookV2FulfillmentConfigAccount, OptionalOrderParams, OracleSource, Order, OrderParams, OrderTriggerCondition, PerpMarketAccount, PerpMarketExtendedInfo, PhoenixV1FulfillmentConfigAccount, PlaceAndTakeOrderSuccessCondition, PositionDirection, ReferrerInfo, ReferrerNameAccount, SerumV3FulfillmentConfigAccount, SettlePnlMode, SignedTxData, SpotMarketAccount, SpotPosition, StateAccount, SwapReduceOnly, SignedMsgOrderParamsMessage, TakerInfo, TxParams, UserAccount, UserStatsAccount } from './types';
8
+ import { DriftClientMetricsEvents, HighLeverageModeConfig, IWallet, MakerInfo, MappedRecord, MarketType, ModifyOrderPolicy, OpenbookV2FulfillmentConfigAccount, OptionalOrderParams, OracleSource, Order, OrderParams, OrderTriggerCondition, PerpMarketAccount, PerpMarketExtendedInfo, PhoenixV1FulfillmentConfigAccount, PlaceAndTakeOrderSuccessCondition, PositionDirection, ReferrerInfo, ReferrerNameAccount, SerumV3FulfillmentConfigAccount, SettlePnlMode, SignedTxData, SpotMarketAccount, SpotPosition, StateAccount, SwapReduceOnly, SignedMsgOrderParamsMessage, TakerInfo, TxParams, UserAccount, UserStatsAccount, ProtectedMakerModeConfig } from './types';
9
9
  import { AccountMeta, AddressLookupTableAccount, BlockhashWithExpiryBlockHeight, ConfirmOptions, Connection, Keypair, PublicKey, Signer, Transaction, TransactionInstruction, TransactionSignature, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
10
10
  import { TokenFaucet } from './tokenFaucet';
11
11
  import { EventEmitter } from 'events';
@@ -125,6 +125,7 @@ export declare class DriftClient {
125
125
  /** @deprecated use fetchAllLookupTableAccounts() */
126
126
  fetchMarketLookupTableAccount(): Promise<AddressLookupTableAccount>;
127
127
  fetchAllLookupTableAccounts(): Promise<AddressLookupTableAccount[]>;
128
+ private getTxVersionForNewWallet;
128
129
  /**
129
130
  * Update the wallet to use for drift transactions and linked user account
130
131
  * @param newWallet
@@ -577,25 +578,25 @@ export declare class DriftClient {
577
578
  takerStats: PublicKey;
578
579
  takerUserAccount: UserAccount;
579
580
  signingAuthority: PublicKey;
580
- }, precedingIxs?: TransactionInstruction[], overrideIxCount?: number, txParams?: TxParams): Promise<TransactionSignature>;
581
+ }, precedingIxs?: TransactionInstruction[], overrideCustomIxIndex?: number, txParams?: TxParams): Promise<TransactionSignature>;
581
582
  getPlaceSignedMsgTakerPerpOrderIxs(signedSignedMsgOrderParams: SignedMsgOrderParams, marketIndex: number, takerInfo: {
582
583
  taker: PublicKey;
583
584
  takerStats: PublicKey;
584
585
  takerUserAccount: UserAccount;
585
586
  signingAuthority: PublicKey;
586
- }, precedingIxs?: TransactionInstruction[], overrideIxCount?: number): Promise<TransactionInstruction[]>;
587
+ }, precedingIxs?: TransactionInstruction[], overrideCustomIxIndex?: number): Promise<TransactionInstruction[]>;
587
588
  placeAndMakeSignedMsgPerpOrder(signedSignedMsgOrderParams: SignedMsgOrderParams, signedMsgOrderUuid: Uint8Array, takerInfo: {
588
589
  taker: PublicKey;
589
590
  takerStats: PublicKey;
590
591
  takerUserAccount: UserAccount;
591
592
  signingAuthority: PublicKey;
592
- }, orderParams: OptionalOrderParams, referrerInfo?: ReferrerInfo, txParams?: TxParams, subAccountId?: number, precedingIxs?: TransactionInstruction[], overrideIxCount?: number): Promise<TransactionSignature>;
593
+ }, orderParams: OptionalOrderParams, referrerInfo?: ReferrerInfo, txParams?: TxParams, subAccountId?: number, precedingIxs?: TransactionInstruction[], overrideCustomIxIndex?: number): Promise<TransactionSignature>;
593
594
  getPlaceAndMakeSignedMsgPerpOrderIxs(signedSignedMsgOrderParams: SignedMsgOrderParams, signedMsgOrderUuid: Uint8Array, takerInfo: {
594
595
  taker: PublicKey;
595
596
  takerStats: PublicKey;
596
597
  takerUserAccount: UserAccount;
597
598
  signingAuthority: PublicKey;
598
- }, orderParams: OptionalOrderParams, referrerInfo?: ReferrerInfo, subAccountId?: number, precedingIxs?: TransactionInstruction[], overrideIxCount?: number): Promise<TransactionInstruction[]>;
599
+ }, orderParams: OptionalOrderParams, referrerInfo?: ReferrerInfo, subAccountId?: number, precedingIxs?: TransactionInstruction[], overrideCustomIxIndex?: number): Promise<TransactionInstruction[]>;
599
600
  preparePlaceAndTakeSpotOrder(orderParams: OptionalOrderParams, fulfillmentConfig?: SerumV3FulfillmentConfigAccount, makerInfo?: MakerInfo, referrerInfo?: ReferrerInfo, txParams?: TxParams, subAccountId?: number): Promise<{
600
601
  placeAndTakeSpotOrderTx: anchor.web3.Transaction | anchor.web3.VersionedTransaction;
601
602
  }>;
@@ -902,7 +903,7 @@ export declare class DriftClient {
902
903
  };
903
904
  }, feedId: string, encodedVaaAddress: PublicKey): Promise<TransactionInstruction>;
904
905
  postPythLazerOracleUpdate(feedIds: number[], pythMessageHex: string): Promise<string>;
905
- getPostPythLazerOracleUpdateIxs(feedIds: number[], pythMessageHex: string, precedingIxs?: TransactionInstruction[], overrideIxCount?: number): Promise<TransactionInstruction[]>;
906
+ getPostPythLazerOracleUpdateIxs(feedIds: number[], pythMessageHex: string, precedingIxs?: TransactionInstruction[], overrideCustomIxIndex?: number): Promise<TransactionInstruction[]>;
906
907
  getPostSwitchboardOnDemandUpdateAtomicIx(feed: PublicKey, recentSlothash?: Slothash, numSignatures?: number): Promise<TransactionInstruction | undefined>;
907
908
  postSwitchboardOnDemandUpdate(feed: PublicKey, recentSlothash?: Slothash, numSignatures?: number): Promise<TransactionSignature>;
908
909
  private getBuildEncodedVaaIxs;
@@ -915,6 +916,7 @@ export declare class DriftClient {
915
916
  disableUserHighLeverageMode(user: PublicKey, userAccount?: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
916
917
  getDisableHighLeverageModeIx(user: PublicKey, userAccount?: UserAccount): Promise<TransactionInstruction>;
917
918
  fetchHighLeverageModeConfig(): Promise<HighLeverageModeConfig>;
919
+ fetchProtectedMakerModeConfig(): Promise<ProtectedMakerModeConfig>;
918
920
  updateUserProtectedMakerOrders(subAccountId: number, protectedOrders: boolean, authority?: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
919
921
  getUpdateUserProtectedMakerOrdersIx(subAccountId: number, protectedOrders: boolean, authority?: PublicKey): Promise<TransactionInstruction>;
920
922
  getPauseSpotMarketDepositWithdrawIx(spotMarketIndex: number): Promise<TransactionInstruction>;
@@ -110,7 +110,8 @@ class DriftClient {
110
110
  this.authority = (_e = config.authority) !== null && _e !== void 0 ? _e : this.wallet.publicKey;
111
111
  this.activeSubAccountId = (_f = config.activeSubAccountId) !== null && _f !== void 0 ? _f : 0;
112
112
  this.skipLoadUsers = (_g = config.skipLoadUsers) !== null && _g !== void 0 ? _g : false;
113
- this.txVersion = (_h = config.txVersion) !== null && _h !== void 0 ? _h : 0;
113
+ this.txVersion =
114
+ (_h = config.txVersion) !== null && _h !== void 0 ? _h : this.getTxVersionForNewWallet(config.wallet);
114
115
  this.txParams = {
115
116
  computeUnits: (_k = (_j = config.txParams) === null || _j === void 0 ? void 0 : _j.computeUnits) !== null && _k !== void 0 ? _k : 600000,
116
117
  computeUnitsPrice: (_m = (_l = config.txParams) === null || _l === void 0 ? void 0 : _l.computeUnitsPrice) !== null && _m !== void 0 ? _m : 0,
@@ -395,6 +396,14 @@ class DriftClient {
395
396
  this.lookupTableAccounts = lookupTableAccounts;
396
397
  return lookupTableAccounts;
397
398
  }
399
+ getTxVersionForNewWallet(newWallet) {
400
+ var _a, _b, _c;
401
+ if (!(newWallet === null || newWallet === void 0 ? void 0 : newWallet.supportedTransactionVersions))
402
+ return 0; // Assume versioned txs supported if wallet doesn't have a supportedTransactionVersions property
403
+ const walletSupportsVersionedTxns = ((_a = newWallet.supportedTransactionVersions) === null || _a === void 0 ? void 0 : _a.has(0)) ||
404
+ ((_c = (_b = newWallet.supportedTransactionVersions) === null || _b === void 0 ? void 0 : _b.size) !== null && _c !== void 0 ? _c : 0) > 1;
405
+ return walletSupportsVersionedTxns ? 0 : 'legacy';
406
+ }
398
407
  /**
399
408
  * Update the wallet to use for drift transactions and linked user account
400
409
  * @param newWallet
@@ -403,7 +412,7 @@ class DriftClient {
403
412
  * @param includeDelegates
404
413
  */
405
414
  async updateWallet(newWallet, subAccountIds, activeSubAccountId, includeDelegates, authoritySubaccountMap) {
406
- var _a, _b, _c;
415
+ var _a;
407
416
  const newProvider = new anchor_1.AnchorProvider(this.connection,
408
417
  // @ts-ignore
409
418
  newWallet, this.opts);
@@ -419,10 +428,7 @@ class DriftClient {
419
428
  this.activeSubAccountId = activeSubAccountId;
420
429
  this.userStatsAccountPublicKey = undefined;
421
430
  this.includeDelegates = includeDelegates !== null && includeDelegates !== void 0 ? includeDelegates : false;
422
- const walletSupportsVersionedTxns =
423
- //@ts-ignore
424
- (_b = (_a = this.wallet.supportedTransactionVersions) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0 > 1;
425
- this.txVersion = walletSupportsVersionedTxns ? 0 : 'legacy';
431
+ this.txVersion = this.getTxVersionForNewWallet(this.wallet);
426
432
  if (includeDelegates && subAccountIds) {
427
433
  throw new Error('Can only pass one of includeDelegates or subAccountIds. If you want to specify subaccount ids for multiple authorities, pass authoritySubaccountMap instead');
428
434
  }
@@ -438,7 +444,7 @@ class DriftClient {
438
444
  ? new Map([[this.authority.toString(), subAccountIds]])
439
445
  : new Map();
440
446
  /* Reset user stats account */
441
- if ((_c = this.userStats) === null || _c === void 0 ? void 0 : _c.isSubscribed) {
447
+ if ((_a = this.userStats) === null || _a === void 0 ? void 0 : _a.isSubscribed) {
442
448
  await this.userStats.unsubscribe();
443
449
  }
444
450
  this.userStats = undefined;
@@ -467,19 +473,16 @@ class DriftClient {
467
473
  * @param emulateAuthority
468
474
  */
469
475
  async emulateAccount(emulateAuthority) {
470
- var _a, _b, _c;
476
+ var _a;
471
477
  this.skipLoadUsers = false;
472
478
  // Update provider for txSender with new wallet details
473
479
  this.authority = emulateAuthority;
474
480
  this.userStatsAccountPublicKey = undefined;
475
481
  this.includeDelegates = true;
476
- const walletSupportsVersionedTxns =
477
- //@ts-ignore
478
- (_b = (_a = this.wallet.supportedTransactionVersions) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0 > 1;
479
- this.txVersion = walletSupportsVersionedTxns ? 0 : 'legacy';
482
+ this.txVersion = this.getTxVersionForNewWallet(this.wallet);
480
483
  this.authoritySubAccountMap = new Map();
481
484
  /* Reset user stats account */
482
- if ((_c = this.userStats) === null || _c === void 0 ? void 0 : _c.isSubscribed) {
485
+ if ((_a = this.userStats) === null || _a === void 0 ? void 0 : _a.isSubscribed) {
483
486
  await this.userStats.unsubscribe();
484
487
  }
485
488
  this.userStats = undefined;
@@ -3322,12 +3325,12 @@ class DriftClient {
3322
3325
  signMessage(message, keypair = this.wallet.payer) {
3323
3326
  return Buffer.from(tweetnacl_1.default.sign.detached(message, keypair.secretKey));
3324
3327
  }
3325
- async placeSignedMsgTakerOrder(signedSignedMsgOrderParams, marketIndex, takerInfo, precedingIxs = [], overrideIxCount, txParams) {
3326
- const ixs = await this.getPlaceSignedMsgTakerPerpOrderIxs(signedSignedMsgOrderParams, marketIndex, takerInfo, precedingIxs, overrideIxCount);
3328
+ async placeSignedMsgTakerOrder(signedSignedMsgOrderParams, marketIndex, takerInfo, precedingIxs = [], overrideCustomIxIndex, txParams) {
3329
+ const ixs = await this.getPlaceSignedMsgTakerPerpOrderIxs(signedSignedMsgOrderParams, marketIndex, takerInfo, precedingIxs, overrideCustomIxIndex);
3327
3330
  const { txSig } = await this.sendTransaction(await this.buildTransaction(ixs, txParams), [], this.opts);
3328
3331
  return txSig;
3329
3332
  }
3330
- async getPlaceSignedMsgTakerPerpOrderIxs(signedSignedMsgOrderParams, marketIndex, takerInfo, precedingIxs = [], overrideIxCount) {
3333
+ async getPlaceSignedMsgTakerPerpOrderIxs(signedSignedMsgOrderParams, marketIndex, takerInfo, precedingIxs = [], overrideCustomIxIndex) {
3331
3334
  const remainingAccounts = this.getRemainingAccounts({
3332
3335
  userAccounts: [takerInfo.takerUserAccount],
3333
3336
  useMarketLastSlotCache: true,
@@ -3341,7 +3344,7 @@ class DriftClient {
3341
3344
  messageLengthBuffer,
3342
3345
  signedSignedMsgOrderParams.orderParams,
3343
3346
  ]);
3344
- const signedMsgOrderParamsSignatureIx = (0, ed25519Utils_1.createMinimalEd25519VerifyIx)(overrideIxCount || precedingIxs.length + 1, 12, signedMsgIxData, 0);
3347
+ const signedMsgOrderParamsSignatureIx = (0, ed25519Utils_1.createMinimalEd25519VerifyIx)(overrideCustomIxIndex || precedingIxs.length + 1, 12, signedMsgIxData, 0);
3345
3348
  const isDelegateSigner = takerInfo.signingAuthority.equals(takerInfo.takerUserAccount.delegate);
3346
3349
  const placeTakerSignedMsgPerpOrderIx = this.program.instruction.placeSignedMsgTakerOrder(signedMsgIxData, isDelegateSigner, {
3347
3350
  accounts: {
@@ -3356,14 +3359,14 @@ class DriftClient {
3356
3359
  });
3357
3360
  return [signedMsgOrderParamsSignatureIx, placeTakerSignedMsgPerpOrderIx];
3358
3361
  }
3359
- async placeAndMakeSignedMsgPerpOrder(signedSignedMsgOrderParams, signedMsgOrderUuid, takerInfo, orderParams, referrerInfo, txParams, subAccountId, precedingIxs = [], overrideIxCount) {
3360
- const ixs = await this.getPlaceAndMakeSignedMsgPerpOrderIxs(signedSignedMsgOrderParams, signedMsgOrderUuid, takerInfo, orderParams, referrerInfo, subAccountId, precedingIxs, overrideIxCount);
3362
+ async placeAndMakeSignedMsgPerpOrder(signedSignedMsgOrderParams, signedMsgOrderUuid, takerInfo, orderParams, referrerInfo, txParams, subAccountId, precedingIxs = [], overrideCustomIxIndex) {
3363
+ const ixs = await this.getPlaceAndMakeSignedMsgPerpOrderIxs(signedSignedMsgOrderParams, signedMsgOrderUuid, takerInfo, orderParams, referrerInfo, subAccountId, precedingIxs, overrideCustomIxIndex);
3361
3364
  const { txSig, slot } = await this.sendTransaction(await this.buildTransaction(ixs, txParams), [], this.opts);
3362
3365
  this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
3363
3366
  return txSig;
3364
3367
  }
3365
- async getPlaceAndMakeSignedMsgPerpOrderIxs(signedSignedMsgOrderParams, signedMsgOrderUuid, takerInfo, orderParams, referrerInfo, subAccountId, precedingIxs = [], overrideIxCount) {
3366
- const [signedMsgOrderSignatureIx, placeTakerSignedMsgPerpOrderIx] = await this.getPlaceSignedMsgTakerPerpOrderIxs(signedSignedMsgOrderParams, orderParams.marketIndex, takerInfo, precedingIxs, overrideIxCount);
3368
+ async getPlaceAndMakeSignedMsgPerpOrderIxs(signedSignedMsgOrderParams, signedMsgOrderUuid, takerInfo, orderParams, referrerInfo, subAccountId, precedingIxs = [], overrideCustomIxIndex) {
3369
+ const [signedMsgOrderSignatureIx, placeTakerSignedMsgPerpOrderIx] = await this.getPlaceSignedMsgTakerPerpOrderIxs(signedSignedMsgOrderParams, orderParams.marketIndex, takerInfo, precedingIxs, overrideCustomIxIndex);
3367
3370
  orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
3368
3371
  const userStatsPublicKey = this.getUserStatsAccountPublicKey();
3369
3372
  const user = await this.getUserAccountPublicKey(subAccountId);
@@ -4744,9 +4747,9 @@ class DriftClient {
4744
4747
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
4745
4748
  return txSig;
4746
4749
  }
4747
- async getPostPythLazerOracleUpdateIxs(feedIds, pythMessageHex, precedingIxs = [], overrideIxCount) {
4750
+ async getPostPythLazerOracleUpdateIxs(feedIds, pythMessageHex, precedingIxs = [], overrideCustomIxIndex) {
4748
4751
  const pythMessageBytes = Buffer.from(pythMessageHex, 'hex');
4749
- const verifyIx = (0, ed25519Utils_1.createMinimalEd25519VerifyIx)(overrideIxCount || precedingIxs.length + 1, 12, pythMessageBytes);
4752
+ const verifyIx = (0, ed25519Utils_1.createMinimalEd25519VerifyIx)(overrideCustomIxIndex || precedingIxs.length + 1, 12, pythMessageBytes);
4750
4753
  const remainingAccountsMeta = feedIds.map((feedId) => {
4751
4754
  return {
4752
4755
  pubkey: (0, pda_1.getPythLazerOraclePublicKey)(this.program.programId, feedId),
@@ -4898,6 +4901,10 @@ class DriftClient {
4898
4901
  const config = await this.program.account.highLeverageModeConfig.fetch((0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId));
4899
4902
  return config;
4900
4903
  }
4904
+ async fetchProtectedMakerModeConfig() {
4905
+ const config = await this.program.account.protectedMakerModeConfig.fetch((0, pda_1.getProtectedMakerModeConfigPublicKey)(this.program.programId));
4906
+ return config;
4907
+ }
4901
4908
  async updateUserProtectedMakerOrders(subAccountId, protectedOrders, authority, txParams) {
4902
4909
  const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders, authority), txParams), [], this.opts);
4903
4910
  return txSig;
@@ -6,6 +6,11 @@ export type FastlaneOrderSubscriberConfig = {
6
6
  driftEnv: DriftEnv;
7
7
  endpoint?: string;
8
8
  marketIndexes: number[];
9
+ /**
10
+ In the future, this will be used for verifying $DRIFT stake as we add
11
+ authentication for delegate signers
12
+ For now, pass a new keypair or a keypair to an empty wallet
13
+ */
9
14
  keypair: Keypair;
10
15
  };
11
16
  export declare class FastlaneOrderSubscriber {
@@ -0,0 +1,22 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { Commitment } from '@solana/web3.js';
4
+ import { grpcProgramAccountSubscriber } from '../accounts/grpcProgramAccountSubscriber';
5
+ import { GrpcConfigs, ResubOpts } from '../accounts/types';
6
+ import { SignedMsgUserOrdersAccount } from '../types';
7
+ import { SignedMsgUserOrdersAccountSubscriber } from './signedMsgUserAccountSubscriber';
8
+ import { DriftClient } from '../driftClient';
9
+ export declare class grpcSignedMsgUserOrdersAccountSubscriber extends SignedMsgUserOrdersAccountSubscriber {
10
+ private grpcConfigs;
11
+ subscriber: grpcProgramAccountSubscriber<SignedMsgUserOrdersAccount>;
12
+ constructor({ grpcConfigs, driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }: {
13
+ grpcConfigs: GrpcConfigs;
14
+ driftClient: DriftClient;
15
+ commitment: Commitment;
16
+ resubOpts?: ResubOpts;
17
+ decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
18
+ resyncIntervalMs?: number;
19
+ });
20
+ subscribe(): Promise<void>;
21
+ unsubscribe(): Promise<void>;
22
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.grpcSignedMsgUserOrdersAccountSubscriber = void 0;
4
+ const grpcProgramAccountSubscriber_1 = require("../accounts/grpcProgramAccountSubscriber");
5
+ const memcmp_1 = require("../memcmp");
6
+ const signedMsgUserAccountSubscriber_1 = require("./signedMsgUserAccountSubscriber");
7
+ class grpcSignedMsgUserOrdersAccountSubscriber extends signedMsgUserAccountSubscriber_1.SignedMsgUserOrdersAccountSubscriber {
8
+ constructor({ grpcConfigs, driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }) {
9
+ super({
10
+ driftClient,
11
+ commitment,
12
+ resubOpts,
13
+ decodeFn,
14
+ resyncIntervalMs,
15
+ });
16
+ this.grpcConfigs = grpcConfigs;
17
+ }
18
+ async subscribe() {
19
+ if (!this.subscriber) {
20
+ this.subscriber =
21
+ await grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber.create(this.grpcConfigs, 'OrderSubscriber', 'User', this.driftClient.program, this.decodeFn, {
22
+ filters: [(0, memcmp_1.getSignedMsgUserOrdersFilter)()],
23
+ }, this.resubOpts);
24
+ }
25
+ await this.subscriber.subscribe((_accountId, account, context) => {
26
+ this.tryUpdateSignedMsgUserOrdersAccount(account, 'decoded', context.slot);
27
+ });
28
+ if (this.resyncIntervalMs) {
29
+ const recursiveResync = () => {
30
+ this.resyncTimeoutId = setTimeout(() => {
31
+ this.fetch()
32
+ .catch((e) => {
33
+ console.error('Failed to resync in OrderSubscriber');
34
+ console.log(e);
35
+ })
36
+ .finally(() => {
37
+ if (!this.resyncTimeoutId)
38
+ return;
39
+ recursiveResync();
40
+ });
41
+ }, this.resyncIntervalMs);
42
+ };
43
+ recursiveResync();
44
+ }
45
+ }
46
+ async unsubscribe() {
47
+ if (!this.subscriber)
48
+ return;
49
+ await this.subscriber.unsubscribe();
50
+ this.subscriber = undefined;
51
+ if (this.resyncTimeoutId !== undefined) {
52
+ clearTimeout(this.resyncTimeoutId);
53
+ this.resyncTimeoutId = undefined;
54
+ }
55
+ }
56
+ }
57
+ exports.grpcSignedMsgUserOrdersAccountSubscriber = grpcSignedMsgUserOrdersAccountSubscriber;
@@ -0,0 +1,3 @@
1
+ export * from './fastlaneOrderSubscriber';
2
+ export * from './signedMsgUserAccountSubscriber';
3
+ export * from './grpcSignedMsgUserAccountSubscriber';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./fastlaneOrderSubscriber"), exports);
18
+ __exportStar(require("./signedMsgUserAccountSubscriber"), exports);
19
+ __exportStar(require("./grpcSignedMsgUserAccountSubscriber"), exports);
@@ -0,0 +1,43 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ import { WebSocketProgramAccountSubscriber } from '../accounts/webSocketProgramAccountSubscriber';
6
+ import { SignedMsgOrderId, SignedMsgUserOrdersAccount } from '../types';
7
+ import { Commitment, PublicKey } from '@solana/web3.js';
8
+ import { ResubOpts } from '../accounts/types';
9
+ import { DriftClient } from '../driftClient';
10
+ import StrictEventEmitter from 'strict-event-emitter-types';
11
+ import { EventEmitter } from 'events';
12
+ export interface SignedMsgUserOrdersAccountSubscriberEvents {
13
+ onAccountUpdate: (activeSignedMsgOrderIds: SignedMsgOrderId[], authorityPubkey: PublicKey, slot: number) => void;
14
+ newSignedMsgOrderIds: (newSignedMsgOrderIds: SignedMsgOrderId[], authorityPubkey: PublicKey, slot: number) => void;
15
+ }
16
+ export declare class SignedMsgUserOrdersAccountSubscriber {
17
+ protected driftClient: DriftClient;
18
+ protected commitment: Commitment;
19
+ protected resubOpts?: ResubOpts;
20
+ protected resyncTimeoutId?: NodeJS.Timeout;
21
+ protected resyncIntervalMs?: number;
22
+ protected decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
23
+ protected signedMsgUserOrderAccounts: Map<string, {
24
+ slot: number;
25
+ signedMsgUserOrdersAccount: SignedMsgUserOrdersAccount;
26
+ }>;
27
+ mostRecentSlot: number;
28
+ fetchPromise?: Promise<void>;
29
+ fetchPromiseResolver: () => void;
30
+ protected subscriber: WebSocketProgramAccountSubscriber<SignedMsgUserOrdersAccount>;
31
+ eventEmitter: StrictEventEmitter<EventEmitter, SignedMsgUserOrdersAccountSubscriberEvents>;
32
+ constructor({ driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }: {
33
+ driftClient: DriftClient;
34
+ commitment: Commitment;
35
+ resubOpts?: ResubOpts;
36
+ decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
37
+ resyncIntervalMs?: number;
38
+ });
39
+ subscribe(): Promise<void>;
40
+ fetch(): Promise<void>;
41
+ tryUpdateSignedMsgUserOrdersAccount(data: Buffer | SignedMsgUserOrdersAccount, dataType: 'buffer' | 'decoded', slot: number, skipEventEmitting?: boolean): void;
42
+ unsubscribe(): Promise<void>;
43
+ }
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SignedMsgUserOrdersAccountSubscriber = void 0;
4
+ const memcmp_1 = require("../memcmp");
5
+ const webSocketProgramAccountSubscriber_1 = require("../accounts/webSocketProgramAccountSubscriber");
6
+ const events_1 = require("events");
7
+ class SignedMsgUserOrdersAccountSubscriber {
8
+ constructor({ driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }) {
9
+ this.signedMsgUserOrderAccounts = new Map();
10
+ this.commitment = commitment;
11
+ this.resubOpts = resubOpts;
12
+ this.decodeFn = decodeFn;
13
+ this.driftClient = driftClient;
14
+ this.resyncIntervalMs = resyncIntervalMs;
15
+ this.eventEmitter = new events_1.EventEmitter();
16
+ this.resubOpts = resubOpts;
17
+ }
18
+ async subscribe() {
19
+ if (!this.subscriber) {
20
+ const filters = [(0, memcmp_1.getSignedMsgUserOrdersFilter)()];
21
+ this.subscriber =
22
+ new webSocketProgramAccountSubscriber_1.WebSocketProgramAccountSubscriber('SingedMsgUserOrdersAccountMap', 'SignedMsgUserOrders', this.driftClient.program, this.decodeFn, {
23
+ filters,
24
+ commitment: this.commitment,
25
+ }, this.resubOpts);
26
+ }
27
+ await this.subscriber.subscribe((_accountId, account, context) => {
28
+ this.tryUpdateSignedMsgUserOrdersAccount(account, 'decoded', context.slot);
29
+ });
30
+ await this.fetch();
31
+ if (this.resyncIntervalMs) {
32
+ const recursiveResync = () => {
33
+ this.resyncTimeoutId = setTimeout(() => {
34
+ this.fetch()
35
+ .catch((e) => {
36
+ console.error('Failed to resync in OrderSubscriber');
37
+ console.log(e);
38
+ })
39
+ .finally(() => {
40
+ if (!this.resyncTimeoutId)
41
+ return;
42
+ recursiveResync();
43
+ });
44
+ }, this.resyncIntervalMs);
45
+ };
46
+ recursiveResync();
47
+ }
48
+ }
49
+ async fetch() {
50
+ if (this.fetchPromise) {
51
+ return this.fetchPromise;
52
+ }
53
+ this.fetchPromise = new Promise((resolver) => {
54
+ this.fetchPromiseResolver = resolver;
55
+ });
56
+ const skipEventEmitting = this.signedMsgUserOrderAccounts.size === 0;
57
+ try {
58
+ const rpcResponseAndContext = await this.driftClient.connection.getProgramAccounts(this.driftClient.program.programId, {
59
+ commitment: this.commitment,
60
+ filters: [(0, memcmp_1.getSignedMsgUserOrdersFilter)()],
61
+ encoding: 'base64',
62
+ withContext: true,
63
+ });
64
+ const slot = rpcResponseAndContext.context.slot;
65
+ for (const programAccount of rpcResponseAndContext.value) {
66
+ this.tryUpdateSignedMsgUserOrdersAccount(programAccount.account.data, 'buffer', slot, skipEventEmitting);
67
+ await new Promise((resolve) => setTimeout(resolve, 0));
68
+ }
69
+ }
70
+ catch (e) {
71
+ console.error(e);
72
+ }
73
+ finally {
74
+ this.fetchPromiseResolver();
75
+ this.fetchPromise = undefined;
76
+ }
77
+ }
78
+ tryUpdateSignedMsgUserOrdersAccount(data, dataType, slot, skipEventEmitting = false) {
79
+ var _a;
80
+ if (!this.mostRecentSlot || slot > this.mostRecentSlot) {
81
+ this.mostRecentSlot = slot;
82
+ }
83
+ const signedMsgUserOrdersAccount = dataType === 'buffer'
84
+ ? this.decodeFn('SignedMsgUserOrders', data)
85
+ : data;
86
+ const key = signedMsgUserOrdersAccount.authorityPubkey.toBase58();
87
+ const slotAndSignedMsgUserOrdersAccount = this.signedMsgUserOrderAccounts.get(key);
88
+ if (!slotAndSignedMsgUserOrdersAccount ||
89
+ slotAndSignedMsgUserOrdersAccount.slot <= slot) {
90
+ if (!skipEventEmitting) {
91
+ this.eventEmitter.emit('onAccountUpdate', signedMsgUserOrdersAccount.signedMsgOrderData.filter((signedMsgOrderId) => signedMsgOrderId.orderId !== 0), signedMsgUserOrdersAccount.authorityPubkey, slot);
92
+ }
93
+ const existingSignedMsgOrderIds = (_a = slotAndSignedMsgUserOrdersAccount === null || slotAndSignedMsgUserOrdersAccount === void 0 ? void 0 : slotAndSignedMsgUserOrdersAccount.signedMsgUserOrdersAccount.signedMsgOrderData.map((signedMsgOrderId) => signedMsgOrderId.orderId)) !== null && _a !== void 0 ? _a : [];
94
+ const newSignedMsgOrderIds = signedMsgUserOrdersAccount.signedMsgOrderData.filter((signedMsgOrderId) => !existingSignedMsgOrderIds.includes(signedMsgOrderId.orderId) &&
95
+ signedMsgOrderId.orderId !== 0);
96
+ if (newSignedMsgOrderIds.length > 0 && !skipEventEmitting) {
97
+ this.eventEmitter.emit('newSignedMsgOrderIds', newSignedMsgOrderIds, signedMsgUserOrdersAccount.authorityPubkey, slot);
98
+ }
99
+ this.signedMsgUserOrderAccounts.set(key, {
100
+ slot,
101
+ signedMsgUserOrdersAccount,
102
+ });
103
+ }
104
+ }
105
+ async unsubscribe() {
106
+ if (!this.subscriber)
107
+ return;
108
+ await this.subscriber.unsubscribe();
109
+ this.subscriber = undefined;
110
+ if (this.resyncTimeoutId !== undefined) {
111
+ clearTimeout(this.resyncTimeoutId);
112
+ this.resyncTimeoutId = undefined;
113
+ }
114
+ }
115
+ }
116
+ exports.SignedMsgUserOrdersAccountSubscriber = SignedMsgUserOrdersAccountSubscriber;
@@ -10912,12 +10912,20 @@
10912
10912
  ],
10913
10913
  "type": "u8"
10914
10914
  },
10915
+ {
10916
+ "name": "bitFlags",
10917
+ "docs": [
10918
+ "Bitflags for further classification",
10919
+ "0: is_signed_message"
10920
+ ],
10921
+ "type": "u8"
10922
+ },
10915
10923
  {
10916
10924
  "name": "padding",
10917
10925
  "type": {
10918
10926
  "array": [
10919
10927
  "u8",
10920
- 2
10928
+ 1
10921
10929
  ]
10922
10930
  }
10923
10931
  }
@@ -88,6 +88,7 @@ export * from './oracles/pythLazerClient';
88
88
  export * from './oracles/switchboardOnDemandClient';
89
89
  export * from './oracles/oracleId';
90
90
  export * from './fastlane/fastlaneOrderSubscriber';
91
+ export * from './fastlane/signedMsgUserAccountSubscriber';
91
92
  export * from './tx/fastSingleTxSender';
92
93
  export * from './tx/retryTxSender';
93
94
  export * from './tx/whileValidTxSender';
@@ -111,6 +111,7 @@ __exportStar(require("./oracles/pythLazerClient"), exports);
111
111
  __exportStar(require("./oracles/switchboardOnDemandClient"), exports);
112
112
  __exportStar(require("./oracles/oracleId"), exports);
113
113
  __exportStar(require("./fastlane/fastlaneOrderSubscriber"), exports);
114
+ __exportStar(require("./fastlane/signedMsgUserAccountSubscriber"), exports);
114
115
  __exportStar(require("./tx/fastSingleTxSender"), exports);
115
116
  __exportStar(require("./tx/retryTxSender"), exports);
116
117
  __exportStar(require("./tx/whileValidTxSender"), exports);
@@ -21,3 +21,4 @@ export declare function mustBeTriggered(order: Order): boolean;
21
21
  export declare function isTriggered(order: Order): boolean;
22
22
  export declare function isRestingLimitOrder(order: Order, slot: number): boolean;
23
23
  export declare function isTakingOrder(order: Order, slot: number): boolean;
24
+ export declare function isSignedMsgOrder(order: Order): boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isTakingOrder = exports.isRestingLimitOrder = exports.isTriggered = exports.mustBeTriggered = exports.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasAuctionPrice = exports.hasLimitPrice = exports.getLimitPrice = exports.standardizePrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
3
+ exports.isSignedMsgOrder = exports.isTakingOrder = exports.isRestingLimitOrder = exports.isTriggered = exports.mustBeTriggered = exports.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasAuctionPrice = exports.hasLimitPrice = exports.getLimitPrice = exports.standardizePrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
4
4
  const types_1 = require("../types");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
6
  const anchor_1 = require("@coral-xyz/anchor");
@@ -223,3 +223,8 @@ function isTakingOrder(order, slot) {
223
223
  return isMarketOrder(order) || !isRestingLimitOrder(order, slot);
224
224
  }
225
225
  exports.isTakingOrder = isTakingOrder;
226
+ const FLAG_IS_SIGNED_MSG = 0x01;
227
+ function isSignedMsgOrder(order) {
228
+ return (order.bitFlags & FLAG_IS_SIGNED_MSG) !== 0;
229
+ }
230
+ exports.isSignedMsgOrder = isSignedMsgOrder;
@@ -9,3 +9,4 @@ export declare function getUserWithName(name: string): MemcmpFilter;
9
9
  export declare function getUserStatsFilter(): MemcmpFilter;
10
10
  export declare function getUserStatsIsReferredFilter(): MemcmpFilter;
11
11
  export declare function getUserStatsIsReferredOrReferrerFilter(): MemcmpFilter;
12
+ export declare function getSignedMsgUserOrdersFilter(): MemcmpFilter;