@drift-labs/sdk 0.1.18-orders.1 → 0.1.18-orders.2

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 (71) hide show
  1. package/README.md +2 -1
  2. package/lib/accounts/bulkAccountLoader.d.ts +32 -0
  3. package/lib/accounts/bulkAccountLoader.js +156 -0
  4. package/lib/accounts/bulkUserSubscription.d.ts +7 -0
  5. package/lib/accounts/bulkUserSubscription.js +28 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +49 -0
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +228 -0
  8. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +25 -0
  9. package/lib/accounts/pollingTokenAccountSubscriber.js +79 -0
  10. package/lib/accounts/pollingUserAccountSubscriber.d.ts +32 -0
  11. package/lib/accounts/pollingUserAccountSubscriber.js +133 -0
  12. package/lib/accounts/types.d.ts +30 -25
  13. package/lib/accounts/utils.d.ts +1 -0
  14. package/lib/accounts/utils.js +7 -0
  15. package/lib/accounts/{defaultClearingHouseAccountSubscriber.d.ts → webSocketClearingHouseAccountSubscriber.d.ts} +6 -4
  16. package/lib/accounts/{defaultClearingHouseAccountSubscriber.js → webSocketClearingHouseAccountSubscriber.js} +5 -4
  17. package/lib/accounts/{defaultUserAccountSubscriber.d.ts → webSocketUserAccountSubscriber.d.ts} +3 -1
  18. package/lib/accounts/{defaultUserAccountSubscriber.js → webSocketUserAccountSubscriber.js} +10 -7
  19. package/lib/addresses.d.ts +2 -2
  20. package/lib/addresses.js +4 -4
  21. package/lib/admin.d.ts +3 -0
  22. package/lib/admin.js +61 -13
  23. package/lib/clearingHouse.d.ts +16 -4
  24. package/lib/clearingHouse.js +50 -10
  25. package/lib/clearingHouseUser.d.ts +9 -1
  26. package/lib/clearingHouseUser.js +19 -5
  27. package/lib/config.js +1 -1
  28. package/lib/constants/markets.js +16 -0
  29. package/lib/factory/clearingHouse.d.ts +25 -0
  30. package/lib/factory/clearingHouse.js +64 -0
  31. package/lib/factory/clearingHouseUser.d.ts +19 -0
  32. package/lib/factory/clearingHouseUser.js +34 -0
  33. package/lib/idl/clearing_house.json +360 -15
  34. package/lib/index.d.ts +9 -4
  35. package/lib/index.js +14 -5
  36. package/lib/math/funding.js +4 -1
  37. package/lib/math/utils.d.ts +2 -2
  38. package/lib/math/utils.js +6 -3
  39. package/lib/orderParams.d.ts +3 -3
  40. package/lib/orderParams.js +23 -3
  41. package/lib/token/index.d.ts +3 -0
  42. package/lib/token/index.js +38 -0
  43. package/lib/types.d.ts +13 -3
  44. package/package.json +3 -3
  45. package/src/accounts/bulkAccountLoader.ts +195 -0
  46. package/src/accounts/bulkUserSubscription.ts +28 -0
  47. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +326 -0
  48. package/src/accounts/pollingTokenAccountSubscriber.ts +99 -0
  49. package/src/accounts/pollingUserAccountSubscriber.ts +186 -0
  50. package/src/accounts/types.ts +35 -30
  51. package/src/accounts/utils.ts +3 -0
  52. package/src/accounts/{defaultClearingHouseAccountSubscriber.ts → webSocketClearingHouseAccountSubscriber.ts} +9 -6
  53. package/src/accounts/{defaultUserAccountSubscriber.ts → webSocketUserAccountSubscriber.ts} +10 -5
  54. package/src/addresses.ts +6 -4
  55. package/src/admin.ts +73 -20
  56. package/src/clearingHouse.ts +69 -25
  57. package/src/clearingHouseUser.ts +26 -6
  58. package/src/config.ts +1 -1
  59. package/src/constants/markets.ts +16 -0
  60. package/src/factory/clearingHouse.ts +125 -0
  61. package/src/factory/clearingHouseUser.ts +73 -0
  62. package/src/idl/clearing_house.json +360 -15
  63. package/src/index.ts +9 -4
  64. package/src/math/funding.ts +5 -1
  65. package/src/math/utils.ts +1 -1
  66. package/src/orderParams.ts +26 -3
  67. package/src/token/index.ts +37 -0
  68. package/src/types.ts +13 -3
  69. package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +0 -28
  70. package/lib/accounts/defaultHistoryAccountSubscriber.js +0 -110
  71. package/src/accounts/defaultHistoryAccountSubscriber.ts +0 -176
package/README.md CHANGED
@@ -84,7 +84,7 @@ convertToNumber(new BN(10500), new BN(1000)); // = 10.5
84
84
  ### Setting up an account and making a trade
85
85
 
86
86
  ```typescript
87
- import { BN, Provider, Wallet } from '@project-serum/anchor';
87
+ import { BN, Provider } from '@project-serum/anchor';
88
88
  import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
89
89
  import { Connection, Keypair, PublicKey } from '@solana/web3.js';
90
90
  import {
@@ -98,6 +98,7 @@ import {
98
98
  calculateTradeSlippage,
99
99
  MARK_PRICE_PRECISION,
100
100
  QUOTE_PRECISION,
101
+ Wallet
101
102
  } from '@drift-labs/sdk';
102
103
 
103
104
  export const getTokenAddress = (
@@ -0,0 +1,32 @@
1
+ /// <reference types="node" />
2
+ import { Commitment, Connection, PublicKey } from '@solana/web3.js';
3
+ declare type AccountToLoad = {
4
+ publicKey: PublicKey;
5
+ callbacks: Map<string, (buffer: Buffer) => void>;
6
+ };
7
+ declare type AccountData = {
8
+ slot: number;
9
+ buffer: Buffer | undefined;
10
+ };
11
+ export declare class BulkAccountLoader {
12
+ connection: Connection;
13
+ commitment: Commitment;
14
+ pollingFrequency: number;
15
+ accountsToLoad: Map<string, AccountToLoad>;
16
+ accountData: Map<string, AccountData>;
17
+ errorCallbacks: Map<string, (e: any) => void>;
18
+ intervalId?: NodeJS.Timer;
19
+ constructor(connection: Connection, commitment: Commitment, pollingFrequency: number);
20
+ addAccount(publicKey: PublicKey, callback: (buffer: Buffer) => void): string;
21
+ removeAccount(publicKey: PublicKey, callbackId: string): void;
22
+ addErrorCallbacks(callback: (error: Error) => void): string;
23
+ removeErrorCallbacks(callbackId: string): void;
24
+ chunks<T>(array: readonly T[], size: number): T[][];
25
+ load(): Promise<void>;
26
+ loadChunk(accountsToLoad: AccountToLoad[]): Promise<void>;
27
+ handleAccountCallbacks(accountToLoad: AccountToLoad, buffer: Buffer): void;
28
+ getAccountData(publicKey: PublicKey): Buffer | undefined;
29
+ startPolling(): void;
30
+ stopPolling(): void;
31
+ }
32
+ export {};
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.BulkAccountLoader = void 0;
13
+ const uuid_1 = require("uuid");
14
+ const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
15
+ class BulkAccountLoader {
16
+ constructor(connection, commitment, pollingFrequency) {
17
+ this.accountsToLoad = new Map();
18
+ this.accountData = new Map();
19
+ this.errorCallbacks = new Map();
20
+ this.connection = connection;
21
+ this.commitment = commitment;
22
+ this.pollingFrequency = pollingFrequency;
23
+ }
24
+ addAccount(publicKey, callback) {
25
+ const existingSize = this.accountsToLoad.size;
26
+ const callbackId = uuid_1.v4();
27
+ const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
28
+ if (existingAccountToLoad) {
29
+ existingAccountToLoad.callbacks.set(callbackId, callback);
30
+ }
31
+ else {
32
+ const callbacks = new Map();
33
+ callbacks.set(callbackId, callback);
34
+ const newAccountToLoad = {
35
+ publicKey,
36
+ callbacks,
37
+ };
38
+ this.accountsToLoad.set(publicKey.toString(), newAccountToLoad);
39
+ }
40
+ if (existingSize === 0) {
41
+ this.startPolling();
42
+ }
43
+ return callbackId;
44
+ }
45
+ removeAccount(publicKey, callbackId) {
46
+ const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
47
+ if (existingAccountToLoad) {
48
+ existingAccountToLoad.callbacks.delete(callbackId);
49
+ if (existingAccountToLoad.callbacks.size === 0) {
50
+ this.accountsToLoad.delete(existingAccountToLoad.publicKey.toString());
51
+ }
52
+ }
53
+ if (this.accountsToLoad.size === 0) {
54
+ this.stopPolling();
55
+ }
56
+ }
57
+ addErrorCallbacks(callback) {
58
+ const callbackId = uuid_1.v4();
59
+ this.errorCallbacks.set(callbackId, callback);
60
+ return callbackId;
61
+ }
62
+ removeErrorCallbacks(callbackId) {
63
+ this.errorCallbacks.delete(callbackId);
64
+ }
65
+ chunks(array, size) {
66
+ return new Array(Math.ceil(array.length / size))
67
+ .fill(null)
68
+ .map((_, index) => index * size)
69
+ .map((begin) => array.slice(begin, begin + size));
70
+ }
71
+ load() {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
74
+ yield Promise.all(chunks.map((chunk) => {
75
+ return this.loadChunk(chunk);
76
+ }));
77
+ });
78
+ }
79
+ loadChunk(accountsToLoad) {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ if (accountsToLoad.length === 0) {
82
+ return;
83
+ }
84
+ const args = [
85
+ accountsToLoad.map((accountToLoad) => {
86
+ return accountToLoad.publicKey.toBase58();
87
+ }),
88
+ { commitment: this.commitment },
89
+ ];
90
+ let rpcResponse;
91
+ try {
92
+ // @ts-ignore
93
+ rpcResponse = yield this.connection._rpcRequest('getMultipleAccounts', args);
94
+ }
95
+ catch (e) {
96
+ for (const [_, callback] of this.errorCallbacks) {
97
+ callback(e);
98
+ }
99
+ return;
100
+ }
101
+ const newSlot = rpcResponse.result.context.slot;
102
+ for (const i in accountsToLoad) {
103
+ const accountToLoad = accountsToLoad[i];
104
+ const key = accountToLoad.publicKey.toString();
105
+ const oldRPCResponse = this.accountData.get(key);
106
+ let newBuffer = undefined;
107
+ if (rpcResponse.result.value[i]) {
108
+ const raw = rpcResponse.result.value[i].data[0];
109
+ const dataType = rpcResponse.result.value[i].data[1];
110
+ newBuffer = Buffer.from(raw, dataType);
111
+ }
112
+ if (!oldRPCResponse) {
113
+ this.accountData.set(key, {
114
+ slot: newSlot,
115
+ buffer: newBuffer,
116
+ });
117
+ this.handleAccountCallbacks(accountToLoad, newBuffer);
118
+ continue;
119
+ }
120
+ if (newSlot <= oldRPCResponse.slot) {
121
+ continue;
122
+ }
123
+ const oldBuffer = oldRPCResponse.buffer;
124
+ if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
125
+ this.accountData.set(key, {
126
+ slot: newSlot,
127
+ buffer: newBuffer,
128
+ });
129
+ this.handleAccountCallbacks(accountToLoad, newBuffer);
130
+ }
131
+ }
132
+ });
133
+ }
134
+ handleAccountCallbacks(accountToLoad, buffer) {
135
+ for (const [_, callback] of accountToLoad.callbacks) {
136
+ callback(buffer);
137
+ }
138
+ }
139
+ getAccountData(publicKey) {
140
+ const accountData = this.accountData.get(publicKey.toString());
141
+ return accountData === null || accountData === void 0 ? void 0 : accountData.buffer;
142
+ }
143
+ startPolling() {
144
+ if (this.intervalId) {
145
+ return;
146
+ }
147
+ this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
148
+ }
149
+ stopPolling() {
150
+ if (this.intervalId) {
151
+ clearInterval(this.intervalId);
152
+ this.intervalId = undefined;
153
+ }
154
+ }
155
+ }
156
+ exports.BulkAccountLoader = BulkAccountLoader;
@@ -0,0 +1,7 @@
1
+ import { ClearingHouseUser } from '../clearingHouseUser';
2
+ import { BulkAccountLoader } from './bulkAccountLoader';
3
+ /**
4
+ * @param users
5
+ * @param accountLoader
6
+ */
7
+ export declare function bulkPollingUserSubscribe(users: ClearingHouseUser[], accountLoader: BulkAccountLoader): Promise<void>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.bulkPollingUserSubscribe = void 0;
13
+ /**
14
+ * @param users
15
+ * @param accountLoader
16
+ */
17
+ function bulkPollingUserSubscribe(users, accountLoader) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ yield Promise.all(users.map((user) => {
20
+ return user.accountSubscriber.addToAccountLoader();
21
+ }));
22
+ yield accountLoader.load();
23
+ yield Promise.all(users.map((user) => __awaiter(this, void 0, void 0, function* () {
24
+ return user.subscribe();
25
+ })));
26
+ });
27
+ }
28
+ exports.bulkPollingUserSubscribe = bulkPollingUserSubscribe;
@@ -0,0 +1,49 @@
1
+ /// <reference types="node" />
2
+ import { AccountToPoll, ClearingHouseAccountEvents, ClearingHouseAccountSubscriber, ClearingHouseAccountTypes } from './types';
3
+ import { Program } from '@project-serum/anchor';
4
+ import StrictEventEmitter from 'strict-event-emitter-types';
5
+ import { EventEmitter } from 'events';
6
+ import { DepositHistoryAccount, ExtendedCurveHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, LiquidationHistoryAccount, MarketsAccount, OrderHistoryAccount, OrderStateAccount, StateAccount, TradeHistoryAccount } from '../types';
7
+ import { BulkAccountLoader } from './bulkAccountLoader';
8
+ import { ClearingHouseConfigType } from '../factory/clearingHouse';
9
+ export declare class PollingClearingHouseAccountSubscriber implements ClearingHouseAccountSubscriber {
10
+ isSubscribed: boolean;
11
+ program: Program;
12
+ eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
13
+ accountLoader: BulkAccountLoader;
14
+ accountsToPoll: Map<string, AccountToPoll>;
15
+ errorCallbackId?: string;
16
+ state?: StateAccount;
17
+ markets?: MarketsAccount;
18
+ orderState?: OrderStateAccount;
19
+ tradeHistory?: TradeHistoryAccount;
20
+ depositHistory?: DepositHistoryAccount;
21
+ fundingPaymentHistory?: FundingPaymentHistoryAccount;
22
+ fundingRateHistory?: FundingRateHistoryAccount;
23
+ liquidationHistory?: LiquidationHistoryAccount;
24
+ extendedCurveHistory: ExtendedCurveHistoryAccount;
25
+ orderHistory?: OrderHistoryAccount;
26
+ optionalExtraSubscriptions: ClearingHouseAccountTypes[];
27
+ type: ClearingHouseConfigType;
28
+ private isSubscribing;
29
+ private subscriptionPromise;
30
+ private subscriptionPromiseResolver;
31
+ constructor(program: Program, accountLoader: BulkAccountLoader);
32
+ subscribe(optionalSubscriptions?: ClearingHouseAccountTypes[]): Promise<boolean>;
33
+ updateAccountsToPoll(): Promise<void>;
34
+ addToAccountLoader(): Promise<void>;
35
+ fetch(): Promise<void>;
36
+ unsubscribe(): Promise<void>;
37
+ assertIsSubscribed(): void;
38
+ assertOptionalIsSubscribed(optionalSubscription: ClearingHouseAccountTypes): void;
39
+ getStateAccount(): StateAccount;
40
+ getMarketsAccount(): MarketsAccount;
41
+ getOrderStateAccount(): OrderStateAccount;
42
+ getTradeHistoryAccount(): TradeHistoryAccount;
43
+ getDepositHistoryAccount(): DepositHistoryAccount;
44
+ getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount;
45
+ getFundingRateHistoryAccount(): FundingRateHistoryAccount;
46
+ getCurveHistoryAccount(): ExtendedCurveHistoryAccount;
47
+ getLiquidationHistoryAccount(): LiquidationHistoryAccount;
48
+ getOrderHistoryAccount(): OrderHistoryAccount;
49
+ }
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PollingClearingHouseAccountSubscriber = void 0;
13
+ const types_1 = require("./types");
14
+ const events_1 = require("events");
15
+ const addresses_1 = require("../addresses");
16
+ const utils_1 = require("./utils");
17
+ class PollingClearingHouseAccountSubscriber {
18
+ constructor(program, accountLoader) {
19
+ this.accountsToPoll = new Map();
20
+ this.optionalExtraSubscriptions = [];
21
+ this.type = 'polling';
22
+ this.isSubscribing = false;
23
+ this.isSubscribed = false;
24
+ this.program = program;
25
+ this.eventEmitter = new events_1.EventEmitter();
26
+ this.accountLoader = accountLoader;
27
+ }
28
+ subscribe(optionalSubscriptions) {
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ if (this.isSubscribed) {
31
+ return true;
32
+ }
33
+ if (this.isSubscribing) {
34
+ return yield this.subscriptionPromise;
35
+ }
36
+ this.optionalExtraSubscriptions = optionalSubscriptions;
37
+ this.isSubscribing = true;
38
+ this.subscriptionPromise = new Promise((res) => {
39
+ this.subscriptionPromiseResolver = res;
40
+ });
41
+ yield this.updateAccountsToPoll();
42
+ yield this.addToAccountLoader();
43
+ yield this.fetch();
44
+ this.eventEmitter.emit('update');
45
+ this.isSubscribing = false;
46
+ this.isSubscribed = true;
47
+ this.subscriptionPromiseResolver(true);
48
+ return true;
49
+ });
50
+ }
51
+ updateAccountsToPoll() {
52
+ var _a, _b, _c, _d, _e, _f, _g;
53
+ return __awaiter(this, void 0, void 0, function* () {
54
+ if (this.accountsToPoll.size > 0) {
55
+ return;
56
+ }
57
+ const statePublicKey = yield addresses_1.getClearingHouseStateAccountPublicKey(this.program.programId);
58
+ const state = (yield this.program.account.state.fetch(statePublicKey));
59
+ this.accountsToPoll.set(statePublicKey.toString(), {
60
+ key: 'state',
61
+ publicKey: statePublicKey,
62
+ eventType: 'stateAccountUpdate',
63
+ });
64
+ this.accountsToPoll.set(state.markets.toString(), {
65
+ key: 'markets',
66
+ publicKey: state.markets,
67
+ eventType: 'marketsAccountUpdate',
68
+ });
69
+ this.accountsToPoll.set(state.orderState.toString(), {
70
+ key: 'orderState',
71
+ publicKey: state.orderState,
72
+ eventType: 'orderStateAccountUpdate',
73
+ });
74
+ if ((_a = this.optionalExtraSubscriptions) === null || _a === void 0 ? void 0 : _a.includes('tradeHistoryAccount')) {
75
+ this.accountsToPoll.set(state.tradeHistory.toString(), {
76
+ key: 'tradeHistory',
77
+ publicKey: state.tradeHistory,
78
+ eventType: 'tradeHistoryAccountUpdate',
79
+ });
80
+ }
81
+ if ((_b = this.optionalExtraSubscriptions) === null || _b === void 0 ? void 0 : _b.includes('depositHistoryAccount')) {
82
+ this.accountsToPoll.set(state.depositHistory.toString(), {
83
+ key: 'depositHistory',
84
+ publicKey: state.depositHistory,
85
+ eventType: 'depositHistoryAccountUpdate',
86
+ });
87
+ }
88
+ if ((_c = this.optionalExtraSubscriptions) === null || _c === void 0 ? void 0 : _c.includes('fundingPaymentHistoryAccount')) {
89
+ this.accountsToPoll.set(state.fundingPaymentHistory.toString(), {
90
+ key: 'fundingPaymentHistory',
91
+ publicKey: state.fundingPaymentHistory,
92
+ eventType: 'fundingPaymentHistoryAccountUpdate',
93
+ });
94
+ }
95
+ if ((_d = this.optionalExtraSubscriptions) === null || _d === void 0 ? void 0 : _d.includes('fundingRateHistoryAccount')) {
96
+ this.accountsToPoll.set(state.fundingRateHistory.toString(), {
97
+ key: 'fundingRateHistory',
98
+ publicKey: state.fundingRateHistory,
99
+ eventType: 'fundingRateHistoryAccountUpdate',
100
+ });
101
+ }
102
+ if ((_e = this.optionalExtraSubscriptions) === null || _e === void 0 ? void 0 : _e.includes('curveHistoryAccount')) {
103
+ this.accountsToPoll.set(state.extendedCurveHistory.toString(), {
104
+ key: 'extendedCurveHistory',
105
+ publicKey: state.extendedCurveHistory,
106
+ eventType: 'curveHistoryAccountUpdate',
107
+ });
108
+ }
109
+ if ((_f = this.optionalExtraSubscriptions) === null || _f === void 0 ? void 0 : _f.includes('liquidationHistoryAccount')) {
110
+ this.accountsToPoll.set(state.liquidationHistory.toString(), {
111
+ key: 'liquidationHistory',
112
+ publicKey: state.liquidationHistory,
113
+ eventType: 'liquidationHistoryAccountUpdate',
114
+ });
115
+ }
116
+ if ((_g = this.optionalExtraSubscriptions) === null || _g === void 0 ? void 0 : _g.includes('orderHistoryAccount')) {
117
+ const orderState = (yield this.program.account.orderState.fetch(state.orderState));
118
+ this.accountsToPoll.set(orderState.orderHistory.toString(), {
119
+ key: 'orderHistory',
120
+ publicKey: orderState.orderHistory,
121
+ eventType: 'orderHistoryAccountUpdate',
122
+ });
123
+ }
124
+ });
125
+ }
126
+ addToAccountLoader() {
127
+ return __awaiter(this, void 0, void 0, function* () {
128
+ for (const [_, accountToPoll] of this.accountsToPoll) {
129
+ accountToPoll.callbackId = this.accountLoader.addAccount(accountToPoll.publicKey, (buffer) => {
130
+ const account = this.program.account[accountToPoll.key].coder.accounts.decode(utils_1.capitalize(accountToPoll.key), buffer);
131
+ this[accountToPoll.key] = account;
132
+ // @ts-ignore
133
+ this.eventEmitter.emit(accountToPoll.eventType, account);
134
+ this.eventEmitter.emit('update');
135
+ });
136
+ }
137
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
138
+ this.eventEmitter.emit('error', error);
139
+ });
140
+ });
141
+ }
142
+ fetch() {
143
+ return __awaiter(this, void 0, void 0, function* () {
144
+ yield this.accountLoader.load();
145
+ for (const [_, accountToPoll] of this.accountsToPoll) {
146
+ const buffer = this.accountLoader.getAccountData(accountToPoll.publicKey);
147
+ if (buffer) {
148
+ this[accountToPoll.key] = this.program.account[accountToPoll.key].coder.accounts.decode(utils_1.capitalize(accountToPoll.key), buffer);
149
+ }
150
+ }
151
+ });
152
+ }
153
+ unsubscribe() {
154
+ return __awaiter(this, void 0, void 0, function* () {
155
+ if (!this.isSubscribed) {
156
+ return;
157
+ }
158
+ for (const [_, accountToPoll] of this.accountsToPoll) {
159
+ this.accountLoader.removeAccount(accountToPoll.publicKey, accountToPoll.callbackId);
160
+ }
161
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
162
+ this.errorCallbackId = undefined;
163
+ this.accountsToPoll.clear();
164
+ this.isSubscribed = false;
165
+ });
166
+ }
167
+ assertIsSubscribed() {
168
+ if (!this.isSubscribed) {
169
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
170
+ }
171
+ }
172
+ assertOptionalIsSubscribed(optionalSubscription) {
173
+ if (!this.isSubscribed) {
174
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
175
+ }
176
+ if (!this.optionalExtraSubscriptions.includes(optionalSubscription)) {
177
+ throw new types_1.NotSubscribedError(`You need to subscribe to the optional Clearing House account "${optionalSubscription}" to use this method`);
178
+ }
179
+ }
180
+ getStateAccount() {
181
+ this.assertIsSubscribed();
182
+ return this.state;
183
+ }
184
+ getMarketsAccount() {
185
+ this.assertIsSubscribed();
186
+ return this.markets;
187
+ }
188
+ getOrderStateAccount() {
189
+ this.assertIsSubscribed();
190
+ return this.orderState;
191
+ }
192
+ getTradeHistoryAccount() {
193
+ this.assertIsSubscribed();
194
+ this.assertOptionalIsSubscribed('tradeHistoryAccount');
195
+ return this.tradeHistory;
196
+ }
197
+ getDepositHistoryAccount() {
198
+ this.assertIsSubscribed();
199
+ this.assertOptionalIsSubscribed('depositHistoryAccount');
200
+ return this.depositHistory;
201
+ }
202
+ getFundingPaymentHistoryAccount() {
203
+ this.assertIsSubscribed();
204
+ this.assertOptionalIsSubscribed('fundingPaymentHistoryAccount');
205
+ return this.fundingPaymentHistory;
206
+ }
207
+ getFundingRateHistoryAccount() {
208
+ this.assertIsSubscribed();
209
+ this.assertOptionalIsSubscribed('fundingRateHistoryAccount');
210
+ return this.fundingRateHistory;
211
+ }
212
+ getCurveHistoryAccount() {
213
+ this.assertIsSubscribed();
214
+ this.assertOptionalIsSubscribed('curveHistoryAccount');
215
+ return this.extendedCurveHistory;
216
+ }
217
+ getLiquidationHistoryAccount() {
218
+ this.assertIsSubscribed();
219
+ this.assertOptionalIsSubscribed('liquidationHistoryAccount');
220
+ return this.liquidationHistory;
221
+ }
222
+ getOrderHistoryAccount() {
223
+ this.assertIsSubscribed();
224
+ this.assertOptionalIsSubscribed('orderHistoryAccount');
225
+ return this.orderHistory;
226
+ }
227
+ }
228
+ exports.PollingClearingHouseAccountSubscriber = PollingClearingHouseAccountSubscriber;
@@ -0,0 +1,25 @@
1
+ /// <reference types="node" />
2
+ import { TokenAccountEvents, TokenAccountSubscriber } from './types';
3
+ import { Program } from '@project-serum/anchor';
4
+ import StrictEventEmitter from 'strict-event-emitter-types';
5
+ import { EventEmitter } from 'events';
6
+ import { PublicKey } from '@solana/web3.js';
7
+ import { BulkAccountLoader } from './bulkAccountLoader';
8
+ import { AccountInfo } from '@solana/spl-token';
9
+ export declare class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
10
+ isSubscribed: boolean;
11
+ program: Program;
12
+ eventEmitter: StrictEventEmitter<EventEmitter, TokenAccountEvents>;
13
+ publicKey: PublicKey;
14
+ accountLoader: BulkAccountLoader;
15
+ callbackId?: string;
16
+ errorCallbackId?: string;
17
+ tokenAccount?: AccountInfo;
18
+ constructor(publicKey: PublicKey, accountLoader: BulkAccountLoader);
19
+ subscribe(): Promise<boolean>;
20
+ addToAccountLoader(): void;
21
+ fetch(): Promise<void>;
22
+ unsubscribe(): Promise<void>;
23
+ assertIsSubscribed(): void;
24
+ getTokenAccount(): AccountInfo;
25
+ }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PollingTokenAccountSubscriber = void 0;
13
+ const types_1 = require("./types");
14
+ const events_1 = require("events");
15
+ const token_1 = require("../token");
16
+ class PollingTokenAccountSubscriber {
17
+ constructor(publicKey, accountLoader) {
18
+ this.isSubscribed = false;
19
+ this.publicKey = publicKey;
20
+ this.accountLoader = accountLoader;
21
+ this.eventEmitter = new events_1.EventEmitter();
22
+ }
23
+ subscribe() {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ if (this.isSubscribed) {
26
+ return true;
27
+ }
28
+ this.addToAccountLoader();
29
+ yield this.fetch();
30
+ this.eventEmitter.emit('update');
31
+ this.isSubscribed = true;
32
+ return true;
33
+ });
34
+ }
35
+ addToAccountLoader() {
36
+ if (this.callbackId) {
37
+ return;
38
+ }
39
+ this.callbackId = this.accountLoader.addAccount(this.publicKey, (buffer) => {
40
+ const tokenAccount = token_1.parseTokenAccount(buffer);
41
+ this.tokenAccount = tokenAccount;
42
+ // @ts-ignore
43
+ this.eventEmitter.emit('tokenAccountUpdate', tokenAccount);
44
+ this.eventEmitter.emit('update');
45
+ });
46
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
47
+ this.eventEmitter.emit('error', error);
48
+ });
49
+ }
50
+ fetch() {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ yield this.accountLoader.load();
53
+ const buffer = this.accountLoader.getAccountData(this.publicKey);
54
+ this.tokenAccount = token_1.parseTokenAccount(buffer);
55
+ });
56
+ }
57
+ unsubscribe() {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ if (!this.isSubscribed) {
60
+ return;
61
+ }
62
+ this.accountLoader.removeAccount(this.publicKey, this.callbackId);
63
+ this.callbackId = undefined;
64
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
65
+ this.errorCallbackId = undefined;
66
+ this.isSubscribed = false;
67
+ });
68
+ }
69
+ assertIsSubscribed() {
70
+ if (!this.isSubscribed) {
71
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
72
+ }
73
+ }
74
+ getTokenAccount() {
75
+ this.assertIsSubscribed();
76
+ return this.tokenAccount;
77
+ }
78
+ }
79
+ exports.PollingTokenAccountSubscriber = PollingTokenAccountSubscriber;
@@ -0,0 +1,32 @@
1
+ /// <reference types="node" />
2
+ import { AccountToPoll, UserAccountEvents, UserAccountSubscriber } from './types';
3
+ import { Program } from '@project-serum/anchor';
4
+ import StrictEventEmitter from 'strict-event-emitter-types';
5
+ import { EventEmitter } from 'events';
6
+ import { PublicKey } from '@solana/web3.js';
7
+ import { UserAccount, UserOrdersAccount, UserPositionsAccount } from '../types';
8
+ import { BulkAccountLoader } from './bulkAccountLoader';
9
+ import { ClearingHouseConfigType } from '../factory/clearingHouse';
10
+ export declare class PollingUserAccountSubscriber implements UserAccountSubscriber {
11
+ isSubscribed: boolean;
12
+ program: Program;
13
+ eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
14
+ authority: PublicKey;
15
+ accountLoader: BulkAccountLoader;
16
+ accountsToPoll: Map<string, AccountToPoll>;
17
+ errorCallbackId?: string;
18
+ user?: UserAccount;
19
+ userPositions?: UserPositionsAccount;
20
+ userOrders?: UserOrdersAccount;
21
+ type: ClearingHouseConfigType;
22
+ constructor(program: Program, authority: PublicKey, accountLoader: BulkAccountLoader);
23
+ subscribe(): Promise<boolean>;
24
+ addToAccountLoader(): Promise<void>;
25
+ fetchIfUnloaded(): Promise<void>;
26
+ fetch(): Promise<void>;
27
+ unsubscribe(): Promise<void>;
28
+ assertIsSubscribed(): void;
29
+ getUserAccount(): UserAccount;
30
+ getUserPositionsAccount(): UserPositionsAccount;
31
+ getUserOrdersAccount(): UserOrdersAccount;
32
+ }