@finatic/client 0.0.137 → 0.0.138

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/dist/index.mjs CHANGED
@@ -664,7 +664,7 @@ class ApiClient {
664
664
  return this.request('/brokers/data/orders', {
665
665
  method: 'GET',
666
666
  headers: {
667
- 'Authorization': `Bearer ${accessToken}`,
667
+ Authorization: `Bearer ${accessToken}`,
668
668
  },
669
669
  });
670
670
  }
@@ -745,8 +745,8 @@ class ApiClient {
745
745
  order: {
746
746
  order_id: orderId,
747
747
  account_number: accountNumber,
748
- ...extras
749
- }
748
+ ...extras,
749
+ },
750
750
  };
751
751
  }
752
752
  return this.request(`/brokers/orders/${orderId}`, {
@@ -1024,7 +1024,7 @@ class ApiClient {
1024
1024
  return this.request(`/auth/session/${sessionId}/user`, {
1025
1025
  method: 'GET',
1026
1026
  headers: {
1027
- 'Authorization': `Bearer ${accessToken}`,
1027
+ Authorization: `Bearer ${accessToken}`,
1028
1028
  },
1029
1029
  });
1030
1030
  }
@@ -1051,12 +1051,9 @@ class ApiClient {
1051
1051
  }
1052
1052
  // Broker Data Management
1053
1053
  async getBrokerList() {
1054
- const accessToken = await this.getValidAccessToken();
1054
+ // Public endpoint - no auth required
1055
1055
  return this.request('/brokers/', {
1056
1056
  method: 'GET',
1057
- headers: {
1058
- 'Authorization': `Bearer ${accessToken}`,
1059
- },
1060
1057
  });
1061
1058
  }
1062
1059
  async getBrokerAccounts(options) {
@@ -1074,7 +1071,7 @@ class ApiClient {
1074
1071
  return this.request('/brokers/data/accounts', {
1075
1072
  method: 'GET',
1076
1073
  headers: {
1077
- 'Authorization': `Bearer ${accessToken}`,
1074
+ Authorization: `Bearer ${accessToken}`,
1078
1075
  },
1079
1076
  params,
1080
1077
  });
@@ -1094,7 +1091,7 @@ class ApiClient {
1094
1091
  return this.request('/brokers/data/orders', {
1095
1092
  method: 'GET',
1096
1093
  headers: {
1097
- 'Authorization': `Bearer ${accessToken}`,
1094
+ Authorization: `Bearer ${accessToken}`,
1098
1095
  },
1099
1096
  params,
1100
1097
  });
@@ -1114,7 +1111,7 @@ class ApiClient {
1114
1111
  return this.request('/brokers/data/positions', {
1115
1112
  method: 'GET',
1116
1113
  headers: {
1117
- 'Authorization': `Bearer ${accessToken}`,
1114
+ Authorization: `Bearer ${accessToken}`,
1118
1115
  },
1119
1116
  params,
1120
1117
  });
@@ -1134,7 +1131,7 @@ class ApiClient {
1134
1131
  return this.request('/brokers/data/balances', {
1135
1132
  method: 'GET',
1136
1133
  headers: {
1137
- 'Authorization': `Bearer ${accessToken}`,
1134
+ Authorization: `Bearer ${accessToken}`,
1138
1135
  },
1139
1136
  params,
1140
1137
  });
@@ -1144,7 +1141,7 @@ class ApiClient {
1144
1141
  return this.request('/brokers/connections', {
1145
1142
  method: 'GET',
1146
1143
  headers: {
1147
- 'Authorization': `Bearer ${accessToken}`,
1144
+ Authorization: `Bearer ${accessToken}`,
1148
1145
  },
1149
1146
  });
1150
1147
  }
@@ -1163,7 +1160,7 @@ class ApiClient {
1163
1160
  return this.request(url, {
1164
1161
  method: 'GET',
1165
1162
  headers: {
1166
- 'Authorization': `Bearer ${accessToken}`,
1163
+ Authorization: `Bearer ${accessToken}`,
1167
1164
  },
1168
1165
  });
1169
1166
  }
@@ -1484,7 +1481,7 @@ class ApiClient {
1484
1481
  return this.request(`/brokers/disconnect/${connectionId}`, {
1485
1482
  method: 'DELETE',
1486
1483
  headers: {
1487
- 'Authorization': `Bearer ${accessToken}`,
1484
+ Authorization: `Bearer ${accessToken}`,
1488
1485
  },
1489
1486
  });
1490
1487
  }
@@ -1547,7 +1544,6 @@ class PortalUI {
1547
1544
  this.messageHandler = null;
1548
1545
  this.sessionId = null;
1549
1546
  this.portalOrigin = null;
1550
- this.userToken = null;
1551
1547
  this.originalBodyStyle = null;
1552
1548
  this.createContainer();
1553
1549
  }
@@ -1674,15 +1670,13 @@ class PortalUI {
1674
1670
  console.warn('[PortalUI] Received message from unauthorized origin:', event.origin, 'Expected:', this.portalOrigin);
1675
1671
  return;
1676
1672
  }
1677
- const { type, userId, access_token, refresh_token, error, height, data } = event.data;
1673
+ const { type, userId, error, height, data } = event.data;
1678
1674
  console.log('[PortalUI] Received message:', event.data);
1679
1675
  switch (type) {
1680
1676
  case 'portal-success': {
1681
1677
  // Handle both direct userId and data.userId formats
1682
1678
  const successUserId = userId || (data && data.userId);
1683
- const successAccessToken = access_token || (data && data.access_token);
1684
- const successRefreshToken = refresh_token || (data && data.refresh_token);
1685
- this.handlePortalSuccess(successUserId, successAccessToken, successRefreshToken);
1679
+ this.handlePortalSuccess(successUserId);
1686
1680
  break;
1687
1681
  }
1688
1682
  case 'portal-error': {
@@ -1702,7 +1696,7 @@ class PortalUI {
1702
1696
  break;
1703
1697
  // Legacy support for old message types
1704
1698
  case 'success':
1705
- this.handleSuccess(userId, access_token, refresh_token);
1699
+ this.handleSuccess(userId);
1706
1700
  break;
1707
1701
  case 'error':
1708
1702
  this.handleError(error);
@@ -1714,28 +1708,12 @@ class PortalUI {
1714
1708
  console.warn('[PortalUI] Received unhandled message type:', type);
1715
1709
  }
1716
1710
  }
1717
- handlePortalSuccess(userId, accessToken, refreshToken) {
1711
+ handlePortalSuccess(userId) {
1718
1712
  if (!userId) {
1719
1713
  console.error('[PortalUI] Missing userId in portal-success message');
1720
1714
  return;
1721
1715
  }
1722
1716
  console.log('[PortalUI] Portal success - User connected:', userId);
1723
- // If tokens are provided, store them internally
1724
- if (accessToken && refreshToken) {
1725
- const userToken = {
1726
- accessToken: accessToken,
1727
- refreshToken: refreshToken,
1728
- expiresIn: 3600, // Default to 1 hour
1729
- user_id: userId,
1730
- tokenType: 'Bearer',
1731
- scope: 'api:access',
1732
- };
1733
- this.userToken = userToken;
1734
- console.log('[PortalUI] Portal authentication successful');
1735
- }
1736
- else {
1737
- console.warn('[PortalUI] No tokens received from portal');
1738
- }
1739
1717
  // Pass userId to parent (SDK will handle tokens internally)
1740
1718
  this.options?.onSuccess?.(userId);
1741
1719
  }
@@ -1760,22 +1738,11 @@ class PortalUI {
1760
1738
  this.options.onEvent(data.type, data.data);
1761
1739
  }
1762
1740
  }
1763
- handleSuccess(userId, access_token, refresh_token) {
1764
- if (!userId || !access_token || !refresh_token) {
1741
+ handleSuccess(userId) {
1742
+ if (!userId) {
1765
1743
  console.error('[PortalUI] Missing required fields in success message');
1766
1744
  return;
1767
1745
  }
1768
- // Convert portal tokens to UserToken format
1769
- const userToken = {
1770
- accessToken: access_token,
1771
- refreshToken: refresh_token,
1772
- expiresIn: 3600, // Default to 1 hour
1773
- user_id: userId,
1774
- tokenType: 'Bearer',
1775
- scope: 'api:access',
1776
- };
1777
- // Store tokens internally
1778
- this.userToken = userToken;
1779
1746
  // Pass userId to parent
1780
1747
  this.options?.onSuccess?.(userId);
1781
1748
  }
@@ -1794,9 +1761,6 @@ class PortalUI {
1794
1761
  this.iframe.style.height = `${height}px`;
1795
1762
  }
1796
1763
  }
1797
- getTokens() {
1798
- return this.userToken;
1799
- }
1800
1764
  }
1801
1765
 
1802
1766
  /**
@@ -2829,7 +2793,7 @@ class MockApiClient {
2829
2793
  paramsBroker: params.broker,
2830
2794
  contextBroker: this.tradingContext.broker,
2831
2795
  paramsAccountNumber: params.accountNumber,
2832
- contextAccountNumber: this.tradingContext.accountNumber
2796
+ contextAccountNumber: this.tradingContext.accountNumber,
2833
2797
  });
2834
2798
  const fullParams = {
2835
2799
  broker: (params.broker || this.tradingContext.broker) ||
@@ -2892,7 +2856,7 @@ class MockApiClient {
2892
2856
  console.log('MockApiClient.setAccount Debug:', {
2893
2857
  accountNumber,
2894
2858
  accountId,
2895
- previousContext: { ...this.tradingContext }
2859
+ previousContext: { ...this.tradingContext },
2896
2860
  });
2897
2861
  this.tradingContext.accountNumber = accountNumber;
2898
2862
  this.tradingContext.accountId = accountId;
@@ -3037,7 +3001,7 @@ class MockApiClient {
3037
3001
  }
3038
3002
  // Broker Data Management
3039
3003
  async getBrokerList() {
3040
- await this.getValidAccessToken();
3004
+ // Public in mock mode as well - no auth required
3041
3005
  return this.mockDataProvider.mockGetBrokerList();
3042
3006
  }
3043
3007
  async getBrokerAccounts(options) {
@@ -4481,6 +4445,196 @@ const orangeTheme = {
4481
4445
  hoverEnd: 'rgba(249, 115, 22, 0.08)',
4482
4446
  },
4483
4447
  };
4448
+ // StockAlgos theme - Clean professional theme matching StockAlgos website
4449
+ const stockAlgosTheme = {
4450
+ mode: 'light', // Light mode like StockAlgos website
4451
+ colors: {
4452
+ background: {
4453
+ primary: '#FFFFFF', // Clean white background
4454
+ secondary: '#FFFFFF', // Also white for consistency
4455
+ tertiary: '#F8FAFC', // Very light gray for subtle elevation
4456
+ accent: 'rgba(79, 70, 229, 0.05)', // Very subtle blue accent
4457
+ glass: '#FFFFFF', // Pure white, no transparency
4458
+ },
4459
+ status: {
4460
+ connected: '#10B981', // Green for positive/connected
4461
+ disconnected: '#EF4444', // Red for negative/disconnected
4462
+ warning: '#F59E0B', // Amber for warnings
4463
+ pending: '#6366F1', // Indigo for pending states
4464
+ error: '#EF4444', // Red for errors
4465
+ success: '#10B981', // Green for success
4466
+ },
4467
+ text: {
4468
+ primary: '#111827', // Very dark text for maximum contrast
4469
+ secondary: '#374151', // Dark gray for secondary text
4470
+ muted: '#6B7280', // Medium gray for muted text
4471
+ inverse: '#FFFFFF', // White for text on dark backgrounds
4472
+ },
4473
+ border: {
4474
+ primary: '#E5E7EB', // Light gray border
4475
+ secondary: '#F3F4F6', // Very light gray border
4476
+ hover: '#D1D5DB', // Slightly darker on hover
4477
+ focus: '#4F46E5', // Blue focus border
4478
+ accent: '#4F46E5', // Blue accent border
4479
+ },
4480
+ input: {
4481
+ background: '#FFFFFF', // White input background
4482
+ border: '#D1D5DB', // Slightly more visible light gray border
4483
+ borderFocus: '#4F46E5', // Blue focus border
4484
+ text: '#111827', // Darker text for better contrast
4485
+ placeholder: '#6B7280', // Darker placeholder for visibility
4486
+ },
4487
+ button: {
4488
+ primary: {
4489
+ background: '#4F46E5', // Blue primary button
4490
+ text: '#FFFFFF', // White text
4491
+ hover: '#4338CA', // Darker blue on hover
4492
+ active: '#3730A3', // Even darker on active
4493
+ },
4494
+ secondary: {
4495
+ background: '#FFFFFF', // White background
4496
+ text: '#4F46E5', // Blue text
4497
+ border: '#E5E7EB', // Light gray border
4498
+ hover: '#F8FAFC', // Very light gray on hover
4499
+ active: '#F1F5F9', // Light gray on active
4500
+ },
4501
+ },
4502
+ },
4503
+ typography: {
4504
+ fontFamily: {
4505
+ primary: 'Inter, system-ui, -apple-system, sans-serif', // Clean, modern font like StockAlgos
4506
+ secondary: 'Inter, system-ui, -apple-system, sans-serif',
4507
+ },
4508
+ fontSize: {
4509
+ xs: '0.75rem', // 12px
4510
+ sm: '0.875rem', // 14px
4511
+ base: '1rem', // 16px
4512
+ lg: '1.125rem', // 18px
4513
+ xl: '1.25rem', // 20px
4514
+ '2xl': '1.5rem', // 24px
4515
+ '3xl': '1.875rem', // 30px
4516
+ '4xl': '2.25rem', // 36px
4517
+ },
4518
+ fontWeight: {
4519
+ normal: 400,
4520
+ medium: 500,
4521
+ semibold: 600,
4522
+ bold: 700,
4523
+ extrabold: 800,
4524
+ },
4525
+ lineHeight: {
4526
+ tight: '1.25',
4527
+ normal: '1.5',
4528
+ relaxed: '1.75',
4529
+ },
4530
+ },
4531
+ spacing: {
4532
+ xs: '0.25rem', // 4px
4533
+ sm: '0.5rem', // 8px
4534
+ md: '1rem', // 16px
4535
+ lg: '1.5rem', // 24px
4536
+ xl: '2rem', // 32px
4537
+ '2xl': '3rem', // 48px
4538
+ '3xl': '4rem', // 64px
4539
+ },
4540
+ layout: {
4541
+ containerMaxWidth: '1440px',
4542
+ gridGap: '1rem',
4543
+ cardPadding: '1.5rem',
4544
+ borderRadius: {
4545
+ sm: '0.25rem', // 4px
4546
+ md: '0.5rem', // 8px
4547
+ lg: '0.75rem', // 12px
4548
+ xl: '1rem', // 16px
4549
+ '2xl': '1.5rem', // 24px
4550
+ full: '9999px',
4551
+ },
4552
+ },
4553
+ components: {
4554
+ brokerCard: {
4555
+ width: '100%',
4556
+ height: '180px',
4557
+ logoSize: '64px',
4558
+ padding: '1.5rem',
4559
+ },
4560
+ statusIndicator: {
4561
+ size: '22px',
4562
+ glowIntensity: 0.1, // Minimal glow for clean look
4563
+ },
4564
+ modal: {
4565
+ background: '#FFFFFF', // Pure white modal background
4566
+ backdrop: 'rgba(0, 0, 0, 0.4)', // Lighter backdrop
4567
+ },
4568
+ brokerCardModern: {
4569
+ width: '150px',
4570
+ height: '150px',
4571
+ padding: '16px',
4572
+ logoSize: '48px',
4573
+ statusSize: '22px',
4574
+ },
4575
+ connectButton: {
4576
+ width: '120px',
4577
+ height: '120px',
4578
+ },
4579
+ themeSwitcher: {
4580
+ indicatorSize: '24px',
4581
+ },
4582
+ },
4583
+ effects: {
4584
+ glassmorphism: {
4585
+ enabled: false, // Disable glass effects for clean look
4586
+ blur: '0px',
4587
+ opacity: 0,
4588
+ border: 'rgba(0, 0, 0, 0.1)',
4589
+ },
4590
+ animations: {
4591
+ enabled: true,
4592
+ duration: {
4593
+ fast: '150ms',
4594
+ normal: '200ms', // Faster, more subtle animations
4595
+ slow: '300ms',
4596
+ },
4597
+ easing: {
4598
+ default: 'cubic-bezier(0.4, 0, 0.2, 1)',
4599
+ smooth: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
4600
+ bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
4601
+ },
4602
+ },
4603
+ shadows: {
4604
+ sm: '0 1px 2px rgba(0, 0, 0, 0.05)', // Very subtle shadows
4605
+ md: '0 4px 6px rgba(0, 0, 0, 0.07)',
4606
+ lg: '0 10px 15px rgba(0, 0, 0, 0.1)',
4607
+ xl: '0 20px 25px rgba(0, 0, 0, 0.1)',
4608
+ card: '0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06)', // Clean card shadow
4609
+ cardHover: '0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06)', // Subtle hover shadow
4610
+ glow: '0 0 0px transparent', // No glow effects
4611
+ focus: '0 0 0 3px rgba(79, 70, 229, 0.1)', // Subtle focus ring
4612
+ },
4613
+ },
4614
+ branding: {
4615
+ logo: '/stockalgos-logo.png', // Custom logo path
4616
+ companyName: 'StockAlgos', // Company name
4617
+ favicon: '/stockalgos-favicon.ico', // Custom favicon
4618
+ primaryColor: '#4F46E5', // Indigo brand color
4619
+ },
4620
+ // Minimal glow effects
4621
+ glow: {
4622
+ primary: 'transparent',
4623
+ secondary: 'transparent',
4624
+ card: 'transparent',
4625
+ cardHover: 'rgba(79, 70, 229, 0.05)', // Very subtle
4626
+ button: 'transparent',
4627
+ focus: 'rgba(79, 70, 229, 0.1)',
4628
+ scrollbar: 'transparent',
4629
+ },
4630
+ // Minimal gradients
4631
+ gradients: {
4632
+ start: 'rgba(79, 70, 229, 0.02)',
4633
+ end: 'rgba(79, 70, 229, 0.01)',
4634
+ hoverStart: 'rgba(79, 70, 229, 0.05)',
4635
+ hoverEnd: 'rgba(79, 70, 229, 0.02)',
4636
+ },
4637
+ };
4484
4638
  // Theme preset mapping
4485
4639
  const portalThemePresets = {
4486
4640
  dark: darkTheme,
@@ -4489,6 +4643,7 @@ const portalThemePresets = {
4489
4643
  purple: purpleTheme,
4490
4644
  green: greenTheme,
4491
4645
  orange: orangeTheme,
4646
+ stockAlgos: stockAlgosTheme,
4492
4647
  };
4493
4648
 
4494
4649
  /**
@@ -4940,7 +5095,7 @@ class FinaticConnect extends EventEmitter {
4940
5095
  expires_in: this.userToken.expiresIn,
4941
5096
  token_type: this.userToken.tokenType,
4942
5097
  scope: this.userToken.scope,
4943
- company_id: this.companyId
5098
+ company_id: this.companyId,
4944
5099
  };
4945
5100
  }
4946
5101
  async initializeWithUser(userId) {
@@ -5021,16 +5176,6 @@ class FinaticConnect extends EventEmitter {
5021
5176
  if (!this.sessionId) {
5022
5177
  throw new SessionError('Session not initialized');
5023
5178
  }
5024
- // Get tokens from portal UI
5025
- const userToken = this.portalUI.getTokens();
5026
- if (!userToken) {
5027
- throw new Error('No tokens received from portal');
5028
- }
5029
- // Set the tokens internally
5030
- this.userToken = userToken;
5031
- // Set tokens in ApiClient for automatic token management
5032
- const expiresAt = new Date(Date.now() + 3600 * 1000).toISOString(); // 1 hour from now
5033
- this.apiClient.setTokens(userToken.accessToken, userToken.refreshToken, expiresAt, userId);
5034
5179
  // Emit portal success event
5035
5180
  this.emit('portal:success', userId);
5036
5181
  // Emit legacy success event
@@ -5211,7 +5356,7 @@ class FinaticConnect extends EventEmitter {
5211
5356
  * Set the broker context for trading
5212
5357
  * @param broker - The broker to use for trading
5213
5358
  */
5214
- setBroker(broker) {
5359
+ setTradingContextBroker(broker) {
5215
5360
  this.apiClient.setBroker(broker);
5216
5361
  }
5217
5362
  /**
@@ -5219,7 +5364,7 @@ class FinaticConnect extends EventEmitter {
5219
5364
  * @param accountNumber - The account number to use for trading
5220
5365
  * @param accountId - Optional account ID
5221
5366
  */
5222
- setAccount(accountNumber, accountId) {
5367
+ setTradingContextAccount(accountNumber, accountId) {
5223
5368
  this.apiClient.setAccount(accountNumber, accountId);
5224
5369
  }
5225
5370
  /**
@@ -5369,33 +5514,6 @@ class FinaticConnect extends EventEmitter {
5369
5514
  throw error;
5370
5515
  }
5371
5516
  }
5372
- /**
5373
- * Set the broker context for trading operations
5374
- * @param broker - The broker to set as context
5375
- */
5376
- setBroker(broker) {
5377
- this.apiClient.setBroker(broker);
5378
- }
5379
- /**
5380
- * Set the account context for trading operations
5381
- * @param accountNumber - The account number to set as context
5382
- */
5383
- setAccount(accountNumber) {
5384
- this.apiClient.setAccount(accountNumber);
5385
- }
5386
- /**
5387
- * Get the current trading context
5388
- * @returns Object with current broker and account context
5389
- */
5390
- getTradingContext() {
5391
- return this.apiClient.getTradingContext();
5392
- }
5393
- /**
5394
- * Clear the trading context
5395
- */
5396
- clearTradingContext() {
5397
- this.apiClient.clearTradingContext();
5398
- }
5399
5517
  /**
5400
5518
  * Get the current user ID
5401
5519
  * @returns The current user ID or undefined if not authenticated
@@ -5415,9 +5533,9 @@ class FinaticConnect extends EventEmitter {
5415
5533
  * @returns Promise with array of broker information
5416
5534
  */
5417
5535
  async getBrokerList() {
5418
- if (!this.isAuthed()) {
5419
- throw new AuthenticationError('Not authenticated');
5420
- }
5536
+ // if (!this.isAuthed()) {
5537
+ // throw new AuthenticationError('Not authenticated');
5538
+ // }
5421
5539
  const response = await this.apiClient.getBrokerList();
5422
5540
  const baseUrl = this.baseUrl.replace('/api/v1', ''); // Remove /api/v1 to get the base URL
5423
5541
  // Transform the broker list to include full logo URLs