@drift-labs/sdk 0.2.0-master.0 → 0.2.0-master.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 (121) hide show
  1. package/lib/admin.d.ts +8 -5
  2. package/lib/admin.js +43 -11
  3. package/lib/clearingHouse.d.ts +28 -18
  4. package/lib/clearingHouse.js +366 -143
  5. package/lib/clearingHouseUser.d.ts +2 -2
  6. package/lib/clearingHouseUser.js +8 -17
  7. package/lib/config.js +1 -1
  8. package/lib/constants/banks.js +9 -2
  9. package/lib/constants/numericConstants.d.ts +2 -0
  10. package/lib/constants/numericConstants.js +3 -1
  11. package/lib/factory/bigNum.d.ts +8 -2
  12. package/lib/factory/bigNum.js +14 -6
  13. package/lib/idl/clearing_house.json +805 -202
  14. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  15. package/lib/index.d.ts +3 -2
  16. package/lib/index.js +7 -2
  17. package/lib/math/amm.d.ts +6 -1
  18. package/lib/math/amm.js +124 -41
  19. package/lib/math/auction.js +4 -1
  20. package/lib/math/orders.d.ts +2 -2
  21. package/lib/math/orders.js +18 -11
  22. package/lib/math/position.js +3 -1
  23. package/lib/math/repeg.js +1 -1
  24. package/lib/math/trade.d.ts +1 -1
  25. package/lib/math/trade.js +7 -10
  26. package/lib/orderParams.d.ts +14 -5
  27. package/lib/orderParams.js +8 -96
  28. package/lib/orders.d.ts +1 -2
  29. package/lib/orders.js +6 -85
  30. package/lib/slot/SlotSubscriber.d.ts +7 -0
  31. package/lib/slot/SlotSubscriber.js +3 -0
  32. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +7 -5
  33. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +41 -40
  34. package/lib/tx/utils.js +1 -1
  35. package/lib/types.d.ts +137 -14
  36. package/lib/types.js +53 -1
  37. package/lib/util/computeUnits.js +1 -1
  38. package/package.json +3 -3
  39. package/src/accounts/bulkAccountLoader.js +197 -0
  40. package/src/accounts/bulkUserSubscription.js +33 -0
  41. package/src/accounts/fetch.js +29 -0
  42. package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
  43. package/src/accounts/pollingOracleSubscriber.js +93 -0
  44. package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
  45. package/src/accounts/pollingUserAccountSubscriber.js +132 -0
  46. package/src/accounts/types.js +10 -0
  47. package/src/accounts/utils.js +7 -0
  48. package/src/accounts/webSocketAccountSubscriber.js +93 -0
  49. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
  50. package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
  51. package/src/addresses/marketAddresses.js +26 -0
  52. package/src/addresses/pda.js +104 -0
  53. package/src/admin.ts +66 -14
  54. package/src/assert/assert.js +9 -0
  55. package/src/clearingHouse.ts +558 -230
  56. package/src/clearingHouseUser.ts +12 -23
  57. package/src/config.ts +1 -1
  58. package/src/constants/banks.ts +9 -2
  59. package/src/constants/numericConstants.ts +2 -0
  60. package/src/events/eventList.js +77 -0
  61. package/src/events/eventSubscriber.js +139 -0
  62. package/src/events/fetchLogs.js +50 -0
  63. package/src/events/pollingLogProvider.js +64 -0
  64. package/src/events/sort.js +44 -0
  65. package/src/events/txEventCache.js +71 -0
  66. package/src/events/types.js +20 -0
  67. package/src/events/webSocketLogProvider.js +41 -0
  68. package/src/examples/makeTradeExample.js +80 -0
  69. package/src/factory/bigNum.js +364 -0
  70. package/src/factory/bigNum.ts +26 -9
  71. package/src/factory/oracleClient.js +20 -0
  72. package/src/idl/clearing_house.json +805 -202
  73. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  74. package/src/index.js +100 -0
  75. package/src/index.ts +3 -2
  76. package/src/math/amm.js +369 -0
  77. package/src/math/amm.ts +207 -52
  78. package/src/math/auction.js +42 -0
  79. package/src/math/auction.ts +5 -1
  80. package/src/math/bankBalance.js +75 -0
  81. package/src/math/conversion.js +11 -0
  82. package/src/math/funding.js +248 -0
  83. package/src/math/market.js +57 -0
  84. package/src/math/oracles.js +26 -0
  85. package/src/math/orders.js +110 -0
  86. package/src/math/orders.ts +17 -13
  87. package/src/math/position.js +140 -0
  88. package/src/math/position.ts +5 -1
  89. package/src/math/repeg.js +128 -0
  90. package/src/math/repeg.ts +2 -1
  91. package/src/math/state.js +15 -0
  92. package/src/math/trade.js +253 -0
  93. package/src/math/trade.ts +23 -25
  94. package/src/math/utils.js +0 -1
  95. package/src/mockUSDCFaucet.js +280 -0
  96. package/src/oracles/oracleClientCache.js +19 -0
  97. package/src/oracles/pythClient.js +46 -0
  98. package/src/oracles/quoteAssetOracleClient.js +32 -0
  99. package/src/oracles/switchboardClient.js +69 -0
  100. package/src/oracles/types.js +2 -0
  101. package/src/orderParams.js +20 -0
  102. package/src/orderParams.ts +20 -141
  103. package/src/orders.js +134 -0
  104. package/src/orders.ts +7 -131
  105. package/src/slot/SlotSubscriber.js +39 -0
  106. package/src/slot/SlotSubscriber.ts +11 -1
  107. package/src/token/index.js +38 -0
  108. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +48 -59
  109. package/src/tx/retryTxSender.js +188 -0
  110. package/src/tx/types.js +2 -0
  111. package/src/tx/utils.js +17 -0
  112. package/src/tx/utils.ts +1 -1
  113. package/src/types.js +114 -0
  114. package/src/types.ts +132 -16
  115. package/src/userName.js +20 -0
  116. package/src/util/computeUnits.ts +1 -1
  117. package/src/util/promiseTimeout.js +14 -0
  118. package/src/util/tps.js +27 -0
  119. package/src/wallet.js +35 -0
  120. package/src/util/computeUnits.js +0 -17
  121. package/src/util/computeUnits.js.map +0 -1
@@ -0,0 +1,311 @@
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 pda_1 = require("../addresses/pda");
16
+ const utils_1 = require("./utils");
17
+ const web3_js_1 = require("@solana/web3.js");
18
+ const oracleClientCache_1 = require("../oracles/oracleClientCache");
19
+ const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
20
+ class PollingClearingHouseAccountSubscriber {
21
+ constructor(program, accountLoader, marketIndexes, bankIndexes, oracleInfos) {
22
+ this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
23
+ this.accountsToPoll = new Map();
24
+ this.oraclesToPoll = new Map();
25
+ this.market = new Map();
26
+ this.bank = new Map();
27
+ this.oracles = new Map();
28
+ this.isSubscribing = false;
29
+ this.isSubscribed = false;
30
+ this.program = program;
31
+ this.eventEmitter = new events_1.EventEmitter();
32
+ this.accountLoader = accountLoader;
33
+ this.marketIndexes = marketIndexes;
34
+ this.bankIndexes = bankIndexes;
35
+ this.oracleInfos = oracleInfos;
36
+ }
37
+ subscribe() {
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ if (this.isSubscribed) {
40
+ return true;
41
+ }
42
+ if (this.isSubscribing) {
43
+ return yield this.subscriptionPromise;
44
+ }
45
+ this.isSubscribing = true;
46
+ this.subscriptionPromise = new Promise((res) => {
47
+ this.subscriptionPromiseResolver = res;
48
+ });
49
+ yield this.updateAccountsToPoll();
50
+ yield this.updateOraclesToPoll();
51
+ yield this.addToAccountLoader();
52
+ let subscriptionSucceeded = false;
53
+ let retries = 0;
54
+ while (!subscriptionSucceeded && retries < 5) {
55
+ yield this.fetch();
56
+ subscriptionSucceeded = this.didSubscriptionSucceed();
57
+ retries++;
58
+ }
59
+ if (subscriptionSucceeded) {
60
+ this.eventEmitter.emit('update');
61
+ }
62
+ this.isSubscribing = false;
63
+ this.isSubscribed = subscriptionSucceeded;
64
+ this.subscriptionPromiseResolver(subscriptionSucceeded);
65
+ return subscriptionSucceeded;
66
+ });
67
+ }
68
+ updateAccountsToPoll() {
69
+ return __awaiter(this, void 0, void 0, function* () {
70
+ if (this.accountsToPoll.size > 0) {
71
+ return;
72
+ }
73
+ const accounts = yield this.getClearingHouseAccounts();
74
+ this.accountsToPoll.set(accounts.state.toString(), {
75
+ key: 'state',
76
+ publicKey: accounts.state,
77
+ eventType: 'stateAccountUpdate',
78
+ });
79
+ yield this.updateMarketAccountsToPoll();
80
+ yield this.updateBankAccountsToPoll();
81
+ });
82
+ }
83
+ updateMarketAccountsToPoll() {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ for (const marketIndex of this.marketIndexes) {
86
+ yield this.addMarketAccountToPoll(marketIndex);
87
+ }
88
+ return true;
89
+ });
90
+ }
91
+ addMarketAccountToPoll(marketIndex) {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ const marketPublicKey = yield pda_1.getMarketPublicKey(this.program.programId, marketIndex);
94
+ this.accountsToPoll.set(marketPublicKey.toString(), {
95
+ key: 'market',
96
+ publicKey: marketPublicKey,
97
+ eventType: 'marketAccountUpdate',
98
+ mapKey: marketIndex.toNumber(),
99
+ });
100
+ return true;
101
+ });
102
+ }
103
+ updateBankAccountsToPoll() {
104
+ return __awaiter(this, void 0, void 0, function* () {
105
+ for (const bankIndex of this.bankIndexes) {
106
+ yield this.addBankAccountToPoll(bankIndex);
107
+ }
108
+ return true;
109
+ });
110
+ }
111
+ addBankAccountToPoll(bankIndex) {
112
+ return __awaiter(this, void 0, void 0, function* () {
113
+ const bankPublicKey = yield pda_1.getBankPublicKey(this.program.programId, bankIndex);
114
+ this.accountsToPoll.set(bankPublicKey.toString(), {
115
+ key: 'bank',
116
+ publicKey: bankPublicKey,
117
+ eventType: 'bankAccountUpdate',
118
+ mapKey: bankIndex.toNumber(),
119
+ });
120
+ return true;
121
+ });
122
+ }
123
+ updateOraclesToPoll() {
124
+ for (const oracleInfo of this.oracleInfos) {
125
+ if (!oracleInfo.publicKey.equals(web3_js_1.PublicKey.default)) {
126
+ this.addOracleToPoll(oracleInfo);
127
+ }
128
+ }
129
+ return true;
130
+ }
131
+ addOracleToPoll(oracleInfo) {
132
+ this.oraclesToPoll.set(oracleInfo.publicKey.toString(), {
133
+ publicKey: oracleInfo.publicKey,
134
+ source: oracleInfo.source,
135
+ });
136
+ return true;
137
+ }
138
+ getClearingHouseAccounts() {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ const statePublicKey = yield pda_1.getClearingHouseStateAccountPublicKey(this.program.programId);
141
+ const accounts = {
142
+ state: statePublicKey,
143
+ };
144
+ return accounts;
145
+ });
146
+ }
147
+ addToAccountLoader() {
148
+ return __awaiter(this, void 0, void 0, function* () {
149
+ for (const [_, accountToPoll] of this.accountsToPoll) {
150
+ this.addAccountToAccountLoader(accountToPoll);
151
+ }
152
+ for (const [_, oracleToPoll] of this.oraclesToPoll) {
153
+ this.addOracleToAccountLoader(oracleToPoll);
154
+ }
155
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
156
+ this.eventEmitter.emit('error', error);
157
+ });
158
+ });
159
+ }
160
+ addAccountToAccountLoader(accountToPoll) {
161
+ accountToPoll.callbackId = this.accountLoader.addAccount(accountToPoll.publicKey, (buffer, slot) => {
162
+ if (!buffer)
163
+ return;
164
+ const account = this.program.account[accountToPoll.key].coder.accounts.decode(utils_1.capitalize(accountToPoll.key), buffer);
165
+ const dataAndSlot = {
166
+ data: account,
167
+ slot,
168
+ };
169
+ if (accountToPoll.mapKey != undefined) {
170
+ this[accountToPoll.key].set(accountToPoll.mapKey, dataAndSlot);
171
+ }
172
+ else {
173
+ this[accountToPoll.key] = dataAndSlot;
174
+ }
175
+ // @ts-ignore
176
+ this.eventEmitter.emit(accountToPoll.eventType, account);
177
+ this.eventEmitter.emit('update');
178
+ if (!this.isSubscribed) {
179
+ this.isSubscribed = this.didSubscriptionSucceed();
180
+ }
181
+ });
182
+ }
183
+ addOracleToAccountLoader(oracleToPoll) {
184
+ const oracleClient = this.oracleClientCache.get(oracleToPoll.source, this.program.provider.connection);
185
+ oracleToPoll.callbackId = this.accountLoader.addAccount(oracleToPoll.publicKey, (buffer, slot) => {
186
+ if (!buffer)
187
+ return;
188
+ const oraclePriceData = oracleClient.getOraclePriceDataFromBuffer(buffer);
189
+ const dataAndSlot = {
190
+ data: oraclePriceData,
191
+ slot,
192
+ };
193
+ this.oracles.set(oracleToPoll.publicKey.toString(), dataAndSlot);
194
+ this.eventEmitter.emit('oraclePriceUpdate', oracleToPoll.publicKey, oraclePriceData);
195
+ this.eventEmitter.emit('update');
196
+ });
197
+ }
198
+ fetch() {
199
+ return __awaiter(this, void 0, void 0, function* () {
200
+ yield this.accountLoader.load();
201
+ for (const [_, accountToPoll] of this.accountsToPoll) {
202
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(accountToPoll.publicKey);
203
+ if (buffer) {
204
+ const account = this.program.account[accountToPoll.key].coder.accounts.decode(utils_1.capitalize(accountToPoll.key), buffer);
205
+ if (accountToPoll.mapKey != undefined) {
206
+ this[accountToPoll.key].set(accountToPoll.mapKey, {
207
+ data: account,
208
+ slot,
209
+ });
210
+ }
211
+ else {
212
+ this[accountToPoll.key] = {
213
+ data: account,
214
+ slot,
215
+ };
216
+ }
217
+ }
218
+ }
219
+ for (const [_, oracleToPoll] of this.oraclesToPoll) {
220
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(oracleToPoll.publicKey);
221
+ if (buffer) {
222
+ const oracleClient = this.oracleClientCache.get(oracleToPoll.source, this.program.provider.connection);
223
+ const oraclePriceData = oracleClient.getOraclePriceDataFromBuffer(buffer);
224
+ this.oracles.set(oracleToPoll.publicKey.toString(), {
225
+ data: oraclePriceData,
226
+ slot,
227
+ });
228
+ }
229
+ }
230
+ });
231
+ }
232
+ didSubscriptionSucceed() {
233
+ if (this.state)
234
+ return true;
235
+ return false;
236
+ }
237
+ unsubscribe() {
238
+ return __awaiter(this, void 0, void 0, function* () {
239
+ if (!this.isSubscribed) {
240
+ return;
241
+ }
242
+ for (const [_, accountToPoll] of this.accountsToPoll) {
243
+ this.accountLoader.removeAccount(accountToPoll.publicKey, accountToPoll.callbackId);
244
+ }
245
+ for (const [_, oracleToPoll] of this.oraclesToPoll) {
246
+ this.accountLoader.removeAccount(oracleToPoll.publicKey, oracleToPoll.callbackId);
247
+ }
248
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
249
+ this.errorCallbackId = undefined;
250
+ this.accountsToPoll.clear();
251
+ this.oraclesToPoll.clear();
252
+ this.isSubscribed = false;
253
+ });
254
+ }
255
+ addBank(bankIndex) {
256
+ return __awaiter(this, void 0, void 0, function* () {
257
+ yield this.addBankAccountToPoll(bankIndex);
258
+ const accountToPoll = this.accountsToPoll.get(bankIndex.toString());
259
+ this.addAccountToAccountLoader(accountToPoll);
260
+ return true;
261
+ });
262
+ }
263
+ addMarket(marketIndex) {
264
+ return __awaiter(this, void 0, void 0, function* () {
265
+ yield this.addMarketAccountToPoll(marketIndex);
266
+ const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
267
+ this.addAccountToAccountLoader(accountToPoll);
268
+ return true;
269
+ });
270
+ }
271
+ addOracle(oracleInfo) {
272
+ return __awaiter(this, void 0, void 0, function* () {
273
+ if (oracleInfo.publicKey.equals(web3_js_1.PublicKey.default)) {
274
+ return true;
275
+ }
276
+ this.addOracleToPoll(oracleInfo);
277
+ const oracleToPoll = this.oraclesToPoll.get(oracleInfo.publicKey.toString());
278
+ this.addOracleToAccountLoader(oracleToPoll);
279
+ return true;
280
+ });
281
+ }
282
+ assertIsSubscribed() {
283
+ if (!this.isSubscribed) {
284
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
285
+ }
286
+ }
287
+ getStateAccountAndSlot() {
288
+ this.assertIsSubscribed();
289
+ return this.state;
290
+ }
291
+ getMarketAccountAndSlot(marketIndex) {
292
+ return this.market.get(marketIndex.toNumber());
293
+ }
294
+ getMarketAccountsAndSlots() {
295
+ return Array.from(this.market.values());
296
+ }
297
+ getBankAccountAndSlot(bankIndex) {
298
+ return this.bank.get(bankIndex.toNumber());
299
+ }
300
+ getOraclePriceDataAndSlot(oraclePublicKey) {
301
+ this.assertIsSubscribed();
302
+ if (oraclePublicKey.equals(web3_js_1.PublicKey.default)) {
303
+ return {
304
+ data: quoteAssetOracleClient_1.QUOTE_ORACLE_PRICE_DATA,
305
+ slot: 0,
306
+ };
307
+ }
308
+ return this.oracles.get(oraclePublicKey.toString());
309
+ }
310
+ }
311
+ exports.PollingClearingHouseAccountSubscriber = PollingClearingHouseAccountSubscriber;
@@ -0,0 +1,93 @@
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.PollingOracleSubscriber = void 0;
13
+ const types_1 = require("./types");
14
+ const events_1 = require("events");
15
+ class PollingOracleSubscriber {
16
+ constructor(publicKey, oracleClient, accountLoader) {
17
+ this.isSubscribed = false;
18
+ this.publicKey = publicKey;
19
+ this.oracleClient = oracleClient;
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
+ let subscriptionSucceeded = false;
30
+ let retries = 0;
31
+ while (!subscriptionSucceeded && retries < 5) {
32
+ yield this.fetch();
33
+ subscriptionSucceeded = this.didSubscriptionSucceed();
34
+ retries++;
35
+ }
36
+ if (subscriptionSucceeded) {
37
+ this.eventEmitter.emit('update');
38
+ }
39
+ this.isSubscribed = subscriptionSucceeded;
40
+ return subscriptionSucceeded;
41
+ });
42
+ }
43
+ addToAccountLoader() {
44
+ if (this.callbackId) {
45
+ return;
46
+ }
47
+ this.callbackId = this.accountLoader.addAccount(this.publicKey, (buffer, slot) => __awaiter(this, void 0, void 0, function* () {
48
+ const oraclePriceData = yield this.oracleClient.getOraclePriceDataFromBuffer(buffer);
49
+ this.oraclePriceData = { data: oraclePriceData, slot };
50
+ // @ts-ignore
51
+ this.eventEmitter.emit('oracleUpdate', oraclePriceData);
52
+ this.eventEmitter.emit('update');
53
+ }));
54
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
55
+ this.eventEmitter.emit('error', error);
56
+ });
57
+ }
58
+ fetch() {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ yield this.accountLoader.load();
61
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(this.publicKey);
62
+ this.oraclePriceData = {
63
+ data: yield this.oracleClient.getOraclePriceDataFromBuffer(buffer),
64
+ slot,
65
+ };
66
+ });
67
+ }
68
+ unsubscribe() {
69
+ return __awaiter(this, void 0, void 0, function* () {
70
+ if (!this.isSubscribed) {
71
+ return;
72
+ }
73
+ this.accountLoader.removeAccount(this.publicKey, this.callbackId);
74
+ this.callbackId = undefined;
75
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
76
+ this.errorCallbackId = undefined;
77
+ this.isSubscribed = false;
78
+ });
79
+ }
80
+ assertIsSubscribed() {
81
+ if (!this.isSubscribed) {
82
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
83
+ }
84
+ }
85
+ getOraclePriceData() {
86
+ this.assertIsSubscribed();
87
+ return this.oraclePriceData;
88
+ }
89
+ didSubscriptionSucceed() {
90
+ return !!this.oraclePriceData;
91
+ }
92
+ }
93
+ exports.PollingOracleSubscriber = PollingOracleSubscriber;
@@ -0,0 +1,90 @@
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
+ let subscriptionSucceeded = false;
30
+ let retries = 0;
31
+ while (!subscriptionSucceeded && retries < 5) {
32
+ yield this.fetch();
33
+ subscriptionSucceeded = this.didSubscriptionSucceed();
34
+ retries++;
35
+ }
36
+ if (subscriptionSucceeded) {
37
+ this.eventEmitter.emit('update');
38
+ }
39
+ this.isSubscribed = subscriptionSucceeded;
40
+ return subscriptionSucceeded;
41
+ });
42
+ }
43
+ addToAccountLoader() {
44
+ if (this.callbackId) {
45
+ return;
46
+ }
47
+ this.callbackId = this.accountLoader.addAccount(this.publicKey, (buffer, slot) => {
48
+ const tokenAccount = token_1.parseTokenAccount(buffer);
49
+ this.tokenAccountAndSlot = { data: tokenAccount, slot };
50
+ // @ts-ignore
51
+ this.eventEmitter.emit('tokenAccountUpdate', tokenAccount);
52
+ this.eventEmitter.emit('update');
53
+ });
54
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
55
+ this.eventEmitter.emit('error', error);
56
+ });
57
+ }
58
+ fetch() {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ yield this.accountLoader.load();
61
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(this.publicKey);
62
+ this.tokenAccountAndSlot = { data: token_1.parseTokenAccount(buffer), slot };
63
+ });
64
+ }
65
+ unsubscribe() {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ if (!this.isSubscribed) {
68
+ return;
69
+ }
70
+ this.accountLoader.removeAccount(this.publicKey, this.callbackId);
71
+ this.callbackId = undefined;
72
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
73
+ this.errorCallbackId = undefined;
74
+ this.isSubscribed = false;
75
+ });
76
+ }
77
+ assertIsSubscribed() {
78
+ if (!this.isSubscribed) {
79
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
80
+ }
81
+ }
82
+ getTokenAccountAndSlot() {
83
+ this.assertIsSubscribed();
84
+ return this.tokenAccountAndSlot;
85
+ }
86
+ didSubscriptionSucceed() {
87
+ return !!this.tokenAccountAndSlot;
88
+ }
89
+ }
90
+ exports.PollingTokenAccountSubscriber = PollingTokenAccountSubscriber;
@@ -0,0 +1,132 @@
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.PollingUserAccountSubscriber = void 0;
13
+ const types_1 = require("./types");
14
+ const events_1 = require("events");
15
+ const utils_1 = require("./utils");
16
+ class PollingUserAccountSubscriber {
17
+ constructor(program, userAccountPublicKey, accountLoader) {
18
+ this.accountsToPoll = new Map();
19
+ this.isSubscribed = false;
20
+ this.program = program;
21
+ this.accountLoader = accountLoader;
22
+ this.eventEmitter = new events_1.EventEmitter();
23
+ this.userAccountPublicKey = userAccountPublicKey;
24
+ }
25
+ subscribe() {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ if (this.isSubscribed) {
28
+ return true;
29
+ }
30
+ yield this.addToAccountLoader();
31
+ let subscriptionSucceeded = false;
32
+ let retries = 0;
33
+ while (!subscriptionSucceeded && retries < 5) {
34
+ yield this.fetchIfUnloaded();
35
+ subscriptionSucceeded = this.didSubscriptionSucceed();
36
+ retries++;
37
+ }
38
+ if (subscriptionSucceeded) {
39
+ this.eventEmitter.emit('update');
40
+ }
41
+ this.isSubscribed = subscriptionSucceeded;
42
+ return subscriptionSucceeded;
43
+ });
44
+ }
45
+ addToAccountLoader() {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ if (this.accountsToPoll.size > 0) {
48
+ return;
49
+ }
50
+ this.accountsToPoll.set(this.userAccountPublicKey.toString(), {
51
+ key: 'user',
52
+ publicKey: this.userAccountPublicKey,
53
+ eventType: 'userAccountUpdate',
54
+ });
55
+ for (const [_, accountToPoll] of this.accountsToPoll) {
56
+ accountToPoll.callbackId = this.accountLoader.addAccount(accountToPoll.publicKey, (buffer, slot) => {
57
+ if (!buffer) {
58
+ return;
59
+ }
60
+ const account = this.program.account[accountToPoll.key].coder.accounts.decode(utils_1.capitalize(accountToPoll.key), buffer);
61
+ this[accountToPoll.key] = { data: account, slot };
62
+ // @ts-ignore
63
+ this.eventEmitter.emit(accountToPoll.eventType, account);
64
+ this.eventEmitter.emit('update');
65
+ });
66
+ }
67
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
68
+ this.eventEmitter.emit('error', error);
69
+ });
70
+ });
71
+ }
72
+ fetchIfUnloaded() {
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ let shouldFetch = false;
75
+ for (const [_, accountToPoll] of this.accountsToPoll) {
76
+ if (this[accountToPoll.key] === undefined) {
77
+ shouldFetch = true;
78
+ break;
79
+ }
80
+ }
81
+ if (shouldFetch) {
82
+ yield this.fetch();
83
+ }
84
+ });
85
+ }
86
+ fetch() {
87
+ return __awaiter(this, void 0, void 0, function* () {
88
+ yield this.accountLoader.load();
89
+ for (const [_, accountToPoll] of this.accountsToPoll) {
90
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(accountToPoll.publicKey);
91
+ if (buffer) {
92
+ const account = this.program.account[accountToPoll.key].coder.accounts.decode(utils_1.capitalize(accountToPoll.key), buffer);
93
+ this[accountToPoll.key] = { data: account, slot };
94
+ }
95
+ }
96
+ });
97
+ }
98
+ didSubscriptionSucceed() {
99
+ let success = true;
100
+ for (const [_, accountToPoll] of this.accountsToPoll) {
101
+ if (!this[accountToPoll.key]) {
102
+ success = false;
103
+ break;
104
+ }
105
+ }
106
+ return success;
107
+ }
108
+ unsubscribe() {
109
+ return __awaiter(this, void 0, void 0, function* () {
110
+ if (!this.isSubscribed) {
111
+ return;
112
+ }
113
+ for (const [_, accountToPoll] of this.accountsToPoll) {
114
+ this.accountLoader.removeAccount(accountToPoll.publicKey, accountToPoll.callbackId);
115
+ }
116
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
117
+ this.errorCallbackId = undefined;
118
+ this.accountsToPoll.clear();
119
+ this.isSubscribed = false;
120
+ });
121
+ }
122
+ assertIsSubscribed() {
123
+ if (!this.isSubscribed) {
124
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
125
+ }
126
+ }
127
+ getUserAccountAndSlot() {
128
+ this.assertIsSubscribed();
129
+ return this.user;
130
+ }
131
+ }
132
+ exports.PollingUserAccountSubscriber = PollingUserAccountSubscriber;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NotSubscribedError = void 0;
4
+ class NotSubscribedError extends Error {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.name = 'NotSubscribedError';
8
+ }
9
+ }
10
+ exports.NotSubscribedError = NotSubscribedError;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.capitalize = void 0;
4
+ function capitalize(value) {
5
+ return value[0].toUpperCase() + value.slice(1);
6
+ }
7
+ exports.capitalize = capitalize;