@finatic/client 0.0.135 → 0.0.137
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/README.md +68 -64
- package/dist/index.d.ts +292 -89
- package/dist/index.js +1244 -249
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1244 -250
- package/dist/index.mjs.map +1 -1
- package/dist/types/core/client/ApiClient.d.ts +21 -13
- package/dist/types/core/client/FinaticConnect.d.ts +39 -21
- package/dist/types/index.d.ts +1 -1
- package/dist/types/mocks/MockApiClient.d.ts +6 -9
- package/dist/types/mocks/MockDataProvider.d.ts +6 -9
- package/dist/types/types/api/broker.d.ts +47 -0
- package/dist/types/types/api/errors.d.ts +8 -0
- package/dist/types/types/connect.d.ts +2 -0
- package/dist/types/types/portal.d.ts +178 -49
- package/dist/types/utils/errors.d.ts +3 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -198,6 +198,12 @@ class OrderValidationError extends ApiError {
|
|
|
198
198
|
this.name = 'OrderValidationError';
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
|
+
class TradingNotEnabledError extends ApiError {
|
|
202
|
+
constructor(message, details) {
|
|
203
|
+
super(403, message, details);
|
|
204
|
+
this.name = 'TradingNotEnabledError';
|
|
205
|
+
}
|
|
206
|
+
}
|
|
201
207
|
|
|
202
208
|
class ApiClient {
|
|
203
209
|
constructor(baseUrl, deviceInfo) {
|
|
@@ -513,6 +519,9 @@ class ApiClient {
|
|
|
513
519
|
if (error.detail?.code === 'NO_COMPANY_ACCESS') {
|
|
514
520
|
return new CompanyAccessError(error.detail.message || 'No broker connections found for this company', error.detail);
|
|
515
521
|
}
|
|
522
|
+
if (error.detail?.code === 'TRADING_NOT_ENABLED') {
|
|
523
|
+
return new TradingNotEnabledError(error.detail.message || 'Trading is not enabled for your company', error.detail);
|
|
524
|
+
}
|
|
516
525
|
return new AuthorizationError(message || 'Forbidden: No access to the requested data', error);
|
|
517
526
|
case 404:
|
|
518
527
|
return new ApiError(status, message || 'Not found: The requested data does not exist', error);
|
|
@@ -643,23 +652,6 @@ class ApiClient {
|
|
|
643
652
|
},
|
|
644
653
|
});
|
|
645
654
|
}
|
|
646
|
-
async validatePortalSession(sessionId, signature) {
|
|
647
|
-
return this.request('/portal/validate', {
|
|
648
|
-
method: 'GET',
|
|
649
|
-
headers: {
|
|
650
|
-
'Content-Type': 'application/json',
|
|
651
|
-
'X-Session-ID': sessionId,
|
|
652
|
-
'X-Device-Info': JSON.stringify({
|
|
653
|
-
ip_address: this.deviceInfo?.ip_address || '',
|
|
654
|
-
user_agent: this.deviceInfo?.user_agent || '',
|
|
655
|
-
fingerprint: this.deviceInfo?.fingerprint || '',
|
|
656
|
-
}),
|
|
657
|
-
},
|
|
658
|
-
params: {
|
|
659
|
-
signature,
|
|
660
|
-
},
|
|
661
|
-
});
|
|
662
|
-
}
|
|
663
655
|
async completePortalSession(sessionId) {
|
|
664
656
|
return this.request(`/portal/${sessionId}/complete`, {
|
|
665
657
|
method: 'POST',
|
|
@@ -669,34 +661,14 @@ class ApiClient {
|
|
|
669
661
|
});
|
|
670
662
|
}
|
|
671
663
|
// Portfolio Management
|
|
672
|
-
async getHoldings() {
|
|
673
|
-
const accessToken = await this.getValidAccessToken();
|
|
674
|
-
return this.request('/portfolio/holdings', {
|
|
675
|
-
method: 'GET',
|
|
676
|
-
headers: {
|
|
677
|
-
'Authorization': `Bearer ${accessToken}`,
|
|
678
|
-
},
|
|
679
|
-
});
|
|
680
|
-
}
|
|
681
664
|
async getOrders() {
|
|
682
665
|
const accessToken = await this.getValidAccessToken();
|
|
683
|
-
return this.request('/data/orders', {
|
|
684
|
-
method: 'GET',
|
|
685
|
-
headers: {
|
|
686
|
-
'Authorization': `Bearer ${accessToken}`,
|
|
687
|
-
},
|
|
688
|
-
});
|
|
689
|
-
}
|
|
690
|
-
async getPortfolio() {
|
|
691
|
-
const accessToken = await this.getValidAccessToken();
|
|
692
|
-
const response = await this.request('/portfolio/', {
|
|
666
|
+
return this.request('/brokers/data/orders', {
|
|
693
667
|
method: 'GET',
|
|
694
668
|
headers: {
|
|
695
669
|
'Authorization': `Bearer ${accessToken}`,
|
|
696
|
-
'Content-Type': 'application/json',
|
|
697
670
|
},
|
|
698
671
|
});
|
|
699
|
-
return response;
|
|
700
672
|
}
|
|
701
673
|
// Enhanced Trading Methods with Session Management
|
|
702
674
|
async placeBrokerOrder(params, extras = {}, connection_id) {
|
|
@@ -759,10 +731,7 @@ class ApiClient {
|
|
|
759
731
|
}
|
|
760
732
|
const accountNumber = this.tradingContext.accountNumber;
|
|
761
733
|
// Build query parameters as required by API documentation
|
|
762
|
-
const queryParams = {
|
|
763
|
-
broker: selectedBroker,
|
|
764
|
-
order_id: orderId,
|
|
765
|
-
};
|
|
734
|
+
const queryParams = {};
|
|
766
735
|
// Add optional parameters if available
|
|
767
736
|
if (accountNumber) {
|
|
768
737
|
queryParams.account_number = accountNumber.toString();
|
|
@@ -782,7 +751,7 @@ class ApiClient {
|
|
|
782
751
|
}
|
|
783
752
|
};
|
|
784
753
|
}
|
|
785
|
-
return this.request(
|
|
754
|
+
return this.request(`/brokers/orders/${orderId}`, {
|
|
786
755
|
method: 'DELETE',
|
|
787
756
|
headers: {
|
|
788
757
|
'Content-Type': 'application/json',
|
|
@@ -1052,19 +1021,9 @@ class ApiClient {
|
|
|
1052
1021
|
return extras;
|
|
1053
1022
|
}
|
|
1054
1023
|
}
|
|
1055
|
-
async
|
|
1024
|
+
async getUserToken(sessionId) {
|
|
1056
1025
|
const accessToken = await this.getValidAccessToken();
|
|
1057
|
-
|
|
1058
|
-
method: 'POST',
|
|
1059
|
-
headers: {
|
|
1060
|
-
'Authorization': `Bearer ${accessToken}`,
|
|
1061
|
-
},
|
|
1062
|
-
});
|
|
1063
|
-
this.clearTokens();
|
|
1064
|
-
}
|
|
1065
|
-
async getUserToken(userId) {
|
|
1066
|
-
const accessToken = await this.getValidAccessToken();
|
|
1067
|
-
return this.request(`/auth/token/user/${userId}`, {
|
|
1026
|
+
return this.request(`/auth/session/${sessionId}/user`, {
|
|
1068
1027
|
method: 'GET',
|
|
1069
1028
|
headers: {
|
|
1070
1029
|
'Authorization': `Bearer ${accessToken}`,
|
|
@@ -1095,7 +1054,7 @@ class ApiClient {
|
|
|
1095
1054
|
// Broker Data Management
|
|
1096
1055
|
async getBrokerList() {
|
|
1097
1056
|
const accessToken = await this.getValidAccessToken();
|
|
1098
|
-
return this.request('/brokers/
|
|
1057
|
+
return this.request('/brokers/', {
|
|
1099
1058
|
method: 'GET',
|
|
1100
1059
|
headers: {
|
|
1101
1060
|
'Authorization': `Bearer ${accessToken}`,
|
|
@@ -1162,6 +1121,26 @@ class ApiClient {
|
|
|
1162
1121
|
params,
|
|
1163
1122
|
});
|
|
1164
1123
|
}
|
|
1124
|
+
async getBrokerBalances(options) {
|
|
1125
|
+
const accessToken = await this.getValidAccessToken();
|
|
1126
|
+
const params = {};
|
|
1127
|
+
if (options?.broker_name) {
|
|
1128
|
+
params.broker_id = options.broker_name;
|
|
1129
|
+
}
|
|
1130
|
+
if (options?.account_id) {
|
|
1131
|
+
params.account_id = options.account_id;
|
|
1132
|
+
}
|
|
1133
|
+
if (options?.symbol) {
|
|
1134
|
+
params.symbol = options.symbol;
|
|
1135
|
+
}
|
|
1136
|
+
return this.request('/brokers/data/balances', {
|
|
1137
|
+
method: 'GET',
|
|
1138
|
+
headers: {
|
|
1139
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
1140
|
+
},
|
|
1141
|
+
params,
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1165
1144
|
async getBrokerConnections() {
|
|
1166
1145
|
const accessToken = await this.getValidAccessToken();
|
|
1167
1146
|
return this.request('/brokers/connections', {
|
|
@@ -1171,6 +1150,25 @@ class ApiClient {
|
|
|
1171
1150
|
},
|
|
1172
1151
|
});
|
|
1173
1152
|
}
|
|
1153
|
+
async getBalances(filters) {
|
|
1154
|
+
const accessToken = await this.getValidAccessToken();
|
|
1155
|
+
const params = new URLSearchParams();
|
|
1156
|
+
if (filters) {
|
|
1157
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
1158
|
+
if (value !== undefined && value !== null) {
|
|
1159
|
+
params.append(key, String(value));
|
|
1160
|
+
}
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
const queryString = params.toString();
|
|
1164
|
+
const url = queryString ? `/brokers/data/balances?${queryString}` : '/brokers/data/balances';
|
|
1165
|
+
return this.request(url, {
|
|
1166
|
+
method: 'GET',
|
|
1167
|
+
headers: {
|
|
1168
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
1169
|
+
},
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1174
1172
|
// Page-based pagination methods
|
|
1175
1173
|
async getBrokerOrdersPage(page = 1, perPage = 100, filters) {
|
|
1176
1174
|
const accessToken = await this.getValidAccessToken();
|
|
@@ -1389,6 +1387,81 @@ class ApiClient {
|
|
|
1389
1387
|
limit: perPage,
|
|
1390
1388
|
}, navigationCallback);
|
|
1391
1389
|
}
|
|
1390
|
+
async getBrokerBalancesPage(page = 1, perPage = 100, filters) {
|
|
1391
|
+
const accessToken = await this.getValidAccessToken();
|
|
1392
|
+
const offset = (page - 1) * perPage;
|
|
1393
|
+
const params = {
|
|
1394
|
+
limit: perPage.toString(),
|
|
1395
|
+
offset: offset.toString(),
|
|
1396
|
+
};
|
|
1397
|
+
// Add filter parameters
|
|
1398
|
+
if (filters) {
|
|
1399
|
+
if (filters.broker_id)
|
|
1400
|
+
params.broker_id = filters.broker_id;
|
|
1401
|
+
if (filters.connection_id)
|
|
1402
|
+
params.connection_id = filters.connection_id;
|
|
1403
|
+
if (filters.account_id)
|
|
1404
|
+
params.account_id = filters.account_id;
|
|
1405
|
+
if (filters.is_end_of_day_snapshot !== undefined)
|
|
1406
|
+
params.is_end_of_day_snapshot = filters.is_end_of_day_snapshot.toString();
|
|
1407
|
+
if (filters.balance_created_after)
|
|
1408
|
+
params.balance_created_after = filters.balance_created_after;
|
|
1409
|
+
if (filters.balance_created_before)
|
|
1410
|
+
params.balance_created_before = filters.balance_created_before;
|
|
1411
|
+
if (filters.with_metadata !== undefined)
|
|
1412
|
+
params.with_metadata = filters.with_metadata.toString();
|
|
1413
|
+
}
|
|
1414
|
+
const response = await this.request('/brokers/data/balances', {
|
|
1415
|
+
method: 'GET',
|
|
1416
|
+
headers: {
|
|
1417
|
+
Authorization: `Bearer ${accessToken}`,
|
|
1418
|
+
},
|
|
1419
|
+
params,
|
|
1420
|
+
});
|
|
1421
|
+
// Create navigation callback for pagination
|
|
1422
|
+
const navigationCallback = async (newOffset, newLimit) => {
|
|
1423
|
+
const newParams = {
|
|
1424
|
+
limit: newLimit.toString(),
|
|
1425
|
+
offset: newOffset.toString(),
|
|
1426
|
+
};
|
|
1427
|
+
// Add filter parameters
|
|
1428
|
+
if (filters) {
|
|
1429
|
+
if (filters.broker_id)
|
|
1430
|
+
newParams.broker_id = filters.broker_id;
|
|
1431
|
+
if (filters.connection_id)
|
|
1432
|
+
newParams.connection_id = filters.connection_id;
|
|
1433
|
+
if (filters.account_id)
|
|
1434
|
+
newParams.account_id = filters.account_id;
|
|
1435
|
+
if (filters.is_end_of_day_snapshot !== undefined)
|
|
1436
|
+
newParams.is_end_of_day_snapshot = filters.is_end_of_day_snapshot.toString();
|
|
1437
|
+
if (filters.balance_created_after)
|
|
1438
|
+
newParams.balance_created_after = filters.balance_created_after;
|
|
1439
|
+
if (filters.balance_created_before)
|
|
1440
|
+
newParams.balance_created_before = filters.balance_created_before;
|
|
1441
|
+
if (filters.with_metadata !== undefined)
|
|
1442
|
+
newParams.with_metadata = filters.with_metadata.toString();
|
|
1443
|
+
}
|
|
1444
|
+
const newResponse = await this.request('/brokers/data/balances', {
|
|
1445
|
+
method: 'GET',
|
|
1446
|
+
headers: {
|
|
1447
|
+
Authorization: `Bearer ${accessToken}`,
|
|
1448
|
+
},
|
|
1449
|
+
params: newParams,
|
|
1450
|
+
});
|
|
1451
|
+
return new PaginatedResult(newResponse.response_data, newResponse.pagination || {
|
|
1452
|
+
has_more: false,
|
|
1453
|
+
next_offset: newOffset,
|
|
1454
|
+
current_offset: newOffset,
|
|
1455
|
+
limit: newLimit,
|
|
1456
|
+
}, navigationCallback);
|
|
1457
|
+
};
|
|
1458
|
+
return new PaginatedResult(response.response_data, response.pagination || {
|
|
1459
|
+
has_more: false,
|
|
1460
|
+
next_offset: offset,
|
|
1461
|
+
current_offset: offset,
|
|
1462
|
+
limit: perPage,
|
|
1463
|
+
}, navigationCallback);
|
|
1464
|
+
}
|
|
1392
1465
|
// Navigation methods
|
|
1393
1466
|
async getNextPage(previousResult, fetchFunction) {
|
|
1394
1467
|
if (!previousResult.hasNext) {
|
|
@@ -1410,7 +1483,7 @@ class ApiClient {
|
|
|
1410
1483
|
*/
|
|
1411
1484
|
async disconnectCompany(connectionId) {
|
|
1412
1485
|
const accessToken = await this.getValidAccessToken();
|
|
1413
|
-
return this.request(`/brokers/disconnect
|
|
1486
|
+
return this.request(`/brokers/disconnect/${connectionId}`, {
|
|
1414
1487
|
method: 'DELETE',
|
|
1415
1488
|
headers: {
|
|
1416
1489
|
'Authorization': `Bearer ${accessToken}`,
|
|
@@ -2065,109 +2138,6 @@ class MockDataProvider {
|
|
|
2065
2138
|
};
|
|
2066
2139
|
}
|
|
2067
2140
|
// Portfolio & Trading Mocks
|
|
2068
|
-
async mockGetHoldings() {
|
|
2069
|
-
await this.simulateDelay();
|
|
2070
|
-
const holdings = [
|
|
2071
|
-
{
|
|
2072
|
-
symbol: 'AAPL',
|
|
2073
|
-
quantity: 100,
|
|
2074
|
-
averagePrice: 150.25,
|
|
2075
|
-
currentPrice: 175.5,
|
|
2076
|
-
marketValue: 17550.0,
|
|
2077
|
-
unrealizedPnL: 2525.0,
|
|
2078
|
-
realizedPnL: 0,
|
|
2079
|
-
costBasis: 15025.0,
|
|
2080
|
-
currency: 'USD',
|
|
2081
|
-
},
|
|
2082
|
-
{
|
|
2083
|
-
symbol: 'TSLA',
|
|
2084
|
-
quantity: 50,
|
|
2085
|
-
averagePrice: 200.0,
|
|
2086
|
-
currentPrice: 220.75,
|
|
2087
|
-
marketValue: 11037.5,
|
|
2088
|
-
unrealizedPnL: 1037.5,
|
|
2089
|
-
realizedPnL: 0,
|
|
2090
|
-
costBasis: 10000.0,
|
|
2091
|
-
currency: 'USD',
|
|
2092
|
-
},
|
|
2093
|
-
{
|
|
2094
|
-
symbol: 'MSFT',
|
|
2095
|
-
quantity: 75,
|
|
2096
|
-
averagePrice: 300.0,
|
|
2097
|
-
currentPrice: 325.25,
|
|
2098
|
-
marketValue: 24393.75,
|
|
2099
|
-
unrealizedPnL: 1893.75,
|
|
2100
|
-
realizedPnL: 0,
|
|
2101
|
-
costBasis: 22500.0,
|
|
2102
|
-
currency: 'USD',
|
|
2103
|
-
},
|
|
2104
|
-
];
|
|
2105
|
-
return { data: holdings };
|
|
2106
|
-
}
|
|
2107
|
-
async mockGetPortfolio() {
|
|
2108
|
-
await this.simulateDelay();
|
|
2109
|
-
const portfolio = {
|
|
2110
|
-
id: uuid.v4(),
|
|
2111
|
-
name: 'Main Portfolio',
|
|
2112
|
-
type: 'individual',
|
|
2113
|
-
status: 'active',
|
|
2114
|
-
cash: 15000.5,
|
|
2115
|
-
buyingPower: 45000.0,
|
|
2116
|
-
equity: 52981.25,
|
|
2117
|
-
longMarketValue: 37981.25,
|
|
2118
|
-
shortMarketValue: 0,
|
|
2119
|
-
initialMargin: 0,
|
|
2120
|
-
maintenanceMargin: 0,
|
|
2121
|
-
lastEquity: 52000.0,
|
|
2122
|
-
positions: [
|
|
2123
|
-
{
|
|
2124
|
-
symbol: 'AAPL',
|
|
2125
|
-
quantity: 100,
|
|
2126
|
-
averagePrice: 150.25,
|
|
2127
|
-
currentPrice: 175.5,
|
|
2128
|
-
marketValue: 17550.0,
|
|
2129
|
-
unrealizedPnL: 2525.0,
|
|
2130
|
-
realizedPnL: 0,
|
|
2131
|
-
costBasis: 15025.0,
|
|
2132
|
-
currency: 'USD',
|
|
2133
|
-
},
|
|
2134
|
-
{
|
|
2135
|
-
symbol: 'TSLA',
|
|
2136
|
-
quantity: 50,
|
|
2137
|
-
averagePrice: 200.0,
|
|
2138
|
-
currentPrice: 220.75,
|
|
2139
|
-
marketValue: 11037.5,
|
|
2140
|
-
unrealizedPnL: 1037.5,
|
|
2141
|
-
realizedPnL: 0,
|
|
2142
|
-
costBasis: 10000.0,
|
|
2143
|
-
currency: 'USD',
|
|
2144
|
-
},
|
|
2145
|
-
{
|
|
2146
|
-
symbol: 'MSFT',
|
|
2147
|
-
quantity: 75,
|
|
2148
|
-
averagePrice: 300.0,
|
|
2149
|
-
currentPrice: 325.25,
|
|
2150
|
-
marketValue: 24393.75,
|
|
2151
|
-
unrealizedPnL: 1893.75,
|
|
2152
|
-
realizedPnL: 0,
|
|
2153
|
-
costBasis: 22500.0,
|
|
2154
|
-
currency: 'USD',
|
|
2155
|
-
},
|
|
2156
|
-
],
|
|
2157
|
-
performance: {
|
|
2158
|
-
totalReturn: 0.089,
|
|
2159
|
-
dailyReturn: 0.002,
|
|
2160
|
-
weeklyReturn: 0.015,
|
|
2161
|
-
monthlyReturn: 0.045,
|
|
2162
|
-
yearlyReturn: 0.089,
|
|
2163
|
-
maxDrawdown: -0.05,
|
|
2164
|
-
sharpeRatio: 1.2,
|
|
2165
|
-
beta: 0.95,
|
|
2166
|
-
alpha: 0.02,
|
|
2167
|
-
},
|
|
2168
|
-
};
|
|
2169
|
-
return { data: portfolio };
|
|
2170
|
-
}
|
|
2171
2141
|
async mockGetOrders(filter) {
|
|
2172
2142
|
await this.simulateDelay();
|
|
2173
2143
|
const mockOrders = [
|
|
@@ -2228,6 +2198,52 @@ class MockDataProvider {
|
|
|
2228
2198
|
data: filteredPositions,
|
|
2229
2199
|
};
|
|
2230
2200
|
}
|
|
2201
|
+
async mockGetBrokerBalances(filter) {
|
|
2202
|
+
await this.simulateDelay();
|
|
2203
|
+
// Determine how many balances to generate based on limit parameter
|
|
2204
|
+
const limit = filter?.limit || 100;
|
|
2205
|
+
const maxLimit = Math.min(limit, 1000); // Cap at 1000
|
|
2206
|
+
const mockBalances = [];
|
|
2207
|
+
for (let i = 0; i < maxLimit; i++) {
|
|
2208
|
+
const totalCashValue = Math.random() * 100000 + 10000; // $10k - $110k
|
|
2209
|
+
const netLiquidationValue = totalCashValue * (0.8 + Math.random() * 0.4); // ±20% variation
|
|
2210
|
+
const initialMargin = netLiquidationValue * 0.1; // 10% of net liquidation
|
|
2211
|
+
const maintenanceMargin = initialMargin * 0.8; // 80% of initial margin
|
|
2212
|
+
const availableToWithdraw = totalCashValue * 0.9; // 90% of cash available
|
|
2213
|
+
const totalRealizedPnl = (Math.random() - 0.5) * 10000; // -$5k to +$5k
|
|
2214
|
+
const balance = {
|
|
2215
|
+
id: `balance_${i + 1}`,
|
|
2216
|
+
account_id: `account_${Math.floor(Math.random() * 3) + 1}`,
|
|
2217
|
+
total_cash_value: totalCashValue,
|
|
2218
|
+
net_liquidation_value: netLiquidationValue,
|
|
2219
|
+
initial_margin: initialMargin,
|
|
2220
|
+
maintenance_margin: maintenanceMargin,
|
|
2221
|
+
available_to_withdraw: availableToWithdraw,
|
|
2222
|
+
total_realized_pnl: totalRealizedPnl,
|
|
2223
|
+
balance_created_at: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
2224
|
+
balance_updated_at: new Date().toISOString(),
|
|
2225
|
+
is_end_of_day_snapshot: Math.random() > 0.7, // 30% chance of being EOD snapshot
|
|
2226
|
+
raw_payload: {
|
|
2227
|
+
broker_specific_data: {
|
|
2228
|
+
margin_ratio: netLiquidationValue / initialMargin,
|
|
2229
|
+
day_trading_buying_power: availableToWithdraw * 4,
|
|
2230
|
+
overnight_buying_power: availableToWithdraw * 2,
|
|
2231
|
+
},
|
|
2232
|
+
},
|
|
2233
|
+
created_at: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000).toISOString(),
|
|
2234
|
+
updated_at: new Date().toISOString(),
|
|
2235
|
+
};
|
|
2236
|
+
mockBalances.push(balance);
|
|
2237
|
+
}
|
|
2238
|
+
// Apply filters if provided
|
|
2239
|
+
let filteredBalances = mockBalances;
|
|
2240
|
+
if (filter) {
|
|
2241
|
+
filteredBalances = this.applyBrokerBalanceFilters(mockBalances, filter);
|
|
2242
|
+
}
|
|
2243
|
+
return {
|
|
2244
|
+
data: filteredBalances,
|
|
2245
|
+
};
|
|
2246
|
+
}
|
|
2231
2247
|
async mockGetBrokerDataAccounts(filter) {
|
|
2232
2248
|
await this.simulateDelay();
|
|
2233
2249
|
// Determine how many accounts to generate based on limit parameter
|
|
@@ -2280,8 +2296,8 @@ class MockDataProvider {
|
|
|
2280
2296
|
/**
|
|
2281
2297
|
* Get stored user token
|
|
2282
2298
|
*/
|
|
2283
|
-
getUserToken(
|
|
2284
|
-
return this.userTokens.get(
|
|
2299
|
+
getUserToken(sessionId) {
|
|
2300
|
+
return this.userTokens.get(sessionId);
|
|
2285
2301
|
}
|
|
2286
2302
|
/**
|
|
2287
2303
|
* Clear all stored data
|
|
@@ -2373,6 +2389,19 @@ class MockDataProvider {
|
|
|
2373
2389
|
return true;
|
|
2374
2390
|
});
|
|
2375
2391
|
}
|
|
2392
|
+
applyBrokerBalanceFilters(balances, filter) {
|
|
2393
|
+
return balances.filter(balance => {
|
|
2394
|
+
if (filter.account_id && balance.account_id !== filter.account_id)
|
|
2395
|
+
return false;
|
|
2396
|
+
if (filter.is_end_of_day_snapshot !== undefined && balance.is_end_of_day_snapshot !== filter.is_end_of_day_snapshot)
|
|
2397
|
+
return false;
|
|
2398
|
+
if (filter.balance_created_after && balance.balance_created_at && new Date(balance.balance_created_at) < new Date(filter.balance_created_after))
|
|
2399
|
+
return false;
|
|
2400
|
+
if (filter.balance_created_before && balance.balance_created_at && new Date(balance.balance_created_at) > new Date(filter.balance_created_before))
|
|
2401
|
+
return false;
|
|
2402
|
+
return true;
|
|
2403
|
+
});
|
|
2404
|
+
}
|
|
2376
2405
|
/**
|
|
2377
2406
|
* Generate mock orders with diverse data
|
|
2378
2407
|
*/
|
|
@@ -2784,18 +2813,10 @@ class MockApiClient {
|
|
|
2784
2813
|
return this.mockDataProvider.mockCompletePortalSession(sessionId);
|
|
2785
2814
|
}
|
|
2786
2815
|
// Portfolio Management
|
|
2787
|
-
async getHoldings(filter) {
|
|
2788
|
-
await this.getValidAccessToken();
|
|
2789
|
-
return this.mockDataProvider.mockGetHoldings();
|
|
2790
|
-
}
|
|
2791
2816
|
async getOrders(filter) {
|
|
2792
2817
|
await this.getValidAccessToken();
|
|
2793
2818
|
return this.mockDataProvider.mockGetOrders(filter);
|
|
2794
2819
|
}
|
|
2795
|
-
async getPortfolio() {
|
|
2796
|
-
await this.getValidAccessToken();
|
|
2797
|
-
return this.mockDataProvider.mockGetPortfolio();
|
|
2798
|
-
}
|
|
2799
2820
|
async placeOrder(order) {
|
|
2800
2821
|
await this.getValidAccessToken();
|
|
2801
2822
|
await this.mockDataProvider.mockPlaceOrder(order);
|
|
@@ -3006,12 +3027,8 @@ class MockApiClient {
|
|
|
3006
3027
|
price,
|
|
3007
3028
|
}, extras);
|
|
3008
3029
|
}
|
|
3009
|
-
async
|
|
3010
|
-
|
|
3011
|
-
this.clearTokens();
|
|
3012
|
-
}
|
|
3013
|
-
async getUserToken(userId) {
|
|
3014
|
-
const token = this.mockDataProvider.getUserToken(userId);
|
|
3030
|
+
async getUserToken(sessionId) {
|
|
3031
|
+
const token = this.mockDataProvider.getUserToken(sessionId);
|
|
3015
3032
|
if (!token) {
|
|
3016
3033
|
throw new AuthenticationError('User token not found');
|
|
3017
3034
|
}
|
|
@@ -3060,6 +3077,9 @@ class MockApiClient {
|
|
|
3060
3077
|
async getBrokerPositionsWithFilter(filter) {
|
|
3061
3078
|
return this.mockDataProvider.mockGetBrokerPositions(filter);
|
|
3062
3079
|
}
|
|
3080
|
+
async getBrokerBalancesWithFilter(filter) {
|
|
3081
|
+
return this.mockDataProvider.mockGetBrokerBalances(filter);
|
|
3082
|
+
}
|
|
3063
3083
|
async getBrokerDataAccountsWithFilter(filter) {
|
|
3064
3084
|
return this.mockDataProvider.mockGetBrokerDataAccounts(filter);
|
|
3065
3085
|
}
|
|
@@ -3154,6 +3174,36 @@ class MockApiClient {
|
|
|
3154
3174
|
limit: perPage,
|
|
3155
3175
|
}, navigationCallback);
|
|
3156
3176
|
}
|
|
3177
|
+
async getBrokerBalancesPage(page = 1, perPage = 100, filters) {
|
|
3178
|
+
const mockBalances = await this.mockDataProvider.mockGetBrokerBalances(filters);
|
|
3179
|
+
const balances = mockBalances.data;
|
|
3180
|
+
// Simulate pagination
|
|
3181
|
+
const startIndex = (page - 1) * perPage;
|
|
3182
|
+
const endIndex = startIndex + perPage;
|
|
3183
|
+
const paginatedBalances = balances.slice(startIndex, endIndex);
|
|
3184
|
+
const hasMore = endIndex < balances.length;
|
|
3185
|
+
const nextOffset = hasMore ? endIndex : startIndex;
|
|
3186
|
+
// Create navigation callback for mock pagination
|
|
3187
|
+
const navigationCallback = async (newOffset, newLimit) => {
|
|
3188
|
+
const newStartIndex = newOffset;
|
|
3189
|
+
const newEndIndex = newStartIndex + newLimit;
|
|
3190
|
+
const newPaginatedBalances = balances.slice(newStartIndex, newEndIndex);
|
|
3191
|
+
const newHasMore = newEndIndex < balances.length;
|
|
3192
|
+
const newNextOffset = newHasMore ? newEndIndex : newStartIndex;
|
|
3193
|
+
return new PaginatedResult(newPaginatedBalances, {
|
|
3194
|
+
has_more: newHasMore,
|
|
3195
|
+
next_offset: newNextOffset,
|
|
3196
|
+
current_offset: newStartIndex,
|
|
3197
|
+
limit: newLimit,
|
|
3198
|
+
}, navigationCallback);
|
|
3199
|
+
};
|
|
3200
|
+
return new PaginatedResult(paginatedBalances, {
|
|
3201
|
+
has_more: hasMore,
|
|
3202
|
+
next_offset: nextOffset,
|
|
3203
|
+
current_offset: startIndex,
|
|
3204
|
+
limit: perPage,
|
|
3205
|
+
}, navigationCallback);
|
|
3206
|
+
}
|
|
3157
3207
|
async getBrokerConnections() {
|
|
3158
3208
|
await this.getValidAccessToken();
|
|
3159
3209
|
return this.mockDataProvider.mockGetBrokerConnections();
|
|
@@ -3392,9 +3442,135 @@ const darkTheme = {
|
|
|
3392
3442
|
},
|
|
3393
3443
|
},
|
|
3394
3444
|
},
|
|
3445
|
+
typography: {
|
|
3446
|
+
fontFamily: {
|
|
3447
|
+
primary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
3448
|
+
secondary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
3449
|
+
},
|
|
3450
|
+
fontSize: {
|
|
3451
|
+
xs: '0.75rem',
|
|
3452
|
+
sm: '0.875rem',
|
|
3453
|
+
base: '1rem',
|
|
3454
|
+
lg: '1.125rem',
|
|
3455
|
+
xl: '1.25rem',
|
|
3456
|
+
'2xl': '1.5rem',
|
|
3457
|
+
'3xl': '1.875rem',
|
|
3458
|
+
'4xl': '2.25rem',
|
|
3459
|
+
},
|
|
3460
|
+
fontWeight: {
|
|
3461
|
+
normal: 400,
|
|
3462
|
+
medium: 500,
|
|
3463
|
+
semibold: 600,
|
|
3464
|
+
bold: 700,
|
|
3465
|
+
extrabold: 800,
|
|
3466
|
+
},
|
|
3467
|
+
lineHeight: {
|
|
3468
|
+
tight: '1.25',
|
|
3469
|
+
normal: '1.5',
|
|
3470
|
+
relaxed: '1.75',
|
|
3471
|
+
},
|
|
3472
|
+
},
|
|
3473
|
+
spacing: {
|
|
3474
|
+
xs: '0.25rem',
|
|
3475
|
+
sm: '0.5rem',
|
|
3476
|
+
md: '1rem',
|
|
3477
|
+
lg: '1.5rem',
|
|
3478
|
+
xl: '2rem',
|
|
3479
|
+
'2xl': '3rem',
|
|
3480
|
+
'3xl': '4rem',
|
|
3481
|
+
},
|
|
3482
|
+
layout: {
|
|
3483
|
+
containerMaxWidth: '1440px',
|
|
3484
|
+
gridGap: '1rem',
|
|
3485
|
+
cardPadding: '1.5rem',
|
|
3486
|
+
borderRadius: {
|
|
3487
|
+
sm: '0.25rem',
|
|
3488
|
+
md: '0.5rem',
|
|
3489
|
+
lg: '0.75rem',
|
|
3490
|
+
xl: '1rem',
|
|
3491
|
+
'2xl': '1.5rem',
|
|
3492
|
+
full: '9999px',
|
|
3493
|
+
},
|
|
3494
|
+
},
|
|
3495
|
+
components: {
|
|
3496
|
+
brokerCard: {
|
|
3497
|
+
width: '100%',
|
|
3498
|
+
height: '180px',
|
|
3499
|
+
logoSize: '64px',
|
|
3500
|
+
padding: '1.5rem',
|
|
3501
|
+
},
|
|
3502
|
+
statusIndicator: {
|
|
3503
|
+
size: '22px',
|
|
3504
|
+
glowIntensity: 0.9,
|
|
3505
|
+
},
|
|
3506
|
+
modal: {
|
|
3507
|
+
background: 'rgba(0, 0, 0, 0.95)',
|
|
3508
|
+
backdrop: 'rgba(0, 0, 0, 0.8)',
|
|
3509
|
+
},
|
|
3510
|
+
brokerCardModern: {
|
|
3511
|
+
width: '150px',
|
|
3512
|
+
height: '150px',
|
|
3513
|
+
padding: '16px',
|
|
3514
|
+
logoSize: '48px',
|
|
3515
|
+
statusSize: '22px',
|
|
3516
|
+
},
|
|
3517
|
+
connectButton: {
|
|
3518
|
+
width: '120px',
|
|
3519
|
+
height: '120px',
|
|
3520
|
+
},
|
|
3521
|
+
themeSwitcher: {
|
|
3522
|
+
indicatorSize: '24px',
|
|
3523
|
+
},
|
|
3524
|
+
},
|
|
3525
|
+
effects: {
|
|
3526
|
+
glassmorphism: {
|
|
3527
|
+
enabled: true,
|
|
3528
|
+
blur: '12px',
|
|
3529
|
+
opacity: 0.15,
|
|
3530
|
+
border: 'rgba(0, 255, 255, 0.3)',
|
|
3531
|
+
},
|
|
3532
|
+
animations: {
|
|
3533
|
+
enabled: true,
|
|
3534
|
+
duration: {
|
|
3535
|
+
fast: '150ms',
|
|
3536
|
+
normal: '300ms',
|
|
3537
|
+
slow: '500ms',
|
|
3538
|
+
},
|
|
3539
|
+
easing: {
|
|
3540
|
+
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
3541
|
+
smooth: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
|
3542
|
+
bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
|
|
3543
|
+
},
|
|
3544
|
+
},
|
|
3545
|
+
shadows: {
|
|
3546
|
+
sm: '0 1px 2px rgba(0, 0, 0, 0.5)',
|
|
3547
|
+
md: '0 4px 6px rgba(0, 0, 0, 0.6)',
|
|
3548
|
+
lg: '0 10px 15px rgba(0, 0, 0, 0.7)',
|
|
3549
|
+
xl: '0 20px 25px rgba(0, 0, 0, 0.8)',
|
|
3550
|
+
card: '0px 4px 12px rgba(0, 0, 0, 0.6), 0 0 20px rgba(0, 255, 255, 0.2)',
|
|
3551
|
+
cardHover: '0px 4px 24px rgba(0, 255, 255, 0.3), 0 0 30px rgba(0, 255, 255, 0.25)',
|
|
3552
|
+
glow: '0 0 20px rgba(0, 255, 255, 0.8)',
|
|
3553
|
+
focus: '0 0 0 2px #00FFFF, 0 0 8px 2px rgba(0, 255, 255, 0.8)',
|
|
3554
|
+
},
|
|
3555
|
+
},
|
|
3395
3556
|
branding: {
|
|
3396
3557
|
primaryColor: '#00FFFF',
|
|
3397
3558
|
},
|
|
3559
|
+
glow: {
|
|
3560
|
+
primary: 'rgba(0, 255, 255, 0.4)',
|
|
3561
|
+
secondary: 'rgba(0, 255, 255, 0.6)',
|
|
3562
|
+
card: 'rgba(0, 255, 255, 0.2)',
|
|
3563
|
+
cardHover: 'rgba(0, 255, 255, 0.3)',
|
|
3564
|
+
button: 'rgba(0, 255, 255, 0.6)',
|
|
3565
|
+
focus: 'rgba(0, 255, 255, 0.8)',
|
|
3566
|
+
scrollbar: 'rgba(0, 255, 255, 0.4)',
|
|
3567
|
+
},
|
|
3568
|
+
gradients: {
|
|
3569
|
+
start: 'rgba(0, 255, 255, 0.08)',
|
|
3570
|
+
end: 'rgba(0, 255, 255, 0.03)',
|
|
3571
|
+
hoverStart: 'rgba(0, 255, 255, 0.15)',
|
|
3572
|
+
hoverEnd: 'rgba(0, 255, 255, 0.08)',
|
|
3573
|
+
},
|
|
3398
3574
|
};
|
|
3399
3575
|
// Light theme with cyan accents
|
|
3400
3576
|
const lightTheme = {
|
|
@@ -3451,9 +3627,121 @@ const lightTheme = {
|
|
|
3451
3627
|
},
|
|
3452
3628
|
},
|
|
3453
3629
|
},
|
|
3630
|
+
typography: {
|
|
3631
|
+
fontFamily: {
|
|
3632
|
+
primary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
3633
|
+
secondary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
3634
|
+
},
|
|
3635
|
+
fontSize: {
|
|
3636
|
+
xs: '0.75rem',
|
|
3637
|
+
sm: '0.875rem',
|
|
3638
|
+
base: '1rem',
|
|
3639
|
+
lg: '1.125rem',
|
|
3640
|
+
xl: '1.25rem',
|
|
3641
|
+
'2xl': '1.5rem',
|
|
3642
|
+
'3xl': '1.875rem',
|
|
3643
|
+
'4xl': '2.25rem',
|
|
3644
|
+
},
|
|
3645
|
+
fontWeight: {
|
|
3646
|
+
normal: 400,
|
|
3647
|
+
medium: 500,
|
|
3648
|
+
semibold: 600,
|
|
3649
|
+
bold: 700,
|
|
3650
|
+
extrabold: 800,
|
|
3651
|
+
},
|
|
3652
|
+
lineHeight: {
|
|
3653
|
+
tight: '1.25',
|
|
3654
|
+
normal: '1.5',
|
|
3655
|
+
relaxed: '1.75',
|
|
3656
|
+
},
|
|
3657
|
+
},
|
|
3658
|
+
spacing: {
|
|
3659
|
+
xs: '0.25rem',
|
|
3660
|
+
sm: '0.5rem',
|
|
3661
|
+
md: '1rem',
|
|
3662
|
+
lg: '1.5rem',
|
|
3663
|
+
xl: '2rem',
|
|
3664
|
+
'2xl': '3rem',
|
|
3665
|
+
'3xl': '4rem',
|
|
3666
|
+
},
|
|
3667
|
+
layout: {
|
|
3668
|
+
containerMaxWidth: '1440px',
|
|
3669
|
+
gridGap: '1rem',
|
|
3670
|
+
cardPadding: '1.5rem',
|
|
3671
|
+
borderRadius: {
|
|
3672
|
+
sm: '0.25rem',
|
|
3673
|
+
md: '0.5rem',
|
|
3674
|
+
lg: '0.75rem',
|
|
3675
|
+
xl: '1rem',
|
|
3676
|
+
'2xl': '1.5rem',
|
|
3677
|
+
full: '9999px',
|
|
3678
|
+
},
|
|
3679
|
+
},
|
|
3680
|
+
components: {
|
|
3681
|
+
brokerCard: {
|
|
3682
|
+
width: '100%',
|
|
3683
|
+
height: '180px',
|
|
3684
|
+
logoSize: '64px',
|
|
3685
|
+
padding: '1.5rem',
|
|
3686
|
+
},
|
|
3687
|
+
statusIndicator: {
|
|
3688
|
+
size: '22px',
|
|
3689
|
+
glowIntensity: 0.9,
|
|
3690
|
+
},
|
|
3691
|
+
modal: {
|
|
3692
|
+
background: 'rgba(255, 255, 255, 0.95)',
|
|
3693
|
+
backdrop: 'rgba(0, 0, 0, 0.5)',
|
|
3694
|
+
},
|
|
3695
|
+
},
|
|
3696
|
+
effects: {
|
|
3697
|
+
glassmorphism: {
|
|
3698
|
+
enabled: true,
|
|
3699
|
+
blur: '12px',
|
|
3700
|
+
opacity: 0.15,
|
|
3701
|
+
border: 'rgba(0, 255, 255, 0.3)',
|
|
3702
|
+
},
|
|
3703
|
+
animations: {
|
|
3704
|
+
enabled: true,
|
|
3705
|
+
duration: {
|
|
3706
|
+
fast: '150ms',
|
|
3707
|
+
normal: '300ms',
|
|
3708
|
+
slow: '500ms',
|
|
3709
|
+
},
|
|
3710
|
+
easing: {
|
|
3711
|
+
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
3712
|
+
smooth: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
|
3713
|
+
bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
|
|
3714
|
+
},
|
|
3715
|
+
},
|
|
3716
|
+
shadows: {
|
|
3717
|
+
sm: '0 1px 2px rgba(0, 0, 0, 0.1)',
|
|
3718
|
+
md: '0 4px 6px rgba(0, 0, 0, 0.1)',
|
|
3719
|
+
lg: '0 10px 15px rgba(0, 0, 0, 0.1)',
|
|
3720
|
+
xl: '0 20px 25px rgba(0, 0, 0, 0.1)',
|
|
3721
|
+
card: '0px 4px 12px rgba(0, 0, 0, 0.1), 0 0 20px rgba(0, 255, 255, 0.2)',
|
|
3722
|
+
cardHover: '0px 4px 24px rgba(0, 255, 255, 0.3), 0 0 30px rgba(0, 255, 255, 0.25)',
|
|
3723
|
+
glow: '0 0 20px rgba(0, 255, 255, 0.8)',
|
|
3724
|
+
focus: '0 0 0 2px #00FFFF, 0 0 8px 2px rgba(0, 255, 255, 0.8)',
|
|
3725
|
+
},
|
|
3726
|
+
},
|
|
3454
3727
|
branding: {
|
|
3455
3728
|
primaryColor: '#00FFFF',
|
|
3456
3729
|
},
|
|
3730
|
+
glow: {
|
|
3731
|
+
primary: 'rgba(0, 255, 255, 0.4)',
|
|
3732
|
+
secondary: 'rgba(0, 255, 255, 0.6)',
|
|
3733
|
+
card: 'rgba(0, 255, 255, 0.2)',
|
|
3734
|
+
cardHover: 'rgba(0, 255, 255, 0.3)',
|
|
3735
|
+
button: 'rgba(0, 255, 255, 0.6)',
|
|
3736
|
+
focus: 'rgba(0, 255, 255, 0.8)',
|
|
3737
|
+
scrollbar: 'rgba(0, 255, 255, 0.4)',
|
|
3738
|
+
},
|
|
3739
|
+
gradients: {
|
|
3740
|
+
start: 'rgba(0, 255, 255, 0.08)',
|
|
3741
|
+
end: 'rgba(0, 255, 255, 0.03)',
|
|
3742
|
+
hoverStart: 'rgba(0, 255, 255, 0.15)',
|
|
3743
|
+
hoverEnd: 'rgba(0, 255, 255, 0.08)',
|
|
3744
|
+
},
|
|
3457
3745
|
};
|
|
3458
3746
|
// Corporate blue theme
|
|
3459
3747
|
const corporateBlueTheme = {
|
|
@@ -3510,14 +3798,140 @@ const corporateBlueTheme = {
|
|
|
3510
3798
|
},
|
|
3511
3799
|
},
|
|
3512
3800
|
},
|
|
3513
|
-
|
|
3514
|
-
|
|
3801
|
+
typography: {
|
|
3802
|
+
fontFamily: {
|
|
3803
|
+
primary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
3804
|
+
secondary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
3805
|
+
},
|
|
3806
|
+
fontSize: {
|
|
3807
|
+
xs: '0.75rem',
|
|
3808
|
+
sm: '0.875rem',
|
|
3809
|
+
base: '1rem',
|
|
3810
|
+
lg: '1.125rem',
|
|
3811
|
+
xl: '1.25rem',
|
|
3812
|
+
'2xl': '1.5rem',
|
|
3813
|
+
'3xl': '1.875rem',
|
|
3814
|
+
'4xl': '2.25rem',
|
|
3815
|
+
},
|
|
3816
|
+
fontWeight: {
|
|
3817
|
+
normal: 400,
|
|
3818
|
+
medium: 500,
|
|
3819
|
+
semibold: 600,
|
|
3820
|
+
bold: 700,
|
|
3821
|
+
extrabold: 800,
|
|
3822
|
+
},
|
|
3823
|
+
lineHeight: {
|
|
3824
|
+
tight: '1.25',
|
|
3825
|
+
normal: '1.5',
|
|
3826
|
+
relaxed: '1.75',
|
|
3827
|
+
},
|
|
3515
3828
|
},
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3829
|
+
spacing: {
|
|
3830
|
+
xs: '0.25rem',
|
|
3831
|
+
sm: '0.5rem',
|
|
3832
|
+
md: '1rem',
|
|
3833
|
+
lg: '1.5rem',
|
|
3834
|
+
xl: '2rem',
|
|
3835
|
+
'2xl': '3rem',
|
|
3836
|
+
'3xl': '4rem',
|
|
3837
|
+
},
|
|
3838
|
+
layout: {
|
|
3839
|
+
containerMaxWidth: '1440px',
|
|
3840
|
+
gridGap: '1rem',
|
|
3841
|
+
cardPadding: '1.5rem',
|
|
3842
|
+
borderRadius: {
|
|
3843
|
+
sm: '0.25rem',
|
|
3844
|
+
md: '0.5rem',
|
|
3845
|
+
lg: '0.75rem',
|
|
3846
|
+
xl: '1rem',
|
|
3847
|
+
'2xl': '1.5rem',
|
|
3848
|
+
full: '9999px',
|
|
3849
|
+
},
|
|
3850
|
+
},
|
|
3851
|
+
components: {
|
|
3852
|
+
brokerCard: {
|
|
3853
|
+
width: '100%',
|
|
3854
|
+
height: '180px',
|
|
3855
|
+
logoSize: '64px',
|
|
3856
|
+
padding: '1.5rem',
|
|
3857
|
+
},
|
|
3858
|
+
statusIndicator: {
|
|
3859
|
+
size: '22px',
|
|
3860
|
+
glowIntensity: 0.9,
|
|
3861
|
+
},
|
|
3862
|
+
modal: {
|
|
3863
|
+
background: 'rgba(0, 0, 0, 0.95)',
|
|
3864
|
+
backdrop: 'rgba(0, 0, 0, 0.8)',
|
|
3865
|
+
},
|
|
3866
|
+
brokerCardModern: {
|
|
3867
|
+
width: '150px',
|
|
3868
|
+
height: '150px',
|
|
3869
|
+
padding: '16px',
|
|
3870
|
+
logoSize: '48px',
|
|
3871
|
+
statusSize: '22px',
|
|
3872
|
+
},
|
|
3873
|
+
connectButton: {
|
|
3874
|
+
width: '120px',
|
|
3875
|
+
height: '120px',
|
|
3876
|
+
},
|
|
3877
|
+
themeSwitcher: {
|
|
3878
|
+
indicatorSize: '24px',
|
|
3879
|
+
},
|
|
3880
|
+
},
|
|
3881
|
+
effects: {
|
|
3882
|
+
glassmorphism: {
|
|
3883
|
+
enabled: true,
|
|
3884
|
+
blur: '12px',
|
|
3885
|
+
opacity: 0.15,
|
|
3886
|
+
border: 'rgba(59, 130, 246, 0.3)',
|
|
3887
|
+
},
|
|
3888
|
+
animations: {
|
|
3889
|
+
enabled: true,
|
|
3890
|
+
duration: {
|
|
3891
|
+
fast: '150ms',
|
|
3892
|
+
normal: '300ms',
|
|
3893
|
+
slow: '500ms',
|
|
3894
|
+
},
|
|
3895
|
+
easing: {
|
|
3896
|
+
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
3897
|
+
smooth: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
|
3898
|
+
bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
|
|
3899
|
+
},
|
|
3900
|
+
},
|
|
3901
|
+
shadows: {
|
|
3902
|
+
sm: '0 1px 2px rgba(0, 0, 0, 0.5)',
|
|
3903
|
+
md: '0 4px 6px rgba(0, 0, 0, 0.6)',
|
|
3904
|
+
lg: '0 10px 15px rgba(0, 0, 0, 0.7)',
|
|
3905
|
+
xl: '0 20px 25px rgba(0, 0, 0, 0.8)',
|
|
3906
|
+
card: '0px 4px 12px rgba(0, 0, 0, 0.6), 0 0 20px rgba(59, 130, 246, 0.2)',
|
|
3907
|
+
cardHover: '0px 4px 24px rgba(59, 130, 246, 0.3), 0 0 30px rgba(59, 130, 246, 0.25)',
|
|
3908
|
+
glow: '0 0 20px rgba(59, 130, 246, 0.8)',
|
|
3909
|
+
focus: '0 0 0 2px #3B82F6, 0 0 8px 2px rgba(59, 130, 246, 0.8)',
|
|
3910
|
+
},
|
|
3911
|
+
},
|
|
3912
|
+
branding: {
|
|
3913
|
+
primaryColor: '#3B82F6',
|
|
3914
|
+
},
|
|
3915
|
+
glow: {
|
|
3916
|
+
primary: 'rgba(59, 130, 246, 0.4)',
|
|
3917
|
+
secondary: 'rgba(59, 130, 246, 0.6)',
|
|
3918
|
+
card: 'rgba(59, 130, 246, 0.2)',
|
|
3919
|
+
cardHover: 'rgba(59, 130, 246, 0.3)',
|
|
3920
|
+
button: 'rgba(59, 130, 246, 0.6)',
|
|
3921
|
+
focus: 'rgba(59, 130, 246, 0.8)',
|
|
3922
|
+
scrollbar: 'rgba(59, 130, 246, 0.4)',
|
|
3923
|
+
},
|
|
3924
|
+
gradients: {
|
|
3925
|
+
start: 'rgba(59, 130, 246, 0.08)',
|
|
3926
|
+
end: 'rgba(59, 130, 246, 0.03)',
|
|
3927
|
+
hoverStart: 'rgba(59, 130, 246, 0.15)',
|
|
3928
|
+
hoverEnd: 'rgba(59, 130, 246, 0.08)',
|
|
3929
|
+
},
|
|
3930
|
+
};
|
|
3931
|
+
// Purple theme
|
|
3932
|
+
const purpleTheme = {
|
|
3933
|
+
mode: 'dark',
|
|
3934
|
+
colors: {
|
|
3521
3935
|
background: {
|
|
3522
3936
|
primary: '#1a1a1a',
|
|
3523
3937
|
secondary: '#2a2a2a',
|
|
@@ -3569,9 +3983,135 @@ const purpleTheme = {
|
|
|
3569
3983
|
},
|
|
3570
3984
|
},
|
|
3571
3985
|
},
|
|
3986
|
+
typography: {
|
|
3987
|
+
fontFamily: {
|
|
3988
|
+
primary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
3989
|
+
secondary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
3990
|
+
},
|
|
3991
|
+
fontSize: {
|
|
3992
|
+
xs: '0.75rem',
|
|
3993
|
+
sm: '0.875rem',
|
|
3994
|
+
base: '1rem',
|
|
3995
|
+
lg: '1.125rem',
|
|
3996
|
+
xl: '1.25rem',
|
|
3997
|
+
'2xl': '1.5rem',
|
|
3998
|
+
'3xl': '1.875rem',
|
|
3999
|
+
'4xl': '2.25rem',
|
|
4000
|
+
},
|
|
4001
|
+
fontWeight: {
|
|
4002
|
+
normal: 400,
|
|
4003
|
+
medium: 500,
|
|
4004
|
+
semibold: 600,
|
|
4005
|
+
bold: 700,
|
|
4006
|
+
extrabold: 800,
|
|
4007
|
+
},
|
|
4008
|
+
lineHeight: {
|
|
4009
|
+
tight: '1.25',
|
|
4010
|
+
normal: '1.5',
|
|
4011
|
+
relaxed: '1.75',
|
|
4012
|
+
},
|
|
4013
|
+
},
|
|
4014
|
+
spacing: {
|
|
4015
|
+
xs: '0.25rem',
|
|
4016
|
+
sm: '0.5rem',
|
|
4017
|
+
md: '1rem',
|
|
4018
|
+
lg: '1.5rem',
|
|
4019
|
+
xl: '2rem',
|
|
4020
|
+
'2xl': '3rem',
|
|
4021
|
+
'3xl': '4rem',
|
|
4022
|
+
},
|
|
4023
|
+
layout: {
|
|
4024
|
+
containerMaxWidth: '1440px',
|
|
4025
|
+
gridGap: '1rem',
|
|
4026
|
+
cardPadding: '1.5rem',
|
|
4027
|
+
borderRadius: {
|
|
4028
|
+
sm: '0.25rem',
|
|
4029
|
+
md: '0.5rem',
|
|
4030
|
+
lg: '0.75rem',
|
|
4031
|
+
xl: '1rem',
|
|
4032
|
+
'2xl': '1.5rem',
|
|
4033
|
+
full: '9999px',
|
|
4034
|
+
},
|
|
4035
|
+
},
|
|
4036
|
+
components: {
|
|
4037
|
+
brokerCard: {
|
|
4038
|
+
width: '100%',
|
|
4039
|
+
height: '180px',
|
|
4040
|
+
logoSize: '64px',
|
|
4041
|
+
padding: '1.5rem',
|
|
4042
|
+
},
|
|
4043
|
+
statusIndicator: {
|
|
4044
|
+
size: '22px',
|
|
4045
|
+
glowIntensity: 0.9,
|
|
4046
|
+
},
|
|
4047
|
+
modal: {
|
|
4048
|
+
background: 'rgba(0, 0, 0, 0.95)',
|
|
4049
|
+
backdrop: 'rgba(0, 0, 0, 0.8)',
|
|
4050
|
+
},
|
|
4051
|
+
brokerCardModern: {
|
|
4052
|
+
width: '150px',
|
|
4053
|
+
height: '150px',
|
|
4054
|
+
padding: '16px',
|
|
4055
|
+
logoSize: '48px',
|
|
4056
|
+
statusSize: '22px',
|
|
4057
|
+
},
|
|
4058
|
+
connectButton: {
|
|
4059
|
+
width: '120px',
|
|
4060
|
+
height: '120px',
|
|
4061
|
+
},
|
|
4062
|
+
themeSwitcher: {
|
|
4063
|
+
indicatorSize: '24px',
|
|
4064
|
+
},
|
|
4065
|
+
},
|
|
4066
|
+
effects: {
|
|
4067
|
+
glassmorphism: {
|
|
4068
|
+
enabled: true,
|
|
4069
|
+
blur: '12px',
|
|
4070
|
+
opacity: 0.15,
|
|
4071
|
+
border: 'rgba(168, 85, 247, 0.3)',
|
|
4072
|
+
},
|
|
4073
|
+
animations: {
|
|
4074
|
+
enabled: true,
|
|
4075
|
+
duration: {
|
|
4076
|
+
fast: '150ms',
|
|
4077
|
+
normal: '300ms',
|
|
4078
|
+
slow: '500ms',
|
|
4079
|
+
},
|
|
4080
|
+
easing: {
|
|
4081
|
+
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
4082
|
+
smooth: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
|
4083
|
+
bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
|
|
4084
|
+
},
|
|
4085
|
+
},
|
|
4086
|
+
shadows: {
|
|
4087
|
+
sm: '0 1px 2px rgba(0, 0, 0, 0.5)',
|
|
4088
|
+
md: '0 4px 6px rgba(0, 0, 0, 0.6)',
|
|
4089
|
+
lg: '0 10px 15px rgba(0, 0, 0, 0.7)',
|
|
4090
|
+
xl: '0 20px 25px rgba(0, 0, 0, 0.8)',
|
|
4091
|
+
card: '0px 4px 12px rgba(0, 0, 0, 0.6), 0 0 20px rgba(168, 85, 247, 0.2)',
|
|
4092
|
+
cardHover: '0px 4px 24px rgba(168, 85, 247, 0.3), 0 0 30px rgba(168, 85, 247, 0.25)',
|
|
4093
|
+
glow: '0 0 20px rgba(168, 85, 247, 0.8)',
|
|
4094
|
+
focus: '0 0 0 2px #A855F7, 0 0 8px 2px rgba(168, 85, 247, 0.8)',
|
|
4095
|
+
},
|
|
4096
|
+
},
|
|
3572
4097
|
branding: {
|
|
3573
4098
|
primaryColor: '#A855F7',
|
|
3574
4099
|
},
|
|
4100
|
+
glow: {
|
|
4101
|
+
primary: 'rgba(168, 85, 247, 0.4)',
|
|
4102
|
+
secondary: 'rgba(168, 85, 247, 0.6)',
|
|
4103
|
+
card: 'rgba(168, 85, 247, 0.2)',
|
|
4104
|
+
cardHover: 'rgba(168, 85, 247, 0.3)',
|
|
4105
|
+
button: 'rgba(168, 85, 247, 0.6)',
|
|
4106
|
+
focus: 'rgba(168, 85, 247, 0.8)',
|
|
4107
|
+
scrollbar: 'rgba(168, 85, 247, 0.4)',
|
|
4108
|
+
},
|
|
4109
|
+
gradients: {
|
|
4110
|
+
start: 'rgba(168, 85, 247, 0.08)',
|
|
4111
|
+
end: 'rgba(168, 85, 247, 0.03)',
|
|
4112
|
+
hoverStart: 'rgba(168, 85, 247, 0.15)',
|
|
4113
|
+
hoverEnd: 'rgba(168, 85, 247, 0.08)',
|
|
4114
|
+
},
|
|
3575
4115
|
};
|
|
3576
4116
|
// Green theme
|
|
3577
4117
|
const greenTheme = {
|
|
@@ -3628,9 +4168,135 @@ const greenTheme = {
|
|
|
3628
4168
|
},
|
|
3629
4169
|
},
|
|
3630
4170
|
},
|
|
4171
|
+
typography: {
|
|
4172
|
+
fontFamily: {
|
|
4173
|
+
primary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
4174
|
+
secondary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
4175
|
+
},
|
|
4176
|
+
fontSize: {
|
|
4177
|
+
xs: '0.75rem',
|
|
4178
|
+
sm: '0.875rem',
|
|
4179
|
+
base: '1rem',
|
|
4180
|
+
lg: '1.125rem',
|
|
4181
|
+
xl: '1.25rem',
|
|
4182
|
+
'2xl': '1.5rem',
|
|
4183
|
+
'3xl': '1.875rem',
|
|
4184
|
+
'4xl': '2.25rem',
|
|
4185
|
+
},
|
|
4186
|
+
fontWeight: {
|
|
4187
|
+
normal: 400,
|
|
4188
|
+
medium: 500,
|
|
4189
|
+
semibold: 600,
|
|
4190
|
+
bold: 700,
|
|
4191
|
+
extrabold: 800,
|
|
4192
|
+
},
|
|
4193
|
+
lineHeight: {
|
|
4194
|
+
tight: '1.25',
|
|
4195
|
+
normal: '1.5',
|
|
4196
|
+
relaxed: '1.75',
|
|
4197
|
+
},
|
|
4198
|
+
},
|
|
4199
|
+
spacing: {
|
|
4200
|
+
xs: '0.25rem',
|
|
4201
|
+
sm: '0.5rem',
|
|
4202
|
+
md: '1rem',
|
|
4203
|
+
lg: '1.5rem',
|
|
4204
|
+
xl: '2rem',
|
|
4205
|
+
'2xl': '3rem',
|
|
4206
|
+
'3xl': '4rem',
|
|
4207
|
+
},
|
|
4208
|
+
layout: {
|
|
4209
|
+
containerMaxWidth: '1440px',
|
|
4210
|
+
gridGap: '1rem',
|
|
4211
|
+
cardPadding: '1.5rem',
|
|
4212
|
+
borderRadius: {
|
|
4213
|
+
sm: '0.25rem',
|
|
4214
|
+
md: '0.5rem',
|
|
4215
|
+
lg: '0.75rem',
|
|
4216
|
+
xl: '1rem',
|
|
4217
|
+
'2xl': '1.5rem',
|
|
4218
|
+
full: '9999px',
|
|
4219
|
+
},
|
|
4220
|
+
},
|
|
4221
|
+
components: {
|
|
4222
|
+
brokerCard: {
|
|
4223
|
+
width: '100%',
|
|
4224
|
+
height: '180px',
|
|
4225
|
+
logoSize: '64px',
|
|
4226
|
+
padding: '1.5rem',
|
|
4227
|
+
},
|
|
4228
|
+
statusIndicator: {
|
|
4229
|
+
size: '22px',
|
|
4230
|
+
glowIntensity: 0.9,
|
|
4231
|
+
},
|
|
4232
|
+
modal: {
|
|
4233
|
+
background: 'rgba(0, 0, 0, 0.95)',
|
|
4234
|
+
backdrop: 'rgba(0, 0, 0, 0.8)',
|
|
4235
|
+
},
|
|
4236
|
+
brokerCardModern: {
|
|
4237
|
+
width: '150px',
|
|
4238
|
+
height: '150px',
|
|
4239
|
+
padding: '16px',
|
|
4240
|
+
logoSize: '48px',
|
|
4241
|
+
statusSize: '22px',
|
|
4242
|
+
},
|
|
4243
|
+
connectButton: {
|
|
4244
|
+
width: '120px',
|
|
4245
|
+
height: '120px',
|
|
4246
|
+
},
|
|
4247
|
+
themeSwitcher: {
|
|
4248
|
+
indicatorSize: '24px',
|
|
4249
|
+
},
|
|
4250
|
+
},
|
|
4251
|
+
effects: {
|
|
4252
|
+
glassmorphism: {
|
|
4253
|
+
enabled: true,
|
|
4254
|
+
blur: '12px',
|
|
4255
|
+
opacity: 0.15,
|
|
4256
|
+
border: 'rgba(34, 197, 94, 0.3)',
|
|
4257
|
+
},
|
|
4258
|
+
animations: {
|
|
4259
|
+
enabled: true,
|
|
4260
|
+
duration: {
|
|
4261
|
+
fast: '150ms',
|
|
4262
|
+
normal: '300ms',
|
|
4263
|
+
slow: '500ms',
|
|
4264
|
+
},
|
|
4265
|
+
easing: {
|
|
4266
|
+
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
4267
|
+
smooth: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
|
4268
|
+
bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
|
|
4269
|
+
},
|
|
4270
|
+
},
|
|
4271
|
+
shadows: {
|
|
4272
|
+
sm: '0 1px 2px rgba(0, 0, 0, 0.5)',
|
|
4273
|
+
md: '0 4px 6px rgba(0, 0, 0, 0.6)',
|
|
4274
|
+
lg: '0 10px 15px rgba(0, 0, 0, 0.7)',
|
|
4275
|
+
xl: '0 20px 25px rgba(0, 0, 0, 0.8)',
|
|
4276
|
+
card: '0px 4px 12px rgba(0, 0, 0, 0.6), 0 0 20px rgba(34, 197, 94, 0.2)',
|
|
4277
|
+
cardHover: '0px 4px 24px rgba(34, 197, 94, 0.3), 0 0 30px rgba(34, 197, 94, 0.25)',
|
|
4278
|
+
glow: '0 0 20px rgba(34, 197, 94, 0.8)',
|
|
4279
|
+
focus: '0 0 0 2px #22C55E, 0 0 8px 2px rgba(34, 197, 94, 0.8)',
|
|
4280
|
+
},
|
|
4281
|
+
},
|
|
3631
4282
|
branding: {
|
|
3632
4283
|
primaryColor: '#22C55E',
|
|
3633
4284
|
},
|
|
4285
|
+
glow: {
|
|
4286
|
+
primary: 'rgba(34, 197, 94, 0.4)',
|
|
4287
|
+
secondary: 'rgba(34, 197, 94, 0.6)',
|
|
4288
|
+
card: 'rgba(34, 197, 94, 0.2)',
|
|
4289
|
+
cardHover: 'rgba(34, 197, 94, 0.3)',
|
|
4290
|
+
button: 'rgba(34, 197, 94, 0.6)',
|
|
4291
|
+
focus: 'rgba(34, 197, 94, 0.8)',
|
|
4292
|
+
scrollbar: 'rgba(34, 197, 94, 0.4)',
|
|
4293
|
+
},
|
|
4294
|
+
gradients: {
|
|
4295
|
+
start: 'rgba(34, 197, 94, 0.08)',
|
|
4296
|
+
end: 'rgba(34, 197, 94, 0.03)',
|
|
4297
|
+
hoverStart: 'rgba(34, 197, 94, 0.15)',
|
|
4298
|
+
hoverEnd: 'rgba(34, 197, 94, 0.08)',
|
|
4299
|
+
},
|
|
3634
4300
|
};
|
|
3635
4301
|
// Orange theme
|
|
3636
4302
|
const orangeTheme = {
|
|
@@ -3687,9 +4353,135 @@ const orangeTheme = {
|
|
|
3687
4353
|
},
|
|
3688
4354
|
},
|
|
3689
4355
|
},
|
|
4356
|
+
typography: {
|
|
4357
|
+
fontFamily: {
|
|
4358
|
+
primary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
4359
|
+
secondary: 'Orbitron, Futura, Inter, system-ui, sans-serif',
|
|
4360
|
+
},
|
|
4361
|
+
fontSize: {
|
|
4362
|
+
xs: '0.75rem',
|
|
4363
|
+
sm: '0.875rem',
|
|
4364
|
+
base: '1rem',
|
|
4365
|
+
lg: '1.125rem',
|
|
4366
|
+
xl: '1.25rem',
|
|
4367
|
+
'2xl': '1.5rem',
|
|
4368
|
+
'3xl': '1.875rem',
|
|
4369
|
+
'4xl': '2.25rem',
|
|
4370
|
+
},
|
|
4371
|
+
fontWeight: {
|
|
4372
|
+
normal: 400,
|
|
4373
|
+
medium: 500,
|
|
4374
|
+
semibold: 600,
|
|
4375
|
+
bold: 700,
|
|
4376
|
+
extrabold: 800,
|
|
4377
|
+
},
|
|
4378
|
+
lineHeight: {
|
|
4379
|
+
tight: '1.25',
|
|
4380
|
+
normal: '1.5',
|
|
4381
|
+
relaxed: '1.75',
|
|
4382
|
+
},
|
|
4383
|
+
},
|
|
4384
|
+
spacing: {
|
|
4385
|
+
xs: '0.25rem',
|
|
4386
|
+
sm: '0.5rem',
|
|
4387
|
+
md: '1rem',
|
|
4388
|
+
lg: '1.5rem',
|
|
4389
|
+
xl: '2rem',
|
|
4390
|
+
'2xl': '3rem',
|
|
4391
|
+
'3xl': '4rem',
|
|
4392
|
+
},
|
|
4393
|
+
layout: {
|
|
4394
|
+
containerMaxWidth: '1440px',
|
|
4395
|
+
gridGap: '1rem',
|
|
4396
|
+
cardPadding: '1.5rem',
|
|
4397
|
+
borderRadius: {
|
|
4398
|
+
sm: '0.25rem',
|
|
4399
|
+
md: '0.5rem',
|
|
4400
|
+
lg: '0.75rem',
|
|
4401
|
+
xl: '1rem',
|
|
4402
|
+
'2xl': '1.5rem',
|
|
4403
|
+
full: '9999px',
|
|
4404
|
+
},
|
|
4405
|
+
},
|
|
4406
|
+
components: {
|
|
4407
|
+
brokerCard: {
|
|
4408
|
+
width: '100%',
|
|
4409
|
+
height: '180px',
|
|
4410
|
+
logoSize: '64px',
|
|
4411
|
+
padding: '1.5rem',
|
|
4412
|
+
},
|
|
4413
|
+
statusIndicator: {
|
|
4414
|
+
size: '22px',
|
|
4415
|
+
glowIntensity: 0.9,
|
|
4416
|
+
},
|
|
4417
|
+
modal: {
|
|
4418
|
+
background: 'rgba(0, 0, 0, 0.95)',
|
|
4419
|
+
backdrop: 'rgba(0, 0, 0, 0.8)',
|
|
4420
|
+
},
|
|
4421
|
+
brokerCardModern: {
|
|
4422
|
+
width: '150px',
|
|
4423
|
+
height: '150px',
|
|
4424
|
+
padding: '16px',
|
|
4425
|
+
logoSize: '48px',
|
|
4426
|
+
statusSize: '22px',
|
|
4427
|
+
},
|
|
4428
|
+
connectButton: {
|
|
4429
|
+
width: '120px',
|
|
4430
|
+
height: '120px',
|
|
4431
|
+
},
|
|
4432
|
+
themeSwitcher: {
|
|
4433
|
+
indicatorSize: '24px',
|
|
4434
|
+
},
|
|
4435
|
+
},
|
|
4436
|
+
effects: {
|
|
4437
|
+
glassmorphism: {
|
|
4438
|
+
enabled: true,
|
|
4439
|
+
blur: '12px',
|
|
4440
|
+
opacity: 0.15,
|
|
4441
|
+
border: 'rgba(249, 115, 22, 0.3)',
|
|
4442
|
+
},
|
|
4443
|
+
animations: {
|
|
4444
|
+
enabled: true,
|
|
4445
|
+
duration: {
|
|
4446
|
+
fast: '150ms',
|
|
4447
|
+
normal: '300ms',
|
|
4448
|
+
slow: '500ms',
|
|
4449
|
+
},
|
|
4450
|
+
easing: {
|
|
4451
|
+
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
4452
|
+
smooth: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
|
4453
|
+
bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
|
|
4454
|
+
},
|
|
4455
|
+
},
|
|
4456
|
+
shadows: {
|
|
4457
|
+
sm: '0 1px 2px rgba(0, 0, 0, 0.5)',
|
|
4458
|
+
md: '0 4px 6px rgba(0, 0, 0, 0.6)',
|
|
4459
|
+
lg: '0 10px 15px rgba(0, 0, 0, 0.7)',
|
|
4460
|
+
xl: '0 20px 25px rgba(0, 0, 0, 0.8)',
|
|
4461
|
+
card: '0px 4px 12px rgba(0, 0, 0, 0.6), 0 0 20px rgba(249, 115, 22, 0.2)',
|
|
4462
|
+
cardHover: '0px 4px 24px rgba(249, 115, 22, 0.3), 0 0 30px rgba(249, 115, 22, 0.25)',
|
|
4463
|
+
glow: '0 0 20px rgba(249, 115, 22, 0.8)',
|
|
4464
|
+
focus: '0 0 0 2px #F97316, 0 0 8px 2px rgba(249, 115, 22, 0.8)',
|
|
4465
|
+
},
|
|
4466
|
+
},
|
|
3690
4467
|
branding: {
|
|
3691
4468
|
primaryColor: '#F97316',
|
|
3692
4469
|
},
|
|
4470
|
+
glow: {
|
|
4471
|
+
primary: 'rgba(249, 115, 22, 0.4)',
|
|
4472
|
+
secondary: 'rgba(249, 115, 22, 0.6)',
|
|
4473
|
+
card: 'rgba(249, 115, 22, 0.2)',
|
|
4474
|
+
cardHover: 'rgba(249, 115, 22, 0.3)',
|
|
4475
|
+
button: 'rgba(249, 115, 22, 0.6)',
|
|
4476
|
+
focus: 'rgba(249, 115, 22, 0.8)',
|
|
4477
|
+
scrollbar: 'rgba(249, 115, 22, 0.4)',
|
|
4478
|
+
},
|
|
4479
|
+
gradients: {
|
|
4480
|
+
start: 'rgba(249, 115, 22, 0.08)',
|
|
4481
|
+
end: 'rgba(249, 115, 22, 0.03)',
|
|
4482
|
+
hoverStart: 'rgba(249, 115, 22, 0.15)',
|
|
4483
|
+
hoverEnd: 'rgba(249, 115, 22, 0.08)',
|
|
4484
|
+
},
|
|
3693
4485
|
};
|
|
3694
4486
|
// Theme preset mapping
|
|
3695
4487
|
const portalThemePresets = {
|
|
@@ -3774,17 +4566,36 @@ function getThemePreset(preset) {
|
|
|
3774
4566
|
*/
|
|
3775
4567
|
function validateCustomTheme(theme) {
|
|
3776
4568
|
try {
|
|
3777
|
-
//
|
|
3778
|
-
if (
|
|
4569
|
+
// Only validate what's provided - everything else gets defaults
|
|
4570
|
+
if (theme.mode && !['dark', 'light', 'auto'].includes(theme.mode)) {
|
|
3779
4571
|
return false;
|
|
3780
4572
|
}
|
|
3781
|
-
|
|
3782
|
-
|
|
4573
|
+
// If colors are provided, validate the structure
|
|
4574
|
+
if (theme.colors) {
|
|
4575
|
+
// Check that any provided color sections have valid structure
|
|
4576
|
+
const colorSections = ['background', 'status', 'text', 'border', 'input', 'button'];
|
|
4577
|
+
for (const section of colorSections) {
|
|
4578
|
+
const colorSection = theme.colors[section];
|
|
4579
|
+
if (colorSection && typeof colorSection !== 'object') {
|
|
4580
|
+
return false;
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4583
|
+
}
|
|
4584
|
+
// If typography is provided, validate structure
|
|
4585
|
+
if (theme.typography) {
|
|
4586
|
+
if (theme.typography.fontSize && typeof theme.typography.fontSize !== 'object') {
|
|
4587
|
+
return false;
|
|
4588
|
+
}
|
|
4589
|
+
if (theme.typography.fontWeight && typeof theme.typography.fontWeight !== 'object') {
|
|
4590
|
+
return false;
|
|
4591
|
+
}
|
|
3783
4592
|
}
|
|
3784
|
-
//
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
4593
|
+
// If effects are provided, validate structure
|
|
4594
|
+
if (theme.effects) {
|
|
4595
|
+
if (theme.effects.animations && typeof theme.effects.animations !== 'object') {
|
|
4596
|
+
return false;
|
|
4597
|
+
}
|
|
4598
|
+
if (theme.effects.shadows && typeof theme.effects.shadows !== 'object') {
|
|
3788
4599
|
return false;
|
|
3789
4600
|
}
|
|
3790
4601
|
}
|
|
@@ -3816,12 +4627,14 @@ function createCustomThemeFromPreset(preset, modifications) {
|
|
|
3816
4627
|
/**
|
|
3817
4628
|
* Broker filtering utility functions
|
|
3818
4629
|
*/
|
|
3819
|
-
// Supported broker names and their corresponding IDs
|
|
4630
|
+
// Supported broker names and their corresponding IDs (including aliases)
|
|
3820
4631
|
const SUPPORTED_BROKERS = {
|
|
3821
4632
|
'alpaca': 'alpaca',
|
|
3822
4633
|
'robinhood': 'robinhood',
|
|
3823
4634
|
'tasty_trade': 'tasty_trade',
|
|
3824
|
-
'ninja_trader': 'ninja_trader'
|
|
4635
|
+
'ninja_trader': 'ninja_trader',
|
|
4636
|
+
'tradovate': 'tradovate', // Alias for ninja_trader
|
|
4637
|
+
'interactive_brokers': 'interactive_brokers',
|
|
3825
4638
|
};
|
|
3826
4639
|
/**
|
|
3827
4640
|
* Convert broker names to broker IDs, filtering out unsupported ones
|
|
@@ -3961,6 +4774,13 @@ class FinaticConnect extends EventEmitter {
|
|
|
3961
4774
|
this.userToken?.refreshToken &&
|
|
3962
4775
|
this.userToken?.user_id);
|
|
3963
4776
|
}
|
|
4777
|
+
/**
|
|
4778
|
+
* Check if the client is authenticated (alias for isAuthed for consistency)
|
|
4779
|
+
* @returns True if authenticated, false otherwise
|
|
4780
|
+
*/
|
|
4781
|
+
is_authenticated() {
|
|
4782
|
+
return this.isAuthed();
|
|
4783
|
+
}
|
|
3964
4784
|
/**
|
|
3965
4785
|
* Get user's orders with pagination and optional filtering
|
|
3966
4786
|
* @param params - Query parameters including page, perPage, and filters
|
|
@@ -4004,20 +4824,18 @@ class FinaticConnect extends EventEmitter {
|
|
|
4004
4824
|
return this.getAccountsPage(page, perPage, filter);
|
|
4005
4825
|
}
|
|
4006
4826
|
/**
|
|
4007
|
-
*
|
|
4827
|
+
* Get user's balances with pagination and optional filtering
|
|
4828
|
+
* @param params - Query parameters including page, perPage, and filters
|
|
4829
|
+
* @returns Promise with paginated result that supports navigation
|
|
4008
4830
|
*/
|
|
4009
|
-
async
|
|
4010
|
-
if (!this.
|
|
4011
|
-
|
|
4012
|
-
}
|
|
4013
|
-
try {
|
|
4014
|
-
await this.apiClient.revokeToken(this.userToken.accessToken);
|
|
4015
|
-
this.userToken = null;
|
|
4016
|
-
}
|
|
4017
|
-
catch (error) {
|
|
4018
|
-
this.emit('error', error);
|
|
4019
|
-
throw error;
|
|
4831
|
+
async getBalances(params) {
|
|
4832
|
+
if (!this.isAuthed()) {
|
|
4833
|
+
throw new AuthenticationError('User is not authenticated');
|
|
4020
4834
|
}
|
|
4835
|
+
const page = params?.page || 1;
|
|
4836
|
+
const perPage = params?.perPage || 100;
|
|
4837
|
+
const filter = params?.filter;
|
|
4838
|
+
return this.getBalancesPage(page, perPage, filter);
|
|
4021
4839
|
}
|
|
4022
4840
|
/**
|
|
4023
4841
|
* Initialize the Finatic Connect SDK
|
|
@@ -4106,9 +4924,33 @@ class FinaticConnect extends EventEmitter {
|
|
|
4106
4924
|
async setUserId(userId) {
|
|
4107
4925
|
await this.initializeWithUser(userId);
|
|
4108
4926
|
}
|
|
4927
|
+
/**
|
|
4928
|
+
* Get the user and tokens for a completed session
|
|
4929
|
+
* @returns Promise with user information and tokens
|
|
4930
|
+
*/
|
|
4931
|
+
async getSessionUser() {
|
|
4932
|
+
if (!this.isAuthed()) {
|
|
4933
|
+
throw new AuthenticationError('User is not authenticated');
|
|
4934
|
+
}
|
|
4935
|
+
if (!this.userToken) {
|
|
4936
|
+
throw new AuthenticationError('No user token available');
|
|
4937
|
+
}
|
|
4938
|
+
return {
|
|
4939
|
+
user_id: this.userToken.userId,
|
|
4940
|
+
access_token: this.userToken.accessToken,
|
|
4941
|
+
refresh_token: this.userToken.refreshToken,
|
|
4942
|
+
expires_in: this.userToken.expiresIn,
|
|
4943
|
+
token_type: this.userToken.tokenType,
|
|
4944
|
+
scope: this.userToken.scope,
|
|
4945
|
+
company_id: this.companyId
|
|
4946
|
+
};
|
|
4947
|
+
}
|
|
4109
4948
|
async initializeWithUser(userId) {
|
|
4110
4949
|
try {
|
|
4111
|
-
|
|
4950
|
+
if (!this.sessionId) {
|
|
4951
|
+
throw new SessionError('Session not initialized');
|
|
4952
|
+
}
|
|
4953
|
+
this.userToken = await this.apiClient.getUserToken(this.sessionId);
|
|
4112
4954
|
// Set tokens in ApiClient for automatic token management
|
|
4113
4955
|
if (this.userToken) {
|
|
4114
4956
|
const expiresAt = new Date(Date.now() + 3600 * 1000).toISOString(); // 1 hour from now
|
|
@@ -4152,20 +4994,8 @@ class FinaticConnect extends EventEmitter {
|
|
|
4152
4994
|
this.apiClient.setSessionContext(this.sessionId, this.companyId, startResponse.data.csrf_token // If available in response
|
|
4153
4995
|
);
|
|
4154
4996
|
}
|
|
4155
|
-
//
|
|
4156
|
-
|
|
4157
|
-
let attempts = 0;
|
|
4158
|
-
while (attempts < maxAttempts) {
|
|
4159
|
-
const sessionResponse = await this.apiClient.validatePortalSession(this.sessionId, '');
|
|
4160
|
-
if (sessionResponse.status === 'active') {
|
|
4161
|
-
break;
|
|
4162
|
-
}
|
|
4163
|
-
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second between attempts
|
|
4164
|
-
attempts++;
|
|
4165
|
-
}
|
|
4166
|
-
if (attempts === maxAttempts) {
|
|
4167
|
-
throw new SessionError('Session failed to become active');
|
|
4168
|
-
}
|
|
4997
|
+
// Session is now active
|
|
4998
|
+
this.currentSessionState = SessionState.ACTIVE;
|
|
4169
4999
|
}
|
|
4170
5000
|
// Get portal URL
|
|
4171
5001
|
const portalResponse = await this.apiClient.getPortalUrl(this.sessionId);
|
|
@@ -4176,6 +5006,12 @@ class FinaticConnect extends EventEmitter {
|
|
|
4176
5006
|
let themedPortalUrl = appendThemeToURL(portalResponse.data.portal_url, options?.theme);
|
|
4177
5007
|
// Apply broker filter to portal URL if provided
|
|
4178
5008
|
themedPortalUrl = appendBrokerFilterToURL(themedPortalUrl, options?.brokers);
|
|
5009
|
+
// Apply email parameter to portal URL if provided
|
|
5010
|
+
if (options?.email) {
|
|
5011
|
+
const url = new URL(themedPortalUrl);
|
|
5012
|
+
url.searchParams.set('email', options.email);
|
|
5013
|
+
themedPortalUrl = url.toString();
|
|
5014
|
+
}
|
|
4179
5015
|
// Create portal UI if not exists
|
|
4180
5016
|
if (!this.portalUI) {
|
|
4181
5017
|
this.portalUI = new PortalUI(this.baseUrl);
|
|
@@ -4271,21 +5107,8 @@ class FinaticConnect extends EventEmitter {
|
|
|
4271
5107
|
}
|
|
4272
5108
|
// For non-direct auth, we need to wait for the session to be ACTIVE
|
|
4273
5109
|
if (response.data.state === SessionState.PENDING) {
|
|
4274
|
-
//
|
|
4275
|
-
|
|
4276
|
-
let attempts = 0;
|
|
4277
|
-
while (attempts < maxAttempts) {
|
|
4278
|
-
const sessionResponse = await this.apiClient.validatePortalSession(this.sessionId, '');
|
|
4279
|
-
if (sessionResponse.status === 'active') {
|
|
4280
|
-
this.currentSessionState = SessionState.ACTIVE;
|
|
4281
|
-
break;
|
|
4282
|
-
}
|
|
4283
|
-
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second between attempts
|
|
4284
|
-
attempts++;
|
|
4285
|
-
}
|
|
4286
|
-
if (attempts === maxAttempts) {
|
|
4287
|
-
throw new SessionError('Session failed to become active');
|
|
4288
|
-
}
|
|
5110
|
+
// Session is now active
|
|
5111
|
+
this.currentSessionState = SessionState.ACTIVE;
|
|
4289
5112
|
}
|
|
4290
5113
|
}
|
|
4291
5114
|
catch (error) {
|
|
@@ -4443,6 +5266,138 @@ class FinaticConnect extends EventEmitter {
|
|
|
4443
5266
|
throw error;
|
|
4444
5267
|
}
|
|
4445
5268
|
}
|
|
5269
|
+
/**
|
|
5270
|
+
* Place a stock stop order (convenience method)
|
|
5271
|
+
*/
|
|
5272
|
+
async placeStockStopOrder(symbol, quantity, side, stopPrice, timeInForce = 'gtc', broker, accountNumber) {
|
|
5273
|
+
if (!this.userToken) {
|
|
5274
|
+
throw new Error('Not initialized with user');
|
|
5275
|
+
}
|
|
5276
|
+
try {
|
|
5277
|
+
return await this.apiClient.placeStockStopOrder(symbol, quantity, side === 'buy' ? 'Buy' : 'Sell', stopPrice, timeInForce, broker, accountNumber);
|
|
5278
|
+
}
|
|
5279
|
+
catch (error) {
|
|
5280
|
+
this.emit('error', error);
|
|
5281
|
+
throw error;
|
|
5282
|
+
}
|
|
5283
|
+
}
|
|
5284
|
+
/**
|
|
5285
|
+
* Place a crypto market order (convenience method)
|
|
5286
|
+
*/
|
|
5287
|
+
async placeCryptoMarketOrder(symbol, quantity, side, broker, accountNumber) {
|
|
5288
|
+
if (!this.userToken) {
|
|
5289
|
+
throw new Error('Not initialized with user');
|
|
5290
|
+
}
|
|
5291
|
+
try {
|
|
5292
|
+
return await this.apiClient.placeCryptoMarketOrder(symbol, quantity, side === 'buy' ? 'Buy' : 'Sell', broker, accountNumber);
|
|
5293
|
+
}
|
|
5294
|
+
catch (error) {
|
|
5295
|
+
this.emit('error', error);
|
|
5296
|
+
throw error;
|
|
5297
|
+
}
|
|
5298
|
+
}
|
|
5299
|
+
/**
|
|
5300
|
+
* Place a crypto limit order (convenience method)
|
|
5301
|
+
*/
|
|
5302
|
+
async placeCryptoLimitOrder(symbol, quantity, side, price, timeInForce = 'gtc', broker, accountNumber) {
|
|
5303
|
+
if (!this.userToken) {
|
|
5304
|
+
throw new Error('Not initialized with user');
|
|
5305
|
+
}
|
|
5306
|
+
try {
|
|
5307
|
+
return await this.apiClient.placeCryptoLimitOrder(symbol, quantity, side === 'buy' ? 'Buy' : 'Sell', price, timeInForce, broker, accountNumber);
|
|
5308
|
+
}
|
|
5309
|
+
catch (error) {
|
|
5310
|
+
this.emit('error', error);
|
|
5311
|
+
throw error;
|
|
5312
|
+
}
|
|
5313
|
+
}
|
|
5314
|
+
/**
|
|
5315
|
+
* Place an options market order (convenience method)
|
|
5316
|
+
*/
|
|
5317
|
+
async placeOptionsMarketOrder(symbol, quantity, side, broker, accountNumber) {
|
|
5318
|
+
if (!this.userToken) {
|
|
5319
|
+
throw new Error('Not initialized with user');
|
|
5320
|
+
}
|
|
5321
|
+
try {
|
|
5322
|
+
return await this.apiClient.placeOptionsMarketOrder(symbol, quantity, side === 'buy' ? 'Buy' : 'Sell', broker, accountNumber);
|
|
5323
|
+
}
|
|
5324
|
+
catch (error) {
|
|
5325
|
+
this.emit('error', error);
|
|
5326
|
+
throw error;
|
|
5327
|
+
}
|
|
5328
|
+
}
|
|
5329
|
+
/**
|
|
5330
|
+
* Place an options limit order (convenience method)
|
|
5331
|
+
*/
|
|
5332
|
+
async placeOptionsLimitOrder(symbol, quantity, side, price, timeInForce = 'gtc', broker, accountNumber) {
|
|
5333
|
+
if (!this.userToken) {
|
|
5334
|
+
throw new Error('Not initialized with user');
|
|
5335
|
+
}
|
|
5336
|
+
try {
|
|
5337
|
+
return await this.apiClient.placeOptionsLimitOrder(symbol, quantity, side === 'buy' ? 'Buy' : 'Sell', price, timeInForce, broker, accountNumber);
|
|
5338
|
+
}
|
|
5339
|
+
catch (error) {
|
|
5340
|
+
this.emit('error', error);
|
|
5341
|
+
throw error;
|
|
5342
|
+
}
|
|
5343
|
+
}
|
|
5344
|
+
/**
|
|
5345
|
+
* Place a futures market order (convenience method)
|
|
5346
|
+
*/
|
|
5347
|
+
async placeFuturesMarketOrder(symbol, quantity, side, broker, accountNumber) {
|
|
5348
|
+
if (!this.userToken) {
|
|
5349
|
+
throw new Error('Not initialized with user');
|
|
5350
|
+
}
|
|
5351
|
+
try {
|
|
5352
|
+
return await this.apiClient.placeFuturesMarketOrder(symbol, quantity, side === 'buy' ? 'Buy' : 'Sell', broker, accountNumber);
|
|
5353
|
+
}
|
|
5354
|
+
catch (error) {
|
|
5355
|
+
this.emit('error', error);
|
|
5356
|
+
throw error;
|
|
5357
|
+
}
|
|
5358
|
+
}
|
|
5359
|
+
/**
|
|
5360
|
+
* Place a futures limit order (convenience method)
|
|
5361
|
+
*/
|
|
5362
|
+
async placeFuturesLimitOrder(symbol, quantity, side, price, timeInForce = 'gtc', broker, accountNumber) {
|
|
5363
|
+
if (!this.userToken) {
|
|
5364
|
+
throw new Error('Not initialized with user');
|
|
5365
|
+
}
|
|
5366
|
+
try {
|
|
5367
|
+
return await this.apiClient.placeFuturesLimitOrder(symbol, quantity, side === 'buy' ? 'Buy' : 'Sell', price, timeInForce, broker, accountNumber);
|
|
5368
|
+
}
|
|
5369
|
+
catch (error) {
|
|
5370
|
+
this.emit('error', error);
|
|
5371
|
+
throw error;
|
|
5372
|
+
}
|
|
5373
|
+
}
|
|
5374
|
+
/**
|
|
5375
|
+
* Set the broker context for trading operations
|
|
5376
|
+
* @param broker - The broker to set as context
|
|
5377
|
+
*/
|
|
5378
|
+
setBroker(broker) {
|
|
5379
|
+
this.apiClient.setBroker(broker);
|
|
5380
|
+
}
|
|
5381
|
+
/**
|
|
5382
|
+
* Set the account context for trading operations
|
|
5383
|
+
* @param accountNumber - The account number to set as context
|
|
5384
|
+
*/
|
|
5385
|
+
setAccount(accountNumber) {
|
|
5386
|
+
this.apiClient.setAccount(accountNumber);
|
|
5387
|
+
}
|
|
5388
|
+
/**
|
|
5389
|
+
* Get the current trading context
|
|
5390
|
+
* @returns Object with current broker and account context
|
|
5391
|
+
*/
|
|
5392
|
+
getTradingContext() {
|
|
5393
|
+
return this.apiClient.getTradingContext();
|
|
5394
|
+
}
|
|
5395
|
+
/**
|
|
5396
|
+
* Clear the trading context
|
|
5397
|
+
*/
|
|
5398
|
+
clearTradingContext() {
|
|
5399
|
+
this.apiClient.clearTradingContext();
|
|
5400
|
+
}
|
|
4446
5401
|
/**
|
|
4447
5402
|
* Get the current user ID
|
|
4448
5403
|
* @returns The current user ID or undefined if not authenticated
|
|
@@ -4592,6 +5547,12 @@ class FinaticConnect extends EventEmitter {
|
|
|
4592
5547
|
}
|
|
4593
5548
|
return this.apiClient.getBrokerAccountsPage(page, perPage, filter);
|
|
4594
5549
|
}
|
|
5550
|
+
async getBalancesPage(page = 1, perPage = 100, filter) {
|
|
5551
|
+
if (!this.isAuthed()) {
|
|
5552
|
+
throw new AuthenticationError('User is not authenticated');
|
|
5553
|
+
}
|
|
5554
|
+
return this.apiClient.getBrokerBalancesPage(page, perPage, filter);
|
|
5555
|
+
}
|
|
4595
5556
|
/**
|
|
4596
5557
|
* Get the next page of orders
|
|
4597
5558
|
* @param previousResult - The previous paginated result
|
|
@@ -4634,6 +5595,15 @@ class FinaticConnect extends EventEmitter {
|
|
|
4634
5595
|
return this.apiClient.getBrokerAccountsPage(page, limit);
|
|
4635
5596
|
});
|
|
4636
5597
|
}
|
|
5598
|
+
async getNextBalancesPage(previousResult) {
|
|
5599
|
+
if (!this.isAuthed()) {
|
|
5600
|
+
throw new AuthenticationError('User is not authenticated');
|
|
5601
|
+
}
|
|
5602
|
+
return this.apiClient.getNextPage(previousResult, (offset, limit) => {
|
|
5603
|
+
const page = Math.floor(offset / limit) + 1;
|
|
5604
|
+
return this.apiClient.getBrokerBalancesPage(page, limit);
|
|
5605
|
+
});
|
|
5606
|
+
}
|
|
4637
5607
|
/**
|
|
4638
5608
|
* Get all orders across all pages (convenience method)
|
|
4639
5609
|
* @param filter - Optional filter parameters
|
|
@@ -4700,6 +5670,23 @@ class FinaticConnect extends EventEmitter {
|
|
|
4700
5670
|
}
|
|
4701
5671
|
return allData;
|
|
4702
5672
|
}
|
|
5673
|
+
async getAllBalances(filter) {
|
|
5674
|
+
if (!this.isAuthed()) {
|
|
5675
|
+
throw new AuthenticationError('User is not authenticated');
|
|
5676
|
+
}
|
|
5677
|
+
const allData = [];
|
|
5678
|
+
let currentResult = await this.getBalancesPage(1, 100, filter);
|
|
5679
|
+
while (currentResult) {
|
|
5680
|
+
allData.push(...currentResult.data);
|
|
5681
|
+
if (!currentResult.hasNext)
|
|
5682
|
+
break;
|
|
5683
|
+
const nextResult = await this.getNextBalancesPage(currentResult);
|
|
5684
|
+
if (!nextResult)
|
|
5685
|
+
break;
|
|
5686
|
+
currentResult = nextResult;
|
|
5687
|
+
}
|
|
5688
|
+
return allData;
|
|
5689
|
+
}
|
|
4703
5690
|
/**
|
|
4704
5691
|
* Register session management (but don't auto-cleanup for 24-hour sessions)
|
|
4705
5692
|
*/
|
|
@@ -4749,20 +5736,9 @@ class FinaticConnect extends EventEmitter {
|
|
|
4749
5736
|
await this.refreshSessionAutomatically();
|
|
4750
5737
|
return;
|
|
4751
5738
|
}
|
|
4752
|
-
//
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
});
|
|
4756
|
-
const validationPromise = this.apiClient.validatePortalSession(this.sessionId, '');
|
|
4757
|
-
const response = await Promise.race([validationPromise, timeoutPromise]);
|
|
4758
|
-
if (response && response.status === 'active') {
|
|
4759
|
-
console.log('[FinaticConnect] Session keep-alive successful');
|
|
4760
|
-
this.currentSessionState = 'active';
|
|
4761
|
-
}
|
|
4762
|
-
else {
|
|
4763
|
-
console.warn('[FinaticConnect] Session keep-alive failed - session not active');
|
|
4764
|
-
this.currentSessionState = response?.status || 'unknown';
|
|
4765
|
-
}
|
|
5739
|
+
// Session keep-alive - assume session is active if we have a session ID
|
|
5740
|
+
console.log('[FinaticConnect] Session keep-alive successful');
|
|
5741
|
+
this.currentSessionState = 'active';
|
|
4766
5742
|
}
|
|
4767
5743
|
catch (error) {
|
|
4768
5744
|
console.warn('[FinaticConnect] Session keep-alive error:', error);
|
|
@@ -4891,6 +5867,24 @@ class FinaticConnect extends EventEmitter {
|
|
|
4891
5867
|
}
|
|
4892
5868
|
return this.apiClient.disconnectCompany(connectionId);
|
|
4893
5869
|
}
|
|
5870
|
+
/**
|
|
5871
|
+
* Get account balances for the authenticated user
|
|
5872
|
+
* @param filters - Optional filters for balances
|
|
5873
|
+
* @returns Promise with balance data
|
|
5874
|
+
*/
|
|
5875
|
+
async getBalances(filters) {
|
|
5876
|
+
if (!this.isAuthed()) {
|
|
5877
|
+
throw new AuthenticationError('User is not authenticated');
|
|
5878
|
+
}
|
|
5879
|
+
try {
|
|
5880
|
+
const response = await this.apiClient.getBalances(filters);
|
|
5881
|
+
return response.response_data || [];
|
|
5882
|
+
}
|
|
5883
|
+
catch (error) {
|
|
5884
|
+
this.emit('error', error);
|
|
5885
|
+
throw error;
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
4894
5888
|
}
|
|
4895
5889
|
FinaticConnect.instance = null;
|
|
4896
5890
|
|
|
@@ -4911,6 +5905,7 @@ exports.RateLimitError = RateLimitError;
|
|
|
4911
5905
|
exports.SecurityError = SecurityError;
|
|
4912
5906
|
exports.SessionError = SessionError;
|
|
4913
5907
|
exports.TokenError = TokenError;
|
|
5908
|
+
exports.TradingNotEnabledError = TradingNotEnabledError;
|
|
4914
5909
|
exports.ValidationError = ValidationError;
|
|
4915
5910
|
exports.appendThemeToURL = appendThemeToURL;
|
|
4916
5911
|
exports.createCustomThemeFromPreset = createCustomThemeFromPreset;
|