@drift-labs/sdk 2.109.0-beta.1 → 2.109.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 (80) hide show
  1. package/VERSION +1 -1
  2. package/lib/browser/accounts/grpcAccountSubscriber.d.ts +5 -5
  3. package/lib/browser/accounts/grpcAccountSubscriber.js +11 -6
  4. package/lib/browser/accounts/grpcDriftClientAccountSubscriber.js +5 -4
  5. package/lib/browser/accounts/grpcInsuranceFundStakeAccountSubscriber.js +4 -3
  6. package/lib/browser/accounts/grpcProgramAccountSubscriber.d.ts +6 -6
  7. package/lib/browser/accounts/grpcProgramAccountSubscriber.js +13 -6
  8. package/lib/browser/accounts/grpcUserAccountSubscriber.js +1 -1
  9. package/lib/browser/accounts/grpcUserStatsAccountSubscriber.js +1 -1
  10. package/lib/browser/auctionSubscriber/auctionSubscriberGrpc.js +1 -1
  11. package/lib/browser/constants/perpMarkets.js +11 -0
  12. package/lib/browser/decode/user.js +3 -1
  13. package/lib/browser/dlob/DLOB.js +2 -6
  14. package/lib/browser/driftClient.d.ts +2 -2
  15. package/lib/browser/driftClient.js +4 -4
  16. package/lib/browser/factory/oracleClient.js +3 -0
  17. package/lib/browser/idl/drift.json +11 -1
  18. package/lib/browser/oracles/oracleId.js +2 -0
  19. package/lib/browser/orderSubscriber/grpcSubscription.js +1 -1
  20. package/lib/browser/tx/baseTxSender.js +1 -1
  21. package/lib/browser/types.d.ts +7 -2
  22. package/lib/browser/types.js +4 -2
  23. package/lib/browser/userMap/grpcSubscription.js +1 -1
  24. package/lib/browser/userMap/userMap.d.ts +10 -0
  25. package/lib/browser/userMap/userMap.js +10 -0
  26. package/lib/browser/userMap/userStatsMap.d.ts +17 -2
  27. package/lib/browser/userMap/userStatsMap.js +108 -1
  28. package/lib/node/accounts/grpcAccountSubscriber.d.ts +5 -5
  29. package/lib/node/accounts/grpcAccountSubscriber.js +11 -6
  30. package/lib/node/accounts/grpcDriftClientAccountSubscriber.js +5 -4
  31. package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.js +4 -3
  32. package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts +6 -6
  33. package/lib/node/accounts/grpcProgramAccountSubscriber.js +13 -6
  34. package/lib/node/accounts/grpcUserAccountSubscriber.js +1 -1
  35. package/lib/node/accounts/grpcUserStatsAccountSubscriber.js +1 -1
  36. package/lib/node/auctionSubscriber/auctionSubscriberGrpc.js +1 -1
  37. package/lib/node/constants/perpMarkets.js +11 -0
  38. package/lib/node/decode/user.js +3 -1
  39. package/lib/node/dlob/DLOB.js +2 -6
  40. package/lib/node/driftClient.d.ts +2 -2
  41. package/lib/node/driftClient.js +4 -4
  42. package/lib/node/factory/oracleClient.js +3 -0
  43. package/lib/node/idl/drift.json +11 -1
  44. package/lib/node/isomorphic/grpc.d.ts +3 -3
  45. package/lib/node/isomorphic/grpc.js +26 -11
  46. package/lib/node/isomorphic/grpc.node.d.ts +3 -3
  47. package/lib/node/isomorphic/grpc.node.js +26 -11
  48. package/lib/node/oracles/oracleId.js +2 -0
  49. package/lib/node/orderSubscriber/grpcSubscription.js +1 -1
  50. package/lib/node/tx/baseTxSender.js +1 -1
  51. package/lib/node/types.d.ts +7 -2
  52. package/lib/node/types.js +4 -2
  53. package/lib/node/userMap/grpcSubscription.js +1 -1
  54. package/lib/node/userMap/userMap.d.ts +10 -0
  55. package/lib/node/userMap/userMap.js +10 -0
  56. package/lib/node/userMap/userStatsMap.d.ts +17 -2
  57. package/lib/node/userMap/userStatsMap.js +108 -1
  58. package/package.json +1 -1
  59. package/src/accounts/grpcAccountSubscriber.ts +31 -8
  60. package/src/accounts/grpcDriftClientAccountSubscriber.ts +38 -34
  61. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +11 -10
  62. package/src/accounts/grpcProgramAccountSubscriber.ts +35 -8
  63. package/src/accounts/grpcUserAccountSubscriber.ts +1 -1
  64. package/src/accounts/grpcUserStatsAccountSubscriber.ts +1 -1
  65. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +1 -1
  66. package/src/constants/perpMarkets.ts +12 -0
  67. package/src/decode/user.ts +3 -1
  68. package/src/dlob/DLOB.ts +2 -6
  69. package/src/driftClient.ts +6 -3
  70. package/src/factory/oracleClient.ts +4 -0
  71. package/src/idl/drift.json +11 -1
  72. package/src/isomorphic/grpc.node.ts +6 -5
  73. package/src/oracles/oracleId.ts +2 -0
  74. package/src/orderSubscriber/grpcSubscription.ts +1 -1
  75. package/src/tx/baseTxSender.ts +1 -1
  76. package/src/types.ts +5 -2
  77. package/src/userMap/grpcSubscription.ts +1 -1
  78. package/src/userMap/userMap.ts +10 -0
  79. package/src/userMap/userStatsMap.ts +148 -1
  80. package/tests/user/helpers.ts +1 -0
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.109.0-beta.1
1
+ 2.109.0-beta.11
@@ -4,13 +4,13 @@ import { ResubOpts, GrpcConfigs } from './types';
4
4
  import { Program } from '@coral-xyz/anchor';
5
5
  import { PublicKey } from '@solana/web3.js';
6
6
  import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
7
- import { Client, ClientDuplexStream, CommitmentLevel, SubscribeRequest, SubscribeUpdate } from '../isomorphic/grpc';
8
7
  export declare class grpcAccountSubscriber<T> extends WebSocketAccountSubscriber<T> {
9
- client: Client;
10
- stream: ClientDuplexStream<SubscribeRequest, SubscribeUpdate>;
11
- commitmentLevel: CommitmentLevel;
8
+ private client;
9
+ private stream;
10
+ private commitmentLevel;
12
11
  listenerId?: number;
13
- constructor(grpcConfigs: GrpcConfigs, accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => T, resubOpts?: ResubOpts);
12
+ private constructor();
13
+ static create<U>(grpcConfigs: GrpcConfigs, accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => U, resubOpts?: ResubOpts): Promise<grpcAccountSubscriber<U>>;
14
14
  subscribe(onChange: (data: T) => void): Promise<void>;
15
15
  unsubscribe(onResub?: boolean): Promise<void>;
16
16
  }
@@ -29,13 +29,18 @@ const Buffer = __importStar(require("buffer"));
29
29
  const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
30
30
  const grpc_1 = require("../isomorphic/grpc");
31
31
  class grpcAccountSubscriber extends webSocketAccountSubscriber_1.WebSocketAccountSubscriber {
32
- constructor(grpcConfigs, accountName, program, accountPublicKey, decodeBuffer, resubOpts) {
33
- var _a, _b;
32
+ constructor(client, commitmentLevel, accountName, program, accountPublicKey, decodeBuffer, resubOpts) {
34
33
  super(accountName, program, accountPublicKey, decodeBuffer, resubOpts);
35
- this.client = (0, grpc_1.createClient)(grpcConfigs.endpoint, grpcConfigs.token, (_a = grpcConfigs.channelOptions) !== null && _a !== void 0 ? _a : {});
36
- this.commitmentLevel =
37
- // @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
38
- (_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : grpc_1.CommitmentLevel.CONFIRMED;
34
+ this.client = client;
35
+ this.commitmentLevel = commitmentLevel;
36
+ }
37
+ static async create(grpcConfigs, accountName, program, accountPublicKey, decodeBuffer, resubOpts) {
38
+ var _a, _b;
39
+ const client = await (0, grpc_1.createClient)(grpcConfigs.endpoint, grpcConfigs.token, (_a = grpcConfigs.channelOptions) !== null && _a !== void 0 ? _a : {});
40
+ const commitmentLevel =
41
+ // @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
42
+ (_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : CommitmentLevel.CONFIRMED;
43
+ return new grpcAccountSubscriber(client, commitmentLevel, accountName, program, accountPublicKey, decodeBuffer, resubOpts);
39
44
  }
40
45
  async subscribe(onChange) {
41
46
  if (this.listenerId != null || this.isUnsubscribing) {
@@ -33,7 +33,8 @@ class gprcDriftClientAccountSubscriber extends webSocketDriftClientAccountSubscr
33
33
  }
34
34
  const statePublicKey = await (0, pda_1.getDriftStateAccountPublicKey)(this.program.programId);
35
35
  // create and activate main state account subscription
36
- this.stateAccountSubscriber = new grpcAccountSubscriber_1.grpcAccountSubscriber(this.grpcConfigs, 'state', this.program, statePublicKey, undefined, undefined);
36
+ this.stateAccountSubscriber =
37
+ await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'state', this.program, statePublicKey, undefined, undefined);
37
38
  await this.stateAccountSubscriber.subscribe((data) => {
38
39
  this.eventEmitter.emit('stateAccountUpdate', data);
39
40
  this.eventEmitter.emit('update');
@@ -60,7 +61,7 @@ class gprcDriftClientAccountSubscriber extends webSocketDriftClientAccountSubscr
60
61
  }
61
62
  async subscribeToSpotMarketAccount(marketIndex) {
62
63
  const marketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex);
63
- const accountSubscriber = new grpcAccountSubscriber_1.grpcAccountSubscriber(this.grpcConfigs, 'spotMarket', this.program, marketPublicKey, undefined, this.resubOpts);
64
+ const accountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'spotMarket', this.program, marketPublicKey, undefined, this.resubOpts);
64
65
  accountSubscriber.setData(this.initialSpotMarketAccountData.get(marketIndex));
65
66
  await accountSubscriber.subscribe((data) => {
66
67
  this.eventEmitter.emit('spotMarketAccountUpdate', data);
@@ -71,7 +72,7 @@ class gprcDriftClientAccountSubscriber extends webSocketDriftClientAccountSubscr
71
72
  }
72
73
  async subscribeToPerpMarketAccount(marketIndex) {
73
74
  const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
74
- const accountSubscriber = new grpcAccountSubscriber_1.grpcAccountSubscriber(this.grpcConfigs, 'perpMarket', this.program, perpMarketPublicKey, undefined, this.resubOpts);
75
+ const accountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'perpMarket', this.program, perpMarketPublicKey, undefined, this.resubOpts);
75
76
  accountSubscriber.setData(this.initialPerpMarketAccountData.get(marketIndex));
76
77
  await accountSubscriber.subscribe((data) => {
77
78
  this.eventEmitter.emit('perpMarketAccountUpdate', data);
@@ -83,7 +84,7 @@ class gprcDriftClientAccountSubscriber extends webSocketDriftClientAccountSubscr
83
84
  async subscribeToOracle(oracleInfo) {
84
85
  const oracleId = (0, oracleId_1.getOracleId)(oracleInfo.publicKey, oracleInfo.source);
85
86
  const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection, this.program);
86
- const accountSubscriber = new grpcAccountSubscriber_1.grpcAccountSubscriber(this.grpcConfigs, 'oracle', this.program, oracleInfo.publicKey, (buffer) => {
87
+ const accountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'oracle', this.program, oracleInfo.publicKey, (buffer) => {
87
88
  return client.getOraclePriceDataFromBuffer(buffer);
88
89
  }, this.resubOpts);
89
90
  accountSubscriber.setData(this.initialOraclePriceData.get(oracleId));
@@ -12,9 +12,10 @@ class grpcInsuranceFundStakeAccountSubscriber extends webSocketInsuranceFundStak
12
12
  if (this.isSubscribed) {
13
13
  return true;
14
14
  }
15
- this.insuranceFundStakeDataAccountSubscriber = new grpcAccountSubscriber_1.grpcAccountSubscriber(this.grpcConfigs, 'insuranceFundStake', this.program, this.insuranceFundStakeAccountPublicKey, undefined, {
16
- resubTimeoutMs: this.resubTimeoutMs,
17
- });
15
+ this.insuranceFundStakeDataAccountSubscriber =
16
+ await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'insuranceFundStake', this.program, this.insuranceFundStakeAccountPublicKey, undefined, {
17
+ resubTimeoutMs: this.resubTimeoutMs,
18
+ });
18
19
  if (insuranceFundStakeAccount) {
19
20
  this.insuranceFundStakeDataAccountSubscriber.setData(insuranceFundStakeAccount);
20
21
  }
@@ -4,15 +4,15 @@ import { ResubOpts, GrpcConfigs } from './types';
4
4
  import { Program } from '@coral-xyz/anchor';
5
5
  import { Context, MemcmpFilter, PublicKey } from '@solana/web3.js';
6
6
  import { WebSocketProgramAccountSubscriber } from './webSocketProgramAccountSubscriber';
7
- import { Client, ClientDuplexStream, CommitmentLevel, SubscribeRequest, SubscribeUpdate } from '../isomorphic/grpc';
8
7
  export declare class grpcProgramAccountSubscriber<T> extends WebSocketProgramAccountSubscriber<T> {
9
- client: Client;
10
- stream: ClientDuplexStream<SubscribeRequest, SubscribeUpdate>;
11
- commitmentLevel: CommitmentLevel;
8
+ private client;
9
+ private stream;
10
+ private commitmentLevel;
12
11
  listenerId?: number;
13
- constructor(grpcConfigs: GrpcConfigs, subscriptionName: string, accountDiscriminator: string, program: Program, decodeBufferFn: (accountName: string, ix: Buffer) => T, options?: {
12
+ private constructor();
13
+ static create<U>(grpcConfigs: GrpcConfigs, subscriptionName: string, accountDiscriminator: string, program: Program, decodeBufferFn: (accountName: string, ix: Buffer) => U, options?: {
14
14
  filters: MemcmpFilter[];
15
- }, resubOpts?: ResubOpts);
15
+ }, resubOpts?: ResubOpts): Promise<grpcProgramAccountSubscriber<U>>;
16
16
  subscribe(onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void): Promise<void>;
17
17
  unsubscribe(onResub?: boolean): Promise<void>;
18
18
  }
@@ -33,15 +33,22 @@ const Buffer = __importStar(require("buffer"));
33
33
  const webSocketProgramAccountSubscriber_1 = require("./webSocketProgramAccountSubscriber");
34
34
  const grpc_1 = require("../isomorphic/grpc");
35
35
  class grpcProgramAccountSubscriber extends webSocketProgramAccountSubscriber_1.WebSocketProgramAccountSubscriber {
36
- constructor(grpcConfigs, subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
36
+ constructor(client, commitmentLevel, subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
37
37
  filters: [],
38
38
  }, resubOpts) {
39
- var _a, _b;
40
39
  super(subscriptionName, accountDiscriminator, program, decodeBufferFn, options, resubOpts);
41
- this.client = (0, grpc_1.createClient)(grpcConfigs.endpoint, grpcConfigs.token, (_a = grpcConfigs.channelOptions) !== null && _a !== void 0 ? _a : {});
42
- this.commitmentLevel =
43
- // @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
44
- (_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : grpc_1.CommitmentLevel.CONFIRMED;
40
+ this.client = client;
41
+ this.commitmentLevel = commitmentLevel;
42
+ }
43
+ static async create(grpcConfigs, subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
44
+ filters: [],
45
+ }, resubOpts) {
46
+ var _a, _b;
47
+ const client = await (0, grpc_1.createClient)(grpcConfigs.endpoint, grpcConfigs.token, (_a = grpcConfigs.channelOptions) !== null && _a !== void 0 ? _a : {});
48
+ const commitmentLevel =
49
+ // @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
50
+ (_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : CommitmentLevel.CONFIRMED;
51
+ return new grpcProgramAccountSubscriber(client, commitmentLevel, subscriptionName, accountDiscriminator, program, decodeBufferFn, options, resubOpts);
45
52
  }
46
53
  async subscribe(onChange) {
47
54
  if (this.listenerId != null || this.isUnsubscribing) {
@@ -12,7 +12,7 @@ class grpcUserAccountSubscriber extends webSocketUserAccountSubscriber_1.WebSock
12
12
  if (this.isSubscribed) {
13
13
  return true;
14
14
  }
15
- this.userDataAccountSubscriber = new grpcAccountSubscriber_1.grpcAccountSubscriber(this.grpcConfigs, 'user', this.program, this.userAccountPublicKey, undefined, this.resubOpts);
15
+ this.userDataAccountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'user', this.program, this.userAccountPublicKey, undefined, this.resubOpts);
16
16
  if (userAccount) {
17
17
  this.userDataAccountSubscriber.setData(userAccount);
18
18
  }
@@ -12,7 +12,7 @@ class grpcUserStatsAccountSubscriber extends webSocketUserStatsAccountSubsriber_
12
12
  if (this.isSubscribed) {
13
13
  return true;
14
14
  }
15
- this.userStatsAccountSubscriber = new grpcAccountSubscriber_1.grpcAccountSubscriber(this.grpcConfigs, 'userStats', this.program, this.userStatsAccountPublicKey, undefined, this.resubOpts);
15
+ this.userStatsAccountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'userStats', this.program, this.userStatsAccountPublicKey, undefined, this.resubOpts);
16
16
  if (userStatsAccount) {
17
17
  this.userStatsAccountSubscriber.setData(userStatsAccount);
18
18
  }
@@ -14,7 +14,7 @@ class AuctionSubscriberGrpc {
14
14
  }
15
15
  async subscribe() {
16
16
  if (!this.subscriber) {
17
- this.subscriber = new grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber(this.grpcConfigs, 'AuctionSubscriber', 'User', this.driftClient.program, this.driftClient.program.account.user.coder.accounts.decode.bind(this.driftClient.program.account.user.coder.accounts), {
17
+ this.subscriber = await grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber.create(this.grpcConfigs, 'AuctionSubscriber', 'User', this.driftClient.program, this.driftClient.program.account.user.coder.accounts.decode.bind(this.driftClient.program.account.user.coder.accounts), {
18
18
  filters: [(0, memcmp_1.getUserFilter)(), (0, memcmp_1.getUserWithAuctionFilter)()],
19
19
  }, this.resubOpts);
20
20
  }
@@ -1089,6 +1089,17 @@ exports.MainnetPerpMarkets = [
1089
1089
  oracleSource: __1.OracleSource.PYTH_PULL,
1090
1090
  pythFeedId: '0x8fef7d52c7f4e3a6258d663f9d27e64a1b6fd95ab5f7d545dbf9a515353d0064',
1091
1091
  },
1092
+ {
1093
+ fullName: 'BERA',
1094
+ category: ['L1', 'EVM'],
1095
+ symbol: 'BERA-PERP',
1096
+ baseAssetSymbol: 'BERA',
1097
+ marketIndex: 66,
1098
+ oracle: new web3_js_1.PublicKey('53Ae7ArP9yCnjqL2CqxJ1zdv3ba64NoVTqRcwjrCg181'),
1099
+ launchTs: 1738850177000,
1100
+ oracleSource: __1.OracleSource.PYTH_PULL,
1101
+ pythFeedId: '0x962088abcfdbdb6e30db2e340c8cf887d9efb311b1f2f17b155a63dbb6d40265',
1102
+ },
1092
1103
  ];
1093
1104
  exports.PerpMarkets = {
1094
1105
  devnet: exports.DevnetPerpMarkets,
@@ -228,7 +228,8 @@ function decodeUser(buffer) {
228
228
  offset += 1;
229
229
  const auctionDuration = buffer.readUInt8(offset);
230
230
  offset += 1;
231
- offset += 3; // padding
231
+ const postedSlotTail = buffer.readUint8(offset);
232
+ offset += 2; // padding
232
233
  orders.push({
233
234
  slot,
234
235
  price,
@@ -254,6 +255,7 @@ function decodeUser(buffer) {
254
255
  immediateOrCancel,
255
256
  triggerCondition,
256
257
  auctionDuration,
258
+ postedSlotTail,
257
259
  });
258
260
  }
259
261
  const lastAddPerpLpSharesTs = readSignedBigInt64LE(buffer, offset);
@@ -573,10 +573,8 @@ class DLOB {
573
573
  const generatorList = [
574
574
  nodeLists.restingLimit.ask.getGenerator(),
575
575
  nodeLists.floatingLimit.ask.getGenerator(),
576
+ nodeLists.protectedFloatingLimit.ask.getGenerator(),
576
577
  ];
577
- if (this.protectedMakerView) {
578
- generatorList.push(nodeLists.protectedFloatingLimit.ask.getGenerator());
579
- }
580
578
  yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode, slot, oraclePriceData) => {
581
579
  return bestNode
582
580
  .getPrice(oraclePriceData, slot)
@@ -596,10 +594,8 @@ class DLOB {
596
594
  const generatorList = [
597
595
  nodeLists.restingLimit.bid.getGenerator(),
598
596
  nodeLists.floatingLimit.bid.getGenerator(),
597
+ nodeLists.protectedFloatingLimit.bid.getGenerator(),
599
598
  ];
600
- if (this.protectedMakerView) {
601
- generatorList.push(nodeLists.protectedFloatingLimit.bid.getGenerator());
602
- }
603
599
  yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode, slot, oraclePriceData) => {
604
600
  return bestNode
605
601
  .getPrice(oraclePriceData, slot)
@@ -888,8 +888,8 @@ export declare class DriftClient {
888
888
  disableUserHighLeverageMode(user: PublicKey, userAccount?: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
889
889
  getDisableHighLeverageModeIx(user: PublicKey, userAccount?: UserAccount): Promise<TransactionInstruction>;
890
890
  fetchHighLeverageModeConfig(): Promise<HighLeverageModeConfig>;
891
- updateUserProtectedMakerOrders(subAccountId: number, protectedOrders: boolean, txParams?: TxParams): Promise<TransactionSignature>;
892
- getUpdateUserProtectedMakerOrdersIx(subAccountId: number, protectedOrders: boolean): Promise<TransactionInstruction>;
891
+ updateUserProtectedMakerOrders(subAccountId: number, protectedOrders: boolean, authority?: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
892
+ getUpdateUserProtectedMakerOrdersIx(subAccountId: number, protectedOrders: boolean, authority?: PublicKey): Promise<TransactionInstruction>;
893
893
  getPauseSpotMarketDepositWithdrawIx(spotMarketIndex: number): Promise<TransactionInstruction>;
894
894
  pauseSpotMarketDepositWithdraw(spotMarketIndex: number, txParams?: TxParams): Promise<TransactionSignature>;
895
895
  private handleSignedTransaction;
@@ -4847,15 +4847,15 @@ class DriftClient {
4847
4847
  const config = await this.program.account.highLeverageModeConfig.fetch((0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId));
4848
4848
  return config;
4849
4849
  }
4850
- async updateUserProtectedMakerOrders(subAccountId, protectedOrders, txParams) {
4851
- const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders), txParams), [], this.opts);
4850
+ async updateUserProtectedMakerOrders(subAccountId, protectedOrders, authority, txParams) {
4851
+ const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders, authority), txParams), [], this.opts);
4852
4852
  return txSig;
4853
4853
  }
4854
- async getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders) {
4854
+ async getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders, authority) {
4855
4855
  const ix = await this.program.instruction.updateUserProtectedMakerOrders(subAccountId, protectedOrders, {
4856
4856
  accounts: {
4857
4857
  state: await this.getStatePublicKey(),
4858
- user: (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, subAccountId),
4858
+ user: (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, authority !== null && authority !== void 0 ? authority : this.authority, subAccountId),
4859
4859
  authority: this.wallet.publicKey,
4860
4860
  protectedMakerModeConfig: (0, pda_1.getProtectedMakerModeConfigPublicKey)(this.program.programId),
4861
4861
  },
@@ -57,6 +57,9 @@ function getOracleClient(oracleSource, connection, program) {
57
57
  if ((0, types_1.isVariant)(oracleSource, 'pythLazer1M')) {
58
58
  return new pythLazerClient_1.PythLazerClient(connection, new anchor_1.BN(1000000));
59
59
  }
60
+ if ((0, types_1.isVariant)(oracleSource, 'pythLazerStableCoin')) {
61
+ return new pythLazerClient_1.PythLazerClient(connection, undefined, true);
62
+ }
60
63
  throw new Error(`Unknown oracle source ${oracleSource}`);
61
64
  }
62
65
  exports.getOracleClient = getOracleClient;
@@ -10875,12 +10875,19 @@
10875
10875
  ],
10876
10876
  "type": "u8"
10877
10877
  },
10878
+ {
10879
+ "name": "postedSlotTail",
10880
+ "docs": [
10881
+ "Last 8 bits of the slot the order was posted on-chain (not order slot for swift orders)"
10882
+ ],
10883
+ "type": "u8"
10884
+ },
10878
10885
  {
10879
10886
  "name": "padding",
10880
10887
  "type": {
10881
10888
  "array": [
10882
10889
  "u8",
10883
- 3
10890
+ 2
10884
10891
  ]
10885
10892
  }
10886
10893
  }
@@ -11463,6 +11470,9 @@
11463
11470
  },
11464
11471
  {
11465
11472
  "name": "PythLazer1M"
11473
+ },
11474
+ {
11475
+ "name": "PythLazerStableCoin"
11466
11476
  }
11467
11477
  ]
11468
11478
  }
@@ -33,6 +33,8 @@ function getOracleSourceNum(source) {
33
33
  return types_1.OracleSourceNum.PYTH_LAZER_1K;
34
34
  if ('pythLazer1M' in source)
35
35
  return types_1.OracleSourceNum.PYTH_LAZER_1M;
36
+ if ('pythLazerStableCoin' in source)
37
+ return types_1.OracleSourceNum.PYTH_LAZER_STABLE_COIN;
36
38
  throw new Error('Invalid oracle source');
37
39
  }
38
40
  exports.getOracleSourceNum = getOracleSourceNum;
@@ -16,7 +16,7 @@ class grpcSubscription {
16
16
  if (this.subscriber) {
17
17
  return;
18
18
  }
19
- this.subscriber = new grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber(this.grpcConfigs, 'OrderSubscriber', 'User', this.orderSubscriber.driftClient.program, this.orderSubscriber.decodeFn, {
19
+ this.subscriber = await grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber.create(this.grpcConfigs, 'OrderSubscriber', 'User', this.orderSubscriber.driftClient.program, this.orderSubscriber.decodeFn, {
20
20
  filters: [(0, memcmp_1.getUserFilter)(), (0, memcmp_1.getNonIdleUserFilter)()],
21
21
  }, this.resubOpts);
22
22
  await this.subscriber.subscribe((accountId, account, context, buffer) => {
@@ -60,7 +60,7 @@ class BaseTxSender {
60
60
  return this.txHandler.prepareTx(tx, additionalSigners, undefined, opts, preSigned);
61
61
  }
62
62
  async getVersionedTransaction(ixs, lookupTableAccounts, _additionalSigners, opts, blockhash) {
63
- return this.txHandler.generateVersionedTransaction(blockhash, ixs, lookupTableAccounts, this.wallet);
63
+ return this.txHandler.generateVersionedTransaction(blockhash !== null && blockhash !== void 0 ? blockhash : (await this.connection.getLatestBlockhash()), ixs, lookupTableAccounts, this.wallet);
64
64
  }
65
65
  async sendVersionedTransaction(tx, additionalSigners, opts, preSigned) {
66
66
  let signedTx;
@@ -207,6 +207,9 @@ export declare class OracleSource {
207
207
  static readonly PYTH_LAZER_1M: {
208
208
  pythLazer1M: {};
209
209
  };
210
+ static readonly PYTH_LAZER_STABLE_COIN: {
211
+ pythLazerStableCoin: {};
212
+ };
210
213
  }
211
214
  export declare class OracleSourceNum {
212
215
  static readonly PYTH = 0;
@@ -222,8 +225,9 @@ export declare class OracleSourceNum {
222
225
  static readonly PRELAUNCH = 10;
223
226
  static readonly SWITCHBOARD_ON_DEMAND = 11;
224
227
  static readonly PYTH_LAZER = 12;
225
- static readonly PYTH_LAZER_1K = 12;
226
- static readonly PYTH_LAZER_1M = 12;
228
+ static readonly PYTH_LAZER_1K = 13;
229
+ static readonly PYTH_LAZER_1M = 14;
230
+ static readonly PYTH_LAZER_STABLE_COIN = 15;
227
231
  }
228
232
  export declare class OrderType {
229
233
  static readonly LIMIT: {
@@ -1096,6 +1100,7 @@ export type Order = {
1096
1100
  auctionStartPrice: BN;
1097
1101
  auctionEndPrice: BN;
1098
1102
  maxTs: BN;
1103
+ postedSlotTail: number;
1099
1104
  };
1100
1105
  export type OrderParams = {
1101
1106
  orderType: OrderType;
@@ -126,6 +126,7 @@ OracleSource.SWITCHBOARD_ON_DEMAND = { switchboardOnDemand: {} };
126
126
  OracleSource.PYTH_LAZER = { pythLazer: {} };
127
127
  OracleSource.PYTH_LAZER_1K = { pythLazer1K: {} };
128
128
  OracleSource.PYTH_LAZER_1M = { pythLazer1M: {} };
129
+ OracleSource.PYTH_LAZER_STABLE_COIN = { pythLazerStableCoin: {} };
129
130
  class OracleSourceNum {
130
131
  }
131
132
  exports.OracleSourceNum = OracleSourceNum;
@@ -142,8 +143,9 @@ OracleSourceNum.PYTH_STABLE_COIN_PULL = 9;
142
143
  OracleSourceNum.PRELAUNCH = 10;
143
144
  OracleSourceNum.SWITCHBOARD_ON_DEMAND = 11;
144
145
  OracleSourceNum.PYTH_LAZER = 12;
145
- OracleSourceNum.PYTH_LAZER_1K = 12;
146
- OracleSourceNum.PYTH_LAZER_1M = 12;
146
+ OracleSourceNum.PYTH_LAZER_1K = 13;
147
+ OracleSourceNum.PYTH_LAZER_1M = 14;
148
+ OracleSourceNum.PYTH_LAZER_STABLE_COIN = 15;
147
149
  class OrderType {
148
150
  }
149
151
  exports.OrderType = OrderType;
@@ -22,7 +22,7 @@ class grpcSubscription {
22
22
  if (this.additionalFilters) {
23
23
  filters.push(...this.additionalFilters);
24
24
  }
25
- this.subscriber = new grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber(this.grpcConfigs, 'UserMap', 'User', this.userMap.driftClient.program, this.decodeFn, {
25
+ this.subscriber = await grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber.create(this.grpcConfigs, 'UserMap', 'User', this.userMap.driftClient.program, this.decodeFn, {
26
26
  filters,
27
27
  }, this.resubOpts);
28
28
  }
@@ -81,7 +81,17 @@ export declare class UserMap implements UserMapInterface {
81
81
  */
82
82
  getUniqueAuthorities(filterCriteria?: UserFilterCriteria): PublicKey[];
83
83
  sync(): Promise<void>;
84
+ /**
85
+ * Syncs the UserMap using the default sync method (single getProgramAccounts call with filters).
86
+ * This method may fail when drift has too many users. (nodejs response size limits)
87
+ * @returns
88
+ */
84
89
  private defaultSync;
90
+ /**
91
+ * Syncs the UserMap using the paginated sync method (multiple getMultipleAccounts calls with filters).
92
+ * This method is more reliable when drift has many users.
93
+ * @returns
94
+ */
85
95
  private paginatedSync;
86
96
  unsubscribe(): Promise<void>;
87
97
  updateUserAccount(key: string, userAccount: UserAccount, slot: number): Promise<void>;
@@ -259,6 +259,11 @@ class UserMap {
259
259
  return this.paginatedSync();
260
260
  }
261
261
  }
262
+ /**
263
+ * Syncs the UserMap using the default sync method (single getProgramAccounts call with filters).
264
+ * This method may fail when drift has too many users. (nodejs response size limits)
265
+ * @returns
266
+ */
262
267
  async defaultSync() {
263
268
  var _a;
264
269
  if (this.syncPromise) {
@@ -334,6 +339,11 @@ class UserMap {
334
339
  this.syncPromise = undefined;
335
340
  }
336
341
  }
342
+ /**
343
+ * Syncs the UserMap using the paginated sync method (multiple getMultipleAccounts calls with filters).
344
+ * This method is more reliable when drift has many users.
345
+ * @returns
346
+ */
337
347
  async paginatedSync() {
338
348
  var _a, _b;
339
349
  if (this.syncPromise) {
@@ -1,4 +1,4 @@
1
- import { DriftClient, OrderRecord, UserStatsAccount, UserStats, WrappedEvent, BulkAccountLoader } from '..';
1
+ import { DriftClient, OrderRecord, UserStatsAccount, UserStats, WrappedEvent, BulkAccountLoader, SyncConfig } from '..';
2
2
  import { PublicKey } from '@solana/web3.js';
3
3
  import { UserMap } from './userMap';
4
4
  export declare class UserStatsMap {
@@ -8,13 +8,17 @@ export declare class UserStatsMap {
8
8
  private userStatsMap;
9
9
  private driftClient;
10
10
  private bulkAccountLoader;
11
+ private decode;
12
+ private syncConfig;
13
+ private syncPromise?;
14
+ private syncPromiseResolver;
11
15
  /**
12
16
  * Creates a new UserStatsMap instance.
13
17
  *
14
18
  * @param {DriftClient} driftClient - The DriftClient instance.
15
19
  * @param {BulkAccountLoader} [bulkAccountLoader] - If not provided, a new BulkAccountLoader with polling disabled will be created.
16
20
  */
17
- constructor(driftClient: DriftClient, bulkAccountLoader?: BulkAccountLoader);
21
+ constructor(driftClient: DriftClient, bulkAccountLoader?: BulkAccountLoader, syncConfig?: SyncConfig);
18
22
  subscribe(authorities: PublicKey[]): Promise<void>;
19
23
  /**
20
24
  *
@@ -42,5 +46,16 @@ export declare class UserStatsMap {
42
46
  * You may want to get this list from UserMap in order to filter out idle users
43
47
  */
44
48
  sync(authorities: PublicKey[]): Promise<void>;
49
+ /**
50
+ * Sync the UserStatsMap using the default sync method, which loads individual users into the bulkAccountLoader and
51
+ * loads them. (bulkAccountLoader uses batch getMultipleAccounts)
52
+ * @param authorities
53
+ */
54
+ private defaultSync;
55
+ /**
56
+ * Sync the UserStatsMap using the paginated sync method, which uses multiple getMultipleAccounts calls (without RPC batching), and limits concurrency.
57
+ * @param authorities
58
+ */
59
+ private paginatedSync;
45
60
  unsubscribe(): Promise<void>;
46
61
  }
@@ -10,7 +10,7 @@ class UserStatsMap {
10
10
  * @param {DriftClient} driftClient - The DriftClient instance.
11
11
  * @param {BulkAccountLoader} [bulkAccountLoader] - If not provided, a new BulkAccountLoader with polling disabled will be created.
12
12
  */
13
- constructor(driftClient, bulkAccountLoader) {
13
+ constructor(driftClient, bulkAccountLoader, syncConfig) {
14
14
  /**
15
15
  * map from authority pubkey to UserStats
16
16
  */
@@ -20,6 +20,11 @@ class UserStatsMap {
20
20
  bulkAccountLoader = new __1.BulkAccountLoader(driftClient.connection, driftClient.opts.commitment, 0);
21
21
  }
22
22
  this.bulkAccountLoader = bulkAccountLoader;
23
+ this.syncConfig = syncConfig !== null && syncConfig !== void 0 ? syncConfig : {
24
+ type: 'default',
25
+ };
26
+ this.decode =
27
+ this.driftClient.program.account.userStats.coder.accounts.decodeUnchecked.bind(this.driftClient.program.account.userStats.coder.accounts);
23
28
  }
24
29
  async subscribe(authorities) {
25
30
  if (this.size() > 0) {
@@ -152,9 +157,111 @@ class UserStatsMap {
152
157
  * You may want to get this list from UserMap in order to filter out idle users
153
158
  */
154
159
  async sync(authorities) {
160
+ if (this.syncConfig.type === 'default') {
161
+ return this.defaultSync(authorities);
162
+ }
163
+ else {
164
+ return this.paginatedSync(authorities);
165
+ }
166
+ }
167
+ /**
168
+ * Sync the UserStatsMap using the default sync method, which loads individual users into the bulkAccountLoader and
169
+ * loads them. (bulkAccountLoader uses batch getMultipleAccounts)
170
+ * @param authorities
171
+ */
172
+ async defaultSync(authorities) {
155
173
  await Promise.all(authorities.map((authority) => this.addUserStat(authority, undefined, true)));
156
174
  await this.bulkAccountLoader.load();
157
175
  }
176
+ /**
177
+ * Sync the UserStatsMap using the paginated sync method, which uses multiple getMultipleAccounts calls (without RPC batching), and limits concurrency.
178
+ * @param authorities
179
+ */
180
+ async paginatedSync(authorities) {
181
+ var _a, _b;
182
+ if (this.syncPromise) {
183
+ return this.syncPromise;
184
+ }
185
+ this.syncPromise = new Promise((resolve) => {
186
+ this.syncPromiseResolver = resolve;
187
+ });
188
+ try {
189
+ let accountsToLoad = authorities;
190
+ if (authorities.length === 0) {
191
+ const accountsPrefetch = await this.driftClient.connection.getProgramAccounts(this.driftClient.program.programId, {
192
+ dataSlice: { offset: 0, length: 0 },
193
+ filters: [(0, __1.getUserStatsFilter)()],
194
+ });
195
+ accountsToLoad = accountsPrefetch.map((account) => account.pubkey);
196
+ }
197
+ const limitConcurrency = async (tasks, limit) => {
198
+ const executing = [];
199
+ const results = [];
200
+ for (let i = 0; i < tasks.length; i++) {
201
+ const executor = Promise.resolve().then(tasks[i]);
202
+ results.push(executor);
203
+ if (executing.length < limit) {
204
+ executing.push(executor);
205
+ executor.finally(() => {
206
+ const index = executing.indexOf(executor);
207
+ if (index > -1) {
208
+ executing.splice(index, 1);
209
+ }
210
+ });
211
+ }
212
+ else {
213
+ await Promise.race(executing);
214
+ }
215
+ }
216
+ return Promise.all(results);
217
+ };
218
+ const programAccountBufferMap = new Set();
219
+ // @ts-ignore
220
+ const chunkSize = (_a = this.syncConfig.chunkSize) !== null && _a !== void 0 ? _a : 100;
221
+ const tasks = [];
222
+ for (let i = 0; i < accountsToLoad.length; i += chunkSize) {
223
+ const chunk = accountsToLoad.slice(i, i + chunkSize);
224
+ tasks.push(async () => {
225
+ const accountInfos = await this.driftClient.connection.getMultipleAccountsInfoAndContext(chunk, {
226
+ commitment: this.driftClient.opts.commitment,
227
+ });
228
+ for (let j = 0; j < accountInfos.value.length; j += 1) {
229
+ const accountInfo = accountInfos.value[j];
230
+ if (accountInfo === null)
231
+ continue;
232
+ const publicKeyString = chunk[j].toString();
233
+ if (!this.has(publicKeyString)) {
234
+ const buffer = Buffer.from(accountInfo.data);
235
+ const decodedUserStats = this.decode('UserStats', buffer);
236
+ programAccountBufferMap.add(decodedUserStats.authority.toBase58());
237
+ this.addUserStat(decodedUserStats.authority, decodedUserStats, false);
238
+ }
239
+ }
240
+ });
241
+ }
242
+ // @ts-ignore
243
+ const concurrencyLimit = (_b = this.syncConfig.concurrencyLimit) !== null && _b !== void 0 ? _b : 10;
244
+ await limitConcurrency(tasks, concurrencyLimit);
245
+ for (const [key] of this.userStatsMap.entries()) {
246
+ if (!programAccountBufferMap.has(key)) {
247
+ const user = this.get(key);
248
+ if (user) {
249
+ await user.unsubscribe();
250
+ this.userStatsMap.delete(key);
251
+ }
252
+ }
253
+ }
254
+ }
255
+ catch (err) {
256
+ console.error(`Error in UserStatsMap.paginatedSync():`, err);
257
+ }
258
+ finally {
259
+ if (this.syncPromiseResolver) {
260
+ this.syncPromiseResolver();
261
+ }
262
+ this.syncPromise = undefined;
263
+ }
264
+ }
158
265
  async unsubscribe() {
159
266
  for (const [key, userStats] of this.userStatsMap.entries()) {
160
267
  await userStats.unsubscribe();