@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
@@ -1,24 +1,52 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
2
+ var __generator = (this && this.__generator) || function (thisArg, body) {
3
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
4
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
5
+ function verb(n) { return function (v) { return step([n, v]); }; }
6
+ function step(op) {
7
+ if (f) throw new TypeError("Generator is already executing.");
8
+ while (_) try {
9
+ 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;
10
+ if (y = 0, t) op = [op[0] & 2, t.value];
11
+ switch (op[0]) {
12
+ case 0: case 1: t = op; break;
13
+ case 4: _.label++; return { value: op[1], done: false };
14
+ case 5: _.label++; y = op[1]; op = [0]; continue;
15
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
16
+ default:
17
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
18
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
19
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
20
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
21
+ if (t[2]) _.ops.pop();
22
+ _.trys.pop(); continue;
23
+ }
24
+ op = body.call(thisArg, _);
25
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
26
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
27
+ }
28
+ };
29
+ exports.__esModule = true;
3
30
  exports.EventList = void 0;
4
- class Node {
5
- constructor(event, next, prev) {
31
+ var Node = /** @class */ (function () {
32
+ function Node(event, next, prev) {
6
33
  this.event = event;
7
34
  this.next = next;
8
35
  this.prev = prev;
9
36
  }
10
- }
11
- class EventList {
12
- constructor(eventType, maxSize, sortFn, orderDirection) {
37
+ return Node;
38
+ }());
39
+ var EventList = /** @class */ (function () {
40
+ function EventList(eventType, maxSize, sortFn, orderDirection) {
13
41
  this.eventType = eventType;
14
42
  this.maxSize = maxSize;
15
43
  this.sortFn = sortFn;
16
44
  this.orderDirection = orderDirection;
17
45
  this.size = 0;
18
46
  }
19
- insert(event) {
47
+ EventList.prototype.insert = function (event) {
20
48
  this.size++;
21
- const newNode = new Node(event);
49
+ var newNode = new Node(event);
22
50
  if (this.head === undefined) {
23
51
  this.head = this.tail = newNode;
24
52
  return;
@@ -30,7 +58,7 @@ class EventList {
30
58
  this.head = newNode;
31
59
  }
32
60
  else {
33
- let currentNode = this.head;
61
+ var currentNode = this.head;
34
62
  while (currentNode.next !== undefined &&
35
63
  this.sortFn(currentNode.next.event, newNode.event) !==
36
64
  (this.orderDirection === 'asc' ? 'less than' : 'greater than')) {
@@ -40,15 +68,18 @@ class EventList {
40
68
  if (currentNode.next !== undefined) {
41
69
  newNode.next.prev = newNode;
42
70
  }
71
+ else {
72
+ this.tail = newNode;
73
+ }
43
74
  currentNode.next = newNode;
44
75
  newNode.prev = currentNode;
45
76
  }
46
77
  if (this.size > this.maxSize) {
47
78
  this.detach();
48
79
  }
49
- }
50
- detach() {
51
- const node = this.tail;
80
+ };
81
+ EventList.prototype.detach = function () {
82
+ var node = this.tail;
52
83
  if (node.prev !== undefined) {
53
84
  node.prev.next = node.next;
54
85
  }
@@ -62,16 +93,28 @@ class EventList {
62
93
  this.tail = node.prev;
63
94
  }
64
95
  this.size--;
65
- }
66
- toArray() {
96
+ };
97
+ EventList.prototype.toArray = function () {
67
98
  return Array.from(this);
68
- }
69
- *[Symbol.iterator]() {
70
- let node = this.head;
71
- while (node) {
72
- yield node.event;
73
- node = node.next;
74
- }
75
- }
76
- }
99
+ };
100
+ EventList.prototype[Symbol.iterator] = function () {
101
+ var node;
102
+ return __generator(this, function (_a) {
103
+ switch (_a.label) {
104
+ case 0:
105
+ node = this.head;
106
+ _a.label = 1;
107
+ case 1:
108
+ if (!node) return [3 /*break*/, 3];
109
+ return [4 /*yield*/, node.event];
110
+ case 2:
111
+ _a.sent();
112
+ node = node.next;
113
+ return [3 /*break*/, 1];
114
+ case 3: return [2 /*return*/];
115
+ }
116
+ });
117
+ };
118
+ return EventList;
119
+ }());
77
120
  exports.EventList = EventList;
@@ -0,0 +1,202 @@
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.EventSubscriber = void 0;
40
+ var types_1 = require("./types");
41
+ var txEventCache_1 = require("./txEventCache");
42
+ var eventList_1 = require("./eventList");
43
+ var pollingLogProvider_1 = require("./pollingLogProvider");
44
+ var fetchLogs_1 = require("./fetchLogs");
45
+ var webSocketLogProvider_1 = require("./webSocketLogProvider");
46
+ var events_1 = require("events");
47
+ var sort_1 = require("./sort");
48
+ var EventSubscriber = /** @class */ (function () {
49
+ function EventSubscriber(connection, program, options) {
50
+ if (options === void 0) { options = types_1.DefaultEventSubscriptionOptions; }
51
+ this.connection = connection;
52
+ this.program = program;
53
+ this.options = options;
54
+ this.awaitTxPromises = new Map();
55
+ this.awaitTxResolver = new Map();
56
+ this.options = Object.assign({}, types_1.DefaultEventSubscriptionOptions, options);
57
+ this.txEventCache = new txEventCache_1.TxEventCache(this.options.maxTx);
58
+ this.eventListMap = new Map();
59
+ for (var _i = 0, _a = this.options.eventTypes; _i < _a.length; _i++) {
60
+ var eventType = _a[_i];
61
+ this.eventListMap.set(eventType, new eventList_1.EventList(eventType, this.options.maxEventsPerType, (0, sort_1.getSortFn)(this.options.orderBy, this.options.orderDir, eventType), this.options.orderDir));
62
+ }
63
+ this.eventEmitter = new events_1.EventEmitter();
64
+ if (this.options.logProviderConfig.type === 'websocket') {
65
+ this.logProvider = new webSocketLogProvider_1.WebSocketLogProvider(this.connection, this.program.programId, this.options.commitment);
66
+ }
67
+ else {
68
+ this.logProvider = new pollingLogProvider_1.PollingLogProvider(this.connection, this.program.programId, options.commitment, this.options.logProviderConfig.frequency);
69
+ }
70
+ }
71
+ EventSubscriber.prototype.subscribe = function () {
72
+ return __awaiter(this, void 0, void 0, function () {
73
+ var _this = this;
74
+ return __generator(this, function (_a) {
75
+ try {
76
+ if (this.logProvider.isSubscribed()) {
77
+ return [2 /*return*/, true];
78
+ }
79
+ this.logProvider.subscribe(function (txSig, slot, logs) {
80
+ _this.handleTxLogs(txSig, slot, logs);
81
+ }, true);
82
+ return [2 /*return*/, true];
83
+ }
84
+ catch (e) {
85
+ console.error('Error fetching previous txs in event subscriber');
86
+ console.error(e);
87
+ return [2 /*return*/, false];
88
+ }
89
+ return [2 /*return*/];
90
+ });
91
+ });
92
+ };
93
+ EventSubscriber.prototype.handleTxLogs = function (txSig, slot, logs) {
94
+ if (this.txEventCache.has(txSig)) {
95
+ return;
96
+ }
97
+ var wrappedEvents = this.parseEventsFromLogs(txSig, slot, logs);
98
+ for (var _i = 0, wrappedEvents_1 = wrappedEvents; _i < wrappedEvents_1.length; _i++) {
99
+ var wrappedEvent = wrappedEvents_1[_i];
100
+ this.eventListMap.get(wrappedEvent.eventType).insert(wrappedEvent);
101
+ this.eventEmitter.emit('newEvent', wrappedEvent);
102
+ }
103
+ if (this.awaitTxPromises.has(txSig)) {
104
+ this.awaitTxPromises["delete"](txSig);
105
+ this.awaitTxResolver.get(txSig)();
106
+ this.awaitTxResolver["delete"](txSig);
107
+ }
108
+ if (slot > this.lastSeenSlot) {
109
+ this.lastSeenTxSig = txSig;
110
+ }
111
+ this.txEventCache.add(txSig, wrappedEvents);
112
+ };
113
+ EventSubscriber.prototype.fetchPreviousTx = function (fetchMax) {
114
+ return __awaiter(this, void 0, void 0, function () {
115
+ var txFetched, beforeTx, untilTx, response, _i, _a, _b, txSig, slot, logs;
116
+ return __generator(this, function (_c) {
117
+ switch (_c.label) {
118
+ case 0:
119
+ if (!this.options.untilTx && !fetchMax) {
120
+ return [2 /*return*/];
121
+ }
122
+ txFetched = 0;
123
+ beforeTx = undefined;
124
+ untilTx = this.options.untilTx;
125
+ _c.label = 1;
126
+ case 1:
127
+ if (!(txFetched < this.options.maxTx)) return [3 /*break*/, 3];
128
+ return [4 /*yield*/, (0, fetchLogs_1.fetchLogs)(this.connection, this.program.programId, this.options.commitment === 'finalized' ? 'finalized' : 'confirmed', beforeTx, untilTx)];
129
+ case 2:
130
+ response = _c.sent();
131
+ if (response === undefined) {
132
+ return [3 /*break*/, 3];
133
+ }
134
+ txFetched += response.transactionLogs.length;
135
+ beforeTx = response.earliestTx;
136
+ for (_i = 0, _a = response.transactionLogs; _i < _a.length; _i++) {
137
+ _b = _a[_i], txSig = _b.txSig, slot = _b.slot, logs = _b.logs;
138
+ this.handleTxLogs(txSig, slot, logs);
139
+ }
140
+ return [3 /*break*/, 1];
141
+ case 3: return [2 /*return*/];
142
+ }
143
+ });
144
+ });
145
+ };
146
+ EventSubscriber.prototype.unsubscribe = function () {
147
+ return __awaiter(this, void 0, void 0, function () {
148
+ return __generator(this, function (_a) {
149
+ switch (_a.label) {
150
+ case 0: return [4 /*yield*/, this.logProvider.unsubscribe()];
151
+ case 1: return [2 /*return*/, _a.sent()];
152
+ }
153
+ });
154
+ });
155
+ };
156
+ EventSubscriber.prototype.parseEventsFromLogs = function (txSig, slot, logs) {
157
+ var _this = this;
158
+ var records = [];
159
+ // @ts-ignore
160
+ this.program._events._eventParser.parseLogs(logs, function (event) {
161
+ var expectRecordType = _this.eventListMap.has(event.name);
162
+ if (expectRecordType) {
163
+ event.data.txSig = txSig;
164
+ event.data.slot = slot;
165
+ event.data.eventType = event.name;
166
+ records.push(event.data);
167
+ }
168
+ });
169
+ return records;
170
+ };
171
+ EventSubscriber.prototype.awaitTx = function (txSig) {
172
+ var _this = this;
173
+ if (this.awaitTxPromises.has(txSig)) {
174
+ return this.awaitTxPromises.get(txSig);
175
+ }
176
+ if (this.txEventCache.has(txSig)) {
177
+ return Promise.resolve();
178
+ }
179
+ var promise = new Promise(function (resolve) {
180
+ _this.awaitTxResolver.set(txSig, resolve);
181
+ });
182
+ this.awaitTxPromises.set(txSig, promise);
183
+ return promise;
184
+ };
185
+ EventSubscriber.prototype.getEventList = function (eventType) {
186
+ return this.eventListMap.get(eventType);
187
+ };
188
+ /**
189
+ * This requires the EventList be cast to an array, which requires reallocation of memory.
190
+ * Would bias to using getEventList over getEvents
191
+ *
192
+ * @param eventType
193
+ */
194
+ EventSubscriber.prototype.getEventsArray = function (eventType) {
195
+ return this.eventListMap.get(eventType).toArray();
196
+ };
197
+ EventSubscriber.prototype.getEventsByTx = function (txSig) {
198
+ return this.txEventCache.get(txSig);
199
+ };
200
+ return EventSubscriber;
201
+ }());
202
+ exports.EventSubscriber = EventSubscriber;
@@ -25,6 +25,8 @@ export class EventSubscriber {
25
25
  private awaitTxResolver = new Map<string, () => void>();
26
26
  private logProvider: LogProvider;
27
27
  public eventEmitter: StrictEventEmitter<EventEmitter, EventSubscriberEvents>;
28
+ private lastSeenSlot: number;
29
+ public lastSeenTxSig: string;
28
30
 
29
31
  public constructor(
30
32
  private connection: Connection,
@@ -62,19 +64,22 @@ export class EventSubscriber {
62
64
  }
63
65
  }
64
66
 
65
- public subscribe(): boolean {
66
- if (this.logProvider.isSubscribed()) {
67
- return true;
68
- }
67
+ public async subscribe(): Promise<boolean> {
68
+ try {
69
+ if (this.logProvider.isSubscribed()) {
70
+ return true;
71
+ }
69
72
 
70
- this.fetchPreviousTx().catch((e) => {
73
+ this.logProvider.subscribe((txSig, slot, logs) => {
74
+ this.handleTxLogs(txSig, slot, logs);
75
+ }, true);
76
+
77
+ return true;
78
+ } catch (e) {
71
79
  console.error('Error fetching previous txs in event subscriber');
72
80
  console.error(e);
73
- });
74
-
75
- return this.logProvider.subscribe((txSig, slot, logs) => {
76
- this.handleTxLogs(txSig, slot, logs);
77
- });
81
+ return false;
82
+ }
78
83
  }
79
84
 
80
85
  private handleTxLogs(
@@ -98,11 +103,14 @@ export class EventSubscriber {
98
103
  this.awaitTxResolver.delete(txSig);
99
104
  }
100
105
 
106
+ if (slot > this.lastSeenSlot) {
107
+ this.lastSeenTxSig = txSig;
108
+ }
101
109
  this.txEventCache.add(txSig, wrappedEvents);
102
110
  }
103
111
 
104
- private async fetchPreviousTx(): Promise<void> {
105
- if (!this.options.untilTx) {
112
+ public async fetchPreviousTx(fetchMax?: boolean): Promise<void> {
113
+ if (!this.options.untilTx && !fetchMax) {
106
114
  return;
107
115
  }
108
116
 
@@ -0,0 +1,117 @@
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.LogParser = exports.fetchLogs = void 0;
40
+ function fetchLogs(connection, programId, finality, beforeTx, untilTx, limit) {
41
+ return __awaiter(this, void 0, void 0, function () {
42
+ var signatures, sortedSignatures, filteredSignatures, chunkedSignatures, transactionLogs, earliest, mostRecent;
43
+ var _this = this;
44
+ return __generator(this, function (_a) {
45
+ switch (_a.label) {
46
+ case 0: return [4 /*yield*/, connection.getSignaturesForAddress(programId, {
47
+ before: beforeTx,
48
+ until: untilTx,
49
+ limit: limit
50
+ }, finality)];
51
+ case 1:
52
+ signatures = _a.sent();
53
+ sortedSignatures = signatures.sort(function (a, b) {
54
+ return a.slot === b.slot ? 0 : a.slot < b.slot ? -1 : 1;
55
+ });
56
+ filteredSignatures = sortedSignatures.filter(function (signature) { return !signature.err; });
57
+ if (filteredSignatures.length === 0) {
58
+ return [2 /*return*/, undefined];
59
+ }
60
+ chunkedSignatures = chunk(filteredSignatures, 100);
61
+ return [4 /*yield*/, Promise.all(chunkedSignatures.map(function (chunk) { return __awaiter(_this, void 0, void 0, function () {
62
+ var transactions;
63
+ return __generator(this, function (_a) {
64
+ switch (_a.label) {
65
+ case 0: return [4 /*yield*/, connection.getTransactions(chunk.map(function (confirmedSignature) { return confirmedSignature.signature; }), finality)];
66
+ case 1:
67
+ transactions = _a.sent();
68
+ return [2 /*return*/, transactions.map(function (transaction) {
69
+ return {
70
+ txSig: transaction.transaction.signatures[0],
71
+ slot: transaction.slot,
72
+ logs: transaction.meta.logMessages
73
+ };
74
+ })];
75
+ }
76
+ });
77
+ }); }))];
78
+ case 2:
79
+ transactionLogs = (_a.sent()).flat();
80
+ earliest = filteredSignatures[0];
81
+ mostRecent = filteredSignatures[filteredSignatures.length - 1];
82
+ return [2 /*return*/, {
83
+ transactionLogs: transactionLogs,
84
+ earliestTx: earliest.signature,
85
+ mostRecentTx: mostRecent.signature,
86
+ earliestSlot: earliest.slot,
87
+ mostRecentSlot: mostRecent.slot
88
+ }];
89
+ }
90
+ });
91
+ });
92
+ }
93
+ exports.fetchLogs = fetchLogs;
94
+ function chunk(array, size) {
95
+ return new Array(Math.ceil(array.length / size))
96
+ .fill(null)
97
+ .map(function (_, index) { return index * size; })
98
+ .map(function (begin) { return array.slice(begin, begin + size); });
99
+ }
100
+ var LogParser = /** @class */ (function () {
101
+ function LogParser(program) {
102
+ this.program = program;
103
+ }
104
+ LogParser.prototype.parseEventsFromLogs = function (event) {
105
+ var records = [];
106
+ // @ts-ignore
107
+ this.program._events._eventParser.parseLogs(event.logs, function (eventLog) {
108
+ eventLog.data.txSig = event.txSig;
109
+ eventLog.data.slot = event.slot;
110
+ eventLog.data.eventType = eventLog.name;
111
+ records.push(eventLog.data);
112
+ });
113
+ return records;
114
+ };
115
+ return LogParser;
116
+ }());
117
+ exports.LogParser = LogParser;
@@ -1,14 +1,18 @@
1
+ import { Program } from '@project-serum/anchor';
1
2
  import {
2
3
  Connection,
3
4
  Finality,
4
5
  PublicKey,
5
6
  TransactionSignature,
6
7
  } from '@solana/web3.js';
8
+ import { WrappedEvents } from './types';
7
9
 
8
10
  type Log = { txSig: TransactionSignature; slot: number; logs: string[] };
9
11
  type FetchLogsResponse = {
10
12
  earliestTx: string;
11
13
  mostRecentTx: string;
14
+ earliestSlot: number;
15
+ mostRecentSlot: number;
12
16
  transactionLogs: Log[];
13
17
  };
14
18
 
@@ -17,19 +21,21 @@ export async function fetchLogs(
17
21
  programId: PublicKey,
18
22
  finality: Finality,
19
23
  beforeTx?: TransactionSignature,
20
- untilTx?: TransactionSignature
21
- ): Promise<FetchLogsResponse | undefined> {
24
+ untilTx?: TransactionSignature,
25
+ limit?: number
26
+ ): Promise<FetchLogsResponse> {
22
27
  const signatures = await connection.getSignaturesForAddress(
23
28
  programId,
24
29
  {
25
30
  before: beforeTx,
26
31
  until: untilTx,
32
+ limit,
27
33
  },
28
34
  finality
29
35
  );
30
36
 
31
37
  const sortedSignatures = signatures.sort((a, b) =>
32
- a.slot < b.slot ? -1 : 1
38
+ a.slot === b.slot ? 0 : a.slot < b.slot ? -1 : 1
33
39
  );
34
40
 
35
41
  const filteredSignatures = sortedSignatures.filter(
@@ -61,14 +67,15 @@ export async function fetchLogs(
61
67
  )
62
68
  ).flat();
63
69
 
64
- const earliestTx = filteredSignatures[0].signature;
65
- const mostRecentTx =
66
- filteredSignatures[filteredSignatures.length - 1].signature;
70
+ const earliest = filteredSignatures[0];
71
+ const mostRecent = filteredSignatures[filteredSignatures.length - 1];
67
72
 
68
73
  return {
69
74
  transactionLogs: transactionLogs,
70
- earliestTx: earliestTx,
71
- mostRecentTx: mostRecentTx,
75
+ earliestTx: earliest.signature,
76
+ mostRecentTx: mostRecent.signature,
77
+ earliestSlot: earliest.slot,
78
+ mostRecentSlot: mostRecent.slot,
72
79
  };
73
80
  }
74
81
 
@@ -78,3 +85,23 @@ function chunk<T>(array: readonly T[], size: number): T[][] {
78
85
  .map((_, index) => index * size)
79
86
  .map((begin) => array.slice(begin, begin + size));
80
87
  }
88
+
89
+ export class LogParser {
90
+ private program: Program;
91
+
92
+ constructor(program: Program) {
93
+ this.program = program;
94
+ }
95
+
96
+ public parseEventsFromLogs(event: Log): WrappedEvents {
97
+ const records: WrappedEvents = [];
98
+ // @ts-ignore
99
+ this.program._events._eventParser.parseLogs(event.logs, (eventLog) => {
100
+ eventLog.data.txSig = event.txSig;
101
+ eventLog.data.slot = event.slot;
102
+ eventLog.data.eventType = eventLog.name;
103
+ records.push(eventLog.data);
104
+ });
105
+ return records;
106
+ }
107
+ }