@drift-labs/sdk 2.95.0-beta.9 → 2.96.0-beta.1

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 (75) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/grpcAccountSubscriber.d.ts +16 -0
  3. package/lib/accounts/grpcAccountSubscriber.js +155 -0
  4. package/lib/accounts/grpcDriftClientAccountSubscriber.d.ts +13 -0
  5. package/lib/accounts/grpcDriftClientAccountSubscriber.js +96 -0
  6. package/lib/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts +10 -0
  7. package/lib/accounts/grpcInsuranceFundStakeAccountSubscriber.js +30 -0
  8. package/lib/accounts/grpcProgramAccountSubscriber.d.ts +19 -0
  9. package/lib/accounts/grpcProgramAccountSubscriber.js +161 -0
  10. package/lib/accounts/grpcUserAccountSubscriber.d.ts +10 -0
  11. package/lib/accounts/grpcUserAccountSubscriber.js +28 -0
  12. package/lib/accounts/grpcUserStatsAccountSubscriber.d.ts +10 -0
  13. package/lib/accounts/grpcUserStatsAccountSubscriber.js +28 -0
  14. package/lib/accounts/pollingDriftClientAccountSubscriber.d.ts +3 -1
  15. package/lib/accounts/pollingDriftClientAccountSubscriber.js +14 -4
  16. package/lib/accounts/types.d.ts +9 -1
  17. package/lib/accounts/webSocketAccountSubscriber.d.ts +1 -1
  18. package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +11 -4
  19. package/lib/accounts/webSocketDriftClientAccountSubscriber.js +70 -8
  20. package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +1 -1
  21. package/lib/addresses/pda.d.ts +2 -0
  22. package/lib/addresses/pda.js +15 -1
  23. package/lib/config.d.ts +3 -0
  24. package/lib/config.js +2 -0
  25. package/lib/constants/spotMarkets.js +10 -0
  26. package/lib/driftClient.js +41 -16
  27. package/lib/driftClientConfig.d.ts +6 -0
  28. package/lib/events/parse.js +1 -17
  29. package/lib/idl/drift.json +9 -4
  30. package/lib/math/insurance.d.ts +3 -1
  31. package/lib/math/insurance.js +31 -1
  32. package/lib/math/spotBalance.d.ts +3 -3
  33. package/lib/math/spotBalance.js +7 -7
  34. package/lib/orderSubscriber/OrderSubscriber.d.ts +2 -1
  35. package/lib/orderSubscriber/OrderSubscriber.js +19 -4
  36. package/lib/orderSubscriber/grpcSubscription.d.ts +25 -0
  37. package/lib/orderSubscriber/grpcSubscription.js +68 -0
  38. package/lib/orderSubscriber/types.d.ts +9 -0
  39. package/lib/user.js +11 -4
  40. package/lib/userConfig.d.ts +6 -1
  41. package/lib/userMap/grpcSubscription.d.ts +26 -0
  42. package/lib/userMap/grpcSubscription.js +42 -0
  43. package/lib/userMap/userMap.js +14 -0
  44. package/lib/userMap/userMapConfig.d.ts +7 -0
  45. package/lib/userStatsConfig.d.ts +6 -0
  46. package/package.json +3 -1
  47. package/src/accounts/grpcAccountSubscriber.ts +158 -0
  48. package/src/accounts/grpcDriftClientAccountSubscriber.ts +196 -0
  49. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +62 -0
  50. package/src/accounts/grpcProgramAccountSubscriber.ts +181 -0
  51. package/src/accounts/grpcUserAccountSubscriber.ts +48 -0
  52. package/src/accounts/grpcUserStatsAccountSubscriber.ts +51 -0
  53. package/src/accounts/pollingDriftClientAccountSubscriber.ts +17 -5
  54. package/src/accounts/types.ts +10 -1
  55. package/src/accounts/webSocketAccountSubscriber.ts +1 -1
  56. package/src/accounts/webSocketDriftClientAccountSubscriber.ts +135 -17
  57. package/src/accounts/webSocketProgramAccountSubscriber.ts +1 -1
  58. package/src/addresses/pda.ts +26 -0
  59. package/src/config.ts +8 -0
  60. package/src/constants/spotMarkets.ts +11 -0
  61. package/src/driftClient.ts +39 -2
  62. package/src/driftClientConfig.ts +7 -0
  63. package/src/events/parse.ts +1 -23
  64. package/src/idl/drift.json +9 -4
  65. package/src/math/insurance.ts +48 -2
  66. package/src/math/spotBalance.ts +13 -7
  67. package/src/orderSubscriber/OrderSubscriber.ts +15 -1
  68. package/src/orderSubscriber/grpcSubscription.ts +126 -0
  69. package/src/orderSubscriber/types.ts +10 -0
  70. package/src/user.ts +11 -0
  71. package/src/userConfig.ts +7 -1
  72. package/src/userMap/grpcSubscription.ts +83 -0
  73. package/src/userMap/userMap.ts +17 -1
  74. package/src/userMap/userMapConfig.ts +8 -0
  75. package/src/userStatsConfig.ts +7 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.94.0",
2
+ "version": "2.95.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -1606,15 +1606,20 @@
1606
1606
  {
1607
1607
  "name": "settleExpiredMarket",
1608
1608
  "accounts": [
1609
+ {
1610
+ "name": "admin",
1611
+ "isMut": false,
1612
+ "isSigner": true
1613
+ },
1609
1614
  {
1610
1615
  "name": "state",
1611
1616
  "isMut": false,
1612
1617
  "isSigner": false
1613
1618
  },
1614
1619
  {
1615
- "name": "authority",
1616
- "isMut": false,
1617
- "isSigner": true
1620
+ "name": "perpMarket",
1621
+ "isMut": true,
1622
+ "isSigner": false
1618
1623
  }
1619
1624
  ],
1620
1625
  "args": [
@@ -1,5 +1,7 @@
1
1
  /// <reference types="bn.js" />
2
- import { BN } from '../index';
2
+ import { BN, SpotMarketAccount } from '../index';
3
+ export declare function nextRevenuePoolSettleApr(spotMarket: SpotMarketAccount, vaultBalance: BN, // vault token amount
4
+ amount?: BN): number;
3
5
  export declare function stakeAmountToShares(amount: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
4
6
  export declare function unstakeSharesToAmount(nShares: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
5
7
  export declare function unstakeSharesToAmountWithOpenRequest(nShares: BN, withdrawRequestShares: BN, withdrawRequestAmount: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
@@ -1,8 +1,38 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.unstakeSharesToAmountWithOpenRequest = exports.unstakeSharesToAmount = exports.stakeAmountToShares = void 0;
3
+ exports.unstakeSharesToAmountWithOpenRequest = exports.unstakeSharesToAmount = exports.stakeAmountToShares = exports.nextRevenuePoolSettleApr = void 0;
4
4
  const numericConstants_1 = require("../constants/numericConstants");
5
5
  const index_1 = require("../index");
6
+ const spotBalance_1 = require("../math/spotBalance");
7
+ function nextRevenuePoolSettleApr(spotMarket, vaultBalance, // vault token amount
8
+ amount // delta token amount
9
+ ) {
10
+ const MAX_APR = new index_1.BN(10).mul(numericConstants_1.PERCENTAGE_PRECISION); // 1000% APR
11
+ // Conmputing the APR:
12
+ const revenuePoolBN = (0, spotBalance_1.getTokenAmount)(spotMarket.revenuePool.scaledBalance, spotMarket, index_1.SpotBalanceType.DEPOSIT);
13
+ const payoutRatio = 0.1;
14
+ const ratioForStakers = spotMarket.insuranceFund.totalFactor > 0 &&
15
+ spotMarket.insuranceFund.userFactor > 0 &&
16
+ spotMarket.insuranceFund.revenueSettlePeriod.gt(numericConstants_1.ZERO)
17
+ ? spotMarket.insuranceFund.userFactor /
18
+ spotMarket.insuranceFund.totalFactor
19
+ : 0;
20
+ // Settle periods from on-chain data:
21
+ const revSettlePeriod = spotMarket.insuranceFund.revenueSettlePeriod.toNumber() * 1000;
22
+ const settlesPerYear = 31536000000 / revSettlePeriod;
23
+ const projectedAnnualRev = revenuePoolBN
24
+ .muln(settlesPerYear)
25
+ .muln(payoutRatio);
26
+ const uncappedApr = vaultBalance.add(amount).eq(numericConstants_1.ZERO)
27
+ ? 0
28
+ : projectedAnnualRev.muln(1000).div(vaultBalance.add(amount)).toNumber() *
29
+ 100 *
30
+ 1000;
31
+ const cappedApr = Math.min(uncappedApr, MAX_APR.toNumber());
32
+ const nextApr = cappedApr * ratioForStakers;
33
+ return nextApr;
34
+ }
35
+ exports.nextRevenuePoolSettleApr = nextRevenuePoolSettleApr;
6
36
  function stakeAmountToShares(amount, totalIfShares, insuranceFundVaultBalance) {
7
37
  let nShares;
8
38
  if (insuranceFundVaultBalance.gt(numericConstants_1.ZERO)) {
@@ -62,9 +62,9 @@ export declare function calculateSpotMarketBorrowCapacity(spotMarketAccount: Spo
62
62
  totalCapacity: BN;
63
63
  remainingCapacity: BN;
64
64
  };
65
- export declare function calculateInterestRate(bank: SpotMarketAccount, delta?: BN): BN;
66
- export declare function calculateDepositRate(bank: SpotMarketAccount, delta?: BN): BN;
67
- export declare function calculateBorrowRate(bank: SpotMarketAccount, delta?: BN): BN;
65
+ export declare function calculateInterestRate(bank: SpotMarketAccount, delta?: BN, currentUtilization?: BN): BN;
66
+ export declare function calculateDepositRate(bank: SpotMarketAccount, delta?: BN, currentUtilization?: BN): BN;
67
+ export declare function calculateBorrowRate(bank: SpotMarketAccount, delta?: BN, currentUtilization?: BN): BN;
68
68
  export declare function calculateInterestAccumulated(bank: SpotMarketAccount, now: BN): {
69
69
  borrowInterest: BN;
70
70
  depositInterest: BN;
@@ -246,8 +246,8 @@ function calculateSpotMarketBorrowCapacity(spotMarketAccount, targetBorrowRate)
246
246
  return { totalCapacity, remainingCapacity };
247
247
  }
248
248
  exports.calculateSpotMarketBorrowCapacity = calculateSpotMarketBorrowCapacity;
249
- function calculateInterestRate(bank, delta = numericConstants_1.ZERO) {
250
- const utilization = calculateUtilization(bank, delta);
249
+ function calculateInterestRate(bank, delta = numericConstants_1.ZERO, currentUtilization = null) {
250
+ const utilization = currentUtilization || calculateUtilization(bank, delta);
251
251
  let interestRate;
252
252
  if (utilization.gt(new anchor_1.BN(bank.optimalUtilization))) {
253
253
  const surplusUtilization = utilization.sub(new anchor_1.BN(bank.optimalUtilization));
@@ -269,11 +269,11 @@ function calculateInterestRate(bank, delta = numericConstants_1.ZERO) {
269
269
  return anchor_1.BN.max(interestRate, new anchor_1.BN(bank.minBorrowRate).mul(numericConstants_2.PERCENTAGE_PRECISION.divn(200)));
270
270
  }
271
271
  exports.calculateInterestRate = calculateInterestRate;
272
- function calculateDepositRate(bank, delta = numericConstants_1.ZERO) {
272
+ function calculateDepositRate(bank, delta = numericConstants_1.ZERO, currentUtilization = null) {
273
273
  // positive delta => adding to deposit
274
274
  // negative delta => adding to borrow
275
- const utilization = calculateUtilization(bank, delta);
276
- const borrowRate = calculateBorrowRate(bank, delta);
275
+ const utilization = currentUtilization || calculateUtilization(bank, delta);
276
+ const borrowRate = calculateBorrowRate(bank, delta, utilization);
277
277
  const depositRate = borrowRate
278
278
  .mul(numericConstants_2.PERCENTAGE_PRECISION.sub(new anchor_1.BN(bank.insuranceFund.totalFactor)))
279
279
  .mul(utilization)
@@ -282,8 +282,8 @@ function calculateDepositRate(bank, delta = numericConstants_1.ZERO) {
282
282
  return depositRate;
283
283
  }
284
284
  exports.calculateDepositRate = calculateDepositRate;
285
- function calculateBorrowRate(bank, delta = numericConstants_1.ZERO) {
286
- return calculateInterestRate(bank, delta);
285
+ function calculateBorrowRate(bank, delta = numericConstants_1.ZERO, currentUtilization = null) {
286
+ return calculateInterestRate(bank, delta, currentUtilization);
287
287
  }
288
288
  exports.calculateBorrowRate = calculateBorrowRate;
289
289
  function calculateInterestAccumulated(bank, now) {
@@ -10,13 +10,14 @@ import { PollingSubscription } from './PollingSubscription';
10
10
  import { WebsocketSubscription } from './WebsocketSubscription';
11
11
  import StrictEventEmitter from 'strict-event-emitter-types';
12
12
  import { EventEmitter } from 'events';
13
+ import { grpcSubscription } from './grpcSubscription';
13
14
  export declare class OrderSubscriber {
14
15
  driftClient: DriftClient;
15
16
  usersAccounts: Map<string, {
16
17
  slot: number;
17
18
  userAccount: UserAccount;
18
19
  }>;
19
- subscription: PollingSubscription | WebsocketSubscription;
20
+ subscription: PollingSubscription | WebsocketSubscription | grpcSubscription;
20
21
  commitment: Commitment;
21
22
  eventEmitter: StrictEventEmitter<EventEmitter, OrderSubscriberEvents>;
22
23
  fetchPromise?: Promise<void>;
@@ -10,9 +10,10 @@ const WebsocketSubscription_1 = require("./WebsocketSubscription");
10
10
  const events_1 = require("events");
11
11
  const index_1 = require("../index");
12
12
  const user_1 = require("../decode/user");
13
+ const grpcSubscription_1 = require("./grpcSubscription");
13
14
  class OrderSubscriber {
14
15
  constructor(config) {
15
- var _a, _b, _c;
16
+ var _a, _b, _c, _d, _e;
16
17
  this.usersAccounts = new Map();
17
18
  this.driftClient = config.driftClient;
18
19
  this.commitment = config.subscriptionConfig.commitment || 'processed';
@@ -22,8 +23,9 @@ class OrderSubscriber {
22
23
  frequency: config.subscriptionConfig.frequency,
23
24
  });
24
25
  }
25
- else {
26
- this.subscription = new WebsocketSubscription_1.WebsocketSubscription({
26
+ else if (config.subscriptionConfig.type === 'grpc') {
27
+ this.subscription = new grpcSubscription_1.grpcSubscription({
28
+ grpcConfigs: config.subscriptionConfig.configs,
27
29
  orderSubscriber: this,
28
30
  commitment: this.commitment,
29
31
  skipInitialLoad: config.subscriptionConfig.skipInitialLoad,
@@ -35,7 +37,20 @@ class OrderSubscriber {
35
37
  decoded: config.decodeData,
36
38
  });
37
39
  }
38
- if ((_c = config.fastDecode) !== null && _c !== void 0 ? _c : true) {
40
+ else {
41
+ this.subscription = new WebsocketSubscription_1.WebsocketSubscription({
42
+ orderSubscriber: this,
43
+ commitment: this.commitment,
44
+ skipInitialLoad: config.subscriptionConfig.skipInitialLoad,
45
+ resubOpts: {
46
+ resubTimeoutMs: (_c = config.subscriptionConfig) === null || _c === void 0 ? void 0 : _c.resubTimeoutMs,
47
+ logResubMessages: (_d = config.subscriptionConfig) === null || _d === void 0 ? void 0 : _d.logResubMessages,
48
+ },
49
+ resyncIntervalMs: config.subscriptionConfig.resyncIntervalMs,
50
+ decoded: config.decodeData,
51
+ });
52
+ }
53
+ if ((_e = config.fastDecode) !== null && _e !== void 0 ? _e : true) {
39
54
  this.decodeFn = (name, data) => (0, user_1.decodeUser)(data);
40
55
  }
41
56
  else {
@@ -0,0 +1,25 @@
1
+ import { Commitment } from '@solana/web3.js';
2
+ import { OrderSubscriber } from './OrderSubscriber';
3
+ import { GrpcConfigs, ResubOpts } from '../accounts/types';
4
+ export declare class grpcSubscription {
5
+ private orderSubscriber;
6
+ private commitment;
7
+ private skipInitialLoad;
8
+ private resubOpts?;
9
+ private resyncIntervalMs?;
10
+ private subscriber?;
11
+ private resyncTimeoutId?;
12
+ private decoded?;
13
+ private grpcConfigs;
14
+ constructor({ grpcConfigs, orderSubscriber, commitment, skipInitialLoad, resubOpts, resyncIntervalMs, decoded, }: {
15
+ grpcConfigs: GrpcConfigs;
16
+ orderSubscriber: OrderSubscriber;
17
+ commitment: Commitment;
18
+ skipInitialLoad?: boolean;
19
+ resubOpts?: ResubOpts;
20
+ resyncIntervalMs?: number;
21
+ decoded?: boolean;
22
+ });
23
+ subscribe(): Promise<void>;
24
+ unsubscribe(): Promise<void>;
25
+ }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.grpcSubscription = void 0;
4
+ const grpcProgramAccountSubscriber_1 = require("../accounts/grpcProgramAccountSubscriber");
5
+ const memcmp_1 = require("../memcmp");
6
+ class grpcSubscription {
7
+ constructor({ grpcConfigs, orderSubscriber, commitment, skipInitialLoad = false, resubOpts, resyncIntervalMs, decoded = true, }) {
8
+ this.orderSubscriber = orderSubscriber;
9
+ this.commitment = commitment;
10
+ this.skipInitialLoad = skipInitialLoad;
11
+ this.resubOpts = resubOpts;
12
+ this.resyncIntervalMs = resyncIntervalMs;
13
+ this.decoded = decoded;
14
+ this.grpcConfigs = grpcConfigs;
15
+ }
16
+ async subscribe() {
17
+ if (this.subscriber) {
18
+ return;
19
+ }
20
+ this.subscriber = new grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber(this.grpcConfigs, 'OrderSubscriber', 'User', this.orderSubscriber.driftClient.program, this.orderSubscriber.decodeFn, {
21
+ filters: [(0, memcmp_1.getUserFilter)(), (0, memcmp_1.getNonIdleUserFilter)()],
22
+ commitment: this.commitment,
23
+ }, this.resubOpts);
24
+ await this.subscriber.subscribe((accountId, account, context, buffer) => {
25
+ var _a;
26
+ const userKey = accountId.toBase58();
27
+ if ((_a = this.decoded) !== null && _a !== void 0 ? _a : true) {
28
+ this.orderSubscriber.tryUpdateUserAccount(userKey, 'decoded', account, context.slot);
29
+ }
30
+ else {
31
+ this.orderSubscriber.tryUpdateUserAccount(userKey, 'buffer', buffer, context.slot);
32
+ }
33
+ });
34
+ if (!this.skipInitialLoad) {
35
+ await this.orderSubscriber.fetch();
36
+ }
37
+ if (this.resyncIntervalMs) {
38
+ const recursiveResync = () => {
39
+ this.resyncTimeoutId = setTimeout(() => {
40
+ this.orderSubscriber
41
+ .fetch()
42
+ .catch((e) => {
43
+ console.error('Failed to resync in OrderSubscriber');
44
+ console.log(e);
45
+ })
46
+ .finally(() => {
47
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
48
+ if (!this.resyncTimeoutId)
49
+ return;
50
+ recursiveResync();
51
+ });
52
+ }, this.resyncIntervalMs);
53
+ };
54
+ recursiveResync();
55
+ }
56
+ }
57
+ async unsubscribe() {
58
+ if (!this.subscriber)
59
+ return;
60
+ await this.subscriber.unsubscribe();
61
+ this.subscriber = undefined;
62
+ if (this.resyncTimeoutId !== undefined) {
63
+ clearTimeout(this.resyncTimeoutId);
64
+ this.resyncTimeoutId = undefined;
65
+ }
66
+ }
67
+ }
68
+ exports.grpcSubscription = grpcSubscription;
@@ -1,12 +1,21 @@
1
1
  import { Commitment, PublicKey } from '@solana/web3.js';
2
2
  import { Order, UserAccount } from '../types';
3
3
  import { DriftClient } from '../driftClient';
4
+ import { GrpcConfigs } from '../accounts/types';
4
5
  export type OrderSubscriberConfig = {
5
6
  driftClient: DriftClient;
6
7
  subscriptionConfig: {
7
8
  type: 'polling';
8
9
  frequency: number;
9
10
  commitment?: Commitment;
11
+ } | {
12
+ type: 'grpc';
13
+ skipInitialLoad?: boolean;
14
+ resubTimeoutMs?: number;
15
+ logResubMessages?: boolean;
16
+ resyncIntervalMs?: number;
17
+ configs: GrpcConfigs;
18
+ commitment?: Commitment;
10
19
  } | {
11
20
  type: 'websocket';
12
21
  skipInitialLoad?: boolean;
package/lib/user.js CHANGED
@@ -15,6 +15,7 @@ const oracles_1 = require("./math/oracles");
15
15
  const tiers_1 = require("./math/tiers");
16
16
  const strictOraclePrice_1 = require("./oracles/strictOraclePrice");
17
17
  const fuel_1 = require("./math/fuel");
18
+ const grpcUserAccountSubscriber_1 = require("./accounts/grpcUserAccountSubscriber");
18
19
  class User {
19
20
  get isSubscribed() {
20
21
  return this._isSubscribed && this.accountSubscriber.isSubscribed;
@@ -23,7 +24,7 @@ class User {
23
24
  this._isSubscribed = val;
24
25
  }
25
26
  constructor(config) {
26
- var _a, _b, _c, _d, _e;
27
+ var _a, _b, _c, _d, _e, _f, _g, _h;
27
28
  this._isSubscribed = false;
28
29
  this.driftClient = config.driftClient;
29
30
  this.userAccountPublicKey = config.userAccountPublicKey;
@@ -33,11 +34,17 @@ class User {
33
34
  else if (((_b = config.accountSubscription) === null || _b === void 0 ? void 0 : _b.type) === 'custom') {
34
35
  this.accountSubscriber = config.accountSubscription.userAccountSubscriber;
35
36
  }
37
+ else if (((_c = config.accountSubscription) === null || _c === void 0 ? void 0 : _c.type) === 'grpc') {
38
+ this.accountSubscriber = new grpcUserAccountSubscriber_1.grpcUserAccountSubscriber(config.accountSubscription.configs, config.driftClient.program, config.userAccountPublicKey, {
39
+ resubTimeoutMs: (_d = config.accountSubscription) === null || _d === void 0 ? void 0 : _d.resubTimeoutMs,
40
+ logResubMessages: (_e = config.accountSubscription) === null || _e === void 0 ? void 0 : _e.logResubMessages,
41
+ });
42
+ }
36
43
  else {
37
44
  this.accountSubscriber = new webSocketUserAccountSubscriber_1.WebSocketUserAccountSubscriber(config.driftClient.program, config.userAccountPublicKey, {
38
- resubTimeoutMs: (_c = config.accountSubscription) === null || _c === void 0 ? void 0 : _c.resubTimeoutMs,
39
- logResubMessages: (_d = config.accountSubscription) === null || _d === void 0 ? void 0 : _d.logResubMessages,
40
- }, (_e = config.accountSubscription) === null || _e === void 0 ? void 0 : _e.commitment);
45
+ resubTimeoutMs: (_f = config.accountSubscription) === null || _f === void 0 ? void 0 : _f.resubTimeoutMs,
46
+ logResubMessages: (_g = config.accountSubscription) === null || _g === void 0 ? void 0 : _g.logResubMessages,
47
+ }, (_h = config.accountSubscription) === null || _h === void 0 ? void 0 : _h.commitment);
41
48
  }
42
49
  this.eventEmitter = this.accountSubscriber.eventEmitter;
43
50
  }
@@ -1,7 +1,7 @@
1
1
  import { DriftClient } from './driftClient';
2
2
  import { Commitment, PublicKey } from '@solana/web3.js';
3
3
  import { BulkAccountLoader } from './accounts/bulkAccountLoader';
4
- import { UserAccountSubscriber } from './accounts/types';
4
+ import { GrpcConfigs, UserAccountSubscriber } from './accounts/types';
5
5
  export type UserConfig = {
6
6
  accountSubscription?: UserSubscriptionConfig;
7
7
  driftClient: DriftClient;
@@ -18,4 +18,9 @@ export type UserSubscriptionConfig = {
18
18
  } | {
19
19
  type: 'custom';
20
20
  userAccountSubscriber: UserAccountSubscriber;
21
+ } | {
22
+ type: 'grpc';
23
+ resubTimeoutMs?: number;
24
+ logResubMessages?: boolean;
25
+ configs: GrpcConfigs;
21
26
  };
@@ -0,0 +1,26 @@
1
+ /// <reference types="node" />
2
+ import { UserMap } from './userMap';
3
+ import { UserAccount } from '../types';
4
+ import { Commitment } from '@solana/web3.js';
5
+ import { GrpcConfigs, ResubOpts } from '../accounts/types';
6
+ export declare class grpcSubscription {
7
+ private configs;
8
+ private userMap;
9
+ private commitment;
10
+ private skipInitialLoad;
11
+ private resubOpts?;
12
+ private includeIdle?;
13
+ private decodeFn;
14
+ private subscriber;
15
+ constructor({ configs, userMap, commitment, skipInitialLoad, resubOpts, includeIdle, decodeFn, }: {
16
+ configs: GrpcConfigs;
17
+ userMap: UserMap;
18
+ commitment: Commitment;
19
+ skipInitialLoad?: boolean;
20
+ resubOpts?: ResubOpts;
21
+ includeIdle?: boolean;
22
+ decodeFn: (name: string, data: Buffer) => UserAccount;
23
+ });
24
+ subscribe(): Promise<void>;
25
+ unsubscribe(): Promise<void>;
26
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.grpcSubscription = void 0;
4
+ const memcmp_1 = require("../memcmp");
5
+ const grpcProgramAccountSubscriber_1 = require("../accounts/grpcProgramAccountSubscriber");
6
+ class grpcSubscription {
7
+ constructor({ configs, userMap, commitment, skipInitialLoad = false, resubOpts, includeIdle = false, decodeFn, }) {
8
+ this.userMap = userMap;
9
+ this.commitment = commitment;
10
+ this.skipInitialLoad = skipInitialLoad;
11
+ this.resubOpts = resubOpts;
12
+ this.includeIdle = includeIdle || false;
13
+ this.decodeFn = decodeFn;
14
+ this.configs = configs;
15
+ }
16
+ async subscribe() {
17
+ if (!this.subscriber) {
18
+ const filters = [(0, memcmp_1.getUserFilter)()];
19
+ if (!this.includeIdle) {
20
+ filters.push((0, memcmp_1.getNonIdleUserFilter)());
21
+ }
22
+ this.subscriber = new grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber(this.configs, 'UserMap', 'User', this.userMap.driftClient.program, this.decodeFn, {
23
+ filters,
24
+ commitment: this.commitment,
25
+ }, this.resubOpts);
26
+ }
27
+ await this.subscriber.subscribe((accountId, account, context) => {
28
+ const userKey = accountId.toBase58();
29
+ this.userMap.updateUserAccount(userKey, account, context.slot);
30
+ });
31
+ if (!this.skipInitialLoad) {
32
+ await this.userMap.sync();
33
+ }
34
+ }
35
+ async unsubscribe() {
36
+ if (!this.subscriber)
37
+ return;
38
+ await this.subscriber.unsubscribe();
39
+ this.subscriber = undefined;
40
+ }
41
+ }
42
+ exports.grpcSubscription = grpcSubscription;
@@ -9,6 +9,7 @@ const memcmp_1 = require("../memcmp");
9
9
  const WebsocketSubscription_1 = require("./WebsocketSubscription");
10
10
  const PollingSubscription_1 = require("./PollingSubscription");
11
11
  const user_1 = require("../decode/user");
12
+ const grpcSubscription_1 = require("./grpcSubscription");
12
13
  const MAX_USER_ACCOUNT_SIZE_BYTES = 4376;
13
14
  class UserMap {
14
15
  /**
@@ -52,6 +53,19 @@ class UserMap {
52
53
  skipInitialLoad: config.skipInitialLoad,
53
54
  });
54
55
  }
56
+ else if (config.subscriptionConfig.type === 'grpc') {
57
+ this.subscription = new grpcSubscription_1.grpcSubscription({
58
+ configs: config.subscriptionConfig.configs,
59
+ userMap: this,
60
+ commitment: this.commitment,
61
+ resubOpts: {
62
+ resubTimeoutMs: config.subscriptionConfig.resubTimeoutMs,
63
+ logResubMessages: config.subscriptionConfig.logResubMessages,
64
+ },
65
+ skipInitialLoad: config.skipInitialLoad,
66
+ decodeFn,
67
+ });
68
+ }
55
69
  else {
56
70
  this.subscription = new WebsocketSubscription_1.WebsocketSubscription({
57
71
  userMap: this,
@@ -1,5 +1,6 @@
1
1
  import { Commitment, Connection } from '@solana/web3.js';
2
2
  import { DriftClient } from '../driftClient';
3
+ import { GrpcConfigs } from '../accounts/types';
3
4
  export type UserAccountFilterCriteria = {
4
5
  hasOpenOrders: boolean;
5
6
  };
@@ -17,6 +18,12 @@ export type UserMapConfig = {
17
18
  type: 'polling';
18
19
  frequency: number;
19
20
  commitment?: Commitment;
21
+ } | {
22
+ type: 'grpc';
23
+ configs: GrpcConfigs;
24
+ resubTimeoutMs?: number;
25
+ logResubMessages?: boolean;
26
+ commitment?: Commitment;
20
27
  } | {
21
28
  type: 'websocket';
22
29
  resubTimeoutMs?: number;
@@ -1,6 +1,7 @@
1
1
  import { DriftClient } from './driftClient';
2
2
  import { Commitment, PublicKey } from '@solana/web3.js';
3
3
  import { BulkAccountLoader } from './accounts/bulkAccountLoader';
4
+ import { GrpcConfigs } from './accounts/types';
4
5
  export type UserStatsConfig = {
5
6
  accountSubscription?: UserStatsSubscriptionConfig;
6
7
  driftClient: DriftClient;
@@ -16,4 +17,9 @@ export type UserStatsSubscriptionConfig = {
16
17
  accountLoader: BulkAccountLoader;
17
18
  } | {
18
19
  type: 'custom';
20
+ } | {
21
+ type: 'grpc';
22
+ resubTimeoutMs?: number;
23
+ logResubMessages?: boolean;
24
+ configs: GrpcConfigs;
19
25
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.95.0-beta.9",
3
+ "version": "2.96.0-beta.1",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -37,6 +37,7 @@
37
37
  "@coral-xyz/anchor": "0.28.0",
38
38
  "@coral-xyz/anchor-30": "npm:@coral-xyz/anchor@0.30.1",
39
39
  "@ellipsis-labs/phoenix-sdk": "^1.4.2",
40
+ "@grpc/grpc-js": "^1.11.2",
40
41
  "@openbook-dex/openbook-v2": "^0.2.10",
41
42
  "@project-serum/serum": "^0.13.38",
42
43
  "@pythnetwork/client": "2.5.3",
@@ -45,6 +46,7 @@
45
46
  "@solana/spl-token": "0.3.7",
46
47
  "@solana/web3.js": "1.92.3",
47
48
  "@switchboard-xyz/on-demand": "1.2.32",
49
+ "@triton-one/yellowstone-grpc": "^0.6.0",
48
50
  "anchor-bankrun": "^0.3.0",
49
51
  "node-cache": "^5.1.2",
50
52
  "rpc-websockets": "7.5.1",