@drift-labs/sdk 0.2.0-master.24 → 0.2.0-master.26

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 (193) hide show
  1. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +13 -13
  2. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +27 -27
  3. package/lib/accounts/types.d.ts +8 -9
  4. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +14 -14
  5. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +35 -34
  6. package/lib/addresses/pda.d.ts +8 -6
  7. package/lib/addresses/pda.js +35 -27
  8. package/lib/admin.d.ts +9 -6
  9. package/lib/admin.js +90 -54
  10. package/lib/clearingHouse.d.ts +71 -42
  11. package/lib/clearingHouse.js +765 -282
  12. package/lib/clearingHouseConfig.d.ts +2 -2
  13. package/lib/clearingHouseUser.d.ts +19 -17
  14. package/lib/clearingHouseUser.js +145 -123
  15. package/lib/config.d.ts +7 -7
  16. package/lib/config.js +21 -21
  17. package/lib/constants/numericConstants.d.ts +12 -12
  18. package/lib/constants/numericConstants.js +13 -13
  19. package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
  20. package/{src/constants/markets.js → lib/constants/perpMarkets.js} +4 -4
  21. package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
  22. package/lib/constants/{banks.js → spotMarkets.js} +16 -16
  23. package/lib/events/eventSubscriber.d.ts +4 -2
  24. package/lib/events/eventSubscriber.js +16 -9
  25. package/lib/events/fetchLogs.d.ts +10 -1
  26. package/lib/events/fetchLogs.js +27 -7
  27. package/lib/events/pollingLogProvider.d.ts +2 -1
  28. package/lib/events/pollingLogProvider.js +6 -2
  29. package/lib/events/types.d.ts +4 -2
  30. package/lib/events/types.js +2 -0
  31. package/lib/examples/makeTradeExample.js +18 -6
  32. package/lib/idl/clearing_house.json +1128 -347
  33. package/lib/index.d.ts +6 -3
  34. package/lib/index.js +6 -3
  35. package/lib/math/amm.d.ts +5 -3
  36. package/lib/math/amm.js +42 -4
  37. package/lib/math/funding.d.ts +6 -6
  38. package/lib/math/funding.js +2 -1
  39. package/lib/math/margin.d.ts +4 -4
  40. package/lib/math/margin.js +18 -11
  41. package/lib/math/market.d.ts +10 -9
  42. package/lib/math/market.js +29 -6
  43. package/lib/math/oracles.d.ts +2 -1
  44. package/lib/math/oracles.js +11 -1
  45. package/lib/math/orders.d.ts +5 -5
  46. package/lib/math/position.d.ts +13 -13
  47. package/lib/math/position.js +19 -19
  48. package/lib/math/spotBalance.d.ts +19 -0
  49. package/lib/math/spotBalance.js +176 -0
  50. package/lib/math/spotMarket.d.ts +4 -0
  51. package/lib/math/spotMarket.js +8 -0
  52. package/lib/math/spotPosition.d.ts +2 -0
  53. package/lib/math/spotPosition.js +8 -0
  54. package/lib/math/state.js +2 -2
  55. package/lib/math/trade.d.ts +4 -4
  56. package/lib/orderParams.d.ts +4 -4
  57. package/lib/orderParams.js +12 -4
  58. package/lib/serum/serumSubscriber.d.ts +23 -0
  59. package/lib/serum/serumSubscriber.js +41 -0
  60. package/lib/serum/types.d.ts +11 -0
  61. package/lib/serum/types.js +2 -0
  62. package/lib/tx/retryTxSender.d.ts +1 -1
  63. package/lib/tx/retryTxSender.js +4 -2
  64. package/lib/tx/types.d.ts +1 -1
  65. package/lib/types.d.ts +148 -39
  66. package/lib/types.js +37 -9
  67. package/my-script/.env +7 -0
  68. package/my-script/getUserStats.ts +106 -0
  69. package/my-script/multiConnections.ts +119 -0
  70. package/my-script/test-regex.ts +11 -0
  71. package/my-script/utils.ts +52 -0
  72. package/package.json +1 -1
  73. package/src/accounts/bulkAccountLoader.js +249 -0
  74. package/src/accounts/bulkUserStatsSubscription.js +75 -0
  75. package/src/accounts/bulkUserSubscription.js +75 -0
  76. package/src/accounts/fetch.js +92 -0
  77. package/src/accounts/pollingClearingHouseAccountSubscriber.js +465 -0
  78. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +38 -38
  79. package/src/accounts/pollingOracleSubscriber.js +156 -0
  80. package/src/accounts/pollingTokenAccountSubscriber.js +141 -0
  81. package/src/accounts/pollingUserAccountSubscriber.js +208 -0
  82. package/src/accounts/pollingUserStatsAccountSubscriber.js +208 -0
  83. package/src/accounts/types.js +28 -0
  84. package/src/accounts/types.ts +11 -9
  85. package/src/accounts/utils.js +7 -0
  86. package/src/accounts/webSocketAccountSubscriber.js +138 -0
  87. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +433 -0
  88. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +59 -52
  89. package/src/accounts/webSocketUserAccountSubscriber.js +113 -0
  90. package/src/accounts/webSocketUserStatsAccountSubsriber.js +113 -0
  91. package/src/addresses/pda.js +186 -0
  92. package/src/addresses/pda.ts +56 -42
  93. package/src/admin.js +1284 -0
  94. package/src/admin.ts +149 -75
  95. package/src/assert/assert.js +1 -1
  96. package/src/clearingHouse.js +3433 -0
  97. package/src/clearingHouse.ts +1097 -380
  98. package/src/clearingHouseConfig.js +2 -0
  99. package/src/clearingHouseConfig.ts +2 -2
  100. package/src/clearingHouseUser.js +874 -0
  101. package/src/clearingHouseUser.ts +237 -172
  102. package/src/clearingHouseUserConfig.js +2 -0
  103. package/src/clearingHouseUserStats.js +115 -0
  104. package/src/clearingHouseUserStatsConfig.js +2 -0
  105. package/src/config.js +80 -0
  106. package/src/config.ts +30 -30
  107. package/src/constants/numericConstants.js +18 -11
  108. package/src/constants/numericConstants.ts +17 -15
  109. package/{lib/constants/markets.js → src/constants/perpMarkets.js} +11 -11
  110. package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
  111. package/src/constants/spotMarkets.js +51 -0
  112. package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
  113. package/src/events/eventList.js +66 -23
  114. package/src/events/eventSubscriber.js +202 -0
  115. package/src/events/eventSubscriber.ts +20 -12
  116. package/src/events/fetchLogs.js +117 -0
  117. package/src/events/fetchLogs.ts +35 -8
  118. package/src/events/pollingLogProvider.js +113 -0
  119. package/src/events/pollingLogProvider.ts +10 -2
  120. package/src/events/sort.js +41 -0
  121. package/src/events/txEventCache.js +22 -19
  122. package/src/events/types.js +25 -0
  123. package/src/events/types.ts +7 -1
  124. package/src/events/webSocketLogProvider.js +76 -0
  125. package/src/examples/makeTradeExample.ts +27 -6
  126. package/src/factory/bigNum.js +183 -180
  127. package/src/factory/oracleClient.js +9 -9
  128. package/src/idl/clearing_house.json +1128 -347
  129. package/src/index.js +75 -0
  130. package/src/index.ts +6 -3
  131. package/src/math/amm.js +422 -0
  132. package/src/math/amm.ts +73 -5
  133. package/src/math/auction.js +10 -10
  134. package/src/math/conversion.js +4 -3
  135. package/src/math/funding.js +223 -175
  136. package/src/math/funding.ts +7 -7
  137. package/src/math/insurance.js +27 -0
  138. package/src/math/margin.js +77 -0
  139. package/src/math/margin.ts +34 -23
  140. package/src/math/market.js +105 -0
  141. package/src/math/market.ts +71 -19
  142. package/src/math/oracles.js +40 -10
  143. package/src/math/oracles.ts +18 -1
  144. package/src/math/orders.js +153 -0
  145. package/src/math/orders.ts +5 -5
  146. package/src/math/position.js +172 -0
  147. package/src/math/position.ts +31 -31
  148. package/src/math/repeg.js +40 -40
  149. package/src/math/spotBalance.js +176 -0
  150. package/src/math/spotBalance.ts +290 -0
  151. package/src/math/spotMarket.js +8 -0
  152. package/src/math/spotMarket.ts +9 -0
  153. package/src/math/spotPosition.js +8 -0
  154. package/src/math/spotPosition.ts +6 -0
  155. package/src/math/state.ts +2 -2
  156. package/src/math/trade.js +81 -74
  157. package/src/math/trade.ts +4 -4
  158. package/src/math/utils.js +8 -7
  159. package/src/oracles/oracleClientCache.js +10 -9
  160. package/src/oracles/pythClient.js +52 -17
  161. package/src/oracles/quoteAssetOracleClient.js +44 -13
  162. package/src/oracles/switchboardClient.js +69 -37
  163. package/src/oracles/types.js +1 -1
  164. package/src/orderParams.js +14 -6
  165. package/src/orderParams.ts +16 -8
  166. package/src/serum/serumSubscriber.js +102 -0
  167. package/src/serum/serumSubscriber.ts +80 -0
  168. package/src/serum/types.js +2 -0
  169. package/src/serum/types.ts +13 -0
  170. package/src/slot/SlotSubscriber.js +67 -20
  171. package/src/token/index.js +4 -4
  172. package/src/tokenFaucet.js +288 -154
  173. package/src/tx/retryTxSender.js +280 -0
  174. package/src/tx/retryTxSender.ts +5 -2
  175. package/src/tx/types.js +1 -1
  176. package/src/tx/types.ts +2 -1
  177. package/src/tx/utils.js +7 -6
  178. package/src/types.js +216 -0
  179. package/src/types.ts +131 -39
  180. package/src/userName.js +5 -5
  181. package/src/util/computeUnits.js +46 -11
  182. package/src/util/promiseTimeout.js +5 -5
  183. package/src/util/tps.js +46 -12
  184. package/src/wallet.js +55 -18
  185. package/lib/math/bankBalance.d.ts +0 -15
  186. package/lib/math/bankBalance.js +0 -150
  187. package/src/addresses/marketAddresses.js +0 -26
  188. package/src/constants/banks.js +0 -42
  189. package/src/examples/makeTradeExample.js +0 -80
  190. package/src/math/bankBalance.ts +0 -258
  191. package/src/math/state.js +0 -15
  192. package/src/math/utils.js.map +0 -1
  193. package/src/util/getTokenAddress.js +0 -9
@@ -0,0 +1,119 @@
1
+ import * as anchor from '@project-serum/anchor';
2
+ import { PublicKey, clusterApiUrl } from '@solana/web3.js';
3
+
4
+ import {
5
+ initialize,
6
+ BulkAccountLoader,
7
+ EventSubscriber,
8
+ DevnetMarkets,
9
+ ClearingHouse,
10
+ } from '..';
11
+ import { printUserStats } from './utils';
12
+
13
+ require('dotenv').config();
14
+
15
+
16
+ async function main(provider: anchor.AnchorProvider) {
17
+ const connection = provider.connection;
18
+ const config = initialize({ env: 'devnet' });
19
+ const clearingHousePublicKey = new PublicKey(
20
+ config.CLEARING_HOUSE_PROGRAM_ID
21
+ );
22
+
23
+ const bulkAccountLoader = new BulkAccountLoader(
24
+ connection,
25
+ 'confirmed',
26
+ 1000
27
+ );
28
+ const clearingHouse = new ClearingHouse({
29
+ connection,
30
+ wallet: provider.wallet,
31
+ programID: clearingHousePublicKey,
32
+ env: 'devnet',
33
+ // accountSubscription: {
34
+ // type: 'websocket',
35
+ // }
36
+ accountSubscription: {
37
+ type: 'polling',
38
+ accountLoader: bulkAccountLoader,
39
+ },
40
+ });
41
+
42
+ console.log(`clearingHouseProgramID: ${clearingHousePublicKey}`);
43
+ console.log(
44
+ `provider.wallet: ${provider.wallet.publicKey.toBase58()}`
45
+ );
46
+
47
+ const eventSubscriber = new EventSubscriber(
48
+ connection,
49
+ clearingHouse.program,
50
+ {
51
+ maxTx: 8192,
52
+ maxEventsPerType: 4096,
53
+ orderBy: 'blockchain',
54
+ orderDir: 'desc',
55
+ commitment: 'confirmed',
56
+ logProviderConfig: {
57
+ type: 'websocket',
58
+ },
59
+ }
60
+ );
61
+
62
+ if (!(await clearingHouse.getUser().exists())) {
63
+ console.error(
64
+ `ClearingHouseUser for ${provider.wallet.publicKey} does not exist`
65
+ );
66
+ console.info(`Creating ClearingHouseUser for ${provider.wallet.publicKey}`);
67
+ const [txSig] = await clearingHouse.initializeUserAccount();
68
+ console.log(`Initialized user account in transaction: ${txSig}`);
69
+ }
70
+
71
+ if (!(await clearingHouse.subscribe())) {
72
+ throw new Error('fail clearingHouse.subscribe');
73
+ }
74
+ if (!(await clearingHouse.accountSubscriber.subscribe())) {
75
+ throw new Error('fail clearingHouse.accountSubscriber.subscribe');
76
+ }
77
+ if (!eventSubscriber.subscribe()) {
78
+ throw new Error('fail eventSubscriber.subscribe');
79
+ }
80
+
81
+ const chUser = clearingHouse.getUser();
82
+ const chUserAccount = clearingHouse.getUserAccount();
83
+ console.log(`chUserAcc.authority: ${chUserAccount!.authority.toBase58()}`);
84
+ console.log(
85
+ ` chUserAccount pubkey: ${chUser.userAccountPublicKey.toBase58()}`
86
+ );
87
+
88
+ const keyToSymbol = new Map<string, string>();
89
+ const marketIndexToSymbol = new Map<number, string>();
90
+ for (const market of DevnetMarkets) {
91
+ keyToSymbol.set(market.oracle.toBase58(), market.baseAssetSymbol);
92
+ marketIndexToSymbol.set(market.marketIndex.toNumber(), market.symbol);
93
+ }
94
+
95
+ const run = async () => {
96
+ await clearingHouse.fetchAccounts();
97
+ await chUser.fetchAccounts();
98
+ printUserStats(chUserAccount!, marketIndexToSymbol);
99
+ };
100
+ await run();
101
+ setInterval(run, 1000);
102
+ }
103
+
104
+ try {
105
+ if (!process.env.ANCHOR_WALLET) {
106
+ throw new Error('ANCHOR_WALLET must be set.');
107
+ }
108
+ main(
109
+ anchor.AnchorProvider.local(clusterApiUrl('devnet'), {
110
+ // anchor.AnchorProvider.local('https://devnet.genesysgo.net', {
111
+ preflightCommitment: 'confirmed',
112
+ skipPreflight: false,
113
+ commitment: 'confirmed',
114
+ })
115
+ );
116
+ // anchor.AnchorProvider.local('https://psytrbhymqlkfrhudd.dev.genesysgo.net:8899/');
117
+ } catch (e) {
118
+ console.error(e);
119
+ }
@@ -0,0 +1,11 @@
1
+ try {
2
+ // const msg = 'Program 65sz7dRiWDRPZjiRxcTxPM7AE6VK4Nag9HEK6oBJXhJn failed: custom program error: 0x179e'
3
+ const msg = 'Program log: AnchorError occurred. Error Code: OrderDoesNotExist. Error Number: 6046. Error Message: Order does not exist.';
4
+ const code = msg.match(
5
+ /Program log: AnchorError occurred. Error Code: ([0-9,a-z,A-Z]+). Error Number/
6
+ );
7
+ console.log(code[1]);
8
+ } catch (e) {
9
+ console.log("nothing");
10
+ // no problem if couldn't match error code
11
+ }
@@ -0,0 +1,52 @@
1
+ import {
2
+ ClearingHouse,
3
+ UserAccount,
4
+ } from '..';
5
+
6
+ export function printUserStats(chUserAccount: UserAccount, marketIndexToSymbol: Map<number, string>) {
7
+
8
+ console.log("");
9
+ console.log(`${new Date(Date.now())}`);
10
+ console.log("Open positions:");
11
+ let openPositions = 0;
12
+ for (const p of chUserAccount!.positions) {
13
+ if (p.baseAssetAmount.isZero()) {
14
+ continue;
15
+ }
16
+ console.log(` [${marketIndexToSymbol.get(p.marketIndex.toNumber())}]`);
17
+ console.log(` . baseAssetAmount: ${p.baseAssetAmount.toString()}`);
18
+ console.log(` . quoteAssetAmount: ${p.quoteAssetAmount.toString()}`);
19
+ console.log(` . quoteEntryAmount: ${p.quoteEntryAmount.toString()}`);
20
+ console.log(` . lastCumulativeFundingRate: ${p.lastCumulativeFundingRate.toString()}`);
21
+ console.log(` . openOrders: ${p.openOrders}`);
22
+ console.log(` . openBids: ${p.openBids.toString()}`);
23
+ console.log(` . openAsks: ${p.openAsks.toString()}`);
24
+ openPositions++;
25
+ }
26
+ console.log(`count: ${openPositions}`);
27
+
28
+ let openOrders = 0;
29
+ console.log("");
30
+ console.log("Open orders:");
31
+ for (const o of chUserAccount!.orders) {
32
+ if (o.baseAssetAmount.isZero()) {
33
+ continue;
34
+ }
35
+ console.log(` . [OrderId: ${o.orderId.toString()}, ${JSON.stringify(o.status)} ${JSON.stringify(o.direction)}, mktIdx: ${o.marketIndex.toString()}]: ${o.baseAssetAmountFilled.toString()}/${o.baseAssetAmount.toString()}`);
36
+ openOrders++;
37
+ }
38
+ console.log(`count: ${openOrders}`);
39
+
40
+ return;
41
+ }
42
+
43
+ export async function cancelOpenOrders(clearingHouse: ClearingHouse, chUserAccount: UserAccount) {
44
+ for (const o of chUserAccount!.orders) {
45
+ if (o.baseAssetAmount.isZero()) {
46
+ continue;
47
+ }
48
+
49
+ const tx = await clearingHouse.cancelOrder(o.orderId);
50
+ console.log(`Canceled orderID ${o.orderId.toString()} on market ${o.marketIndex.toString()}, tx: ${tx}`);
51
+ }
52
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.2.0-master.24",
3
+ "version": "0.2.0-master.26",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -0,0 +1,249 @@
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
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ exports.__esModule = true;
39
+ exports.BulkAccountLoader = void 0;
40
+ var uuid_1 = require("uuid");
41
+ var promiseTimeout_1 = require("../util/promiseTimeout");
42
+ var GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
43
+ var oneMinute = 60 * 1000;
44
+ var BulkAccountLoader = /** @class */ (function () {
45
+ function BulkAccountLoader(connection, commitment, pollingFrequency) {
46
+ this.accountsToLoad = new Map();
47
+ this.bufferAndSlotMap = new Map();
48
+ this.errorCallbacks = new Map();
49
+ this.lastTimeLoadingPromiseCleared = Date.now();
50
+ this.mostRecentSlot = 0;
51
+ this.connection = connection;
52
+ this.commitment = commitment;
53
+ this.pollingFrequency = pollingFrequency;
54
+ }
55
+ BulkAccountLoader.prototype.addAccount = function (publicKey, callback) {
56
+ var existingSize = this.accountsToLoad.size;
57
+ var callbackId = (0, uuid_1.v4)();
58
+ var existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
59
+ if (existingAccountToLoad) {
60
+ existingAccountToLoad.callbacks.set(callbackId, callback);
61
+ }
62
+ else {
63
+ var callbacks = new Map();
64
+ callbacks.set(callbackId, callback);
65
+ var newAccountToLoad = {
66
+ publicKey: publicKey,
67
+ callbacks: callbacks
68
+ };
69
+ this.accountsToLoad.set(publicKey.toString(), newAccountToLoad);
70
+ }
71
+ if (existingSize === 0) {
72
+ this.startPolling();
73
+ }
74
+ // if a new account needs to be polled, remove the cached loadPromise in case client calls load immediately after
75
+ this.loadPromise = undefined;
76
+ return callbackId;
77
+ };
78
+ BulkAccountLoader.prototype.removeAccount = function (publicKey, callbackId) {
79
+ var existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
80
+ if (existingAccountToLoad) {
81
+ existingAccountToLoad.callbacks["delete"](callbackId);
82
+ if (existingAccountToLoad.callbacks.size === 0) {
83
+ this.accountsToLoad["delete"](existingAccountToLoad.publicKey.toString());
84
+ }
85
+ }
86
+ if (this.accountsToLoad.size === 0) {
87
+ this.stopPolling();
88
+ }
89
+ };
90
+ BulkAccountLoader.prototype.addErrorCallbacks = function (callback) {
91
+ var callbackId = (0, uuid_1.v4)();
92
+ this.errorCallbacks.set(callbackId, callback);
93
+ return callbackId;
94
+ };
95
+ BulkAccountLoader.prototype.removeErrorCallbacks = function (callbackId) {
96
+ this.errorCallbacks["delete"](callbackId);
97
+ };
98
+ BulkAccountLoader.prototype.chunks = function (array, size) {
99
+ return new Array(Math.ceil(array.length / size))
100
+ .fill(null)
101
+ .map(function (_, index) { return index * size; })
102
+ .map(function (begin) { return array.slice(begin, begin + size); });
103
+ };
104
+ BulkAccountLoader.prototype.load = function () {
105
+ return __awaiter(this, void 0, void 0, function () {
106
+ var now, chunks, e_1, _i, _a, _b, _1, callback;
107
+ var _this = this;
108
+ return __generator(this, function (_c) {
109
+ switch (_c.label) {
110
+ case 0:
111
+ if (this.loadPromise) {
112
+ now = Date.now();
113
+ if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
114
+ this.loadPromise = undefined;
115
+ }
116
+ else {
117
+ return [2 /*return*/, this.loadPromise];
118
+ }
119
+ }
120
+ this.loadPromise = new Promise(function (resolver) {
121
+ _this.loadPromiseResolver = resolver;
122
+ });
123
+ this.lastTimeLoadingPromiseCleared = Date.now();
124
+ _c.label = 1;
125
+ case 1:
126
+ _c.trys.push([1, 3, 4, 5]);
127
+ chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
128
+ return [4 /*yield*/, Promise.all(chunks.map(function (chunk) {
129
+ return _this.loadChunk(chunk);
130
+ }))];
131
+ case 2:
132
+ _c.sent();
133
+ return [3 /*break*/, 5];
134
+ case 3:
135
+ e_1 = _c.sent();
136
+ console.error("Error in bulkAccountLoader.load()");
137
+ console.error(e_1);
138
+ for (_i = 0, _a = this.errorCallbacks; _i < _a.length; _i++) {
139
+ _b = _a[_i], _1 = _b[0], callback = _b[1];
140
+ callback(e_1);
141
+ }
142
+ return [3 /*break*/, 5];
143
+ case 4:
144
+ this.loadPromiseResolver();
145
+ this.loadPromise = undefined;
146
+ return [7 /*endfinally*/];
147
+ case 5: return [2 /*return*/];
148
+ }
149
+ });
150
+ });
151
+ };
152
+ BulkAccountLoader.prototype.loadChunk = function (accountsToLoad) {
153
+ return __awaiter(this, void 0, void 0, function () {
154
+ var args, rpcResponse, newSlot, i, accountToLoad, key, oldRPCResponse, newBuffer, raw, dataType, oldBuffer;
155
+ return __generator(this, function (_a) {
156
+ switch (_a.label) {
157
+ case 0:
158
+ if (accountsToLoad.length === 0) {
159
+ return [2 /*return*/];
160
+ }
161
+ args = [
162
+ accountsToLoad.map(function (accountToLoad) {
163
+ return accountToLoad.publicKey.toBase58();
164
+ }),
165
+ { commitment: this.commitment },
166
+ ];
167
+ return [4 /*yield*/, (0, promiseTimeout_1.promiseTimeout)(
168
+ // @ts-ignore
169
+ this.connection._rpcRequest('getMultipleAccounts', args), 10 * 1000 // 30 second timeout
170
+ )];
171
+ case 1:
172
+ rpcResponse = _a.sent();
173
+ if (rpcResponse === null) {
174
+ this.log('request to rpc timed out');
175
+ return [2 /*return*/];
176
+ }
177
+ newSlot = rpcResponse.result.context.slot;
178
+ if (newSlot > this.mostRecentSlot) {
179
+ this.mostRecentSlot = newSlot;
180
+ }
181
+ for (i in accountsToLoad) {
182
+ accountToLoad = accountsToLoad[i];
183
+ key = accountToLoad.publicKey.toString();
184
+ oldRPCResponse = this.bufferAndSlotMap.get(key);
185
+ newBuffer = undefined;
186
+ if (rpcResponse.result.value[i]) {
187
+ raw = rpcResponse.result.value[i].data[0];
188
+ dataType = rpcResponse.result.value[i].data[1];
189
+ newBuffer = Buffer.from(raw, dataType);
190
+ }
191
+ if (!oldRPCResponse) {
192
+ this.bufferAndSlotMap.set(key, {
193
+ slot: newSlot,
194
+ buffer: newBuffer
195
+ });
196
+ this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
197
+ continue;
198
+ }
199
+ if (newSlot <= oldRPCResponse.slot) {
200
+ continue;
201
+ }
202
+ oldBuffer = oldRPCResponse.buffer;
203
+ if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
204
+ this.bufferAndSlotMap.set(key, {
205
+ slot: newSlot,
206
+ buffer: newBuffer
207
+ });
208
+ this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
209
+ }
210
+ }
211
+ return [2 /*return*/];
212
+ }
213
+ });
214
+ });
215
+ };
216
+ BulkAccountLoader.prototype.handleAccountCallbacks = function (accountToLoad, buffer, slot) {
217
+ for (var _i = 0, _a = accountToLoad.callbacks; _i < _a.length; _i++) {
218
+ var _b = _a[_i], _2 = _b[0], callback = _b[1];
219
+ callback(buffer, slot);
220
+ }
221
+ };
222
+ BulkAccountLoader.prototype.getBufferAndSlot = function (publicKey) {
223
+ return this.bufferAndSlotMap.get(publicKey.toString());
224
+ };
225
+ BulkAccountLoader.prototype.startPolling = function () {
226
+ if (this.intervalId) {
227
+ return;
228
+ }
229
+ this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
230
+ };
231
+ BulkAccountLoader.prototype.stopPolling = function () {
232
+ if (this.intervalId) {
233
+ clearInterval(this.intervalId);
234
+ this.intervalId = undefined;
235
+ }
236
+ };
237
+ BulkAccountLoader.prototype.log = function (msg) {
238
+ console.log(msg);
239
+ };
240
+ BulkAccountLoader.prototype.updatePollingFrequency = function (pollingFrequency) {
241
+ this.stopPolling();
242
+ this.pollingFrequency = pollingFrequency;
243
+ if (this.accountsToLoad.size > 0) {
244
+ this.startPolling();
245
+ }
246
+ };
247
+ return BulkAccountLoader;
248
+ }());
249
+ exports.BulkAccountLoader = BulkAccountLoader;
@@ -0,0 +1,75 @@
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
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ exports.__esModule = true;
39
+ exports.bulkPollingUserStatsSubscribe = void 0;
40
+ /**
41
+ * @param userStats
42
+ * @param accountLoader
43
+ */
44
+ function bulkPollingUserStatsSubscribe(userStats, accountLoader) {
45
+ return __awaiter(this, void 0, void 0, function () {
46
+ var _this = this;
47
+ return __generator(this, function (_a) {
48
+ switch (_a.label) {
49
+ case 0:
50
+ if (!(userStats.length === 0)) return [3 /*break*/, 2];
51
+ return [4 /*yield*/, accountLoader.load()];
52
+ case 1:
53
+ _a.sent();
54
+ return [2 /*return*/];
55
+ case 2: return [4 /*yield*/, Promise.all(userStats.map(function (userStat) {
56
+ return userStat.accountSubscriber.addToAccountLoader();
57
+ }))];
58
+ case 3:
59
+ _a.sent();
60
+ return [4 /*yield*/, accountLoader.load()];
61
+ case 4:
62
+ _a.sent();
63
+ return [4 /*yield*/, Promise.all(userStats.map(function (userStat) { return __awaiter(_this, void 0, void 0, function () {
64
+ return __generator(this, function (_a) {
65
+ return [2 /*return*/, userStat.subscribe()];
66
+ });
67
+ }); }))];
68
+ case 5:
69
+ _a.sent();
70
+ return [2 /*return*/];
71
+ }
72
+ });
73
+ });
74
+ }
75
+ exports.bulkPollingUserStatsSubscribe = bulkPollingUserStatsSubscribe;
@@ -0,0 +1,75 @@
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
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ exports.__esModule = true;
39
+ exports.bulkPollingUserSubscribe = void 0;
40
+ /**
41
+ * @param users
42
+ * @param accountLoader
43
+ */
44
+ function bulkPollingUserSubscribe(users, accountLoader) {
45
+ return __awaiter(this, void 0, void 0, function () {
46
+ var _this = this;
47
+ return __generator(this, function (_a) {
48
+ switch (_a.label) {
49
+ case 0:
50
+ if (!(users.length === 0)) return [3 /*break*/, 2];
51
+ return [4 /*yield*/, accountLoader.load()];
52
+ case 1:
53
+ _a.sent();
54
+ return [2 /*return*/];
55
+ case 2: return [4 /*yield*/, Promise.all(users.map(function (user) {
56
+ return user.accountSubscriber.addToAccountLoader();
57
+ }))];
58
+ case 3:
59
+ _a.sent();
60
+ return [4 /*yield*/, accountLoader.load()];
61
+ case 4:
62
+ _a.sent();
63
+ return [4 /*yield*/, Promise.all(users.map(function (user) { return __awaiter(_this, void 0, void 0, function () {
64
+ return __generator(this, function (_a) {
65
+ return [2 /*return*/, user.subscribe()];
66
+ });
67
+ }); }))];
68
+ case 5:
69
+ _a.sent();
70
+ return [2 /*return*/];
71
+ }
72
+ });
73
+ });
74
+ }
75
+ exports.bulkPollingUserSubscribe = bulkPollingUserSubscribe;