@drift-labs/sdk 2.112.0-beta.1 → 2.112.0-beta.11

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 +3 -1
  5. package/lib/browser/driftClient.js +20 -13
  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 +3 -1
  24. package/lib/node/driftClient.js +20 -13
  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 +22 -9
  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.1
1
+ 2.112.0-beta.11
@@ -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
@@ -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;
@@ -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;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getUserStatsIsReferredOrReferrerFilter = exports.getUserStatsIsReferredFilter = exports.getUserStatsFilter = exports.getUserWithName = exports.getUserThatHasBeenLP = exports.getUserWithAuctionFilter = exports.getUserWithoutOrderFilter = exports.getUserWithOrderFilter = exports.getNonIdleUserFilter = exports.getUserFilter = void 0;
6
+ exports.getSignedMsgUserOrdersFilter = exports.getUserStatsIsReferredOrReferrerFilter = exports.getUserStatsIsReferredFilter = exports.getUserStatsFilter = exports.getUserWithName = exports.getUserThatHasBeenLP = exports.getUserWithAuctionFilter = exports.getUserWithoutOrderFilter = exports.getUserWithOrderFilter = exports.getNonIdleUserFilter = exports.getUserFilter = void 0;
7
7
  const bs58_1 = __importDefault(require("bs58"));
8
8
  const anchor_1 = require("@coral-xyz/anchor");
9
9
  const userName_1 = require("./userName");
@@ -97,3 +97,12 @@ function getUserStatsIsReferredOrReferrerFilter() {
97
97
  };
98
98
  }
99
99
  exports.getUserStatsIsReferredOrReferrerFilter = getUserStatsIsReferredOrReferrerFilter;
100
+ function getSignedMsgUserOrdersFilter() {
101
+ return {
102
+ memcmp: {
103
+ offset: 0,
104
+ bytes: bs58_1.default.encode(anchor_1.BorshAccountsCoder.accountDiscriminator('SignedMsgUserOrders')),
105
+ },
106
+ };
107
+ }
108
+ exports.getSignedMsgUserOrdersFilter = getSignedMsgUserOrdersFilter;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="bn.js" />
2
2
  /// <reference types="node" />
3
3
  /// <reference types="node" />
4
- import { Keypair, PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js';
4
+ import { Keypair, PublicKey, Transaction, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
5
5
  import { BN } from '.';
6
6
  export type MappedRecord<A extends Record<string, unknown>, B> = {
7
7
  [K in keyof A]: B;
@@ -1142,6 +1142,7 @@ export type Order = {
1142
1142
  auctionStartPrice: BN;
1143
1143
  auctionEndPrice: BN;
1144
1144
  maxTs: BN;
1145
+ bitFlags: number;
1145
1146
  postedSlotTail: number;
1146
1147
  };
1147
1148
  export type OrderParams = {
@@ -1261,6 +1262,7 @@ export interface IWallet {
1261
1262
  signAllTransactions(txs: Transaction[]): Promise<Transaction[]>;
1262
1263
  publicKey: PublicKey;
1263
1264
  payer?: Keypair;
1265
+ supportedTransactionVersions?: ReadonlySet<TransactionVersion> | null | undefined;
1264
1266
  }
1265
1267
  export interface IVersionedWallet {
1266
1268
  signVersionedTransaction(tx: VersionedTransaction): Promise<VersionedTransaction>;
@@ -1417,6 +1419,11 @@ export type HighLeverageModeConfig = {
1417
1419
  currentUsers: number;
1418
1420
  reduceOnly: boolean;
1419
1421
  };
1422
+ export type ProtectedMakerModeConfig = {
1423
+ maxUsers: number;
1424
+ currentUsers: number;
1425
+ reduceOnly: boolean;
1426
+ };
1420
1427
  export interface SignedMsgOrderParams {
1421
1428
  /**
1422
1429
  * The encoded order params that were signed (borsh encoded then hexified).
@@ -1427,4 +1434,13 @@ export interface SignedMsgOrderParams {
1427
1434
  */
1428
1435
  signature: Buffer;
1429
1436
  }
1437
+ export type SignedMsgOrderId = {
1438
+ maxSlot: BN;
1439
+ uuid: Uint8Array;
1440
+ orderId: number;
1441
+ };
1442
+ export type SignedMsgUserOrdersAccount = {
1443
+ authorityPubkey: PublicKey;
1444
+ signedMsgOrderData: SignedMsgOrderId[];
1445
+ };
1430
1446
  export {};
@@ -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
  }