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