@edge-markets/connect-node 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,314 @@
1
+ # @edgeboost/edge-connect-server
2
+
3
+ Server SDK for EDGE Connect token exchange and API calls.
4
+
5
+ ## Features
6
+
7
+ - 🔐 **Secure token exchange** - Exchange codes for tokens with PKCE
8
+ - 🔄 **Token refresh** - Automatic refresh token handling
9
+ - 📡 **Full API client** - User, balance, transfers
10
+ - 🛡️ **Typed errors** - Specific error classes for each scenario
11
+ - 📝 **TypeScript first** - Complete type definitions
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @edgeboost/edge-connect-server
17
+ # or
18
+ pnpm add @edgeboost/edge-connect-server
19
+ # or
20
+ yarn add @edgeboost/edge-connect-server
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```typescript
26
+ import { EdgeConnectServer } from '@edgeboost/edge-connect-server'
27
+
28
+ // Create instance once (reuse for all requests)
29
+ const edge = new EdgeConnectServer({
30
+ clientId: process.env.EDGE_CLIENT_ID!,
31
+ clientSecret: process.env.EDGE_CLIENT_SECRET!,
32
+ environment: 'staging',
33
+ })
34
+
35
+ // Exchange code from EdgeLink for tokens
36
+ const tokens = await edge.exchangeCode(code, codeVerifier)
37
+
38
+ // Make API calls
39
+ const user = await edge.getUser(tokens.accessToken)
40
+ const balance = await edge.getBalance(tokens.accessToken)
41
+ ```
42
+
43
+ ## ⚠️ Security
44
+
45
+ **This SDK requires your client secret. Use it ONLY on your backend server!**
46
+
47
+ Never expose your client secret to browsers or client-side code.
48
+
49
+ ## Configuration
50
+
51
+ ```typescript
52
+ interface EdgeConnectServerConfig {
53
+ clientId: string // Your OAuth client ID
54
+ clientSecret: string // Your OAuth client secret (keep secret!)
55
+ environment: EdgeEnvironment // 'production' | 'staging' | 'sandbox'
56
+
57
+ // Optional
58
+ apiBaseUrl?: string // Custom API URL (dev only)
59
+ authDomain?: string // Custom Cognito domain (dev only)
60
+ timeout?: number // Request timeout (default: 30000ms)
61
+ }
62
+ ```
63
+
64
+ ## Token Exchange
65
+
66
+ After EdgeLink completes, exchange the code for tokens:
67
+
68
+ ```typescript
69
+ // In your /api/edge/exchange endpoint
70
+ export async function POST(req: Request) {
71
+ const { code, codeVerifier } = await req.json()
72
+
73
+ try {
74
+ const tokens = await edge.exchangeCode(code, codeVerifier)
75
+
76
+ // Store tokens securely (encrypted in database)
77
+ await db.edgeConnections.upsert({
78
+ userId: req.user.id,
79
+ accessToken: encrypt(tokens.accessToken),
80
+ refreshToken: encrypt(tokens.refreshToken),
81
+ expiresAt: new Date(tokens.expiresAt),
82
+ })
83
+
84
+ return Response.json({ success: true })
85
+ } catch (error) {
86
+ if (error instanceof EdgeTokenExchangeError) {
87
+ // Code expired or already used
88
+ return Response.json({ error: 'Please try again' }, { status: 400 })
89
+ }
90
+ throw error
91
+ }
92
+ }
93
+ ```
94
+
95
+ ## Token Refresh
96
+
97
+ Refresh tokens before they expire:
98
+
99
+ ```typescript
100
+ async function getValidAccessToken(userId: string): Promise<string> {
101
+ const connection = await db.edgeConnections.get(userId)
102
+
103
+ // Refresh 5 minutes before expiry
104
+ const BUFFER = 5 * 60 * 1000
105
+
106
+ if (Date.now() > connection.expiresAt.getTime() - BUFFER) {
107
+ const newTokens = await edge.refreshTokens(
108
+ decrypt(connection.refreshToken)
109
+ )
110
+
111
+ await db.edgeConnections.update(userId, {
112
+ accessToken: encrypt(newTokens.accessToken),
113
+ refreshToken: encrypt(newTokens.refreshToken),
114
+ expiresAt: new Date(newTokens.expiresAt),
115
+ })
116
+
117
+ return newTokens.accessToken
118
+ }
119
+
120
+ return decrypt(connection.accessToken)
121
+ }
122
+ ```
123
+
124
+ ## API Methods
125
+
126
+ ### User & Balance
127
+
128
+ ```typescript
129
+ // Get user profile
130
+ const user = await edge.getUser(accessToken)
131
+ // Returns: { id, email, firstName, lastName, createdAt }
132
+
133
+ // Get balance
134
+ const balance = await edge.getBalance(accessToken)
135
+ // Returns: { userId, availableBalance, currency, asOf }
136
+ ```
137
+
138
+ ### Transfers
139
+
140
+ ```typescript
141
+ // Initiate transfer (requires OTP verification)
142
+ const transfer = await edge.initiateTransfer(accessToken, {
143
+ type: 'debit', // 'debit' = pull from user, 'credit' = push to user
144
+ amount: '100.00',
145
+ idempotencyKey: `txn_${userId}_${Date.now()}`,
146
+ })
147
+ // Returns: { transferId, status: 'pending_verification', otpMethod }
148
+
149
+ // Verify with OTP
150
+ const result = await edge.verifyTransfer(accessToken, transfer.transferId, userOtp)
151
+ // Returns: { transferId, status: 'completed' | 'failed' }
152
+
153
+ // Get transfer status
154
+ const status = await edge.getTransfer(accessToken, transferId)
155
+
156
+ // List transfers
157
+ const { transfers, total } = await edge.listTransfers(accessToken, {
158
+ status: 'completed',
159
+ limit: 10,
160
+ offset: 0,
161
+ })
162
+ ```
163
+
164
+ ### Consent
165
+
166
+ ```typescript
167
+ // Revoke consent (disconnect user)
168
+ await edge.revokeConsent(accessToken)
169
+
170
+ // Clean up stored tokens
171
+ await db.edgeConnections.delete(userId)
172
+ ```
173
+
174
+ ## Error Handling
175
+
176
+ ```typescript
177
+ import {
178
+ EdgeError,
179
+ EdgeAuthenticationError,
180
+ EdgeTokenExchangeError,
181
+ EdgeConsentRequiredError,
182
+ isEdgeError,
183
+ } from '@edgeboost/edge-connect-server'
184
+
185
+ try {
186
+ const balance = await edge.getBalance(accessToken)
187
+ } catch (error) {
188
+ if (error instanceof EdgeAuthenticationError) {
189
+ // Token expired - try refresh or reconnect
190
+ return { error: 'session_expired' }
191
+ }
192
+
193
+ if (error instanceof EdgeConsentRequiredError) {
194
+ // User revoked consent - need to reconnect
195
+ return { error: 'reconnect_required' }
196
+ }
197
+
198
+ if (isEdgeError(error)) {
199
+ // Some other SDK error
200
+ console.error(`Edge Error [${error.code}]: ${error.message}`)
201
+ return { error: error.code }
202
+ }
203
+
204
+ // Unknown error
205
+ throw error
206
+ }
207
+ ```
208
+
209
+ ### Error Types
210
+
211
+ | Error | When | What to do |
212
+ |-------|------|------------|
213
+ | `EdgeAuthenticationError` | Token invalid/expired | Refresh token or reconnect |
214
+ | `EdgeTokenExchangeError` | Code exchange failed | Ask user to try again |
215
+ | `EdgeConsentRequiredError` | User hasn't granted consent | Open EdgeLink |
216
+ | `EdgeInsufficientScopeError` | Missing required scopes | Request more scopes |
217
+ | `EdgeNotFoundError` | Resource not found | Check ID |
218
+ | `EdgeApiError` | Other API error | Check error.code |
219
+ | `EdgeNetworkError` | Network failure | Retry request |
220
+
221
+ ## NestJS Example
222
+
223
+ ```typescript
224
+ import { Injectable, Logger } from '@nestjs/common'
225
+ import { ConfigService } from '@nestjs/config'
226
+ import { EdgeConnectServer, EdgeConsentRequiredError } from '@edgeboost/edge-connect-server'
227
+
228
+ @Injectable()
229
+ export class EdgeService {
230
+ private readonly edge: EdgeConnectServer
231
+ private readonly logger = new Logger(EdgeService.name)
232
+
233
+ constructor(private config: ConfigService) {
234
+ this.edge = new EdgeConnectServer({
235
+ clientId: this.config.getOrThrow('EDGE_CLIENT_ID'),
236
+ clientSecret: this.config.getOrThrow('EDGE_CLIENT_SECRET'),
237
+ environment: this.config.get('EDGE_ENVIRONMENT', 'staging'),
238
+ })
239
+ }
240
+
241
+ async exchangeCode(code: string, codeVerifier: string) {
242
+ return this.edge.exchangeCode(code, codeVerifier)
243
+ }
244
+
245
+ async getBalance(accessToken: string) {
246
+ try {
247
+ return await this.edge.getBalance(accessToken)
248
+ } catch (error) {
249
+ if (error instanceof EdgeConsentRequiredError) {
250
+ this.logger.warn('User consent required')
251
+ throw error
252
+ }
253
+ this.logger.error('Failed to get balance', error)
254
+ throw error
255
+ }
256
+ }
257
+ }
258
+ ```
259
+
260
+ ## Express Example
261
+
262
+ ```typescript
263
+ import express from 'express'
264
+ import { EdgeConnectServer, isEdgeError } from '@edgeboost/edge-connect-server'
265
+
266
+ const edge = new EdgeConnectServer({
267
+ clientId: process.env.EDGE_CLIENT_ID!,
268
+ clientSecret: process.env.EDGE_CLIENT_SECRET!,
269
+ environment: 'staging',
270
+ })
271
+
272
+ const app = express()
273
+ app.use(express.json())
274
+
275
+ // Exchange code for tokens
276
+ app.post('/api/edge/exchange', async (req, res) => {
277
+ try {
278
+ const { code, codeVerifier } = req.body
279
+ const tokens = await edge.exchangeCode(code, codeVerifier)
280
+
281
+ // Store tokens for user...
282
+
283
+ res.json({ success: true })
284
+ } catch (error) {
285
+ if (isEdgeError(error)) {
286
+ res.status(400).json({ error: error.code, message: error.message })
287
+ } else {
288
+ res.status(500).json({ error: 'internal_error' })
289
+ }
290
+ }
291
+ })
292
+
293
+ // Get balance
294
+ app.get('/api/edge/balance', async (req, res) => {
295
+ try {
296
+ const accessToken = await getAccessTokenForUser(req.user.id)
297
+ const balance = await edge.getBalance(accessToken)
298
+ res.json(balance)
299
+ } catch (error) {
300
+ // Handle errors...
301
+ }
302
+ })
303
+ ```
304
+
305
+ ## Related Packages
306
+
307
+ - `@edgeboost/edge-connect-sdk` - Core types and utilities
308
+ - `@edgeboost/edge-connect-link` - Browser SDK for popup authentication
309
+
310
+ ## License
311
+
312
+ MIT
313
+
314
+
@@ -0,0 +1,387 @@
1
+ import { EdgeEnvironment, EdgeTokens, User, Balance, Transfer, ListTransfersParams, TransferList } from '@edge-markets/connect';
2
+ export { Balance, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, EdgeEnvironment, EdgeError, EdgeInsufficientScopeError, EdgeNetworkError, EdgeNotFoundError, EdgeTokenExchangeError, EdgeTokens, ListTransfersParams, Transfer, TransferList, TransferListItem, TransferStatus, TransferType, User, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isEdgeError, isNetworkError, isProductionEnvironment } from '@edge-markets/connect';
3
+
4
+ /**
5
+ * EdgeConnectServer - Server-Side SDK for EDGE Connect
6
+ *
7
+ * This SDK handles operations that require your client secret:
8
+ * - Exchanging authorization codes for tokens
9
+ * - Refreshing access tokens
10
+ * - Making authenticated API calls
11
+ *
12
+ * **Security:** This SDK should ONLY run on your backend server.
13
+ * Never expose your client secret to the browser.
14
+ *
15
+ * @module @edge-markets/connect-node
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { EdgeConnectServer } from '@edge-markets/connect-node'
20
+ *
21
+ * const edge = new EdgeConnectServer({
22
+ * clientId: process.env.EDGE_CLIENT_ID!,
23
+ * clientSecret: process.env.EDGE_CLIENT_SECRET!,
24
+ * environment: 'staging',
25
+ * })
26
+ *
27
+ * // Exchange code from EdgeLink for tokens
28
+ * const tokens = await edge.exchangeCode(code, codeVerifier)
29
+ *
30
+ * // Make API calls
31
+ * const user = await edge.getUser(tokens.accessToken)
32
+ * const balance = await edge.getBalance(tokens.accessToken)
33
+ * ```
34
+ */
35
+
36
+ /**
37
+ * Configuration for EdgeConnectServer.
38
+ *
39
+ * All fields except `environment` are required for production use.
40
+ */
41
+ interface EdgeConnectServerConfig {
42
+ /**
43
+ * Your OAuth client ID from the EdgeBoost partner portal.
44
+ */
45
+ clientId: string;
46
+ /**
47
+ * Your OAuth client secret.
48
+ * **Keep this secret!** Never expose in frontend code.
49
+ */
50
+ clientSecret: string;
51
+ /**
52
+ * Environment to connect to.
53
+ * - `'production'` - Live environment with real money
54
+ * - `'staging'` - Test environment for development
55
+ * - `'sandbox'` - Isolated mock environment (coming soon)
56
+ */
57
+ environment: EdgeEnvironment;
58
+ /**
59
+ * Custom API base URL (for local development).
60
+ * @default Derived from environment config
61
+ */
62
+ apiBaseUrl?: string;
63
+ /**
64
+ * Custom Cognito domain (for local development).
65
+ * @default Derived from environment config
66
+ */
67
+ authDomain?: string;
68
+ /**
69
+ * Request timeout in milliseconds.
70
+ * @default 30000 (30 seconds)
71
+ */
72
+ timeout?: number;
73
+ }
74
+ /**
75
+ * Options for initiating a transfer.
76
+ */
77
+ interface TransferOptions {
78
+ /**
79
+ * Type of transfer.
80
+ * - `'debit'` - Pull funds FROM user's EdgeBoost TO partner
81
+ * - `'credit'` - Push funds FROM partner TO user's EdgeBoost
82
+ */
83
+ type: 'debit' | 'credit';
84
+ /**
85
+ * Amount in USD as a string (preserves precision).
86
+ * @example '100.00'
87
+ */
88
+ amount: string;
89
+ /**
90
+ * Unique key to prevent duplicate transfers.
91
+ * If a transfer with this key exists, its current status is returned.
92
+ *
93
+ * @example `txn_${userId}_${Date.now()}`
94
+ */
95
+ idempotencyKey: string;
96
+ }
97
+ /**
98
+ * Server-side SDK for EDGE Connect.
99
+ *
100
+ * Handles token exchange and API calls that require your client secret.
101
+ * Create one instance and reuse it for all requests.
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * // Create instance (do once, e.g., in module scope)
106
+ * const edge = new EdgeConnectServer({
107
+ * clientId: process.env.EDGE_CLIENT_ID!,
108
+ * clientSecret: process.env.EDGE_CLIENT_SECRET!,
109
+ * environment: 'staging',
110
+ * })
111
+ *
112
+ * // In your API route handler
113
+ * export async function POST(req: Request) {
114
+ * const { code, codeVerifier } = await req.json()
115
+ *
116
+ * // Exchange code for tokens
117
+ * const tokens = await edge.exchangeCode(code, codeVerifier)
118
+ *
119
+ * // Store tokens securely (e.g., encrypted in database)
120
+ * await saveTokens(userId, tokens)
121
+ *
122
+ * return Response.json({ success: true })
123
+ * }
124
+ * ```
125
+ */
126
+ declare class EdgeConnectServer {
127
+ private readonly config;
128
+ private readonly apiBaseUrl;
129
+ private readonly oauthBaseUrl;
130
+ private readonly timeout;
131
+ /**
132
+ * Creates a new EdgeConnectServer instance.
133
+ *
134
+ * @param config - Server configuration
135
+ * @throws Error if required config is missing
136
+ */
137
+ constructor(config: EdgeConnectServerConfig);
138
+ /**
139
+ * Exchanges an authorization code for tokens.
140
+ *
141
+ * Call this after receiving the code from EdgeLink's `onSuccess` callback.
142
+ * The code is single-use and expires in ~10 minutes.
143
+ *
144
+ * @param code - Authorization code from EdgeLink
145
+ * @param codeVerifier - PKCE code verifier from EdgeLink
146
+ * @returns Access token, refresh token, and metadata
147
+ * @throws EdgeTokenExchangeError if exchange fails
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * // In your /api/edge/exchange endpoint
152
+ * const { code, codeVerifier } = req.body
153
+ *
154
+ * try {
155
+ * const tokens = await edge.exchangeCode(code, codeVerifier)
156
+ *
157
+ * // Store tokens securely
158
+ * await db.edgeConnections.upsert({
159
+ * userId: req.user.id,
160
+ * accessToken: encrypt(tokens.accessToken),
161
+ * refreshToken: encrypt(tokens.refreshToken),
162
+ * expiresAt: new Date(tokens.expiresAt),
163
+ * })
164
+ *
165
+ * return { success: true }
166
+ * } catch (error) {
167
+ * if (error instanceof EdgeTokenExchangeError) {
168
+ * // Code expired or already used
169
+ * return { error: 'Please try connecting again' }
170
+ * }
171
+ * throw error
172
+ * }
173
+ * ```
174
+ */
175
+ exchangeCode(code: string, codeVerifier: string): Promise<EdgeTokens>;
176
+ /**
177
+ * Refreshes an access token using a refresh token.
178
+ *
179
+ * Call this when the access token is expired or about to expire.
180
+ * Check `tokens.expiresAt` to know when to refresh.
181
+ *
182
+ * @param refreshToken - Refresh token from previous exchange
183
+ * @returns New tokens (refresh token may or may not change)
184
+ * @throws EdgeAuthenticationError if refresh fails
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * // Check if token needs refresh (with 5 minute buffer)
189
+ * const BUFFER_MS = 5 * 60 * 1000
190
+ *
191
+ * async function getValidAccessToken(userId: string): Promise<string> {
192
+ * const connection = await db.edgeConnections.get(userId)
193
+ *
194
+ * if (Date.now() > connection.expiresAt.getTime() - BUFFER_MS) {
195
+ * // Token expired or expiring soon - refresh it
196
+ * const newTokens = await edge.refreshTokens(decrypt(connection.refreshToken))
197
+ *
198
+ * // Update stored tokens
199
+ * await db.edgeConnections.update(userId, {
200
+ * accessToken: encrypt(newTokens.accessToken),
201
+ * refreshToken: encrypt(newTokens.refreshToken),
202
+ * expiresAt: new Date(newTokens.expiresAt),
203
+ * })
204
+ *
205
+ * return newTokens.accessToken
206
+ * }
207
+ *
208
+ * return decrypt(connection.accessToken)
209
+ * }
210
+ * ```
211
+ */
212
+ refreshTokens(refreshToken: string): Promise<EdgeTokens>;
213
+ /**
214
+ * Gets the connected user's profile.
215
+ *
216
+ * Requires scope: `user.read`
217
+ *
218
+ * @param accessToken - Valid access token
219
+ * @returns User profile information
220
+ *
221
+ * @example
222
+ * ```typescript
223
+ * const user = await edge.getUser(accessToken)
224
+ * console.log(`Connected: ${user.firstName} ${user.lastName}`)
225
+ * ```
226
+ */
227
+ getUser(accessToken: string): Promise<User>;
228
+ /**
229
+ * Gets the connected user's EdgeBoost balance.
230
+ *
231
+ * Requires scope: `balance.read`
232
+ *
233
+ * @param accessToken - Valid access token
234
+ * @returns Balance information
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * const balance = await edge.getBalance(accessToken)
239
+ * console.log(`Balance: $${balance.availableBalance.toFixed(2)} ${balance.currency}`)
240
+ * ```
241
+ */
242
+ getBalance(accessToken: string): Promise<Balance>;
243
+ /**
244
+ * Initiates a fund transfer.
245
+ *
246
+ * Requires scope: `transfer.write`
247
+ *
248
+ * **Transfer Types:**
249
+ * - `debit`: Pull funds FROM user's EdgeBoost TO your platform
250
+ * - `credit`: Push funds FROM your platform TO user's EdgeBoost
251
+ *
252
+ * **Idempotency:** Using the same `idempotencyKey` returns the existing
253
+ * transfer instead of creating a duplicate. Use a unique key per transaction.
254
+ *
255
+ * **OTP Verification:** Transfers require OTP verification before completion.
256
+ * The response includes `otpMethod` indicating how the user will receive the code.
257
+ *
258
+ * @param accessToken - Valid access token
259
+ * @param options - Transfer options
260
+ * @returns Transfer with status and OTP method
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * const transfer = await edge.initiateTransfer(accessToken, {
265
+ * type: 'debit',
266
+ * amount: '100.00',
267
+ * idempotencyKey: `withdraw_${userId}_${Date.now()}`,
268
+ * })
269
+ *
270
+ * if (transfer.status === 'pending_verification') {
271
+ * // Show OTP input to user
272
+ * console.log(`Enter code sent via ${transfer.otpMethod}`)
273
+ * }
274
+ * ```
275
+ */
276
+ initiateTransfer(accessToken: string, options: TransferOptions): Promise<Transfer>;
277
+ /**
278
+ * Verifies a pending transfer with OTP.
279
+ *
280
+ * Call this after the user enters the OTP code they received.
281
+ * The OTP is valid for ~5 minutes.
282
+ *
283
+ * @param accessToken - Valid access token
284
+ * @param transferId - Transfer ID from initiateTransfer
285
+ * @param otp - 6-digit OTP code from user
286
+ * @returns Updated transfer (status will be 'completed' or 'failed')
287
+ *
288
+ * @example
289
+ * ```typescript
290
+ * const result = await edge.verifyTransfer(accessToken, transferId, userOtp)
291
+ *
292
+ * if (result.status === 'completed') {
293
+ * console.log('Transfer successful!')
294
+ * } else if (result.status === 'failed') {
295
+ * console.log('Transfer failed - possibly wrong OTP')
296
+ * }
297
+ * ```
298
+ */
299
+ verifyTransfer(accessToken: string, transferId: string, otp: string): Promise<Transfer>;
300
+ /**
301
+ * Gets the status of a transfer.
302
+ *
303
+ * Use for polling after initiating a transfer.
304
+ *
305
+ * @param accessToken - Valid access token
306
+ * @param transferId - Transfer ID
307
+ * @returns Current transfer status
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * const transfer = await edge.getTransfer(accessToken, transferId)
312
+ * console.log(`Status: ${transfer.status}`)
313
+ * ```
314
+ */
315
+ getTransfer(accessToken: string, transferId: string): Promise<Transfer>;
316
+ /**
317
+ * Lists transfers for the connected user.
318
+ *
319
+ * Useful for reconciliation and showing transfer history.
320
+ *
321
+ * @param accessToken - Valid access token
322
+ * @param params - Pagination and filter options
323
+ * @returns Paginated list of transfers
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * // Get first page of completed transfers
328
+ * const { transfers, total } = await edge.listTransfers(accessToken, {
329
+ * status: 'completed',
330
+ * limit: 10,
331
+ * offset: 0,
332
+ * })
333
+ *
334
+ * console.log(`Showing ${transfers.length} of ${total} transfers`)
335
+ * ```
336
+ */
337
+ listTransfers(accessToken: string, params?: ListTransfersParams): Promise<TransferList>;
338
+ /**
339
+ * Revokes the user's consent (disconnects their account).
340
+ *
341
+ * After revocation:
342
+ * - All API calls will fail with `consent_required` error
343
+ * - User must go through EdgeLink again to reconnect
344
+ * - Stored tokens become invalid
345
+ *
346
+ * Use this for "Disconnect" or "Unlink" features in your app.
347
+ *
348
+ * @param accessToken - Valid access token
349
+ * @returns Confirmation of revocation
350
+ *
351
+ * @example
352
+ * ```typescript
353
+ * // Disconnect user's EdgeBoost account
354
+ * await edge.revokeConsent(accessToken)
355
+ *
356
+ * // Clean up stored tokens
357
+ * await db.edgeConnections.delete(userId)
358
+ *
359
+ * console.log('EdgeBoost disconnected')
360
+ * ```
361
+ */
362
+ revokeConsent(accessToken: string): Promise<{
363
+ revoked: boolean;
364
+ }>;
365
+ /**
366
+ * Makes an authenticated API request.
367
+ */
368
+ private apiRequest;
369
+ /**
370
+ * Fetch with timeout support.
371
+ */
372
+ private fetchWithTimeout;
373
+ /**
374
+ * Parses token response from Cognito.
375
+ */
376
+ private parseTokenResponse;
377
+ /**
378
+ * Handles token exchange errors.
379
+ */
380
+ private handleTokenError;
381
+ /**
382
+ * Handles API errors.
383
+ */
384
+ private handleApiError;
385
+ }
386
+
387
+ export { EdgeConnectServer, type EdgeConnectServerConfig, type TransferOptions };