@drift-labs/sdk 0.1.36-master.7 → 0.2.0-master.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 (197) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +6 -6
  2. package/lib/accounts/bulkAccountLoader.js +81 -95
  3. package/lib/accounts/bulkUserSubscription.js +13 -57
  4. package/lib/accounts/fetch.d.ts +4 -0
  5. package/lib/accounts/fetch.js +18 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
  8. package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
  9. package/lib/accounts/pollingOracleSubscriber.js +37 -49
  10. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
  11. package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
  12. package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
  13. package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
  14. package/lib/accounts/types.d.ts +34 -41
  15. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
  16. package/lib/accounts/webSocketAccountSubscriber.js +39 -35
  17. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
  18. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
  19. package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
  20. package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
  21. package/lib/addresses/marketAddresses.d.ts +4 -0
  22. package/lib/addresses/marketAddresses.js +15 -0
  23. package/lib/addresses/pda.d.ts +12 -0
  24. package/lib/addresses/pda.js +83 -0
  25. package/lib/admin.d.ts +9 -17
  26. package/lib/admin.js +375 -558
  27. package/lib/clearingHouse.d.ts +86 -109
  28. package/lib/clearingHouse.js +828 -895
  29. package/lib/clearingHouseConfig.d.ts +34 -0
  30. package/lib/clearingHouseConfig.js +2 -0
  31. package/lib/clearingHouseUser.d.ts +19 -22
  32. package/lib/clearingHouseUser.js +155 -141
  33. package/lib/clearingHouseUserConfig.d.ts +14 -0
  34. package/lib/clearingHouseUserConfig.js +2 -0
  35. package/lib/config.d.ts +12 -0
  36. package/lib/config.js +35 -4
  37. package/lib/constants/banks.d.ts +16 -0
  38. package/lib/constants/banks.js +34 -0
  39. package/lib/constants/markets.d.ts +8 -3
  40. package/lib/constants/markets.js +13 -206
  41. package/lib/constants/numericConstants.d.ts +17 -0
  42. package/lib/constants/numericConstants.js +23 -6
  43. package/lib/events/eventList.d.ts +22 -0
  44. package/lib/events/eventList.js +77 -0
  45. package/lib/events/eventSubscriber.d.ts +34 -0
  46. package/lib/events/eventSubscriber.js +126 -0
  47. package/lib/events/fetchLogs.d.ts +13 -0
  48. package/lib/events/fetchLogs.js +39 -0
  49. package/lib/events/pollingLogProvider.d.ts +15 -0
  50. package/lib/events/pollingLogProvider.js +53 -0
  51. package/lib/events/sort.d.ts +2 -0
  52. package/lib/events/sort.js +44 -0
  53. package/lib/events/txEventCache.d.ts +24 -0
  54. package/lib/events/txEventCache.js +71 -0
  55. package/lib/events/types.d.ts +49 -0
  56. package/lib/events/types.js +20 -0
  57. package/lib/events/webSocketLogProvider.d.ts +12 -0
  58. package/lib/events/webSocketLogProvider.js +30 -0
  59. package/lib/examples/makeTradeExample.js +26 -27
  60. package/lib/factory/bigNum.d.ts +118 -0
  61. package/lib/factory/bigNum.js +364 -0
  62. package/lib/factory/oracleClient.d.ts +1 -2
  63. package/lib/factory/oracleClient.js +6 -2
  64. package/lib/idl/clearing_house.json +2287 -2938
  65. package/lib/index.d.ts +12 -4
  66. package/lib/index.js +12 -4
  67. package/lib/math/amm.d.ts +24 -29
  68. package/lib/math/amm.js +239 -178
  69. package/lib/math/auction.d.ts +5 -0
  70. package/lib/math/auction.js +39 -0
  71. package/lib/math/bankBalance.d.ts +9 -0
  72. package/lib/math/bankBalance.js +75 -0
  73. package/lib/math/conversion.d.ts +0 -1
  74. package/lib/math/conversion.js +1 -5
  75. package/lib/math/funding.d.ts +6 -6
  76. package/lib/math/funding.js +158 -175
  77. package/lib/math/market.d.ts +6 -6
  78. package/lib/math/market.js +10 -9
  79. package/lib/math/orders.d.ts +5 -0
  80. package/lib/math/orders.js +31 -1
  81. package/lib/math/position.d.ts +7 -5
  82. package/lib/math/position.js +27 -27
  83. package/lib/math/repeg.d.ts +22 -0
  84. package/lib/math/repeg.js +128 -0
  85. package/lib/math/trade.d.ts +5 -4
  86. package/lib/math/trade.js +29 -21
  87. package/lib/mockUSDCFaucet.js +87 -116
  88. package/lib/oracles/oracleClientCache.d.ts +8 -0
  89. package/lib/oracles/oracleClientCache.js +19 -0
  90. package/lib/oracles/pythClient.d.ts +3 -5
  91. package/lib/oracles/pythClient.js +12 -31
  92. package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
  93. package/lib/oracles/quoteAssetOracleClient.js +21 -0
  94. package/lib/oracles/switchboardClient.d.ts +3 -5
  95. package/lib/oracles/switchboardClient.js +29 -50
  96. package/lib/oracles/types.d.ts +6 -1
  97. package/lib/orders.d.ts +6 -7
  98. package/lib/orders.js +10 -80
  99. package/lib/slot/SlotSubscriber.d.ts +12 -0
  100. package/lib/slot/SlotSubscriber.js +23 -0
  101. package/lib/tx/retryTxSender.d.ts +2 -2
  102. package/lib/tx/retryTxSender.js +108 -123
  103. package/lib/tx/types.d.ts +5 -1
  104. package/lib/tx/utils.d.ts +1 -1
  105. package/lib/tx/utils.js +11 -2
  106. package/lib/types.d.ts +110 -109
  107. package/lib/types.js +14 -1
  108. package/lib/userName.d.ts +4 -0
  109. package/lib/userName.js +20 -0
  110. package/lib/util/computeUnits.js +10 -21
  111. package/lib/util/tps.js +11 -22
  112. package/lib/wallet.js +7 -20
  113. package/package.json +11 -4
  114. package/src/accounts/bulkAccountLoader.ts +21 -15
  115. package/src/accounts/bulkUserSubscription.ts +1 -45
  116. package/src/accounts/fetch.ts +33 -0
  117. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
  118. package/src/accounts/pollingOracleSubscriber.ts +16 -8
  119. package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
  120. package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
  121. package/src/accounts/types.ts +41 -70
  122. package/src/accounts/webSocketAccountSubscriber.ts +33 -16
  123. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
  124. package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
  125. package/src/addresses/marketAddresses.ts +18 -0
  126. package/src/addresses/pda.ts +118 -0
  127. package/src/admin.ts +218 -346
  128. package/src/clearingHouse.ts +983 -952
  129. package/src/clearingHouseConfig.ts +37 -0
  130. package/src/clearingHouseUser.ts +275 -185
  131. package/src/clearingHouseUserConfig.ts +18 -0
  132. package/src/config.ts +54 -1
  133. package/src/constants/banks.ts +43 -0
  134. package/src/constants/markets.ts +16 -207
  135. package/src/constants/numericConstants.ts +34 -5
  136. package/src/events/eventList.ts +94 -0
  137. package/src/events/eventSubscriber.ts +194 -0
  138. package/src/events/fetchLogs.ts +80 -0
  139. package/src/events/pollingLogProvider.ts +79 -0
  140. package/src/events/sort.ts +65 -0
  141. package/src/events/txEventCache.ts +74 -0
  142. package/src/events/types.ts +98 -0
  143. package/src/events/webSocketLogProvider.ts +38 -0
  144. package/src/examples/makeTradeExample.ts +20 -11
  145. package/src/factory/bigNum.ts +524 -0
  146. package/src/factory/oracleClient.ts +7 -4
  147. package/src/idl/clearing_house.json +2287 -2938
  148. package/src/index.ts +12 -4
  149. package/src/math/amm.ts +414 -245
  150. package/src/math/auction.ts +39 -0
  151. package/src/math/bankBalance.ts +112 -0
  152. package/src/math/conversion.ts +1 -11
  153. package/src/math/funding.ts +12 -9
  154. package/src/math/market.ts +37 -30
  155. package/src/math/orders.ts +38 -0
  156. package/src/math/position.ts +48 -35
  157. package/src/math/repeg.ts +176 -0
  158. package/src/math/trade.ts +45 -35
  159. package/src/math/utils.js +27 -0
  160. package/src/math/utils.js.map +1 -0
  161. package/src/oracles/oracleClientCache.ts +20 -0
  162. package/src/oracles/pythClient.ts +4 -11
  163. package/src/oracles/quoteAssetOracleClient.ts +25 -0
  164. package/src/oracles/switchboardClient.ts +11 -24
  165. package/src/oracles/types.ts +7 -1
  166. package/src/orders.ts +24 -126
  167. package/src/slot/SlotSubscriber.ts +32 -0
  168. package/src/tx/retryTxSender.ts +6 -4
  169. package/src/tx/types.ts +6 -1
  170. package/src/tx/utils.ts +22 -3
  171. package/src/types.ts +111 -122
  172. package/src/userName.ts +20 -0
  173. package/src/util/computeUnits.js +17 -0
  174. package/src/util/computeUnits.js.map +1 -0
  175. package/tests/bn/test.ts +255 -0
  176. package/tsconfig.json +12 -12
  177. package/lib/addresses.d.ts +0 -10
  178. package/lib/addresses.js +0 -93
  179. package/lib/constants/accounts.d.ts +0 -15
  180. package/lib/constants/accounts.js +0 -18
  181. package/lib/factory/clearingHouse.d.ts +0 -35
  182. package/lib/factory/clearingHouse.js +0 -81
  183. package/lib/factory/clearingHouseUser.d.ts +0 -19
  184. package/lib/factory/clearingHouseUser.js +0 -34
  185. package/lib/math/insuranceFund.d.ts +0 -15
  186. package/lib/math/insuranceFund.js +0 -33
  187. package/lib/settlement.d.ts +0 -4
  188. package/lib/settlement.js +0 -10
  189. package/lib/tx/defaultTxSender.d.ts +0 -8
  190. package/lib/tx/defaultTxSender.js +0 -12
  191. package/src/addresses.ts +0 -82
  192. package/src/constants/accounts.ts +0 -26
  193. package/src/factory/clearingHouse.ts +0 -173
  194. package/src/factory/clearingHouseUser.ts +0 -73
  195. package/src/math/insuranceFund.ts +0 -29
  196. package/src/settlement.ts +0 -9
  197. package/src/tx/defaultTxSender.ts +0 -24
package/lib/types.js CHANGED
@@ -1,12 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TradeSide = exports.isVariant = exports.OrderTriggerCondition = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.PositionDirection = exports.SwapDirection = void 0;
3
+ exports.TradeSide = exports.isOneOfVariant = exports.isVariant = exports.OrderTriggerCondition = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.PositionDirection = exports.BankBalanceType = exports.SwapDirection = void 0;
4
4
  // # Utility Types / Enums / Constants
5
5
  class SwapDirection {
6
6
  }
7
7
  exports.SwapDirection = SwapDirection;
8
8
  SwapDirection.ADD = { add: {} };
9
9
  SwapDirection.REMOVE = { remove: {} };
10
+ class BankBalanceType {
11
+ }
12
+ exports.BankBalanceType = BankBalanceType;
13
+ BankBalanceType.DEPOSIT = { deposit: {} };
14
+ BankBalanceType.BORROW = { borrow: {} };
10
15
  class PositionDirection {
11
16
  }
12
17
  exports.PositionDirection = PositionDirection;
@@ -17,6 +22,7 @@ class OracleSource {
17
22
  exports.OracleSource = OracleSource;
18
23
  OracleSource.PYTH = { pyth: {} };
19
24
  OracleSource.SWITCHBOARD = { switchboard: {} };
25
+ OracleSource.QUOTE_ASSET = { quoteAsset: {} };
20
26
  class OrderType {
21
27
  }
22
28
  exports.OrderType = OrderType;
@@ -44,6 +50,7 @@ OrderAction.PLACE = { place: {} };
44
50
  OrderAction.CANCEL = { cancel: {} };
45
51
  OrderAction.EXPIRE = { expire: {} };
46
52
  OrderAction.FILL = { fill: {} };
53
+ OrderAction.TRIGGER = { trigger: {} };
47
54
  class OrderTriggerCondition {
48
55
  }
49
56
  exports.OrderTriggerCondition = OrderTriggerCondition;
@@ -53,6 +60,12 @@ function isVariant(object, type) {
53
60
  return object.hasOwnProperty(type);
54
61
  }
55
62
  exports.isVariant = isVariant;
63
+ function isOneOfVariant(object, types) {
64
+ return types.reduce((result, type) => {
65
+ return result || object.hasOwnProperty(type);
66
+ }, false);
67
+ }
68
+ exports.isOneOfVariant = isOneOfVariant;
56
69
  var TradeSide;
57
70
  (function (TradeSide) {
58
71
  TradeSide[TradeSide["None"] = 0] = "None";
@@ -0,0 +1,4 @@
1
+ export declare const MAX_NAME_LENGTH = 32;
2
+ export declare const DEFAULT_USER_NAME = "Main Account";
3
+ export declare function encodeName(name: string): number[];
4
+ export declare function decodeName(bytes: number[]): string;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decodeName = exports.encodeName = exports.DEFAULT_USER_NAME = exports.MAX_NAME_LENGTH = void 0;
4
+ exports.MAX_NAME_LENGTH = 32;
5
+ exports.DEFAULT_USER_NAME = 'Main Account';
6
+ function encodeName(name) {
7
+ if (name.length > exports.MAX_NAME_LENGTH) {
8
+ throw Error(`User name (${name}) longer than 32 characters`);
9
+ }
10
+ const buffer = Buffer.alloc(32);
11
+ buffer.fill(name);
12
+ buffer.fill(' ', name.length);
13
+ return Array(...buffer);
14
+ }
15
+ exports.encodeName = encodeName;
16
+ function decodeName(bytes) {
17
+ const buffer = Buffer.from(bytes);
18
+ return buffer.toString('utf8').trim();
19
+ }
20
+ exports.decodeName = decodeName;
@@ -1,27 +1,16 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.findComputeUnitConsumption = void 0;
13
- function findComputeUnitConsumption(programId, connection, txSignature, commitment = 'confirmed') {
14
- return __awaiter(this, void 0, void 0, function* () {
15
- const tx = yield connection.getTransaction(txSignature, { commitment });
16
- const computeUnits = [];
17
- const regex = new RegExp(`Program ${programId.toString()} consumed ([0-9]{0,6}) of 200000 compute units`);
18
- tx.meta.logMessages.forEach((logMessage) => {
19
- const match = logMessage.match(regex);
20
- if (match && match[1]) {
21
- computeUnits.push(match[1]);
22
- }
23
- });
24
- return computeUnits;
4
+ async function findComputeUnitConsumption(programId, connection, txSignature, commitment = 'confirmed') {
5
+ const tx = await connection.getTransaction(txSignature, { commitment });
6
+ const computeUnits = [];
7
+ const regex = new RegExp(`Program ${programId.toString()} consumed ([0-9]{0,6}) of 200000 compute units`);
8
+ tx.meta.logMessages.forEach((logMessage) => {
9
+ const match = logMessage.match(regex);
10
+ if (match && match[1]) {
11
+ computeUnits.push(match[1]);
12
+ }
25
13
  });
14
+ return computeUnits;
26
15
  }
27
16
  exports.findComputeUnitConsumption = findComputeUnitConsumption;
package/lib/util/tps.js CHANGED
@@ -1,27 +1,16 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.estimateTps = void 0;
13
- function estimateTps(programId, connection, failed) {
14
- return __awaiter(this, void 0, void 0, function* () {
15
- let signatures = yield connection.getSignaturesForAddress(programId, undefined, 'finalized');
16
- if (failed) {
17
- signatures = signatures.filter((signature) => signature.err);
18
- }
19
- const numberOfSignatures = signatures.length;
20
- if (numberOfSignatures === 0) {
21
- return 0;
22
- }
23
- return (numberOfSignatures /
24
- (signatures[0].blockTime - signatures[numberOfSignatures - 1].blockTime));
25
- });
4
+ async function estimateTps(programId, connection, failed) {
5
+ let signatures = await connection.getSignaturesForAddress(programId, undefined, 'finalized');
6
+ if (failed) {
7
+ signatures = signatures.filter((signature) => signature.err);
8
+ }
9
+ const numberOfSignatures = signatures.length;
10
+ if (numberOfSignatures === 0) {
11
+ return 0;
12
+ }
13
+ return (numberOfSignatures /
14
+ (signatures[0].blockTime - signatures[numberOfSignatures - 1].blockTime));
26
15
  }
27
16
  exports.estimateTps = estimateTps;
package/lib/wallet.js CHANGED
@@ -1,31 +1,18 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.Wallet = void 0;
13
4
  class Wallet {
14
5
  constructor(payer) {
15
6
  this.payer = payer;
16
7
  }
17
- signTransaction(tx) {
18
- return __awaiter(this, void 0, void 0, function* () {
19
- tx.partialSign(this.payer);
20
- return tx;
21
- });
8
+ async signTransaction(tx) {
9
+ tx.partialSign(this.payer);
10
+ return tx;
22
11
  }
23
- signAllTransactions(txs) {
24
- return __awaiter(this, void 0, void 0, function* () {
25
- return txs.map((t) => {
26
- t.partialSign(this.payer);
27
- return t;
28
- });
12
+ async signAllTransactions(txs) {
13
+ return txs.map((t) => {
14
+ t.partialSign(this.payer);
15
+ return t;
29
16
  });
30
17
  }
31
18
  get publicKey() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.1.36-master.7",
3
+ "version": "0.2.0-master.2",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -13,6 +13,7 @@
13
13
  "lint": "eslint './**/*.{ts,tsx}' --quiet",
14
14
  "build": "yarn clean && tsc",
15
15
  "clean": "rm -rf lib",
16
+ "test": "mocha -r ts-node/register tests/**/*.ts",
16
17
  "patch-and-pub": "npm version patch --force && npm publish"
17
18
  },
18
19
  "keywords": [
@@ -29,19 +30,25 @@
29
30
  },
30
31
  "dependencies": {
31
32
  "@project-serum/anchor": "0.24.2",
32
- "@pythnetwork/client": "^2.5.1",
33
+ "@pythnetwork/client": "2.5.1",
33
34
  "@solana/spl-token": "^0.1.6",
34
- "@solana/web3.js": "^1.22.0",
35
+ "@solana/web3.js": "1.41.0",
35
36
  "@switchboard-xyz/switchboard-v2": "^0.0.67",
36
37
  "strict-event-emitter-types": "^2.0.0",
37
38
  "uuid": "^8.3.2"
38
39
  },
39
40
  "devDependencies": {
41
+ "@types/chai": "^4.3.1",
42
+ "@types/mocha": "^9.1.1",
40
43
  "@typescript-eslint/eslint-plugin": "^4.28.0",
41
44
  "@typescript-eslint/parser": "^4.28.0",
45
+ "@types/jest": "^28.1.3",
46
+ "chai": "^4.3.6",
42
47
  "eslint": "^7.29.0",
43
48
  "eslint-config-prettier": "^8.3.0",
44
- "eslint-plugin-prettier": "^3.4.0"
49
+ "eslint-plugin-prettier": "^3.4.0",
50
+ "mocha": "^10.0.0",
51
+ "ts-node": "^10.8.0"
45
52
  },
46
53
  "description": "SDK for Drift Protocol v1",
47
54
  "engines": {
@@ -1,11 +1,11 @@
1
1
  import { Commitment, Connection, PublicKey } from '@solana/web3.js';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
- import { AccountData } from './types';
3
+ import { BufferAndSlot } from './types';
4
4
  import { promiseTimeout } from '../util/promiseTimeout';
5
5
 
6
6
  type AccountToLoad = {
7
7
  publicKey: PublicKey;
8
- callbacks: Map<string, (buffer: Buffer) => void>;
8
+ callbacks: Map<string, (buffer: Buffer, slot: number) => void>;
9
9
  };
10
10
 
11
11
  const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
@@ -17,7 +17,7 @@ export class BulkAccountLoader {
17
17
  commitment: Commitment;
18
18
  pollingFrequency: number;
19
19
  accountsToLoad = new Map<string, AccountToLoad>();
20
- accountData = new Map<string, AccountData>();
20
+ bufferAndSlotMap = new Map<string, BufferAndSlot>();
21
21
  errorCallbacks = new Map<string, (e) => void>();
22
22
  intervalId?: NodeJS.Timer;
23
23
  // to handle clients spamming load
@@ -38,7 +38,7 @@ export class BulkAccountLoader {
38
38
 
39
39
  public addAccount(
40
40
  publicKey: PublicKey,
41
- callback: (buffer: Buffer) => void
41
+ callback: (buffer: Buffer, slot: number) => void
42
42
  ): string {
43
43
  const existingSize = this.accountsToLoad.size;
44
44
 
@@ -47,7 +47,10 @@ export class BulkAccountLoader {
47
47
  if (existingAccountToLoad) {
48
48
  existingAccountToLoad.callbacks.set(callbackId, callback);
49
49
  } else {
50
- const callbacks = new Map<string, (buffer: Buffer) => void>();
50
+ const callbacks = new Map<
51
+ string,
52
+ (buffer: Buffer, slot: number) => void
53
+ >();
51
54
  callbacks.set(callbackId, callback);
52
55
  const newAccountToLoad = {
53
56
  publicKey,
@@ -167,7 +170,7 @@ export class BulkAccountLoader {
167
170
  for (const i in accountsToLoad) {
168
171
  const accountToLoad = accountsToLoad[i];
169
172
  const key = accountToLoad.publicKey.toString();
170
- const oldRPCResponse = this.accountData.get(key);
173
+ const oldRPCResponse = this.bufferAndSlotMap.get(key);
171
174
 
172
175
  let newBuffer: Buffer | undefined = undefined;
173
176
  if (rpcResponse.result.value[i]) {
@@ -177,11 +180,11 @@ export class BulkAccountLoader {
177
180
  }
178
181
 
179
182
  if (!oldRPCResponse) {
180
- this.accountData.set(key, {
183
+ this.bufferAndSlotMap.set(key, {
181
184
  slot: newSlot,
182
185
  buffer: newBuffer,
183
186
  });
184
- this.handleAccountCallbacks(accountToLoad, newBuffer);
187
+ this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
185
188
  continue;
186
189
  }
187
190
 
@@ -191,24 +194,27 @@ export class BulkAccountLoader {
191
194
 
192
195
  const oldBuffer = oldRPCResponse.buffer;
193
196
  if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
194
- this.accountData.set(key, {
197
+ this.bufferAndSlotMap.set(key, {
195
198
  slot: newSlot,
196
199
  buffer: newBuffer,
197
200
  });
198
- this.handleAccountCallbacks(accountToLoad, newBuffer);
201
+ this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
199
202
  }
200
203
  }
201
204
  }
202
205
 
203
- handleAccountCallbacks(accountToLoad: AccountToLoad, buffer: Buffer): void {
206
+ handleAccountCallbacks(
207
+ accountToLoad: AccountToLoad,
208
+ buffer: Buffer,
209
+ slot: number
210
+ ): void {
204
211
  for (const [_, callback] of accountToLoad.callbacks) {
205
- callback(buffer);
212
+ callback(buffer, slot);
206
213
  }
207
214
  }
208
215
 
209
- public getAccountData(publicKey: PublicKey): Buffer | undefined {
210
- const accountData = this.accountData.get(publicKey.toString());
211
- return accountData?.buffer;
216
+ public getBufferAndSlot(publicKey: PublicKey): BufferAndSlot | undefined {
217
+ return this.bufferAndSlotMap.get(publicKey.toString());
212
218
  }
213
219
 
214
220
  public startPolling(): void {
@@ -1,9 +1,6 @@
1
1
  import { ClearingHouseUser } from '../clearingHouseUser';
2
2
  import { BulkAccountLoader } from './bulkAccountLoader';
3
3
  import { PollingUserAccountSubscriber } from './pollingUserAccountSubscriber';
4
- import { UserAccount, UserOrdersAccount } from '../types';
5
- import { UserPublicKeys } from './types';
6
- import { ProgramAccount } from '@project-serum/anchor';
7
4
 
8
5
  /**
9
6
  * @param users
@@ -18,53 +15,12 @@ export async function bulkPollingUserSubscribe(
18
15
  return;
19
16
  }
20
17
 
21
- // Fetch all the accounts first
22
- const program = users[0].clearingHouse.program;
23
- let userProgramAccounts: ProgramAccount[];
24
- let orderProgramAccounts: ProgramAccount[];
25
- await Promise.all([
26
- (async () => {
27
- userProgramAccounts = await program.account.user.all();
28
- })(),
29
- (async () => {
30
- orderProgramAccounts = await program.account.userOrders.all();
31
- })(),
32
- ]);
33
-
34
- // Create a map of the authority to keys
35
- const authorityToKeys = new Map<string, UserPublicKeys>();
36
- const userToAuthority = new Map<string, string>();
37
- for (const userProgramAccount of userProgramAccounts) {
38
- const userAccountPublicKey = userProgramAccount.publicKey;
39
- const userAccount = userProgramAccount.account as UserAccount;
40
-
41
- authorityToKeys.set(userAccount.authority.toString(), {
42
- user: userAccountPublicKey,
43
- userPositions: userAccount.positions,
44
- userOrders: undefined,
45
- });
46
-
47
- userToAuthority.set(
48
- userAccountPublicKey.toString(),
49
- userAccount.authority.toString()
50
- );
51
- }
52
- for (const orderProgramAccount of orderProgramAccounts) {
53
- const userOrderAccountPublicKey = orderProgramAccount.publicKey;
54
- const userOrderAccount = orderProgramAccount.account as UserOrdersAccount;
55
-
56
- const authority = userToAuthority.get(userOrderAccount.user.toString());
57
- const userPublicKeys = authorityToKeys.get(authority);
58
- userPublicKeys.userOrders = userOrderAccountPublicKey;
59
- }
60
-
61
18
  await Promise.all(
62
19
  users.map((user) => {
63
20
  // Pull the keys from the authority map so we can skip fetching them in addToAccountLoader
64
- const userPublicKeys = authorityToKeys.get(user.authority.toString());
65
21
  return (
66
22
  user.accountSubscriber as PollingUserAccountSubscriber
67
- ).addToAccountLoader(userPublicKeys);
23
+ ).addToAccountLoader();
68
24
  })
69
25
  );
70
26
 
@@ -0,0 +1,33 @@
1
+ import { Connection, PublicKey } from '@solana/web3.js';
2
+ import { UserAccount } from '../types';
3
+ import { getUserAccountPublicKey } from '../addresses/pda';
4
+ import { Program } from '@project-serum/anchor';
5
+
6
+ export async function fetchUserAccounts(
7
+ connection: Connection,
8
+ program: Program,
9
+ authority: PublicKey,
10
+ limit = 8
11
+ ): Promise<(UserAccount | undefined)[]> {
12
+ const userAccountPublicKeys = new Array<PublicKey>();
13
+ for (let i = 0; i < limit; i++) {
14
+ userAccountPublicKeys.push(
15
+ await getUserAccountPublicKey(program.programId, authority, i)
16
+ );
17
+ }
18
+
19
+ const accountInfos = await connection.getMultipleAccountsInfo(
20
+ userAccountPublicKeys,
21
+ 'confirmed'
22
+ );
23
+
24
+ return accountInfos.map((accountInfo) => {
25
+ if (!accountInfo) {
26
+ return undefined;
27
+ }
28
+ return program.account.user.coder.accounts.decode(
29
+ 'User',
30
+ accountInfo.data
31
+ ) as UserAccount;
32
+ });
33
+ }