@finatic/client 0.0.131
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 +489 -0
- package/dist/index.d.ts +2037 -0
- package/dist/index.js +4815 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4787 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types/client/ApiClient.d.ts +234 -0
- package/dist/types/client/FinaticConnect.d.ts +307 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/mocks/MockApiClient.d.ts +228 -0
- package/dist/types/mocks/MockDataProvider.d.ts +132 -0
- package/dist/types/mocks/MockFactory.d.ts +53 -0
- package/dist/types/mocks/index.d.ts +5 -0
- package/dist/types/mocks/utils.d.ts +29 -0
- package/dist/types/portal/PortalUI.d.ts +38 -0
- package/dist/types/security/ApiSecurity.d.ts +24 -0
- package/dist/types/security/RuntimeSecurity.d.ts +28 -0
- package/dist/types/security/SecurityUtils.d.ts +21 -0
- package/dist/types/security/index.d.ts +2 -0
- package/dist/types/services/AnalyticsService.d.ts +18 -0
- package/dist/types/services/ApiClient.d.ts +121 -0
- package/dist/types/services/PortalService.d.ts +24 -0
- package/dist/types/services/TradingService.d.ts +55 -0
- package/dist/types/services/api.d.ts +23 -0
- package/dist/types/services/auth.d.ts +9 -0
- package/dist/types/services/index.d.ts +4 -0
- package/dist/types/services/portfolio.d.ts +10 -0
- package/dist/types/services/trading.d.ts +10 -0
- package/dist/types/shared/index.d.ts +2 -0
- package/dist/types/shared/themes/index.d.ts +2 -0
- package/dist/types/shared/themes/portalPresets.d.ts +8 -0
- package/dist/types/shared/themes/presets.d.ts +3 -0
- package/dist/types/shared/themes/system.d.ts +2 -0
- package/dist/types/shared/types/index.d.ts +110 -0
- package/dist/types/types/api.d.ts +486 -0
- package/dist/types/types/config.d.ts +12 -0
- package/dist/types/types/connect.d.ts +51 -0
- package/dist/types/types/errors.d.ts +47 -0
- package/dist/types/types/portal.d.ts +75 -0
- package/dist/types/types/security.d.ts +35 -0
- package/dist/types/types/shared.d.ts +50 -0
- package/dist/types/types/theme.d.ts +101 -0
- package/dist/types/types.d.ts +157 -0
- package/dist/types/utils/errors.d.ts +42 -0
- package/dist/types/utils/events.d.ts +12 -0
- package/dist/types/utils/themeUtils.d.ts +34 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
# Finatic Client SDK
|
|
2
|
+
|
|
3
|
+
A comprehensive browser SDK for integrating Finatic Client into your web applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @finatic/client
|
|
9
|
+
# or
|
|
10
|
+
yarn add @finatic/client
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
### Simple Initialization
|
|
16
|
+
```typescript
|
|
17
|
+
import { FinaticConnect } from '@finatic/client';
|
|
18
|
+
|
|
19
|
+
// Just pass the token - everything else uses defaults
|
|
20
|
+
const finatic = await FinaticConnect.init('your-one-time-token');
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### With User ID (for returning users)
|
|
24
|
+
```typescript
|
|
25
|
+
// Pass token and user ID from previous session
|
|
26
|
+
const finatic = await FinaticConnect.init('your-one-time-token', 'user-123');
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### With Custom Configuration
|
|
30
|
+
```typescript
|
|
31
|
+
// Pass token, user ID, and custom API URL
|
|
32
|
+
const finatic = await FinaticConnect.init('your-one-time-token', 'user-123', {
|
|
33
|
+
baseUrl: 'https://api.finatic.dev'
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
// Open the portal
|
|
38
|
+
await finatic.openPortal({
|
|
39
|
+
onSuccess: (userId) => {
|
|
40
|
+
console.log('Authentication successful:', userId);
|
|
41
|
+
},
|
|
42
|
+
onError: (error) => {
|
|
43
|
+
console.error('Authentication failed:', error);
|
|
44
|
+
},
|
|
45
|
+
onClose: () => {
|
|
46
|
+
console.log('Portal closed');
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// After successful authentication, you can use these methods:
|
|
51
|
+
|
|
52
|
+
// Get list of supported brokers
|
|
53
|
+
const brokers = await finatic.getBrokerList();
|
|
54
|
+
|
|
55
|
+
// Get broker accounts with pagination
|
|
56
|
+
const accountsPage = await finatic.getAccounts({
|
|
57
|
+
page: 1,
|
|
58
|
+
perPage: 100
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Navigate through pages
|
|
62
|
+
const nextPage = await accountsPage.nextPage();
|
|
63
|
+
const prevPage = await accountsPage.previousPage();
|
|
64
|
+
|
|
65
|
+
// Get all accounts (convenience method)
|
|
66
|
+
const allAccounts = await finatic.getAllAccounts();
|
|
67
|
+
|
|
68
|
+
// Get orders with filtering
|
|
69
|
+
const ordersPage = await finatic.getOrders({
|
|
70
|
+
page: 1,
|
|
71
|
+
perPage: 50,
|
|
72
|
+
filter: { status: 'filled', symbol: 'AAPL' }
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Get positions
|
|
76
|
+
const positionsPage = await finatic.getPositions({
|
|
77
|
+
page: 1,
|
|
78
|
+
perPage: 100
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Place orders
|
|
82
|
+
await finatic.placeOrder({
|
|
83
|
+
symbol: 'AAPL',
|
|
84
|
+
side: 'buy',
|
|
85
|
+
quantity: 10,
|
|
86
|
+
type: 'market',
|
|
87
|
+
timeInForce: 'day'
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Close the portal when done
|
|
91
|
+
finatic.closePortal();
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## API Reference
|
|
95
|
+
|
|
96
|
+
### Initialization
|
|
97
|
+
|
|
98
|
+
#### `FinaticConnect.init(token, userId?, options?)`
|
|
99
|
+
|
|
100
|
+
Initialize the Finatic Client SDK.
|
|
101
|
+
|
|
102
|
+
- `token` (string): One-time token from your backend
|
|
103
|
+
- `userId` (string, optional): Pre-authenticated user ID from previous session
|
|
104
|
+
- `options` (object, optional): Configuration options
|
|
105
|
+
- `baseUrl` (string, optional): Custom API base URL
|
|
106
|
+
|
|
107
|
+
Returns: Promise<FinaticConnect>
|
|
108
|
+
|
|
109
|
+
### Portal Management
|
|
110
|
+
|
|
111
|
+
#### `openPortal(options?)`
|
|
112
|
+
|
|
113
|
+
Opens the authentication portal in an iframe.
|
|
114
|
+
|
|
115
|
+
- `options` (object, optional): Portal options
|
|
116
|
+
- `onSuccess` (function): Called when authentication succeeds
|
|
117
|
+
- `onError` (function): Called when authentication fails
|
|
118
|
+
- `onClose` (function): Called when portal is closed
|
|
119
|
+
- `onEvent` (function): Called when portal events occur
|
|
120
|
+
- `theme` (object, optional): Theme configuration
|
|
121
|
+
- `preset` (string, optional): Preset theme name ('dark', 'light', 'corporateBlue', 'purple', 'green', 'orange')
|
|
122
|
+
- `custom` (object, optional): Custom theme configuration object
|
|
123
|
+
|
|
124
|
+
#### `closePortal()`
|
|
125
|
+
|
|
126
|
+
Closes the authentication portal.
|
|
127
|
+
|
|
128
|
+
### Portal Theming
|
|
129
|
+
|
|
130
|
+
The Finatic Portal supports dynamic theme switching via URL parameters. You can customize the portal's appearance to match your application's branding.
|
|
131
|
+
|
|
132
|
+
#### Using Preset Themes
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
// Use a preset theme
|
|
136
|
+
await finatic.openPortal({
|
|
137
|
+
theme: { preset: 'corporateBlue' }
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Available presets: 'dark', 'light', 'corporateBlue', 'purple', 'green', 'orange'
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Using Custom Themes
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
// Use a custom theme
|
|
147
|
+
const customTheme = {
|
|
148
|
+
mode: 'dark',
|
|
149
|
+
colors: {
|
|
150
|
+
background: {
|
|
151
|
+
primary: '#1a1a1a',
|
|
152
|
+
secondary: '#2a2a2a',
|
|
153
|
+
tertiary: '#3a3a3a',
|
|
154
|
+
accent: 'rgba(59, 130, 246, 0.1)',
|
|
155
|
+
glass: 'rgba(255, 255, 255, 0.05)'
|
|
156
|
+
},
|
|
157
|
+
status: {
|
|
158
|
+
connected: '#10B981',
|
|
159
|
+
disconnected: '#EF4444',
|
|
160
|
+
warning: '#F59E0B',
|
|
161
|
+
pending: '#8B5CF6',
|
|
162
|
+
error: '#EF4444',
|
|
163
|
+
success: '#10B981'
|
|
164
|
+
},
|
|
165
|
+
text: {
|
|
166
|
+
primary: '#F8FAFC',
|
|
167
|
+
secondary: '#CBD5E1',
|
|
168
|
+
muted: '#94A3B8',
|
|
169
|
+
inverse: '#1a1a1a'
|
|
170
|
+
},
|
|
171
|
+
border: {
|
|
172
|
+
primary: 'rgba(59, 130, 246, 0.2)',
|
|
173
|
+
secondary: 'rgba(255, 255, 255, 0.1)',
|
|
174
|
+
hover: 'rgba(59, 130, 246, 0.4)',
|
|
175
|
+
focus: 'rgba(59, 130, 246, 0.6)',
|
|
176
|
+
accent: '#3B82F6'
|
|
177
|
+
},
|
|
178
|
+
input: {
|
|
179
|
+
background: '#334155',
|
|
180
|
+
border: 'rgba(59, 130, 246, 0.2)',
|
|
181
|
+
borderFocus: '#3B82F6',
|
|
182
|
+
text: '#F8FAFC',
|
|
183
|
+
placeholder: '#94A3B8'
|
|
184
|
+
},
|
|
185
|
+
button: {
|
|
186
|
+
primary: {
|
|
187
|
+
background: '#3B82F6',
|
|
188
|
+
text: '#FFFFFF',
|
|
189
|
+
hover: '#2563EB',
|
|
190
|
+
active: '#1D4ED8'
|
|
191
|
+
},
|
|
192
|
+
secondary: {
|
|
193
|
+
background: 'transparent',
|
|
194
|
+
text: '#3B82F6',
|
|
195
|
+
border: '#3B82F6',
|
|
196
|
+
hover: 'rgba(59, 130, 246, 0.1)',
|
|
197
|
+
active: 'rgba(59, 130, 246, 0.2)'
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
branding: {
|
|
202
|
+
primaryColor: '#3B82F6'
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
await finatic.openPortal({
|
|
207
|
+
theme: { custom: customTheme }
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### Theme Utilities
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
import {
|
|
215
|
+
generatePortalThemeURL,
|
|
216
|
+
appendThemeToURL,
|
|
217
|
+
getThemePreset,
|
|
218
|
+
validateCustomTheme,
|
|
219
|
+
createCustomThemeFromPreset,
|
|
220
|
+
portalThemePresets
|
|
221
|
+
} from 'finatic-sdk';
|
|
222
|
+
|
|
223
|
+
// Generate a themed portal URL
|
|
224
|
+
const themedUrl = generatePortalThemeURL('http://localhost:5173/companies', { preset: 'corporateBlue' });
|
|
225
|
+
|
|
226
|
+
// Get a theme preset
|
|
227
|
+
const darkTheme = getThemePreset('dark');
|
|
228
|
+
|
|
229
|
+
// Validate a custom theme
|
|
230
|
+
const isValid = validateCustomTheme(customTheme);
|
|
231
|
+
|
|
232
|
+
// Create a custom theme from a preset
|
|
233
|
+
const modifiedTheme = createCustomThemeFromPreset('dark', {
|
|
234
|
+
colors: {
|
|
235
|
+
background: {
|
|
236
|
+
primary: '#000000'
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Data Access (Paginated)
|
|
243
|
+
|
|
244
|
+
#### `getAccounts(params?)`
|
|
245
|
+
|
|
246
|
+
Returns paginated broker accounts.
|
|
247
|
+
|
|
248
|
+
- `params` (object, optional): Query parameters
|
|
249
|
+
- `page` (number, optional): Page number (default: 1)
|
|
250
|
+
- `perPage` (number, optional): Items per page (default: 100)
|
|
251
|
+
- `filter` (object, optional): Filter parameters
|
|
252
|
+
|
|
253
|
+
Returns: Promise<PaginatedResult<BrokerDataAccount[]>>
|
|
254
|
+
|
|
255
|
+
#### `getOrders(params?)`
|
|
256
|
+
|
|
257
|
+
Returns paginated order history.
|
|
258
|
+
|
|
259
|
+
- `params` (object, optional): Query parameters
|
|
260
|
+
- `page` (number, optional): Page number (default: 1)
|
|
261
|
+
- `perPage` (number, optional): Items per page (default: 100)
|
|
262
|
+
- `filter` (object, optional): Filter parameters
|
|
263
|
+
|
|
264
|
+
Returns: Promise<PaginatedResult<BrokerDataOrder[]>>
|
|
265
|
+
|
|
266
|
+
#### `getPositions(params?)`
|
|
267
|
+
|
|
268
|
+
Returns paginated positions.
|
|
269
|
+
|
|
270
|
+
- `params` (object, optional): Query parameters
|
|
271
|
+
- `page` (number, optional): Page number (default: 1)
|
|
272
|
+
- `perPage` (number, optional): Items per page (default: 100)
|
|
273
|
+
- `filter` (object, optional): Filter parameters
|
|
274
|
+
|
|
275
|
+
Returns: Promise<PaginatedResult<BrokerDataPosition[]>>
|
|
276
|
+
|
|
277
|
+
### Data Access (Get All - Convenience Methods)
|
|
278
|
+
|
|
279
|
+
#### `getAllAccounts(filter?)`
|
|
280
|
+
|
|
281
|
+
Returns all broker accounts across all pages.
|
|
282
|
+
|
|
283
|
+
- `filter` (object, optional): Filter parameters
|
|
284
|
+
|
|
285
|
+
Returns: Promise<BrokerDataAccount[]>
|
|
286
|
+
|
|
287
|
+
#### `getAllOrders(filter?)`
|
|
288
|
+
|
|
289
|
+
Returns all orders across all pages.
|
|
290
|
+
|
|
291
|
+
- `filter` (object, optional): Filter parameters
|
|
292
|
+
|
|
293
|
+
Returns: Promise<BrokerDataOrder[]>
|
|
294
|
+
|
|
295
|
+
#### `getAllPositions(filter?)`
|
|
296
|
+
|
|
297
|
+
Returns all positions across all pages.
|
|
298
|
+
|
|
299
|
+
- `filter` (object, optional): Filter parameters
|
|
300
|
+
|
|
301
|
+
Returns: Promise<BrokerDataPosition[]>
|
|
302
|
+
|
|
303
|
+
### Convenience Methods
|
|
304
|
+
|
|
305
|
+
#### `getOpenPositions()`
|
|
306
|
+
|
|
307
|
+
Returns only open positions.
|
|
308
|
+
|
|
309
|
+
Returns: Promise<BrokerDataPosition[]>
|
|
310
|
+
|
|
311
|
+
#### `getFilledOrders()`
|
|
312
|
+
|
|
313
|
+
Returns only filled orders.
|
|
314
|
+
|
|
315
|
+
Returns: Promise<BrokerDataOrder[]>
|
|
316
|
+
|
|
317
|
+
#### `getPendingOrders()`
|
|
318
|
+
|
|
319
|
+
Returns only pending orders.
|
|
320
|
+
|
|
321
|
+
Returns: Promise<BrokerDataOrder[]>
|
|
322
|
+
|
|
323
|
+
#### `getActiveAccounts()`
|
|
324
|
+
|
|
325
|
+
Returns only active accounts.
|
|
326
|
+
|
|
327
|
+
Returns: Promise<BrokerDataAccount[]>
|
|
328
|
+
|
|
329
|
+
#### `getOrdersBySymbol(symbol)`
|
|
330
|
+
|
|
331
|
+
Returns orders for a specific symbol.
|
|
332
|
+
|
|
333
|
+
- `symbol` (string): Stock symbol
|
|
334
|
+
|
|
335
|
+
Returns: Promise<BrokerDataOrder[]>
|
|
336
|
+
|
|
337
|
+
#### `getPositionsBySymbol(symbol)`
|
|
338
|
+
|
|
339
|
+
Returns positions for a specific symbol.
|
|
340
|
+
|
|
341
|
+
- `symbol` (string): Stock symbol
|
|
342
|
+
|
|
343
|
+
Returns: Promise<BrokerDataPosition[]>
|
|
344
|
+
|
|
345
|
+
#### `getOrdersByBroker(brokerId)`
|
|
346
|
+
|
|
347
|
+
Returns orders for a specific broker.
|
|
348
|
+
|
|
349
|
+
- `brokerId` (string): Broker ID
|
|
350
|
+
|
|
351
|
+
Returns: Promise<BrokerDataOrder[]>
|
|
352
|
+
|
|
353
|
+
#### `getPositionsByBroker(brokerId)`
|
|
354
|
+
|
|
355
|
+
Returns positions for a specific broker.
|
|
356
|
+
|
|
357
|
+
- `brokerId` (string): Broker ID
|
|
358
|
+
|
|
359
|
+
Returns: Promise<BrokerDataPosition[]>
|
|
360
|
+
|
|
361
|
+
### Broker Information
|
|
362
|
+
|
|
363
|
+
#### `getBrokerList()`
|
|
364
|
+
|
|
365
|
+
Returns a list of supported brokers.
|
|
366
|
+
|
|
367
|
+
Returns: Promise<BrokerInfo[]>
|
|
368
|
+
|
|
369
|
+
#### `getBrokerConnections()`
|
|
370
|
+
|
|
371
|
+
Returns broker connections for the authenticated user.
|
|
372
|
+
|
|
373
|
+
Returns: Promise<BrokerConnection[]>
|
|
374
|
+
|
|
375
|
+
### Trading
|
|
376
|
+
|
|
377
|
+
#### `placeOrder(order)`
|
|
378
|
+
|
|
379
|
+
Places a new order.
|
|
380
|
+
|
|
381
|
+
- `order` (object): Order details
|
|
382
|
+
- `symbol` (string): Stock symbol
|
|
383
|
+
- `side` (string): 'buy' or 'sell'
|
|
384
|
+
- `quantity` (number): Number of shares
|
|
385
|
+
- `type` (string): 'market', 'limit', 'stop', or 'stop_limit'
|
|
386
|
+
- `timeInForce` (string): 'day', 'gtc', 'opg', 'cls', 'ioc', or 'fok'
|
|
387
|
+
- `price` (number, optional): Limit price
|
|
388
|
+
- `stopPrice` (number, optional): Stop price
|
|
389
|
+
|
|
390
|
+
#### `cancelOrder(orderId, broker?)`
|
|
391
|
+
|
|
392
|
+
Cancels an existing order.
|
|
393
|
+
|
|
394
|
+
- `orderId` (string): Order ID to cancel
|
|
395
|
+
- `broker` (string, optional): Broker name
|
|
396
|
+
|
|
397
|
+
#### `modifyOrder(orderId, modifications, broker?)`
|
|
398
|
+
|
|
399
|
+
Modifies an existing order.
|
|
400
|
+
|
|
401
|
+
- `orderId` (string): Order ID to modify
|
|
402
|
+
- `modifications` (object): Order modifications
|
|
403
|
+
- `broker` (string, optional): Broker name
|
|
404
|
+
|
|
405
|
+
### Authentication
|
|
406
|
+
|
|
407
|
+
#### `isAuthenticated()`
|
|
408
|
+
|
|
409
|
+
Returns true if the user is authenticated.
|
|
410
|
+
|
|
411
|
+
#### `isAuthed()`
|
|
412
|
+
|
|
413
|
+
Returns true if the user is fully authenticated (has userId, access token, and refresh token).
|
|
414
|
+
|
|
415
|
+
#### `getUserId()`
|
|
416
|
+
|
|
417
|
+
Returns the current user ID, or `null` if not authenticated.
|
|
418
|
+
|
|
419
|
+
#### `revokeToken()`
|
|
420
|
+
|
|
421
|
+
Revokes the current access token.
|
|
422
|
+
|
|
423
|
+
### Pagination Navigation
|
|
424
|
+
|
|
425
|
+
The `PaginatedResult` object returned by paginated methods includes navigation methods:
|
|
426
|
+
|
|
427
|
+
#### `nextPage()`
|
|
428
|
+
|
|
429
|
+
Returns the next page of results.
|
|
430
|
+
|
|
431
|
+
Returns: Promise<PaginatedResult<T> | null>
|
|
432
|
+
|
|
433
|
+
#### `previousPage()`
|
|
434
|
+
|
|
435
|
+
Returns the previous page of results.
|
|
436
|
+
|
|
437
|
+
Returns: Promise<PaginatedResult<T> | null>
|
|
438
|
+
|
|
439
|
+
#### `firstPage()`
|
|
440
|
+
|
|
441
|
+
Returns the first page of results.
|
|
442
|
+
|
|
443
|
+
Returns: Promise<PaginatedResult<T>>
|
|
444
|
+
|
|
445
|
+
#### `goToPage(pageNumber)`
|
|
446
|
+
|
|
447
|
+
Goes to a specific page.
|
|
448
|
+
|
|
449
|
+
- `pageNumber` (number): Page number to navigate to
|
|
450
|
+
|
|
451
|
+
Returns: Promise<PaginatedResult<T> | null>
|
|
452
|
+
|
|
453
|
+
## Error Handling
|
|
454
|
+
|
|
455
|
+
The SDK throws specific error types for different scenarios:
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
import {
|
|
459
|
+
ApiError,
|
|
460
|
+
SessionError,
|
|
461
|
+
AuthenticationError,
|
|
462
|
+
AuthorizationError,
|
|
463
|
+
RateLimitError,
|
|
464
|
+
CompanyAccessError
|
|
465
|
+
} from '@finatic/client';
|
|
466
|
+
|
|
467
|
+
try {
|
|
468
|
+
await finatic.openPortal();
|
|
469
|
+
} catch (error) {
|
|
470
|
+
if (error instanceof CompanyAccessError) {
|
|
471
|
+
console.log('No broker connections found for this company');
|
|
472
|
+
} else if (error instanceof AuthenticationError) {
|
|
473
|
+
console.log('Authentication failed');
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
## Browser Support
|
|
479
|
+
|
|
480
|
+
This SDK is designed for modern browsers and requires:
|
|
481
|
+
|
|
482
|
+
- ES2020 support
|
|
483
|
+
- Fetch API
|
|
484
|
+
- Promise support
|
|
485
|
+
- LocalStorage (for token caching)
|
|
486
|
+
|
|
487
|
+
## License
|
|
488
|
+
|
|
489
|
+
MIT
|