@tastytrade/api 4.0.0 → 6.0.0
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.
- package/CHANGELOG.md +44 -0
- package/README.md +103 -28
- package/dist/account-streamer.d.ts +8 -4
- package/dist/account-streamer.d.ts.map +1 -1
- package/dist/account-streamer.js +28 -21
- package/dist/account-streamer.js.map +1 -1
- package/dist/logger.d.ts +24 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +40 -0
- package/dist/logger.js.map +1 -0
- package/dist/market-data-streamer.d.ts.map +1 -1
- package/dist/market-data-streamer.js +1 -0
- package/dist/market-data-streamer.js.map +1 -1
- package/dist/models/access-token.d.ts +12 -0
- package/dist/models/access-token.d.ts.map +1 -0
- package/dist/models/access-token.js +35 -0
- package/dist/models/access-token.js.map +1 -0
- package/dist/models/tastytrade-session.d.ts.map +1 -1
- package/dist/models/tastytrade-session.js.map +1 -1
- package/dist/quote-streamer.d.ts +58 -0
- package/dist/quote-streamer.d.ts.map +1 -0
- package/dist/quote-streamer.js +132 -0
- package/dist/quote-streamer.js.map +1 -0
- package/dist/services/account-status-service.js +0 -1
- package/dist/services/account-status-service.js.map +1 -1
- package/dist/services/accounts-and-customers-service.js +0 -1
- package/dist/services/accounts-and-customers-service.js.map +1 -1
- package/dist/services/balances-and-positions-service.js +0 -1
- package/dist/services/balances-and-positions-service.js.map +1 -1
- package/dist/services/instruments-service.js +1 -2
- package/dist/services/instruments-service.js.map +1 -1
- package/dist/services/margin-requirements-service.js +0 -1
- package/dist/services/margin-requirements-service.js.map +1 -1
- package/dist/services/market-metrics-service.js +0 -1
- package/dist/services/market-metrics-service.js.map +1 -1
- package/dist/services/net-liquidating-value-history-service.js +0 -1
- package/dist/services/net-liquidating-value-history-service.js.map +1 -1
- package/dist/services/orders-service.js +0 -1
- package/dist/services/orders-service.js.map +1 -1
- package/dist/services/risk-parameters-service.js +0 -1
- package/dist/services/risk-parameters-service.js.map +1 -1
- package/dist/services/session-service.d.ts +6 -1
- package/dist/services/session-service.d.ts.map +1 -1
- package/dist/services/session-service.js +10 -2
- package/dist/services/session-service.js.map +1 -1
- package/dist/services/symbol-search-service.js +0 -1
- package/dist/services/symbol-search-service.js.map +1 -1
- package/dist/services/tastytrade-http-client.d.ts +18 -2
- package/dist/services/tastytrade-http-client.d.ts.map +1 -1
- package/dist/services/tastytrade-http-client.js +73 -14
- package/dist/services/tastytrade-http-client.js.map +1 -1
- package/dist/services/transactions-service.js +0 -1
- package/dist/services/transactions-service.js.map +1 -1
- package/dist/services/watchlists-service.js +0 -1
- package/dist/services/watchlists-service.js.map +1 -1
- package/dist/tastytrade-api.d.ts +24 -5
- package/dist/tastytrade-api.d.ts.map +1 -1
- package/dist/tastytrade-api.js +26 -9
- package/dist/tastytrade-api.js.map +1 -1
- package/dist/utils/json-util.d.ts.map +1 -1
- package/dist/utils/json-util.js +0 -2
- package/dist/utils/json-util.js.map +1 -1
- package/dist/utils/response-util.d.ts.map +1 -1
- package/dist/utils/response-util.js +0 -1
- package/dist/utils/response-util.js.map +1 -1
- package/eslint.config.cjs +46 -0
- package/lib/account-streamer.ts +44 -29
- package/lib/logger.ts +53 -0
- package/lib/models/access-token.ts +40 -0
- package/lib/models/tastytrade-session.ts +1 -1
- package/lib/quote-streamer.ts +151 -0
- package/lib/services/instruments-service.ts +1 -1
- package/lib/services/session-service.ts +13 -1
- package/lib/services/tastytrade-http-client.ts +98 -16
- package/lib/tastytrade-api.ts +45 -5
- package/lib/utils/json-util.ts +0 -2
- package/lib/utils/response-util.ts +3 -4
- package/package.json +26 -18
- package/tsconfig.json +3 -3
- package/.eslintrc.cjs +0 -18
- package/lib/market-data-streamer.ts +0 -376
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import TastytradeSession from "../models/tastytrade-session.js";
|
|
2
|
+
import AccessToken from "../models/access-token.js";
|
|
2
3
|
import axios from "axios";
|
|
3
4
|
import qs from 'qs';
|
|
4
5
|
import { recursiveDasherizeKeys } from "../utils/json-util.js";
|
|
@@ -8,36 +9,85 @@ const ParamsSerializer = {
|
|
|
8
9
|
return qs.stringify(queryParams, { arrayFormat: 'brackets' });
|
|
9
10
|
}
|
|
10
11
|
};
|
|
12
|
+
const ApiVersionRegex = /^\d{8}$/;
|
|
11
13
|
export default class TastytradeHttpClient {
|
|
12
|
-
constructor(
|
|
13
|
-
this.
|
|
14
|
+
constructor(clientConfig, logger) {
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
this.baseUrl = clientConfig.baseUrl;
|
|
17
|
+
this.accessToken = new AccessToken();
|
|
14
18
|
this.session = new TastytradeSession();
|
|
19
|
+
this.updateConfig(clientConfig);
|
|
20
|
+
}
|
|
21
|
+
updateConfig(config) {
|
|
22
|
+
const httpClientConfig = _.pick(config, ['clientSecret', 'refreshToken', 'oauthScopes', 'targetApiVersion']);
|
|
23
|
+
if (!_.isEmpty(httpClientConfig)) {
|
|
24
|
+
Object.assign(this, httpClientConfig);
|
|
25
|
+
this.accessToken.clear();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
get needsTokenRefresh() {
|
|
29
|
+
if (this.session.isValid) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (_.isNil(this.refreshToken) || _.isNil(this.clientSecret)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return this.accessToken.isExpired;
|
|
36
|
+
}
|
|
37
|
+
get authHeader() {
|
|
38
|
+
if (this.session.isValid) {
|
|
39
|
+
return this.session.authToken;
|
|
40
|
+
}
|
|
41
|
+
if (this.accessToken.isValid) {
|
|
42
|
+
return this.accessToken.authorizationHeader;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
15
45
|
}
|
|
16
46
|
getDefaultHeaders() {
|
|
17
47
|
const headers = {
|
|
18
48
|
"Content-Type": "application/json",
|
|
19
49
|
"Accept": "application/json",
|
|
20
|
-
"Authorization": this.
|
|
50
|
+
"Authorization": this.authHeader
|
|
21
51
|
};
|
|
52
|
+
if (!_.isNil(this.targetApiVersion)) {
|
|
53
|
+
headers["Accept-Version"] = this.targetApiVersion;
|
|
54
|
+
}
|
|
22
55
|
// Only set user agent if running in node
|
|
23
56
|
if (typeof window === 'undefined') {
|
|
24
57
|
headers["User-Agent"] = 'tastytrade-sdk-js';
|
|
25
58
|
}
|
|
26
59
|
return headers;
|
|
27
60
|
}
|
|
61
|
+
axiosConfig(method, url, data = {}, headers = {}, params = {}) {
|
|
62
|
+
return _.omitBy({ method, url, baseURL: this.baseUrl, data, headers, params, paramsSerializer: ParamsSerializer }, _.isEmpty);
|
|
63
|
+
}
|
|
64
|
+
async generateAccessToken() {
|
|
65
|
+
if (_.isNil(this.refreshToken) || _.isNil(this.clientSecret) || _.isNil(this.oauthScopes)) {
|
|
66
|
+
throw new Error('Missing required parameters to generate access token (refreshToken, clientSecret, oauthScopes)');
|
|
67
|
+
}
|
|
68
|
+
const params = {
|
|
69
|
+
refresh_token: this.refreshToken,
|
|
70
|
+
client_secret: this.clientSecret,
|
|
71
|
+
scope: this.oauthScopes.join(' '),
|
|
72
|
+
grant_type: 'refresh_token'
|
|
73
|
+
};
|
|
74
|
+
const config = this.axiosConfig('post', '/oauth/token', params);
|
|
75
|
+
this.logger?.info('Making request', config);
|
|
76
|
+
const tokenResponse = await axios.request(config);
|
|
77
|
+
this.accessToken.updateFromTokenResponse(tokenResponse);
|
|
78
|
+
return this.accessToken;
|
|
79
|
+
}
|
|
28
80
|
async executeRequest(method, url, data = {}, headers = {}, params = {}) {
|
|
29
|
-
|
|
30
|
-
|
|
81
|
+
if (this.needsTokenRefresh) {
|
|
82
|
+
await this.generateAccessToken();
|
|
83
|
+
}
|
|
84
|
+
let dasherizedParams = params;
|
|
85
|
+
let dasherizedData = data;
|
|
86
|
+
dasherizedParams = recursiveDasherizeKeys(params);
|
|
87
|
+
dasherizedData = recursiveDasherizeKeys(data);
|
|
31
88
|
const mergedHeaders = { ...headers, ...this.getDefaultHeaders() };
|
|
32
|
-
const config =
|
|
33
|
-
|
|
34
|
-
url,
|
|
35
|
-
baseURL: this.baseUrl,
|
|
36
|
-
data: dasherizedData,
|
|
37
|
-
headers: mergedHeaders,
|
|
38
|
-
params: dasherizedParams,
|
|
39
|
-
paramsSerializer: ParamsSerializer
|
|
40
|
-
}, _.isEmpty);
|
|
89
|
+
const config = this.axiosConfig(method, url, dasherizedData, mergedHeaders, dasherizedParams);
|
|
90
|
+
this.logger?.info('Making request', config);
|
|
41
91
|
return axios.request(config);
|
|
42
92
|
}
|
|
43
93
|
async getData(url, headers = {}, queryParams = {}) {
|
|
@@ -55,5 +105,14 @@ export default class TastytradeHttpClient {
|
|
|
55
105
|
async deleteData(url, headers) {
|
|
56
106
|
return this.executeRequest('delete', url, headers);
|
|
57
107
|
}
|
|
108
|
+
get targetApiVersion() {
|
|
109
|
+
return this._targetApiVersion;
|
|
110
|
+
}
|
|
111
|
+
set targetApiVersion(version) {
|
|
112
|
+
if (!_.isNil(version) && !ApiVersionRegex.test(version)) {
|
|
113
|
+
throw new Error('Invalid API version format. Expected YYYYMMDD.');
|
|
114
|
+
}
|
|
115
|
+
this._targetApiVersion = version;
|
|
116
|
+
}
|
|
58
117
|
}
|
|
59
118
|
//# sourceMappingURL=tastytrade-http-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tastytrade-http-client.js","sourceRoot":"","sources":["../../lib/services/tastytrade-http-client.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,iCAAiC,CAAA;AAC/D,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,CAAC,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"tastytrade-http-client.js","sourceRoot":"","sources":["../../lib/services/tastytrade-http-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactions-service.js","sourceRoot":"","sources":["../../lib/services/transactions-service.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"transactions-service.js","sourceRoot":"","sources":["../../lib/services/transactions-service.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,2BAA2B,CAAC;AAG5D,MAAM,CAAC,OAAO,OAAO,mBAAmB;IACpC,YAAoB,UAAgC;QAAhC,eAAU,GAAV,UAAU,CAAsB;IACpD,CAAC;IAED,sCAAsC;IACtC,KAAK,CAAC,cAAc,CAAC,aAAqB,EAAE,EAAU;QAClD,iDAAiD;QACjD,MAAM,UAAU,GAAI,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,aAAa,aAAa,iBAAiB,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAC5G,OAAO,mBAAmB,CAAC,UAAU,CAAC,CAAA;IAC1C,CAAC;IACD,KAAK,CAAC,YAAY,CAAC,aAAqB;QACpC,sDAAsD;QACtD,MAAM,SAAS,GAAI,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,aAAa,aAAa,0BAA0B,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAChH,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAA;IACzC,CAAC;IAED,8CAA8C;IAC9C,KAAK,CAAC,sBAAsB,CAAC,aAAqB,EAAE,WAAW,GAAG,EAAE;QAChE,8GAA8G;QAC9G,gFAAgF;QAChF,MAAM,mBAAmB,GAAI,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,aAAa,aAAa,eAAe,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC,CAAA;QACxH,OAAO,mBAAmB,CAAC,mBAAmB,CAAC,CAAA;IACnD,CAAC;CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watchlists-service.js","sourceRoot":"","sources":["../../lib/services/watchlists-service.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"watchlists-service.js","sourceRoot":"","sources":["../../lib/services/watchlists-service.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,2BAA2B,CAAC;AAG5D,MAAM,CAAC,OAAO,OAAO,iBAAiB;IAClC,YAAoB,UAAgC;QAAhC,eAAU,GAAV,UAAU,CAAsB;IACpD,CAAC;IAED,mEAAmE;IACnE,KAAK,CAAC,kBAAkB;QACpB,mDAAmD;QACnD,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAClF,OAAO,mBAAmB,CAAC,eAAe,CAAC,CAAA;IAC/C,CAAC;IACD,KAAK,CAAC,iBAAiB,CAAC,kBAA0B;QAC9C,gDAAgD;QAChD,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,qBAAqB,kBAAkB,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QACvG,OAAO,mBAAmB,CAAC,cAAc,CAAC,CAAA;IAC9C,CAAC;IAED,yEAAyE;IACzE,KAAK,CAAC,mBAAmB,CAAC,UAAU,GAAI,KAAK;QACzC,6CAA6C;QAC7C,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,EAAE,EAAC,aAAa,EAAE,UAAU,EAAE,CAAC,CAAA;QAC9G,OAAO,mBAAmB,CAAC,gBAAgB,CAAC,CAAA;IAChD,CAAC;IACD,KAAK,CAAC,kBAAkB,CAAC,aAAqB;QAC1C,0CAA0C;QAC1C,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,sBAAsB,aAAa,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QACpG,OAAO,mBAAmB,CAAC,eAAe,CAAC,CAAA;IAC/C,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,sBAAsB,CAAC,SAAiB;QAC1C,6BAA6B;QAC7B,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,aAAa,EAAE,SAAS,EAAE,EAAE,CAAC,CAAA;QACrF,OAAO,mBAAmB,CAAC,gBAAgB,CAAC,CAAA;IAChD,CAAC;IACD,KAAK,CAAC,gBAAgB;QAClB,wDAAwD;QACxD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAC1E,OAAO,mBAAmB,CAAC,aAAa,CAAC,CAAA;IAC7C,CAAC;IACD,KAAK,CAAC,gBAAgB,CAAC,aAAqB,EAAE,oBAA4B;QACtE,gDAAgD;QAChD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,aAAa,EAAE,EAAE,oBAAoB,EAAG,EAAE,CAAC,CAAA;QAC1G,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAA;IACzC,CAAC;IACD,KAAK,CAAC,eAAe,CAAC,aAAqB;QACvC,0CAA0C;QAC1C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,eAAe,aAAa,EAAE,EAAE,EAAE,CAAC,CAAA;QACtF,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAA;IACzC,CAAC;IACD,KAAK,CAAC,kBAAkB,CAAC,aAAqB;QAC1C,uCAAuC;QACvC,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,aAAa,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAC7F,OAAO,mBAAmB,CAAC,eAAe,CAAC,CAAA;IAC/C,CAAC;CACJ"}
|
package/dist/tastytrade-api.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import TastytradeHttpClient from "./services/tastytrade-http-client.js";
|
|
2
2
|
import { AccountStreamer, STREAMER_STATE, type Disposer, type StreamerStateObserver } from './account-streamer.js';
|
|
3
|
-
import MarketDataStreamer, { type CandleSubscriptionOptions, CandleType, MarketDataSubscriptionType, type MarketDataListener } from "./market-data-streamer.js";
|
|
4
3
|
import SessionService from "./services/session-service.js";
|
|
5
4
|
import AccountStatusService from "./services/account-status-service.js";
|
|
6
5
|
import AccountsAndCustomersService from "./services/accounts-and-customers-service.js";
|
|
@@ -15,11 +14,27 @@ import SymbolSearchService from "./services/symbol-search-service.js";
|
|
|
15
14
|
import TransactionsService from "./services/transactions-service.js";
|
|
16
15
|
import WatchlistsService from "./services/watchlists-service.js";
|
|
17
16
|
import TastytradeSession from "./models/tastytrade-session.js";
|
|
17
|
+
import type Logger from "./logger.js";
|
|
18
|
+
import { TastytradeLogger, LogLevel } from "./logger.js";
|
|
19
|
+
import QuoteStreamer, { MarketDataSubscriptionType, CandleType } from "./quote-streamer.js";
|
|
20
|
+
import type AccessToken from "./models/access-token.js";
|
|
21
|
+
export type ClientConfig = {
|
|
22
|
+
baseUrl: string;
|
|
23
|
+
accountStreamerUrl: string;
|
|
24
|
+
clientSecret?: string;
|
|
25
|
+
refreshToken?: string;
|
|
26
|
+
oauthScopes?: string[];
|
|
27
|
+
logger?: Logger;
|
|
28
|
+
logLevel?: LogLevel;
|
|
29
|
+
targetApiVersion?: string;
|
|
30
|
+
};
|
|
18
31
|
export default class TastytradeClient {
|
|
19
|
-
readonly
|
|
20
|
-
readonly
|
|
32
|
+
static readonly ProdConfig: ClientConfig;
|
|
33
|
+
static readonly SandboxConfig: ClientConfig;
|
|
34
|
+
readonly logger: TastytradeLogger;
|
|
21
35
|
readonly httpClient: TastytradeHttpClient;
|
|
22
36
|
readonly accountStreamer: AccountStreamer;
|
|
37
|
+
readonly quoteStreamer: QuoteStreamer;
|
|
23
38
|
readonly sessionService: SessionService;
|
|
24
39
|
readonly accountStatusService: AccountStatusService;
|
|
25
40
|
readonly accountsAndCustomersService: AccountsAndCustomersService;
|
|
@@ -33,9 +48,13 @@ export default class TastytradeClient {
|
|
|
33
48
|
readonly symbolSearchService: SymbolSearchService;
|
|
34
49
|
readonly transactionsService: TransactionsService;
|
|
35
50
|
readonly watchlistsService: WatchlistsService;
|
|
36
|
-
constructor(
|
|
51
|
+
constructor(config: ClientConfig);
|
|
52
|
+
updateConfig(config: Partial<ClientConfig>): void;
|
|
37
53
|
get session(): TastytradeSession;
|
|
54
|
+
get accessToken(): AccessToken;
|
|
38
55
|
}
|
|
39
|
-
export {
|
|
56
|
+
export { MarketDataSubscriptionType, CandleType };
|
|
40
57
|
export { AccountStreamer, STREAMER_STATE, type Disposer, type StreamerStateObserver };
|
|
58
|
+
export { TastytradeLogger, LogLevel };
|
|
59
|
+
export type { Logger };
|
|
41
60
|
//# sourceMappingURL=tastytrade-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tastytrade-api.d.ts","sourceRoot":"","sources":["../lib/tastytrade-api.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,MAAM,sCAAsC,CAAA;AACvE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"tastytrade-api.d.ts","sourceRoot":"","sources":["../lib/tastytrade-api.ts"],"names":[],"mappings":"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"}
|
package/dist/tastytrade-api.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import TastytradeHttpClient from "./services/tastytrade-http-client.js";
|
|
2
2
|
import { AccountStreamer, STREAMER_STATE } from './account-streamer.js';
|
|
3
|
-
import MarketDataStreamer, { CandleType, MarketDataSubscriptionType } from "./market-data-streamer.js";
|
|
4
3
|
//Services:
|
|
5
4
|
import SessionService from "./services/session-service.js";
|
|
6
5
|
import AccountStatusService from "./services/account-status-service.js";
|
|
@@ -15,13 +14,12 @@ import RiskParametersService from "./services/risk-parameters-service.js";
|
|
|
15
14
|
import SymbolSearchService from "./services/symbol-search-service.js";
|
|
16
15
|
import TransactionsService from "./services/transactions-service.js";
|
|
17
16
|
import WatchlistsService from "./services/watchlists-service.js";
|
|
18
|
-
import
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.
|
|
23
|
-
this.httpClient = new TastytradeHttpClient(
|
|
24
|
-
this.accountStreamer = new AccountStreamer(accountStreamerUrl, this.session);
|
|
17
|
+
import { TastytradeLogger, LogLevel } from "./logger.js";
|
|
18
|
+
import QuoteStreamer, { MarketDataSubscriptionType, CandleType } from "./quote-streamer.js";
|
|
19
|
+
class TastytradeClient {
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.logger = new TastytradeLogger(config.logger, config.logLevel);
|
|
22
|
+
this.httpClient = new TastytradeHttpClient(config, this.logger);
|
|
25
23
|
this.sessionService = new SessionService(this.httpClient);
|
|
26
24
|
this.accountStatusService = new AccountStatusService(this.httpClient);
|
|
27
25
|
this.accountsAndCustomersService = new AccountsAndCustomersService(this.httpClient);
|
|
@@ -35,11 +33,30 @@ export default class TastytradeClient {
|
|
|
35
33
|
this.symbolSearchService = new SymbolSearchService(this.httpClient);
|
|
36
34
|
this.transactionsService = new TransactionsService(this.httpClient);
|
|
37
35
|
this.watchlistsService = new WatchlistsService(this.httpClient);
|
|
36
|
+
this.accountStreamer = new AccountStreamer(config.accountStreamerUrl, this.session, this.accessToken, this.logger);
|
|
37
|
+
this.quoteStreamer = new QuoteStreamer(this.accountsAndCustomersService, this.logger);
|
|
38
|
+
}
|
|
39
|
+
updateConfig(config) {
|
|
40
|
+
this.httpClient.updateConfig(config);
|
|
41
|
+
this.logger.updateConfig(config);
|
|
38
42
|
}
|
|
39
43
|
get session() {
|
|
40
44
|
return this.httpClient.session;
|
|
41
45
|
}
|
|
46
|
+
get accessToken() {
|
|
47
|
+
return this.httpClient.accessToken;
|
|
48
|
+
}
|
|
42
49
|
}
|
|
43
|
-
|
|
50
|
+
TastytradeClient.ProdConfig = {
|
|
51
|
+
baseUrl: 'https://api.tastyworks.com',
|
|
52
|
+
accountStreamerUrl: 'wss://streamer.tastyworks.com',
|
|
53
|
+
};
|
|
54
|
+
TastytradeClient.SandboxConfig = {
|
|
55
|
+
baseUrl: 'https://api.cert.tastyworks.com',
|
|
56
|
+
accountStreamerUrl: 'wss://streamer.cert.tastyworks.com',
|
|
57
|
+
};
|
|
58
|
+
export default TastytradeClient;
|
|
59
|
+
export { MarketDataSubscriptionType, CandleType };
|
|
44
60
|
export { AccountStreamer, STREAMER_STATE };
|
|
61
|
+
export { TastytradeLogger, LogLevel };
|
|
45
62
|
//# sourceMappingURL=tastytrade-api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tastytrade-api.js","sourceRoot":"","sources":["../lib/tastytrade-api.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,MAAM,sCAAsC,CAAA;AACvE,OAAO,EAAE,eAAe,EAAE,cAAc,EAA6C,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"tastytrade-api.js","sourceRoot":"","sources":["../lib/tastytrade-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-util.d.ts","sourceRoot":"","sources":["../../lib/utils/json-util.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAA;AAEtB,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;AACzE,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,SAAS,GAAG,OAAO,CAAA;AAC5D,MAAM,WAAW,OAAO;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAA;CACrC;AACD,MAAM,MAAM,SAAS,GAAG,SAAS,EAAE,CAAA;AAEnC,qBAAa,WAAW;aACa,IAAI,EAAE,OAAO;gBAAb,IAAI,GAAE,OAAY;IAE9C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,UAAQ,GAAG,IAAI;CAQxE;
|
|
1
|
+
{"version":3,"file":"json-util.d.ts","sourceRoot":"","sources":["../../lib/utils/json-util.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAA;AAEtB,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;AACzE,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,SAAS,GAAG,OAAO,CAAA;AAC5D,MAAM,WAAW,OAAO;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAA;CACrC;AACD,MAAM,MAAM,SAAS,GAAG,SAAS,EAAE,CAAA;AAEnC,qBAAa,WAAW;aACa,IAAI,EAAE,OAAO;gBAAb,IAAI,GAAE,OAAY;IAE9C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,UAAQ,GAAG,IAAI;CAQxE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,qBAY/C;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKhD"}
|
package/dist/utils/json-util.js
CHANGED
|
@@ -11,10 +11,8 @@ export class JsonBuilder {
|
|
|
11
11
|
return this;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
14
|
export function recursiveDasherizeKeys(body) {
|
|
16
15
|
let dasherized = _.mapKeys(body, (_value, key) => dasherize(key));
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
16
|
dasherized = _.mapValues(dasherized, (value) => {
|
|
19
17
|
if (_.isPlainObject(value)) {
|
|
20
18
|
return recursiveDasherizeKeys(value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-util.js","sourceRoot":"","sources":["../../lib/utils/json-util.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAA;AAStB,MAAM,OAAO,WAAW;IACtB,YAAmC,OAAgB,EAAE;QAAlB,SAAI,GAAJ,IAAI,CAAc;IAAG,CAAC;IAElD,GAAG,CAAC,GAAW,EAAE,KAAgB,EAAE,cAAc,GAAG,KAAK;QAC9D,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACxD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QACtB,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAED,
|
|
1
|
+
{"version":3,"file":"json-util.js","sourceRoot":"","sources":["../../lib/utils/json-util.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAA;AAStB,MAAM,OAAO,WAAW;IACtB,YAAmC,OAAgB,EAAE;QAAlB,SAAI,GAAJ,IAAI,CAAc;IAAG,CAAC;IAElD,GAAG,CAAC,GAAW,EAAE,KAAgB,EAAE,cAAc,GAAG,KAAK;QAC9D,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACxD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QACtB,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAS;IAC9C,IAAI,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IAEjE,UAAU,GAAG,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,KAAU,EAAE,EAAE;QAClD,IAAI,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAA;QACtC,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CAAA;IAEF,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,kBAAkB;IAClB,OAAO,MAAM;SACV,OAAO,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,EAAU,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;SACpF,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AACxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-util.d.ts","sourceRoot":"","sources":["../../lib/utils/response-util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"response-util.d.ts","sourceRoot":"","sources":["../../lib/utils/response-util.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,YAAY,EAAE,GAAG,OAQ5D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-util.js","sourceRoot":"","sources":["../../lib/utils/response-util.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAA;AAEtB,
|
|
1
|
+
{"version":3,"file":"response-util.js","sourceRoot":"","sources":["../../lib/utils/response-util.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAA;AAEtB,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,YAAiB;IAC3D,IAAI,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,iBAAiB,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAA;IAC/C,CAAC;SAAM,IAAI,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;IACzC,CAAC;SAAM,CAAC;QACN,OAAO,YAAY,CAAA;IACrB,CAAC;AACH,CAAC;AAED,wBAAwB;AACxB,yDAAyD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const { defineConfig } = require('eslint/config')
|
|
2
|
+
|
|
3
|
+
const tsParser = require('@typescript-eslint/parser')
|
|
4
|
+
const typescriptEslint = require('@typescript-eslint/eslint-plugin')
|
|
5
|
+
const js = require('@eslint/js')
|
|
6
|
+
|
|
7
|
+
const { FlatCompat } = require('@eslint/eslintrc')
|
|
8
|
+
|
|
9
|
+
const compat = new FlatCompat({
|
|
10
|
+
baseDirectory: __dirname,
|
|
11
|
+
recommendedConfig: js.configs.recommended,
|
|
12
|
+
allConfig: js.configs.all
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
module.exports = defineConfig([
|
|
16
|
+
{
|
|
17
|
+
extends: compat.extends(
|
|
18
|
+
'eslint:recommended',
|
|
19
|
+
'plugin:@typescript-eslint/recommended'
|
|
20
|
+
),
|
|
21
|
+
|
|
22
|
+
languageOptions: {
|
|
23
|
+
parser: tsParser
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
plugins: {
|
|
27
|
+
'@typescript-eslint': typescriptEslint
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
rules: {
|
|
31
|
+
'@typescript-eslint/no-inferrable-types': 'warn',
|
|
32
|
+
|
|
33
|
+
'@typescript-eslint/no-unused-vars': [
|
|
34
|
+
'error',
|
|
35
|
+
{
|
|
36
|
+
argsIgnorePattern: '^_',
|
|
37
|
+
varsIgnorePattern: '^_',
|
|
38
|
+
caughtErrorsIgnorePattern: '^_'
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
|
|
42
|
+
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
43
|
+
'@typescript-eslint/no-explicit-any': 'off'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
])
|
package/lib/account-streamer.ts
CHANGED
|
@@ -4,6 +4,8 @@ import type { JsonMap, JsonValue } from './utils/json-util.js'
|
|
|
4
4
|
import { JsonBuilder } from './utils/json-util.js'
|
|
5
5
|
import TastytradeSession from './models/tastytrade-session.js'
|
|
6
6
|
import { MinTlsVersion } from './utils/constants.js'
|
|
7
|
+
import type Logger from './logger.js'
|
|
8
|
+
import type AccessToken from './models/access-token.js'
|
|
7
9
|
|
|
8
10
|
export enum STREAMER_STATE {
|
|
9
11
|
Open = 0,
|
|
@@ -20,7 +22,7 @@ enum MessageAction {
|
|
|
20
22
|
USER_MESSAGE_SUBSCRIBE = 'user-message-subscribe'
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
const
|
|
25
|
+
const DEFAULT_HEARTBEAT_INTERVAL = 2000 // 20 seconds
|
|
24
26
|
|
|
25
27
|
const SOURCE = 'tastytrade-api-js-sdk'
|
|
26
28
|
|
|
@@ -42,10 +44,11 @@ function removeElement<T>(array: T[], element: T): void {
|
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
export class AccountStreamer {
|
|
47
|
+
private readonly logger: Logger
|
|
45
48
|
private websocket: WebSocket | null = null
|
|
46
49
|
private startResolve: ((result: boolean) => void) | null = null
|
|
47
50
|
private startReject: ((reason?: any) => void) | null = null
|
|
48
|
-
private requestCounter
|
|
51
|
+
private requestCounter = 0
|
|
49
52
|
private queued: string[] = []
|
|
50
53
|
|
|
51
54
|
private heartbeatTimerId: number | NodeJS.Timeout | null = null
|
|
@@ -65,13 +68,19 @@ export class AccountStreamer {
|
|
|
65
68
|
[(status: string) => void, (error: string) => void]
|
|
66
69
|
> = new Map()
|
|
67
70
|
|
|
68
|
-
private readonly logger = console
|
|
69
|
-
|
|
70
71
|
/**
|
|
71
|
-
*
|
|
72
|
+
*
|
|
72
73
|
* @param url Url of the account streamer service
|
|
73
74
|
*/
|
|
74
|
-
constructor(
|
|
75
|
+
constructor(
|
|
76
|
+
private readonly url: string,
|
|
77
|
+
private readonly session: TastytradeSession,
|
|
78
|
+
private readonly accessToken: AccessToken,
|
|
79
|
+
logger: Logger,
|
|
80
|
+
private readonly heartbeatInterval: number = DEFAULT_HEARTBEAT_INTERVAL
|
|
81
|
+
) {
|
|
82
|
+
this.logger = logger
|
|
83
|
+
}
|
|
75
84
|
|
|
76
85
|
get streamerState(): STREAMER_STATE {
|
|
77
86
|
return this._streamerState
|
|
@@ -80,19 +89,25 @@ export class AccountStreamer {
|
|
|
80
89
|
set streamerState(streamerState: STREAMER_STATE) {
|
|
81
90
|
this._streamerState = streamerState
|
|
82
91
|
|
|
83
|
-
this.streamerStateObservers.forEach(observer => {
|
|
92
|
+
this.streamerStateObservers.forEach((observer) => {
|
|
84
93
|
observer(streamerState)
|
|
85
94
|
})
|
|
86
95
|
}
|
|
87
96
|
|
|
88
|
-
private get
|
|
89
|
-
|
|
97
|
+
private get authHeader() {
|
|
98
|
+
if (this.session.isValid) {
|
|
99
|
+
return this.session.authToken
|
|
100
|
+
}
|
|
101
|
+
if (this.accessToken.isValid) {
|
|
102
|
+
return this.accessToken.authorizationHeader
|
|
103
|
+
}
|
|
104
|
+
return null
|
|
90
105
|
}
|
|
91
106
|
|
|
92
107
|
/**
|
|
93
108
|
* Adds a custom callback that fires when the streamer state changes
|
|
94
|
-
* @param observer
|
|
95
|
-
* @returns
|
|
109
|
+
* @param observer
|
|
110
|
+
* @returns
|
|
96
111
|
*/
|
|
97
112
|
addStreamerStateObserver(observer: StreamerStateObserver): Disposer {
|
|
98
113
|
this.streamerStateObservers.push(observer)
|
|
@@ -116,7 +131,7 @@ export class AccountStreamer {
|
|
|
116
131
|
|
|
117
132
|
/**
|
|
118
133
|
* Entrypoint for beginning a websocket session
|
|
119
|
-
* You must have a valid tastytrade
|
|
134
|
+
* You must have a valid tastytrade session or access token before calling this method
|
|
120
135
|
* @returns Promise that resolves when the "opened" message is received (see handleOpen)
|
|
121
136
|
*/
|
|
122
137
|
async start(): Promise<boolean> {
|
|
@@ -181,11 +196,11 @@ export class AccountStreamer {
|
|
|
181
196
|
return
|
|
182
197
|
}
|
|
183
198
|
|
|
184
|
-
this.logger.info('Scheduling heartbeat with interval: ',
|
|
199
|
+
this.logger.info('Scheduling heartbeat with interval: ', this.heartbeatInterval)
|
|
185
200
|
const scheduler = typeof window === 'undefined' ? setTimeout : window.setTimeout
|
|
186
201
|
this.heartbeatTimerId = scheduler(
|
|
187
202
|
this.sendHeartbeat,
|
|
188
|
-
|
|
203
|
+
this.heartbeatInterval
|
|
189
204
|
)
|
|
190
205
|
}
|
|
191
206
|
|
|
@@ -215,7 +230,7 @@ export class AccountStreamer {
|
|
|
215
230
|
* Send a message via websocket
|
|
216
231
|
* @param json JsonBuilder
|
|
217
232
|
* @param includeSessionToken Attaches session token to message if true
|
|
218
|
-
* @returns
|
|
233
|
+
* @returns
|
|
219
234
|
*/
|
|
220
235
|
send(json: JsonBuilder, includeSessionToken = true): number {
|
|
221
236
|
this.requestCounter += 1
|
|
@@ -223,12 +238,11 @@ export class AccountStreamer {
|
|
|
223
238
|
json.add('source', SOURCE)
|
|
224
239
|
|
|
225
240
|
if (includeSessionToken) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
throw new Error('sessionToken not set')
|
|
241
|
+
if (!this.authHeader) {
|
|
242
|
+
throw new Error('session or access token not set')
|
|
229
243
|
}
|
|
230
244
|
|
|
231
|
-
json.add('auth-token',
|
|
245
|
+
json.add('auth-token', this.authHeader)
|
|
232
246
|
}
|
|
233
247
|
|
|
234
248
|
const message = JSON.stringify(json.json)
|
|
@@ -237,6 +251,7 @@ export class AccountStreamer {
|
|
|
237
251
|
// Queue up and send on open
|
|
238
252
|
this.queued.push(message)
|
|
239
253
|
} else {
|
|
254
|
+
this.logger.info('Sending message: ', message)
|
|
240
255
|
websocket.send(message)
|
|
241
256
|
}
|
|
242
257
|
|
|
@@ -245,9 +260,9 @@ export class AccountStreamer {
|
|
|
245
260
|
|
|
246
261
|
/**
|
|
247
262
|
* Used by other methods to send a specific `action` message
|
|
248
|
-
* @param action
|
|
249
|
-
* @param value
|
|
250
|
-
* @returns
|
|
263
|
+
* @param action
|
|
264
|
+
* @param value
|
|
265
|
+
* @returns
|
|
251
266
|
*/
|
|
252
267
|
public subscribeTo(action: string, value?: JsonValue): number {
|
|
253
268
|
const json = new JsonBuilder()
|
|
@@ -297,19 +312,19 @@ export class AccountStreamer {
|
|
|
297
312
|
}
|
|
298
313
|
|
|
299
314
|
const websocket = this.websocket
|
|
300
|
-
queued.forEach(msg => {
|
|
315
|
+
queued.forEach((msg) => {
|
|
301
316
|
websocket.send(msg)
|
|
302
317
|
})
|
|
303
318
|
|
|
304
319
|
this.queued = []
|
|
305
320
|
}
|
|
306
321
|
|
|
307
|
-
private readonly handleOpen = (
|
|
322
|
+
private readonly handleOpen = (_event: WebSocket.Event) => {
|
|
308
323
|
if (this.startResolve === null) {
|
|
309
324
|
return
|
|
310
325
|
}
|
|
311
326
|
|
|
312
|
-
this.logger.info('AccountStreamer opened'
|
|
327
|
+
this.logger.info('AccountStreamer opened')
|
|
313
328
|
|
|
314
329
|
this.startResolve(true)
|
|
315
330
|
this.startResolve = this.startReject = null
|
|
@@ -320,7 +335,7 @@ export class AccountStreamer {
|
|
|
320
335
|
}
|
|
321
336
|
|
|
322
337
|
private readonly handleClose = (event: WebSocket.CloseEvent) => {
|
|
323
|
-
this.logger.info('AccountStreamer closed'
|
|
338
|
+
this.logger.info('AccountStreamer closed')
|
|
324
339
|
if (this.websocket === null) {
|
|
325
340
|
return
|
|
326
341
|
}
|
|
@@ -335,7 +350,7 @@ export class AccountStreamer {
|
|
|
335
350
|
return
|
|
336
351
|
}
|
|
337
352
|
|
|
338
|
-
this.logger.
|
|
353
|
+
this.logger.error('AccountStreamer error', event)
|
|
339
354
|
|
|
340
355
|
this.lastErrorEvent = event
|
|
341
356
|
this.streamerState = STREAMER_STATE.Error
|
|
@@ -370,10 +385,10 @@ export class AccountStreamer {
|
|
|
370
385
|
}
|
|
371
386
|
|
|
372
387
|
private readonly handleOneMessage = (json: JsonMap) => {
|
|
373
|
-
this.logger.info(json)
|
|
388
|
+
this.logger.info('Message received: ', json)
|
|
374
389
|
|
|
375
390
|
const action = json.action as string
|
|
376
|
-
this.streamerMessageObservers.forEach(observer => observer(json))
|
|
391
|
+
this.streamerMessageObservers.forEach((observer) => observer(json))
|
|
377
392
|
if (action) {
|
|
378
393
|
if (action === MessageAction.HEARTBEAT) {
|
|
379
394
|
// schedule next heartbeat
|