firstock 1.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.
@@ -0,0 +1,1770 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const axios_1 = __importDefault(require("axios"));
40
+ const sha256 = __importStar(require("sha256"));
41
+ const AFirstock_1 = __importDefault(require("./AFirstock"));
42
+ const commonFunction_1 = require("../shared/commonFunction");
43
+ const constant_1 = require("../shared/constant");
44
+ const axiosInterceptor = axios_1.default.create({
45
+ baseURL: constant_1.API_LINK,
46
+ });
47
+ class Firstock extends AFirstock_1.default {
48
+ constructor() {
49
+ super();
50
+ this.jsonObj = {};
51
+ this.token = "";
52
+ this.userId = "";
53
+ }
54
+ /**
55
+ * Authenticates the user with Firstock using credentials and retrieves a session token (susertoken).
56
+ *
57
+ * This method sends a secure login request to the Firstock API with SHA256-hashed password and TOTP (if applicable),
58
+ * and stores the received session token locally for future authenticated requests.
59
+ *
60
+ * On success, updates the instance with `token` and `userId`, and saves the token to a configuration file.
61
+ *
62
+ * @param {Object} params - Login parameters.
63
+ * @param {string} params.userId - Firstock user ID (e.g., AB1234).
64
+ * @param {string} params.password - Plain password (will be SHA256 hashed before sending).
65
+ * @param {string} params.TOTP - Two-factor authentication code, if enabled.
66
+ * @param {string} params.vendorCode - Unique vendor code provided by Firstock.
67
+ * @param {string} params.apiKey - API key issued by Firstock.
68
+ *
69
+ * @param {function} callBack - Callback with `(error, result)`:
70
+ * - `error`: Error object if login fails.
71
+ * - `result`: Parsed response containing login information and token if successful.
72
+ */
73
+ login({ userId, password, TOTP, vendorCode, apiKey }, callBack) {
74
+ const encryptedPassword = sha256.default(password);
75
+ axiosInterceptor
76
+ .post(`login`, {
77
+ userId,
78
+ password: encryptedPassword,
79
+ TOTP,
80
+ vendorCode,
81
+ apiKey,
82
+ })
83
+ .then((response) => {
84
+ const { data } = response;
85
+ this.token = data.data.susertoken;
86
+ this.userId = data.data.actid;
87
+ const finished = (error) => {
88
+ if (error) {
89
+ callBack(error, null);
90
+ return;
91
+ }
92
+ callBack(null, data);
93
+ };
94
+ (0, commonFunction_1.readData)((err, jsonData) => {
95
+ if (err) {
96
+ if (err instanceof Error && err.message === "Unexpected end of JSON input") {
97
+ let obj = {};
98
+ obj[data.data.actid] = {
99
+ jKey: data.data.susertoken,
100
+ };
101
+ (0, commonFunction_1.saveData)(Object.assign({}, obj), "config.json", finished);
102
+ }
103
+ else {
104
+ callBack(err instanceof Error ? err : new Error(err), null);
105
+ }
106
+ }
107
+ else if (jsonData) {
108
+ jsonData[data.data.actid] = {
109
+ jKey: data.data.susertoken,
110
+ };
111
+ (0, commonFunction_1.saveData)(Object.assign({}, jsonData), "config.json", finished);
112
+ }
113
+ else {
114
+ callBack(new Error("No JSON data returned"), null);
115
+ }
116
+ });
117
+ })
118
+ .catch((error) => {
119
+ callBack((0, commonFunction_1.handleError)(error), null);
120
+ });
121
+ }
122
+ /**
123
+ * Fetches the Option Chain data from the Firstock API.
124
+ *
125
+ * This method retrieves nearby call and put option contracts for a given symbol and strike price.
126
+ * It's useful for constructing an option chain view or for identifying options for trading.
127
+ *
128
+ * The user must be logged in before calling this method (valid `jKey` required).
129
+ *
130
+ * @param {Object} params - Parameters required to fetch the option chain.
131
+ * @param {string} params.userId - Your Firstock user ID (must be same as used during login).
132
+ * @param {string} params.exchange - Exchange name (typically `"NFO"` for NSE options).
133
+ * @param {string} params.symbol - Underlying symbol or index (e.g., `"NIFTY"`).
134
+ * @param {string|number} params.strikePrice - Central strike price to base the option chain on.
135
+ * @param {string|number} params.count - Number of strike levels above and below the central price to retrieve.
136
+ * @param {string} [params.expiry] - (Optional) Expiry date of options in `DDMONYY` format (e.g., `"17APR25"`).
137
+ *
138
+ * @param {function} callBack - A callback function receiving `(error, result)`.
139
+ * On success, `result` contains an array of option contracts:
140
+ * - `exchange`: "NFO"
141
+ * - `lotSize`: Lot size of contract
142
+ * - `optionType`: "CE" or "PE"
143
+ * - `strikePrice`: Strike price of the contract
144
+ * - `tradingSymbol`: Usable symbol to place orders
145
+ * - `lastTradedPrice`: LTP of the option
146
+ */
147
+ optionChain(params, callBack) {
148
+ const currentUserId = params.userId;
149
+ (0, commonFunction_1.readData)((err, data) => {
150
+ if (err) {
151
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
152
+ }
153
+ else if (data) {
154
+ const userId = currentUserId;
155
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
156
+ if (err) {
157
+ callBack(err, null);
158
+ }
159
+ else if (jKey) {
160
+ axiosInterceptor
161
+ .post(`optionChain`, Object.assign({ userId,
162
+ jKey, exchange: params.exchange, symbol: params.symbol, strikePrice: params.strikePrice, count: params.count }, (params.expiry && { expiry: params.expiry })))
163
+ .then((response) => {
164
+ const { data } = response;
165
+ callBack(null, data);
166
+ })
167
+ .catch((error) => {
168
+ callBack((0, commonFunction_1.handleError)(error), null);
169
+ });
170
+ }
171
+ else {
172
+ callBack("No jKey found", null);
173
+ }
174
+ });
175
+ }
176
+ else {
177
+ callBack("No config data found", null);
178
+ }
179
+ });
180
+ }
181
+ /**
182
+ * Fetches intraday candlestick data for a given trading symbol and interval.
183
+ *
184
+ * This method provides time-series data (OHLCV) for short-term intervals like 1min, 2min, 5min, etc.
185
+ * It's ideal for charting, intraday analysis, and short-term strategy backtesting.
186
+ *
187
+ * ⚠️ The user must be logged in (valid jKey) before calling this method.
188
+ *
189
+ * @param {Object} params - Parameters for fetching time price series.
190
+ * @param {string} params.userId - Firstock user ID (same as used during login).
191
+ * @param {string} params.exchange - Exchange code (e.g., "NSE", "BSE", "NFO").
192
+ * @param {string} params.tradingSymbol - Symbol or instrument for intraday data (e.g., "NIFTY").
193
+ * @param {string} params.startTime - Start time in `"HH:MM:SS DD-MM-YYYY"` format (24-hour clock).
194
+ * @param {string} params.endTime - End time in `"HH:MM:SS DD-MM-YYYY"` format.
195
+ * @param {string|number} params.interval - Candle interval (e.g., `"1mi"`, `"2mi"`, `"5mi"`).
196
+ *
197
+ * @param {function} callBack - Callback function receiving `(error, result)`.
198
+ * On success, result includes an array of candlestick objects:
199
+ * - `time`: ISO timestamp
200
+ * - `epochTime`: UNIX time
201
+ * - `open`, `high`, `low`, `close`: Prices for the interval
202
+ * - `volume`: Volume during the interval
203
+ * - `oi`: Open interest (if applicable)
204
+ */
205
+ timePriceSeries(params, callBack) {
206
+ const currentUserId = params.userId;
207
+ (0, commonFunction_1.readData)((err, data) => {
208
+ if (err) {
209
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
210
+ }
211
+ else if (data) {
212
+ const userId = currentUserId;
213
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
214
+ if (err) {
215
+ callBack(err, null);
216
+ }
217
+ else if (jKey) {
218
+ axiosInterceptor
219
+ .post(`timePriceSeries`, {
220
+ userId,
221
+ jKey,
222
+ exchange: params.exchange,
223
+ tradingSymbol: params.tradingSymbol,
224
+ endTime: params.endTime,
225
+ startTime: params.startTime,
226
+ interval: params.interval,
227
+ })
228
+ .then((response) => {
229
+ const { data } = response;
230
+ callBack(null, data);
231
+ })
232
+ .catch((error) => {
233
+ callBack((0, commonFunction_1.handleError)(error), null);
234
+ });
235
+ }
236
+ else {
237
+ callBack("No jKey found", null);
238
+ }
239
+ });
240
+ }
241
+ else {
242
+ callBack("No config data found", null);
243
+ }
244
+ });
245
+ }
246
+ // Implement other abstract methods from AFirstock
247
+ getPosts() {
248
+ throw new Error("Method 'getPosts()' must be implemented.");
249
+ }
250
+ getUsers() {
251
+ throw new Error("Method 'getUsers()' must be implemented.");
252
+ }
253
+ getPostByUserId() {
254
+ throw new Error("Method 'getPostByUserId()' must be implemented.");
255
+ }
256
+ /**
257
+ * Logs the user out of the Firstock platform and invalidates the session token (`jKey`).
258
+ *
259
+ * This method securely ends the authenticated session by calling the Firstock `/logout` API.
260
+ * It ensures that the session token is no longer valid, preventing unauthorized future requests.
261
+ *
262
+ * The user must be logged in before calling this method. Otherwise, it returns an error.
263
+ *
264
+ * Best Practice: Always log the user out after completing trading activity or on app exit.
265
+ *
266
+ * @param {Object} params - Parameters for logout.
267
+ * @param {string} params.userId - Firstock user ID (same as used during login).
268
+ *
269
+ * @param {function} callBack - Callback function receiving `(error, result)`:
270
+ * - `error`: Error message or `null` on success.
271
+ * - `result`: Logout response object if successful, otherwise `null`.
272
+ *
273
+ * Security:
274
+ * - After successful logout, the jKey/token becomes invalid.
275
+ * - Any further API calls with the same token will be rejected.
276
+ */
277
+ logout(params, callBack) {
278
+ const currentUserId = params.userId;
279
+ (0, commonFunction_1.readData)((err, data) => {
280
+ if (err) {
281
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
282
+ }
283
+ else if (data) {
284
+ const userId = currentUserId;
285
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data || {} }, (err, jKey) => {
286
+ if (err) {
287
+ callBack(err, null);
288
+ }
289
+ else if (jKey) {
290
+ axiosInterceptor
291
+ .post(`logout`, {
292
+ userId,
293
+ jKey,
294
+ })
295
+ .then((response) => {
296
+ const { data } = response;
297
+ const finished = (error) => {
298
+ if (error) {
299
+ callBack(error, null);
300
+ return;
301
+ }
302
+ else {
303
+ callBack(null, data);
304
+ }
305
+ };
306
+ delete this.jsonObj[userId]; // Use this.jsonObj
307
+ (0, commonFunction_1.saveData)(Object.assign({}, this.jsonObj), "config.json", finished);
308
+ })
309
+ .catch((error) => {
310
+ callBack((0, commonFunction_1.handleError)(error), null);
311
+ });
312
+ }
313
+ else {
314
+ callBack("No jKey found", null);
315
+ }
316
+ });
317
+ }
318
+ else {
319
+ callBack("No config data found", null);
320
+ }
321
+ });
322
+ }
323
+ /**
324
+ * Fetches detailed profile and privilege information of the logged-in Firstock user.
325
+ *
326
+ * This method sends a POST request to the `/userDetails` endpoint to retrieve user-specific
327
+ * account information including email, enabled exchanges, order types, and privilege level.
328
+ * It first checks for valid login session data (jKey) before making the API call.
329
+ *
330
+ * @param {Object} params - Parameters for the request.
331
+ * @param {string} params.userId - The Firstock user ID used during login.
332
+ *
333
+ * @param {function} callBack - Callback function that returns either an error or the result.
334
+ * @param {Error|string|null} callBack.error - An error message if the request fails.
335
+ * @param {UserDetailsResponse|null} callBack.result - The user details data if successful.
336
+ *
337
+ * Response includes:
338
+ * - actid: Account ID (same as userId)
339
+ * - email: Registered email address
340
+ * - exchange: Array of enabled exchanges (e.g., NSE, BSE)
341
+ * - orarr: Allowed order types (e.g., MKT, LMT)
342
+ * - uprev: User privilege level (e.g., INVESTOR)
343
+ * - userName: Full name of the user
344
+ * - requestTime: Timestamp of the request
345
+ *
346
+ * Notes:
347
+ * - If the user is not logged in or the session token is expired, an appropriate error is returned.
348
+ * - Always ensure the session token (jKey) used is from the latest successful login.
349
+ */
350
+ userDetails(params, callBack) {
351
+ const currentUserId = params.userId;
352
+ (0, commonFunction_1.readData)((err, data) => {
353
+ if (err) {
354
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
355
+ }
356
+ else if (data) {
357
+ const userId = currentUserId;
358
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
359
+ if (err) {
360
+ callBack(err, null);
361
+ }
362
+ else if (jKey) {
363
+ axiosInterceptor
364
+ .post(`userDetails`, {
365
+ userId,
366
+ jKey,
367
+ })
368
+ .then((response) => {
369
+ const { data } = response;
370
+ callBack(null, data);
371
+ })
372
+ .catch((error) => {
373
+ callBack((0, commonFunction_1.handleError)(error), null);
374
+ });
375
+ }
376
+ else {
377
+ callBack("No jKey found", null);
378
+ }
379
+ });
380
+ }
381
+ else {
382
+ callBack("No config data found", null);
383
+ }
384
+ });
385
+ }
386
+ /**
387
+ * Places a new trade order on the Firstock trading platform.
388
+ *
389
+ * This method sends a POST request to the `/placeOrder` endpoint using the provided parameters.
390
+ * It supports market, limit, and stop-loss order types across supported exchanges like NSE, BSE, and NFO.
391
+ *
392
+ * @param {Object} params - Required order parameters.
393
+ * @param {string} params.userId - Firstock user ID (same as used during login).
394
+ * @param {string} params.exchange - Exchange to place order on (e.g., "NSE", "BSE", "NFO").
395
+ * @param {string} params.retention - Order validity period ("DAY", "IOC").
396
+ * @param {string} params.product - Product type ("C", "I", "M").
397
+ * @param {string} params.priceType - Type of order ("MKT", "LMT", "SL-MKT", "SL-LMT").
398
+ * @param {string} params.tradingSymbol - Instrument symbol (e.g., "IDEA-EQ", "NIFTY06MAR25C22500").
399
+ * @param {string} params.transactionType - "B" (Buy) or "S" (Sell).
400
+ * @param {string} params.price - Order price (0 for market orders).
401
+ * @param {string} params.triggerPrice - Trigger price for stop-loss orders (0 for others).
402
+ * @param {string} params.quantity - Quantity of shares or lots to trade.
403
+ * @param {string} params.remarks - Optional order remark or note.
404
+ *
405
+ * @param {function} callBack - Callback function.
406
+ * @param {Error|string|null} callBack.error - Error message, if any.
407
+ * @param {OrderResponse|null} callBack.result - Response data containing the order details.
408
+ *
409
+ * Notes:
410
+ * - Requires a valid session token (jKey), obtained during login.
411
+ * - Returns `orderNumber` and `requestTime` on success.
412
+ * - Handles various error conditions such as missing fields or invalid sessions.
413
+ * - URL-encode special characters in trading symbols (e.g., use `L%26TFH-EQ` instead of `L&TFH-EQ`).
414
+ */
415
+ placeOrder(params, callBack) {
416
+ const currentUserId = params.userId;
417
+ (0, commonFunction_1.readData)((err, data) => {
418
+ if (err) {
419
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
420
+ }
421
+ else if (data) {
422
+ const userId = currentUserId;
423
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
424
+ if (err) {
425
+ callBack(err, null);
426
+ }
427
+ else if (jKey) {
428
+ axiosInterceptor
429
+ .post(`placeOrder`, {
430
+ userId,
431
+ jKey,
432
+ exchange: params.exchange,
433
+ tradingSymbol: params.tradingSymbol,
434
+ quantity: params.quantity,
435
+ price: params.price,
436
+ product: params.product,
437
+ transactionType: params.transactionType,
438
+ priceType: params.priceType,
439
+ retention: params.retention,
440
+ remarks: params.remarks,
441
+ triggerPrice: params.triggerPrice,
442
+ })
443
+ .then((response) => {
444
+ const { data } = response;
445
+ callBack(null, data);
446
+ })
447
+ .catch((error) => {
448
+ callBack((0, commonFunction_1.handleError)(error), null);
449
+ });
450
+ }
451
+ else {
452
+ callBack("No jKey found", null);
453
+ }
454
+ });
455
+ }
456
+ else {
457
+ callBack("No config data found", null);
458
+ }
459
+ });
460
+ }
461
+ /**
462
+ * Fetches the margin requirements for a prospective order on the Firstock trading platform.
463
+ *
464
+ * This API helps preview the required margin, available margin, cash balance, and potential warnings (e.g., insufficient funds)
465
+ * before placing a live trade. It's recommended for risk checks and order feasibility validation.
466
+ *
467
+ * @param {Object} params - Required parameters for order margin calculation.
468
+ * @param {string} params.userId - Firstock user ID (same as used during login).
469
+ * @param {string} params.exchange - Exchange where the order is intended ("NSE", "BSE", "NFO", etc.).
470
+ * @param {string} params.transactionType - "B" for Buy or "S" for Sell.
471
+ * @param {string} params.product - Product type ("C", "M", "I").
472
+ * @param {string} params.tradingSymbol - Instrument symbol (e.g., "IDEA-EQ", "NIFTY06MAR25C22500").
473
+ * @param {string} params.quantity - Number of shares or lots.
474
+ * @param {string} params.priceType - Order type ("MKT", "LMT", "SL-LMT", "SL-MKT").
475
+ * @param {string} params.price - Order price (use "0" for market orders).
476
+ *
477
+ * @param {function} callBack - Callback function.
478
+ * @param {Error|string|null} callBack.error - Error object or message, if any.
479
+ * @param {OrderMarginResponse|null} callBack.result - Margin data including total cash, required margin, available margin, remarks, and timestamp.
480
+ *
481
+ * Notes:
482
+ * - Requires a valid `jKey` (session token) obtained during login.
483
+ * - The method returns key margin fields: `marginOnNewOrder`, `availableMargin`, `cash`, `remarks`, and `requestTime`.
484
+ * - Use this to verify sufficient margin before attempting to place the order.
485
+ * - `remarks` may include warnings such as "Insufficient Balance".
486
+ * - Ensure that the selected product type is supported on the specified exchange.
487
+ * - If `jKey` is missing or expired, the response will indicate session invalidation.
488
+ */
489
+ orderMargin(params, callBack) {
490
+ const currentUserId = params.userId;
491
+ (0, commonFunction_1.readData)((err, data) => {
492
+ if (err) {
493
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
494
+ }
495
+ else if (data) {
496
+ const userId = currentUserId;
497
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
498
+ if (err) {
499
+ callBack(err, null);
500
+ }
501
+ else if (jKey) {
502
+ axiosInterceptor
503
+ .post(`orderMargin`, {
504
+ userId,
505
+ actid: userId, // Added as per your code
506
+ jKey,
507
+ exchange: params.exchange,
508
+ tradingSymbol: params.tradingSymbol,
509
+ quantity: params.quantity,
510
+ price: params.price,
511
+ product: params.product,
512
+ transactionType: params.transactionType,
513
+ priceType: params.priceType,
514
+ })
515
+ .then((response) => {
516
+ const { data } = response;
517
+ callBack(null, data);
518
+ })
519
+ .catch((error) => {
520
+ callBack((0, commonFunction_1.handleError)(error), null);
521
+ });
522
+ }
523
+ else {
524
+ callBack("No jKey found", null);
525
+ }
526
+ });
527
+ }
528
+ else {
529
+ callBack("No config data found", null);
530
+ }
531
+ });
532
+ }
533
+ /**
534
+ * Retrieves the list of all orders placed by the user, including open, filled, and rejected orders.
535
+ *
536
+ * This method sends a request to the Firstock Order Book API and returns a structured list of all orders
537
+ * along with their details such as exchange, transaction type, quantity, price, status, rejection reasons, etc.
538
+ *
539
+ * Useful for real-time order tracking, trade reconciliation, and identifying rejected or pending trades.
540
+ *
541
+ * @param {Object} params - Required parameters for retrieving the order book.
542
+ * @param {string} params.userId - Unique Firstock user ID (same as used during login).
543
+ *
544
+ * @param {function} callBack - Callback function.
545
+ * @param {Error|string|null} callBack.error - Error object or message, if any.
546
+ * @param {OrderBookResponse|null} callBack.result - Array of order details including order number, quantity, status, average price, and rejection reason.
547
+ *
548
+ * Notes:
549
+ * - Requires a valid `jKey` (session token) obtained at login.
550
+ * - Orders include both current and historical data such as `REJECTED`, `FILLED`, or `OPEN`.
551
+ * - Each order record contains fields like `orderNumber`, `exchange`, `transactionType`, `quantity`, `priceType`, `status`, `remarks`, and `rejectReason`.
552
+ * - Use this data for populating order history in user dashboards or triggering logic based on order state.
553
+ * - If `jKey` is invalid or expired, response will indicate session expiration.
554
+ * - Frequent polling should be rate-limited; consider WebSocket alternatives if available.
555
+ */
556
+ orderBook(params, callBack) {
557
+ const currentUserId = params.userId;
558
+ (0, commonFunction_1.readData)((err, data) => {
559
+ if (err) {
560
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
561
+ }
562
+ else if (data) {
563
+ const userId = currentUserId;
564
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
565
+ if (err) {
566
+ callBack(err, null);
567
+ }
568
+ else if (jKey) {
569
+ axiosInterceptor
570
+ .post(`orderBook`, {
571
+ userId,
572
+ jKey,
573
+ })
574
+ .then((response) => {
575
+ const { data } = response;
576
+ callBack(null, data);
577
+ })
578
+ .catch((error) => {
579
+ callBack((0, commonFunction_1.handleError)(error), null);
580
+ });
581
+ }
582
+ else {
583
+ callBack("No jKey found", null);
584
+ }
585
+ });
586
+ }
587
+ else {
588
+ callBack("No config data found", null);
589
+ }
590
+ });
591
+ }
592
+ /**
593
+ * Cancels a previously placed order that has not yet been fully executed.
594
+ *
595
+ * This method interacts with the Firstock Cancel Order API to invalidate an active order. It is useful for
596
+ * real-time risk management and preventing undesired executions when market conditions change or the user
597
+ * decides to withdraw the order.
598
+ *
599
+ * @param {Object} params - Required parameters for cancelling an order.
600
+ * @param {string} params.userId - Unique Firstock user ID (same as used during login).
601
+ * @param {string} params.orderNumber - The unique identifier of the order to be cancelled.
602
+ *
603
+ * @param {function} callBack - Callback function to handle the response.
604
+ * @param {Error|string|null} callBack.error - Error message or object, if the request fails.
605
+ * @param {OrderResponse|null} callBack.result - Response data containing order cancellation status.
606
+ *
607
+ * Notes:
608
+ * - Only orders in an “open” or “partially filled” state are eligible for cancellation.
609
+ * - The session token (`jKey`) must be valid and active; otherwise, a re-login may be required.
610
+ * - Responses include fields like `orderNumber`, `rejreason`, and `requestTime`.
611
+ * - A failed cancellation may return reasons such as "order is not open to cancel".
612
+ * - It's recommended to verify the final order status using the Order Book API after cancellation.
613
+ */
614
+ cancelOrder(params, callBack) {
615
+ const currentUserId = params.userId;
616
+ (0, commonFunction_1.readData)((err, data) => {
617
+ if (err) {
618
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
619
+ }
620
+ else if (data) {
621
+ const userId = currentUserId;
622
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
623
+ if (err) {
624
+ callBack(err, null);
625
+ }
626
+ else if (jKey) {
627
+ axiosInterceptor
628
+ .post(`cancelOrder`, {
629
+ userId,
630
+ jKey,
631
+ orderNumber: params.orderNumber,
632
+ })
633
+ .then((response) => {
634
+ const { data } = response;
635
+ callBack(null, data);
636
+ })
637
+ .catch((error) => {
638
+ callBack((0, commonFunction_1.handleError)(error), null);
639
+ });
640
+ }
641
+ else {
642
+ callBack("No jKey found", null);
643
+ }
644
+ });
645
+ }
646
+ else {
647
+ callBack("No config data found", null);
648
+ }
649
+ });
650
+ }
651
+ /**
652
+ * Modifies an existing active order with updated parameters like price, quantity, or trigger price.
653
+ *
654
+ * This method interacts with the Firstock Modify Order API to alter a live order without canceling it.
655
+ * It's useful for adapting orders in response to changing market conditions without losing order priority.
656
+ *
657
+ * @param {Object} params - Parameters required to modify an order.
658
+ * @param {string} params.userId - Firstock user ID used during login.
659
+ * @param {string} params.orderNumber - The order identifier to be modified.
660
+ * @param {string} params.priceType - Order type ("MKT", "LMT", "SL-LMT", "SL-MKT").
661
+ * @param {string} params.tradingSymbol - Trading symbol (e.g., "IDEA-EQ").
662
+ * @param {string} [params.price] - Price for limit orders. Should be "0" for market orders.
663
+ * @param {string} [params.quantity] - Number of shares/lots to modify.
664
+ * @param {string} [params.triggerPrice] - Trigger price for SL orders. Optional for other types.
665
+ * @param {string} [params.retention] - Optional order duration (e.g., "DAY", "IOC").
666
+ * @param {string} [params.product] - Product type (e.g., "C", "M", "I").
667
+ *
668
+ * @param {function} callBack - Callback to handle response or error.
669
+ * @param {Error|string|null} callBack.error - Error object or message if request fails.
670
+ * @param {OrderResponse|null} callBack.result - Response data on successful order modification.
671
+ *
672
+ * Notes:
673
+ * - Only open or partially filled orders can be modified.
674
+ * - Session token (jKey) must be valid.
675
+ * - Use consistent combinations of `priceType`, `price`, and `triggerPrice`.
676
+ * - Invalid combinations or closed orders will cause the request to fail.
677
+ * - Always verify status using the Order Book API after calling this method.
678
+ */
679
+ modifyOrder(params, callBack) {
680
+ const currentUserId = params.userId;
681
+ (0, commonFunction_1.readData)((err, data) => {
682
+ if (err) {
683
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
684
+ }
685
+ else if (data) {
686
+ const userId = currentUserId;
687
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
688
+ if (err) {
689
+ callBack(err, null);
690
+ }
691
+ else if (jKey) {
692
+ axiosInterceptor
693
+ .post(`modifyOrder`, {
694
+ userId,
695
+ jKey,
696
+ quantity: params.quantity,
697
+ price: params.price,
698
+ triggerPrice: params.triggerPrice,
699
+ orderNumber: params.orderNumber,
700
+ exchange: params.exchange,
701
+ tradingSymbol: params.tradingSymbol,
702
+ priceType: params.priceType,
703
+ })
704
+ .then((response) => {
705
+ const { data } = response;
706
+ callBack(null, data);
707
+ })
708
+ .catch((error) => {
709
+ callBack((0, commonFunction_1.handleError)(error), null);
710
+ });
711
+ }
712
+ else {
713
+ callBack("No jKey found", null);
714
+ }
715
+ });
716
+ }
717
+ else {
718
+ callBack("No config data found", null);
719
+ }
720
+ });
721
+ }
722
+ /**
723
+ * Fetches detailed history of a specific order including each step or fill event.
724
+ *
725
+ * This method provides a breakdown of an order's lifecycle such as status changes,
726
+ * partial fills, rejection reasons, and timestamps for each transition.
727
+ *
728
+ * **Endpoint:** POST `/singleOrderHistory`
729
+ * **URL:** https://api.firstock.in/V1/singleOrderHistory
730
+ *
731
+ * @param {SingleOrderHistoryParams} params - The order details required to fetch history.
732
+ * @param {string} params.userId - Unique Firstock user ID (same as login).
733
+ * @param {string} params.orderNumber - Unique identifier for the order to retrieve.
734
+ *
735
+ * @param {(error: Error | string | null, result: OrderResponse | null) => void} callBack - Callback function with either error or response.
736
+ *
737
+ * @returns {void}
738
+ *
739
+ * @example
740
+ * firstock.singleOrderHistory(
741
+ * { userId: "AB1234", orderNumber: "24121300003425" },
742
+ * (err, result) => {
743
+ * if (err) console.error(err);
744
+ * else console.log(result);
745
+ * }
746
+ * );
747
+ */
748
+ singleOrderHistory(params, callBack) {
749
+ const currentUserId = params.userId;
750
+ (0, commonFunction_1.readData)((err, data) => {
751
+ if (err) {
752
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
753
+ }
754
+ else if (data) {
755
+ const userId = currentUserId;
756
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
757
+ if (err) {
758
+ callBack(err, null);
759
+ }
760
+ else if (jKey) {
761
+ axiosInterceptor
762
+ .post(`singleOrderHistory`, {
763
+ userId,
764
+ jKey,
765
+ orderNumber: params.orderNumber,
766
+ })
767
+ .then((response) => {
768
+ const { data } = response;
769
+ callBack(null, data);
770
+ })
771
+ .catch((error) => {
772
+ callBack((0, commonFunction_1.handleError)(error), null);
773
+ });
774
+ }
775
+ else {
776
+ callBack("No jKey found", null);
777
+ }
778
+ });
779
+ }
780
+ else {
781
+ callBack("No config data found", null);
782
+ }
783
+ });
784
+ }
785
+ /**
786
+ * Retrieves the trade history (executed orders) for a user account.
787
+ *
788
+ * Unlike the Order Book, which includes pending and partially filled orders, this method
789
+ * returns only completed or partially executed trades, including fill details such as
790
+ * price, quantity, and timestamps.
791
+ *
792
+ * **Endpoint:** POST `/tradeBook`
793
+ * **URL:** https://api.firstock.in/V1/tradeBook
794
+ *
795
+ * @param {TradeBookParams} params - Parameters for fetching the trade book.
796
+ * @param {string} params.userId - Unique Firstock user ID (used during login).
797
+ *
798
+ * @param {(error: Error | string | null, result: TradeBookResponse | null) => void} callBack - Callback function with error or trade data.
799
+ *
800
+ * @returns {void}
801
+ *
802
+ * @remarks
803
+ * - Ensure `jKey` is valid (session token from login). An invalid or expired session will trigger an error.
804
+ * - Useful for profit/loss calculations, compliance audits, and trade reconciliation.
805
+ * - Typical failure reasons: invalid `userId`, expired session, or no trades found.
806
+ */
807
+ tradeBook(params, callBack) {
808
+ const currentUserId = params.userId;
809
+ (0, commonFunction_1.readData)((err, data) => {
810
+ if (err) {
811
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
812
+ }
813
+ else if (data) {
814
+ const userId = currentUserId;
815
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
816
+ if (err) {
817
+ callBack(err, null);
818
+ }
819
+ else if (jKey) {
820
+ axiosInterceptor
821
+ .post(`tradeBook`, {
822
+ userId,
823
+ jKey,
824
+ actid: userId,
825
+ })
826
+ .then((response) => {
827
+ const { data } = response;
828
+ callBack(null, data);
829
+ })
830
+ .catch((error) => {
831
+ callBack((0, commonFunction_1.handleError)(error), null);
832
+ });
833
+ }
834
+ else {
835
+ callBack("No jKey found", null);
836
+ }
837
+ });
838
+ }
839
+ else {
840
+ callBack("No config data found", null);
841
+ }
842
+ });
843
+ }
844
+ /**
845
+ * Fetches the list of current open positions for the given user.
846
+ *
847
+ * This API provides detailed information about each open position such as:
848
+ * - Buy/sell quantities and average prices for the day
849
+ * - Net quantity and average price
850
+ * - Unrealized mark-to-market (MTM) and realized profit/loss
851
+ * - Exchange, product type, trading symbol, and more
852
+ *
853
+ * Common uses include:
854
+ * - Real-time profit/loss tracking
855
+ * - Position reconciliation with order/trade books
856
+ * - Margin requirement assessment based on product type
857
+ *
858
+ * @param {PositionsBookParams} params - Parameters including userId (Firstock ID)
859
+ * @param {(error: Error | string | null, result: PositionsBookResponse | null) => void} callBack - Callback to receive either error or response
860
+ *
861
+ * @returns {void}
862
+ */
863
+ positionBook(params, callBack) {
864
+ const currentUserId = params.userId;
865
+ (0, commonFunction_1.readData)((err, data) => {
866
+ if (err) {
867
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
868
+ }
869
+ else if (data) {
870
+ const userId = currentUserId;
871
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
872
+ if (err) {
873
+ callBack(err, null);
874
+ }
875
+ else if (jKey) {
876
+ axiosInterceptor
877
+ .post(`positionBook`, {
878
+ userId,
879
+ jKey,
880
+ actid: userId,
881
+ })
882
+ .then((response) => {
883
+ const { data } = response;
884
+ callBack(null, data);
885
+ })
886
+ .catch((error) => {
887
+ callBack((0, commonFunction_1.handleError)(error), null); // Fixed to use handleError
888
+ });
889
+ }
890
+ else {
891
+ callBack("No jKey found", null);
892
+ }
893
+ });
894
+ }
895
+ else {
896
+ callBack("No config data found", null);
897
+ }
898
+ });
899
+ }
900
+ /**
901
+ * Converts the product type for an existing open position.
902
+ *
903
+ * Enables traders to change a position's product type (e.g., from MIS to CNC) without closing and reopening it.
904
+ * This is useful for margin optimization or carrying over intraday positions.
905
+ *
906
+ * Benefits:
907
+ * - Adjust strategy without exiting trades
908
+ * - Free up or reallocate margin
909
+ * - Avoid unnecessary brokerage or slippage
910
+ *
911
+ * Restrictions and considerations:
912
+ * - Ensure jKey (session token) is valid
913
+ * - Conversion may not be allowed after square-off time
914
+ * - Check position size before attempting partial conversions
915
+ * - Only supported symbols and product types are eligible
916
+ *
917
+ * @param {ProductConversionParams} params - Includes userId, tradingSymbol, exchange, quantity, product, and previousProduct
918
+ * @param {(error: Error | string | null, result: ProductConversionResponse | null) => void} callBack - Callback that returns the conversion result or error
919
+ *
920
+ * @returns {void}
921
+ */
922
+ productConversion(params, callBack) {
923
+ const currentUserId = params.userId;
924
+ (0, commonFunction_1.readData)((err, data) => {
925
+ if (err) {
926
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
927
+ }
928
+ else if (data) {
929
+ const userId = currentUserId;
930
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
931
+ if (err) {
932
+ callBack(err, null);
933
+ }
934
+ else if (jKey) {
935
+ axiosInterceptor
936
+ .post(`productConversion`, {
937
+ userId,
938
+ jKey,
939
+ exchange: params.exchange,
940
+ tradingSymbol: params.tradingSymbol,
941
+ quantity: params.quantity,
942
+ product: params.product,
943
+ previousProduct: params.previousProduct,
944
+ })
945
+ .then((response) => {
946
+ const { data } = response;
947
+ callBack(null, data);
948
+ })
949
+ .catch((error) => {
950
+ callBack((0, commonFunction_1.handleError)(error), null);
951
+ });
952
+ }
953
+ else {
954
+ callBack("No jKey found", null);
955
+ }
956
+ });
957
+ }
958
+ else {
959
+ callBack("No config data found", null);
960
+ }
961
+ });
962
+ }
963
+ /**
964
+ * Retrieves the user's holdings (portfolio) from Firstock.
965
+ *
966
+ * This method fetches a summary of securities held in the user's Demat account or portfolio.
967
+ * Unlike the position book (which reflects intraday/open positions), holdings represent delivery-based investments.
968
+ *
969
+ * Key Features:
970
+ * - Provides long-term investment details.
971
+ * - Shows exchange and trading symbol for each holding.
972
+ * - Useful for portfolio valuation and analysis.
973
+ *
974
+ * @param {HoldingsParams} params - Required parameters to fetch holdings.
975
+ * @param {string} params.userId - Unique identifier of the user (same as login).
976
+ * @param {string} [params.product] - Optional product type (e.g., CNC, MIS).
977
+ * @param {(error: Error | string | null, result: HoldingsResponse | null) => void} callBack - Callback function with error or result.
978
+ *
979
+ * Endpoint: POST /holdings
980
+ * Headers: { "Content-Type": "application/json" }
981
+ *
982
+ * Response:
983
+ * - On success: { status: "success", message: "Fetched holdings", data: [...] }
984
+ * - On error: Error string such as "INVALID_JKEY" or "No config data found"
985
+ *
986
+ * Notes:
987
+ * - Requires a valid session (jKey). If the jKey is invalid or expired, prompt the user to log in again.
988
+ */
989
+ holdings(params, callBack) {
990
+ const currentUserId = params.userId;
991
+ (0, commonFunction_1.readData)((err, data) => {
992
+ if (err) {
993
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
994
+ }
995
+ else if (data) {
996
+ const userId = currentUserId;
997
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
998
+ if (err) {
999
+ callBack(err, null);
1000
+ }
1001
+ else if (jKey) {
1002
+ axiosInterceptor
1003
+ .post(`holdings`, Object.assign({ userId,
1004
+ jKey }, (params.product && { product: params.product })))
1005
+ .then((response) => {
1006
+ const { data } = response;
1007
+ callBack(null, data);
1008
+ })
1009
+ .catch((error) => {
1010
+ callBack((0, commonFunction_1.handleError)(error), null);
1011
+ });
1012
+ }
1013
+ else {
1014
+ callBack("No jKey found", null);
1015
+ }
1016
+ });
1017
+ }
1018
+ else {
1019
+ callBack("No config data found", null);
1020
+ }
1021
+ });
1022
+ }
1023
+ /**
1024
+ * Calculates the margin required for placing a basket of orders in a single request.
1025
+ *
1026
+ * The Basket Margin API is used to compute the net margin impact of multiple orders, which is particularly useful
1027
+ * for complex strategies like spreads, options combinations, or simultaneous stock purchases.
1028
+ *
1029
+ * Key Features:
1030
+ * - Evaluates margin requirements for multiple trades together.
1031
+ * - Helps prevent partial order failures due to insufficient margin.
1032
+ * - Optimized for complex order execution.
1033
+ *
1034
+ * @param {Object} params - Basket margin request parameters.
1035
+ * @param {string} params.userId - Firstock user ID (same as used during login).
1036
+ * @param {string} params.exchange - Exchange code (e.g., "NSE", "BSE", "NFO").
1037
+ * @param {string} params.transactionType - "B" (Buy) or "S" (Sell) for the first order.
1038
+ * @param {string} params.product - Product type (e.g., "C", "M", "I").
1039
+ * @param {string} params.tradingSymbol - Trading symbol (e.g., "RELIANCE-EQ").
1040
+ * @param {string | number} params.quantity - Quantity of the first order.
1041
+ * @param {string} params.priceType - Price type (e.g., "MKT", "LMT").
1042
+ * @param {string | number} params.price - Price for the first order. Use "0" for market orders.
1043
+ * @param {Array<Object>} params.BasketList_Params - Additional orders in the basket.
1044
+ * @param {string} params.BasketList_Params[].exchange - Exchange code for each order.
1045
+ * @param {string} params.BasketList_Params[].transactionType - "B" or "S" for each order.
1046
+ * @param {string} params.BasketList_Params[].product - Product type for each order.
1047
+ * @param {string} params.BasketList_Params[].tradingSymbol - Symbol for each order.
1048
+ * @param {string | number} params.BasketList_Params[].quantity - Quantity for each order.
1049
+ * @param {string} params.BasketList_Params[].priceType - Price type for each order.
1050
+ * @param {string | number} params.BasketList_Params[].price - Price for each order.
1051
+ *
1052
+ * @param {(error: Error | string | null, result: any | null) => void} callBack - Callback with error or result.
1053
+ *
1054
+ * Response:
1055
+ * - status: "success" or "error"
1056
+ * - message: Description of result
1057
+ * - data: Contains fields like `BasketMargin`, `MarginOnNewOrder`, `PreviousMargin`, `TradedMargin`, and `Remarks`.
1058
+ *
1059
+ * Notes:
1060
+ * - Requires a valid `jKey` (session token).
1061
+ * - Combine this with the RMS Limits API to check available margin.
1062
+ * - Ensure all basket items are accurately populated to avoid miscalculations.
1063
+ *
1064
+ * Endpoint: POST /basketMargin
1065
+ * Content-Type: application/json
1066
+ */
1067
+ basketMargin(params, callBack) {
1068
+ const currentUserId = params.userId;
1069
+ (0, commonFunction_1.readData)((err, data) => {
1070
+ if (err) {
1071
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1072
+ }
1073
+ else if (data) {
1074
+ const userId = currentUserId;
1075
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1076
+ if (err) {
1077
+ callBack(err, null);
1078
+ }
1079
+ else if (jKey) {
1080
+ axiosInterceptor
1081
+ .post(`basketMargin`, {
1082
+ userId,
1083
+ jKey,
1084
+ exchange: params.exchange,
1085
+ transactionType: params.transactionType,
1086
+ product: params.product,
1087
+ tradingSymbol: params.tradingSymbol,
1088
+ quantity: params.quantity,
1089
+ priceType: params.priceType,
1090
+ price: params.price,
1091
+ BasketList_Params: params.BasketList_Params,
1092
+ })
1093
+ .then((response) => {
1094
+ const { data } = response;
1095
+ callBack(null, data);
1096
+ })
1097
+ .catch((error) => {
1098
+ callBack((0, commonFunction_1.handleError)(error), null);
1099
+ });
1100
+ }
1101
+ else {
1102
+ callBack("No jKey found", null);
1103
+ }
1104
+ });
1105
+ }
1106
+ else {
1107
+ callBack("No config data found", null);
1108
+ }
1109
+ });
1110
+ }
1111
+ /**
1112
+ * Fetches the real-time RMS limits for a user account.
1113
+ *
1114
+ * This API provides detailed information about a user's trading limits and margin utilization.
1115
+ * It helps in assessing available margin, broker collateral, cash balance, collateral values,
1116
+ * exposure used, and other key risk metrics.
1117
+ *
1118
+ * Key Use Cases:
1119
+ * - Check if the user has sufficient buying power before placing new trades.
1120
+ * - Monitor exposure, margin used, collateral, and available limits.
1121
+ * - Ensure session is valid using the jKey.
1122
+ *
1123
+ * @param {Object} params - The input parameters.
1124
+ * @param {string} params.userId - The Firstock user ID (used during login).
1125
+ *
1126
+ * @param {(error: Error | string | null, result: LimitsResponse | null) => void} callBack - Callback function
1127
+ * to handle the response. Returns either an error or a `LimitsResponse` object.
1128
+ *
1129
+ * Response Structure:
1130
+ * - status: "success" or "error"
1131
+ * - message: Description of the result
1132
+ * - data: Object containing:
1133
+ * - availableMargin: Margin available for new orders
1134
+ * - brkcollamt: Broker collateral amount
1135
+ * - cash: Cash balance in the account
1136
+ * - collateral: Value of pledged holdings
1137
+ * - expo: Exposure margin used
1138
+ * - marginused: Total margin used
1139
+ * - payin: Incoming funds not yet cleared
1140
+ * - peak_mar: Peak margin used in the session
1141
+ * - premium: Option premium paid or received
1142
+ * - span: SPAN margin used (for F&O)
1143
+ * - requestTime: Timestamp of data retrieval
1144
+ *
1145
+ * Notes:
1146
+ * - Always ensure the session token (`jKey`) is valid.
1147
+ * - If jKey is invalid, prompt the user to re-authenticate.
1148
+ * - This API is essential for real-time risk and margin tracking.
1149
+ *
1150
+ * Endpoint: POST /limit
1151
+ * Headers: Content-Type: application/json
1152
+ */
1153
+ limit(params, callBack) {
1154
+ const currentUserId = params.userId;
1155
+ (0, commonFunction_1.readData)((err, data) => {
1156
+ if (err) {
1157
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1158
+ }
1159
+ else if (data) {
1160
+ const userId = currentUserId;
1161
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data || {} }, (err, jKey) => {
1162
+ if (err) {
1163
+ callBack(err, null);
1164
+ }
1165
+ else if (jKey) {
1166
+ axiosInterceptor
1167
+ .post(`limit`, {
1168
+ userId,
1169
+ jKey,
1170
+ })
1171
+ .then((response) => {
1172
+ const { data } = response;
1173
+ callBack(null, data);
1174
+ })
1175
+ .catch((error) => {
1176
+ callBack((0, commonFunction_1.handleError)(error), null);
1177
+ });
1178
+ }
1179
+ else {
1180
+ callBack("No jKey found", null);
1181
+ }
1182
+ });
1183
+ }
1184
+ else {
1185
+ callBack("No config data found", null);
1186
+ }
1187
+ });
1188
+ }
1189
+ /**
1190
+ * Fetches live market quotes for a given trading symbol on a specified exchange.
1191
+ *
1192
+ * This method retrieves real-time pricing and order book data such as last traded price,
1193
+ * day high/low, and best bid/ask levels. It is useful for market analysis and building
1194
+ * live trading interfaces.
1195
+ *
1196
+ * @param {GetQuotesParams} params - Request parameters including userId, exchange, and tradingSymbol.
1197
+ * @param {(error: Error | string | null, result: GetQuotesResponse | null) => void} callBack -
1198
+ * Callback function that handles the response or error.
1199
+ *
1200
+ * @remarks
1201
+ * - Requires the user to be logged in with a valid session key (`jKey`).
1202
+ * - Calls the POST /getQuote endpoint.
1203
+ * - Parses and returns the latest quote data if successful.
1204
+ *
1205
+ * @example
1206
+ * firstock.getQuotes(
1207
+ * {
1208
+ * userId: 'AB1234',
1209
+ * exchange: 'NSE',
1210
+ * tradingSymbol: 'RELIANCE-EQ'
1211
+ * },
1212
+ * (error, result) => {
1213
+ * if (error) {
1214
+ * console.error('Quote Error:', error);
1215
+ * } else {
1216
+ * console.log('Quote Data:', result);
1217
+ * }
1218
+ * }
1219
+ * );
1220
+ */
1221
+ getQuote(params, callBack) {
1222
+ const currentUserId = params.userId;
1223
+ (0, commonFunction_1.readData)((err, data) => {
1224
+ if (err) {
1225
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1226
+ }
1227
+ else if (data) {
1228
+ const userId = currentUserId;
1229
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1230
+ if (err) {
1231
+ callBack(err, null);
1232
+ }
1233
+ else if (jKey) {
1234
+ axiosInterceptor
1235
+ .post(`getQuote`, {
1236
+ userId,
1237
+ jKey,
1238
+ exchange: params.exchange,
1239
+ tradingSymbol: params.tradingSymbol,
1240
+ })
1241
+ .then((response) => {
1242
+ const { data } = response;
1243
+ callBack(null, data);
1244
+ })
1245
+ .catch((error) => {
1246
+ callBack((0, commonFunction_1.handleError)(error), null);
1247
+ });
1248
+ }
1249
+ else {
1250
+ callBack("No jKey found", null);
1251
+ }
1252
+ });
1253
+ }
1254
+ else {
1255
+ callBack("No config data found", null);
1256
+ }
1257
+ });
1258
+ }
1259
+ /**
1260
+ * Fetches the Last Traded Price (LTP) for a given trading symbol on a specified exchange.
1261
+ *
1262
+ * This API provides a lightweight response containing the most recent traded price,
1263
+ * without full market depth. Ideal for simple UIs or price checks.
1264
+ *
1265
+ * @param {GetQuoteLTPParams} params - Request parameters including:
1266
+ * - `userId` (string): Unique Firstock user ID.
1267
+ * - `exchange` (string): Exchange name ("NSE", "BSE", "NFO", etc.).
1268
+ * - `tradingSymbol` (string): Trading symbol (e.g., "RELIANCE-EQ").
1269
+ *
1270
+ * @param {(error: Error | string | null, result: GetQuoteLTPResponse | null) => void} callBack -
1271
+ * Callback function invoked with the LTP response or error.
1272
+ *
1273
+ * @remarks
1274
+ * - Endpoint: `POST /getQuote/ltp`
1275
+ * - Requires valid session (`jKey`) from a successful login.
1276
+ * - Returns fields like company name, exchange, last traded price, and token.
1277
+ * - Useful for real-time updates, alerts, or minimal display dashboards.
1278
+ *
1279
+ * @returns {void}
1280
+ *
1281
+ */
1282
+ getQuoteltp(params, callBack) {
1283
+ const currentUserId = params.userId;
1284
+ (0, commonFunction_1.readData)((err, data) => {
1285
+ if (err) {
1286
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1287
+ }
1288
+ else if (data) {
1289
+ const userId = currentUserId;
1290
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1291
+ if (err) {
1292
+ callBack(err, null);
1293
+ }
1294
+ else if (jKey) {
1295
+ axiosInterceptor
1296
+ .post(`getQuote/ltp`, {
1297
+ userId,
1298
+ jKey,
1299
+ exchange: params.exchange,
1300
+ tradingSymbol: params.tradingSymbol,
1301
+ })
1302
+ .then((response) => {
1303
+ const { data } = response;
1304
+ callBack(null, data);
1305
+ })
1306
+ .catch((error) => {
1307
+ callBack((0, commonFunction_1.handleError)(error), null);
1308
+ });
1309
+ }
1310
+ else {
1311
+ callBack("No jKey found", null);
1312
+ }
1313
+ });
1314
+ }
1315
+ else {
1316
+ callBack("No config data found", null);
1317
+ }
1318
+ });
1319
+ }
1320
+ /**
1321
+ * Get Last Traded Prices (LTP) for multiple instruments.
1322
+ *
1323
+ * This method is used to retrieve the latest traded prices (LTP) for multiple stocks or derivatives
1324
+ * from Firstock's trading API. It is efficient for watchlists or dashboards where only price is required.
1325
+ *
1326
+ * **Endpoint:** POST `/getMultiQuotes/ltp`
1327
+ *
1328
+ * **Required Fields in `params`:**
1329
+ * - `userId` (string): Firstock user ID.
1330
+ * - `data` (Array<{ exchange: string, tradingSymbol: string }>): List of instruments to fetch LTP for.
1331
+ *
1332
+ * **Usage Notes:**
1333
+ * - Each item in `data` must have `exchange` (e.g., NSE, BSE) and `tradingSymbol`.
1334
+ * - A valid `jKey` (from login) is auto-fetched from local config.
1335
+ * - This is a lightweight alternative to the full quote API.
1336
+ *
1337
+ * **Example Data:**
1338
+ * ```ts
1339
+ * {
1340
+ * userId: "AB1234",
1341
+ * data: [
1342
+ * { exchange: "NSE", tradingSymbol: "RELIANCE-EQ" },
1343
+ * { exchange: "NFO", tradingSymbol: "NIFTY03APR25C23500" }
1344
+ * ]
1345
+ * }
1346
+ * ```
1347
+ *
1348
+ * @param {GetMultiQuotesLTPParams} params - Parameters including userId and instrument list.
1349
+ * @param {(error: Error | string | null, result: GetMultiQuotesLTPResponse | null) => void} callBack - Callback with either error or result.
1350
+ *
1351
+ * @returns {void}
1352
+ */
1353
+ getMultiQuotesltp(params, callBack) {
1354
+ const currentUserId = params.userId;
1355
+ (0, commonFunction_1.readData)((err, data) => {
1356
+ if (err) {
1357
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1358
+ }
1359
+ else if (data) {
1360
+ const userId = currentUserId;
1361
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1362
+ if (err) {
1363
+ callBack(err, null);
1364
+ }
1365
+ else if (jKey) {
1366
+ axiosInterceptor
1367
+ .post(`getMultiQuotes/ltp`, {
1368
+ userId,
1369
+ jKey,
1370
+ data: params.data,
1371
+ })
1372
+ .then((response) => {
1373
+ callBack(null, response.data);
1374
+ })
1375
+ .catch((error) => {
1376
+ callBack((0, commonFunction_1.handleError)(error), null);
1377
+ });
1378
+ }
1379
+ else {
1380
+ callBack("No jKey found", null);
1381
+ }
1382
+ });
1383
+ }
1384
+ else {
1385
+ callBack("No config data found", null);
1386
+ }
1387
+ });
1388
+ }
1389
+ /**
1390
+ * Fetches detailed market quotes for multiple instruments (symbols) in a single API request.
1391
+ * This includes last traded price, best bid/ask levels, open interest, daily high/low/open/close prices, and more.
1392
+ *
1393
+ * @param {GetMultiQuotesParams} params - Parameters required for the API call.
1394
+ * @param {string} params.userId - Unique identifier for the Firstock user.
1395
+ * @param {Array<{ exchange: string, tradingSymbol: string }>} params.data - Array of exchange-symbol pairs for which quotes are to be retrieved.
1396
+ * @param {(error: Error | string | null, result: GetMultiQuotesResponse | null) => void} callBack - Callback function to handle the API response or error.
1397
+ *
1398
+ * @returns {void} - No return value; the result is returned via the callback.
1399
+ *
1400
+ * @example
1401
+ * getMultiQuotes(
1402
+ * {
1403
+ * userId: 'AB1234',
1404
+ * data: [
1405
+ * { exchange: 'NSE', tradingSymbol: 'RELIANCE-EQ' },
1406
+ * { exchange: 'NFO', tradingSymbol: 'NIFTY28JUN29P39000' }
1407
+ * ]
1408
+ * },
1409
+ * (err, result) => {
1410
+ * if (err) {
1411
+ * console.error(err);
1412
+ * } else {
1413
+ * console.log(result);
1414
+ * }
1415
+ * }
1416
+ * );
1417
+ */
1418
+ getMultiQuotes(params, callBack) {
1419
+ const currentUserId = params.userId;
1420
+ (0, commonFunction_1.readData)((err, data) => {
1421
+ if (err) {
1422
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1423
+ }
1424
+ else if (data) {
1425
+ const userId = currentUserId;
1426
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1427
+ if (err) {
1428
+ callBack(err, null);
1429
+ }
1430
+ else if (jKey) {
1431
+ axiosInterceptor
1432
+ .post(`getMultiQuotes`, {
1433
+ userId,
1434
+ jKey,
1435
+ data: params.data,
1436
+ })
1437
+ .then((response) => {
1438
+ callBack(null, response.data);
1439
+ })
1440
+ .catch((error) => {
1441
+ callBack((0, commonFunction_1.handleError)(error), null);
1442
+ });
1443
+ }
1444
+ else {
1445
+ callBack("No jKey found", null);
1446
+ }
1447
+ });
1448
+ }
1449
+ else {
1450
+ callBack("No config data found", null);
1451
+ }
1452
+ });
1453
+ }
1454
+ /**
1455
+ * Searches for tradable instruments (scrips) across multiple exchanges based on partial or full input text.
1456
+ *
1457
+ * This API is useful for autocompleting trading symbols in client applications.
1458
+ *
1459
+ * @param {SearchScriptsParams} params - Parameters for the search request.
1460
+ * @param {string} params.userId - Unique identifier for the Firstock user (same as used during login).
1461
+ * @param {string} params.stext - Partial or full text to search trading symbols (e.g., "ITC").
1462
+ *
1463
+ * @param {(error: Error | string | null, result: SearchScriptsResponse | null) => void} callBack -
1464
+ * Callback to handle the response or error.
1465
+ *
1466
+ * @returns {void} - Result is returned via the callback function.
1467
+ *
1468
+ * @example
1469
+ * searchScripts(
1470
+ * {
1471
+ * userId: 'AB1234',
1472
+ * stext: 'ITC'
1473
+ * },
1474
+ * (err, result) => {
1475
+ * if (err) {
1476
+ * console.error('Error:', err);
1477
+ * } else {
1478
+ * console.log('Matched Scrips:', result?.data);
1479
+ * }
1480
+ * }
1481
+ * );
1482
+ */
1483
+ searchScrips(params, callBack) {
1484
+ const currentUserId = params.userId;
1485
+ (0, commonFunction_1.readData)((err, data) => {
1486
+ if (err) {
1487
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1488
+ }
1489
+ else if (data) {
1490
+ const userId = currentUserId;
1491
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1492
+ if (err) {
1493
+ callBack(err, null);
1494
+ }
1495
+ else if (jKey) {
1496
+ axiosInterceptor
1497
+ .post(`searchScrips`, {
1498
+ userId,
1499
+ jKey,
1500
+ stext: params.stext,
1501
+ })
1502
+ .then((response) => {
1503
+ const { data } = response;
1504
+ callBack(null, data);
1505
+ })
1506
+ .catch((error) => {
1507
+ callBack((0, commonFunction_1.handleError)(error), null);
1508
+ });
1509
+ }
1510
+ else {
1511
+ callBack("No jKey found", null);
1512
+ }
1513
+ });
1514
+ }
1515
+ else {
1516
+ callBack("No config data found", null);
1517
+ }
1518
+ });
1519
+ }
1520
+ /**
1521
+ * Retrieves detailed security information about a trading symbol on a specific exchange.
1522
+ *
1523
+ * This API helps validate and fetch metadata like segment, instrument name, lot size, and token ID
1524
+ * before placing or managing trades (especially useful in derivatives trading).
1525
+ *
1526
+ * @param {GetSecurityInfoParams} params - Parameters for fetching security information.
1527
+ * @param {string} params.userId - Firstock user ID (used during login).
1528
+ * @param {string} params.exchange - Exchange name (e.g., "NSE", "BSE", "NFO").
1529
+ * @param {string} params.tradingSymbol - Symbol identifier (e.g., "IDEA-EQ", "NIFTY06MAR25C22500").
1530
+ *
1531
+ * @param {(error: Error | string | null, result: GetSecurityInfoResponse | null) => void} callBack -
1532
+ * Callback function to handle the response or error.
1533
+ *
1534
+ * @returns {void} - Result is returned via the callback.
1535
+ *
1536
+ * @example
1537
+ * getSecurityInfo(
1538
+ * {
1539
+ * userId: "AB1234",
1540
+ * exchange: "NSE",
1541
+ * tradingSymbol: "NIFTY"
1542
+ * },
1543
+ * (err, result) => {
1544
+ * if (err) {
1545
+ * console.error("Security Info Error:", err);
1546
+ * } else {
1547
+ * console.log("Security Info:", result?.data);
1548
+ * }
1549
+ * }
1550
+ * );
1551
+ */
1552
+ securityInfo(params, callBack) {
1553
+ const currentUserId = params.userId;
1554
+ (0, commonFunction_1.readData)((err, data) => {
1555
+ if (err) {
1556
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1557
+ }
1558
+ else if (data) {
1559
+ const userId = currentUserId;
1560
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1561
+ if (err) {
1562
+ callBack(err, null);
1563
+ }
1564
+ else if (jKey) {
1565
+ axiosInterceptor
1566
+ .post(`securityInfo`, {
1567
+ userId,
1568
+ jKey,
1569
+ exchange: params.exchange,
1570
+ tradingSymbol: params.tradingSymbol,
1571
+ })
1572
+ .then((response) => {
1573
+ const { data } = response;
1574
+ callBack(null, data);
1575
+ })
1576
+ .catch((error) => {
1577
+ callBack((0, commonFunction_1.handleError)(error), null);
1578
+ });
1579
+ }
1580
+ else {
1581
+ callBack("No jKey found", null);
1582
+ }
1583
+ });
1584
+ }
1585
+ else {
1586
+ callBack("No config data found", null);
1587
+ }
1588
+ });
1589
+ }
1590
+ /**
1591
+ * Fetches the list of major stock market indices from the Firstock API.
1592
+ *
1593
+ * This method is useful for retrieving a consolidated list of index tokens and trading symbols
1594
+ * (such as NIFTY50, BANKNIFTY, SENSEX, etc.). These identifiers can then be used for quote-related APIs.
1595
+ *
1596
+ * The user must be logged in before calling this method (a valid `jKey` is required).
1597
+ *
1598
+ * @param {Object} params - Parameters required to fetch the index list.
1599
+ * @param {string} params.userId - Your Firstock user ID (must be the same as used during login).
1600
+ * @param {string} params.exchange - Exchange from which to fetch index list (e.g., "NSE" or "BSE").
1601
+ *
1602
+ * @param {function} callBack - A callback function receiving `(error, result)`.
1603
+ * On success, `result` contains an array of index objects:
1604
+ * - `exchange`: The exchange code (e.g., "NSE")
1605
+ * - `token`: Numeric identifier for the index
1606
+ * - `tradingSymbol`: Usable symbol for quote APIs
1607
+ * - `symbol`: Abbreviated symbol
1608
+ * - `idxname`: Descriptive name like "NIFTY 50", "BANKNIFTY", etc.
1609
+ *
1610
+ * @returns {void}
1611
+ */
1612
+ indexList(params, callBack) {
1613
+ const currentUserId = params.userId;
1614
+ (0, commonFunction_1.readData)((err, data) => {
1615
+ if (err) {
1616
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1617
+ }
1618
+ else if (data) {
1619
+ const userId = currentUserId;
1620
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1621
+ if (err) {
1622
+ callBack(err, null);
1623
+ }
1624
+ else if (jKey) {
1625
+ axiosInterceptor
1626
+ .post(`indexList`, {
1627
+ userId,
1628
+ jKey,
1629
+ exchange: params.exchange,
1630
+ })
1631
+ .then((response) => {
1632
+ const { data } = response;
1633
+ callBack(null, data);
1634
+ })
1635
+ .catch((error) => {
1636
+ callBack((0, commonFunction_1.handleError)(error), null);
1637
+ });
1638
+ }
1639
+ else {
1640
+ callBack("No jKey found", null);
1641
+ }
1642
+ });
1643
+ }
1644
+ else {
1645
+ callBack("No config data found", null);
1646
+ }
1647
+ });
1648
+ }
1649
+ /**
1650
+ * Fetches available expiry dates for a given trading symbol on the specified exchange.
1651
+ *
1652
+ * Useful for retrieving valid expiry dates for derivatives (Futures & Options) contracts.
1653
+ * A valid session (jKey) is required before calling this method.
1654
+ *
1655
+ * @param {Object} params - Parameters for the API call.
1656
+ * @param {string} params.userId - The Firstock user ID (must match the login session).
1657
+ * @param {string} params.exchange - The exchange code (e.g., "NSE", "NFO").
1658
+ * @param {string} params.tradingSymbol - The trading symbol (e.g., "NIFTY").
1659
+ *
1660
+ * @param {function} callBack - Callback function with `(error, result)` arguments.
1661
+ * On success, result contains an array of expiry dates.
1662
+ */
1663
+ getExpiry(params, callBack) {
1664
+ const currentUserId = params.userId;
1665
+ (0, commonFunction_1.readData)((err, data) => {
1666
+ if (err) {
1667
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1668
+ }
1669
+ else if (data) {
1670
+ const userId = currentUserId;
1671
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1672
+ if (err) {
1673
+ callBack(err, null);
1674
+ }
1675
+ else if (jKey) {
1676
+ axiosInterceptor
1677
+ .post(`getExpiry`, {
1678
+ userId,
1679
+ jKey,
1680
+ exchange: params.exchange,
1681
+ tradingSymbol: params.tradingSymbol,
1682
+ })
1683
+ .then((response) => {
1684
+ const { data } = response;
1685
+ callBack(null, data);
1686
+ })
1687
+ .catch((error) => {
1688
+ callBack((0, commonFunction_1.handleError)(error), null);
1689
+ });
1690
+ }
1691
+ else {
1692
+ callBack("No jKey found", null);
1693
+ }
1694
+ });
1695
+ }
1696
+ else {
1697
+ callBack("No config data found", null);
1698
+ }
1699
+ });
1700
+ }
1701
+ /**
1702
+ * Calculates total brokerage charges, taxes, and final costs for a given trade.
1703
+ *
1704
+ * This API helps estimate the net cost or profitability of a trade before execution.
1705
+ * It supports equity and derivatives markets and provides a breakdown of all applicable charges.
1706
+ *
1707
+ * Requires a valid login session (jKey). Ideal for use before placing or simulating trades.
1708
+ *
1709
+ * @param {Object} params - Parameters required for brokerage calculation.
1710
+ * @param {string} params.userId - The Firstock user ID (must match logged-in session).
1711
+ * @param {string} params.exchange - The exchange where the order is placed (e.g., "NSE", "NFO").
1712
+ * @param {string} params.tradingSymbol - The symbol of the instrument (e.g., "RELIANCE27FEB25F").
1713
+ * @param {string} params.transactionType - The order side: "B" (Buy) or "S" (Sell).
1714
+ * @param {string} params.Product - The product type: e.g., "M", "C", "I".
1715
+ * @param {string|number} params.quantity - Quantity of the instrument to trade.
1716
+ * @param {string|number} params.price - Price at which the order is to be placed.
1717
+ * @param {string|number} params.strike_price - Applicable strike price (mandatory for F&O instruments).
1718
+ * @param {string} params.inst_name - Instrument name, such as FUTSTK, OPTIDX, etc. (required for derivatives).
1719
+ * @param {string|number} params.lot_size - Lot size of the instrument (required for derivatives).
1720
+ *
1721
+ * @param {function} callBack - Callback function with signature `(error, result)`.
1722
+ * On success, result contains detailed brokerage information.
1723
+ */
1724
+ brokerageCalculator(params, callBack) {
1725
+ const currentUserId = params.userId;
1726
+ (0, commonFunction_1.readData)((err, data) => {
1727
+ if (err) {
1728
+ callBack((0, commonFunction_1.errorMessageMapping)({ message: err instanceof Error ? err.message : err }), null);
1729
+ }
1730
+ else if (data) {
1731
+ const userId = currentUserId;
1732
+ (0, commonFunction_1.checkifUserLoggedIn)({ userId, jsonData: data }, (err, jKey) => {
1733
+ if (err) {
1734
+ callBack(err, null);
1735
+ }
1736
+ else if (jKey) {
1737
+ axiosInterceptor
1738
+ .post(`brokerageCalculator`, {
1739
+ userId,
1740
+ jKey,
1741
+ exchange: params.exchange,
1742
+ tradingSymbol: params.tradingSymbol,
1743
+ transactionType: params.transactionType,
1744
+ Product: params.Product,
1745
+ quantity: params.quantity,
1746
+ price: params.price,
1747
+ strike_price: params.strike_price,
1748
+ inst_name: params.inst_name,
1749
+ lot_size: params.lot_size,
1750
+ })
1751
+ .then((response) => {
1752
+ const { data } = response;
1753
+ callBack(null, data);
1754
+ })
1755
+ .catch((error) => {
1756
+ callBack((0, commonFunction_1.handleError)(error), null);
1757
+ });
1758
+ }
1759
+ else {
1760
+ callBack("No jKey found", null);
1761
+ }
1762
+ });
1763
+ }
1764
+ else {
1765
+ callBack("No config data found", null);
1766
+ }
1767
+ });
1768
+ }
1769
+ }
1770
+ exports.default = Firstock;