@edge-markets/connect-node 1.4.0 → 1.6.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 +29 -25
- package/dist/index.d.mts +39 -4
- package/dist/index.d.ts +39 -4
- package/dist/index.js +148 -26
- package/dist/index.mjs +145 -27
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Server SDK for EDGE Connect token exchange and API calls.
|
|
|
6
6
|
|
|
7
7
|
- 🔐 **Secure token exchange** - Exchange codes for tokens with PKCE
|
|
8
8
|
- 🔄 **Token refresh** - Automatic refresh token handling
|
|
9
|
-
- 📡 **Full API client** - User, balance, transfers
|
|
9
|
+
- 📡 **Full API client** - User, balance, transfers via `forUser()` pattern
|
|
10
10
|
- 🛡️ **Typed errors** - Specific error classes for each scenario
|
|
11
11
|
- 📝 **TypeScript first** - Complete type definitions
|
|
12
12
|
|
|
@@ -23,7 +23,7 @@ yarn add @edge-markets/connect-node
|
|
|
23
23
|
## Quick Start
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
|
-
import { EdgeConnectServer } from '@
|
|
26
|
+
import { EdgeConnectServer } from '@edge-markets/connect-node'
|
|
27
27
|
|
|
28
28
|
// Create instance once (reuse for all requests)
|
|
29
29
|
const edge = new EdgeConnectServer({
|
|
@@ -35,9 +35,10 @@ const edge = new EdgeConnectServer({
|
|
|
35
35
|
// Exchange code from EdgeLink for tokens
|
|
36
36
|
const tokens = await edge.exchangeCode(code, codeVerifier)
|
|
37
37
|
|
|
38
|
-
//
|
|
39
|
-
const
|
|
40
|
-
const
|
|
38
|
+
// Create a user-scoped client and make API calls
|
|
39
|
+
const client = edge.forUser(tokens.accessToken)
|
|
40
|
+
const user = await client.getUser()
|
|
41
|
+
const balance = await client.getBalance()
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
## ⚠️ Security
|
|
@@ -56,8 +57,11 @@ interface EdgeConnectServerConfig {
|
|
|
56
57
|
|
|
57
58
|
// Optional
|
|
58
59
|
apiBaseUrl?: string // Custom API URL (dev only)
|
|
59
|
-
|
|
60
|
+
oauthBaseUrl?: string // Custom OAuth URL (dev only)
|
|
60
61
|
timeout?: number // Request timeout (default: 30000ms)
|
|
62
|
+
retry?: RetryConfig // Retry configuration
|
|
63
|
+
onRequest?: (info) => void // Hook called before each request
|
|
64
|
+
onResponse?: (info) => void // Hook called after each response
|
|
61
65
|
|
|
62
66
|
// Optional: Message Level Encryption (Connect endpoints only)
|
|
63
67
|
mle?: {
|
|
@@ -152,15 +156,19 @@ async function getValidAccessToken(userId: string): Promise<string> {
|
|
|
152
156
|
|
|
153
157
|
## API Methods
|
|
154
158
|
|
|
159
|
+
All user-scoped API methods live on `EdgeUserClient`, created via `edge.forUser(accessToken)`:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const client = edge.forUser(accessToken)
|
|
163
|
+
```
|
|
164
|
+
|
|
155
165
|
### User & Balance
|
|
156
166
|
|
|
157
167
|
```typescript
|
|
158
|
-
|
|
159
|
-
const user = await edge.getUser(accessToken)
|
|
168
|
+
const user = await client.getUser()
|
|
160
169
|
// Returns: { id, email, firstName, lastName, createdAt }
|
|
161
170
|
|
|
162
|
-
|
|
163
|
-
const balance = await edge.getBalance(accessToken)
|
|
171
|
+
const balance = await client.getBalance()
|
|
164
172
|
// Returns: { userId, availableBalance, currency, asOf }
|
|
165
173
|
```
|
|
166
174
|
|
|
@@ -168,7 +176,7 @@ const balance = await edge.getBalance(accessToken)
|
|
|
168
176
|
|
|
169
177
|
```typescript
|
|
170
178
|
// Initiate transfer (requires OTP verification)
|
|
171
|
-
const transfer = await
|
|
179
|
+
const transfer = await client.initiateTransfer({
|
|
172
180
|
type: 'debit', // 'debit' = pull from user, 'credit' = push to user
|
|
173
181
|
amount: '100.00',
|
|
174
182
|
idempotencyKey: `txn_${userId}_${Date.now()}`,
|
|
@@ -176,14 +184,14 @@ const transfer = await edge.initiateTransfer(accessToken, {
|
|
|
176
184
|
// Returns: { transferId, status: 'pending_verification', otpMethod }
|
|
177
185
|
|
|
178
186
|
// Verify with OTP
|
|
179
|
-
const result = await
|
|
187
|
+
const result = await client.verifyTransfer(transfer.transferId, userOtp)
|
|
180
188
|
// Returns: { transferId, status: 'completed' | 'failed' }
|
|
181
189
|
|
|
182
190
|
// Get transfer status
|
|
183
|
-
const status = await
|
|
191
|
+
const status = await client.getTransfer(transferId)
|
|
184
192
|
|
|
185
193
|
// List transfers
|
|
186
|
-
const { transfers, total } = await
|
|
194
|
+
const { transfers, total } = await client.listTransfers({
|
|
187
195
|
status: 'completed',
|
|
188
196
|
limit: 10,
|
|
189
197
|
offset: 0,
|
|
@@ -194,7 +202,7 @@ const { transfers, total } = await edge.listTransfers(accessToken, {
|
|
|
194
202
|
|
|
195
203
|
```typescript
|
|
196
204
|
// Revoke consent (disconnect user)
|
|
197
|
-
await
|
|
205
|
+
await client.revokeConsent()
|
|
198
206
|
|
|
199
207
|
// Clean up stored tokens
|
|
200
208
|
await db.edgeConnections.delete(userId)
|
|
@@ -212,7 +220,8 @@ import {
|
|
|
212
220
|
} from '@edge-markets/connect-node'
|
|
213
221
|
|
|
214
222
|
try {
|
|
215
|
-
const
|
|
223
|
+
const client = edge.forUser(accessToken)
|
|
224
|
+
const balance = await client.getBalance()
|
|
216
225
|
} catch (error) {
|
|
217
226
|
if (error instanceof EdgeAuthenticationError) {
|
|
218
227
|
// Token expired - try refresh or reconnect
|
|
@@ -273,7 +282,8 @@ export class EdgeService {
|
|
|
273
282
|
|
|
274
283
|
async getBalance(accessToken: string) {
|
|
275
284
|
try {
|
|
276
|
-
|
|
285
|
+
const client = this.edge.forUser(accessToken)
|
|
286
|
+
return await client.getBalance()
|
|
277
287
|
} catch (error) {
|
|
278
288
|
if (error instanceof EdgeConsentRequiredError) {
|
|
279
289
|
this.logger.warn('User consent required')
|
|
@@ -323,7 +333,8 @@ app.post('/api/edge/exchange', async (req, res) => {
|
|
|
323
333
|
app.get('/api/edge/balance', async (req, res) => {
|
|
324
334
|
try {
|
|
325
335
|
const accessToken = await getAccessTokenForUser(req.user.id)
|
|
326
|
-
const
|
|
336
|
+
const client = edge.forUser(accessToken)
|
|
337
|
+
const balance = await client.getBalance()
|
|
327
338
|
res.json(balance)
|
|
328
339
|
} catch (error) {
|
|
329
340
|
// Handle errors...
|
|
@@ -339,10 +350,3 @@ app.get('/api/edge/balance', async (req, res) => {
|
|
|
339
350
|
## License
|
|
340
351
|
|
|
341
352
|
MIT
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import * as node_https from 'node:https';
|
|
2
|
+
import { EdgeEnvironment, TransferCategory, SdkGeolocation, User, VerifyIdentityOptions, VerifyIdentityResult, Balance, Transfer, ListTransfersParams, TransferList, CreateVerificationSessionRequest, VerificationSession, VerificationSessionStatusResponse, EdgeTokens } from '@edge-markets/connect';
|
|
3
|
+
export { Balance, CreateVerificationSessionRequest, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, EdgeEnvironment, EdgeError, EdgeIdentityVerificationError, EdgeInsufficientScopeError, EdgeNetworkError, EdgeNotFoundError, EdgeTokenExchangeError, EdgeTokens, ListTransfersParams, SdkGeolocation, TRANSFER_CATEGORIES, Transfer, TransferCategory, TransferList, TransferListItem, TransferStatus, TransferType, User, UserAddress, VerificationSession, VerificationSessionStatus, VerificationSessionStatusResponse, VerifyIdentityAddress, VerifyIdentityOptions, VerifyIdentityResult, VerifyIdentityScores, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isEdgeError, isIdentityVerificationError, isNetworkError, isProductionEnvironment } from '@edge-markets/connect';
|
|
3
4
|
|
|
4
5
|
interface RequestInfo {
|
|
5
6
|
method: string;
|
|
@@ -40,11 +41,27 @@ interface EdgeConnectServerConfig {
|
|
|
40
41
|
partnerKeyId: string;
|
|
41
42
|
strictResponseEncryption?: boolean;
|
|
42
43
|
};
|
|
44
|
+
mtls?: MtlsConfig;
|
|
45
|
+
}
|
|
46
|
+
interface MtlsConfig {
|
|
47
|
+
enabled: boolean;
|
|
48
|
+
cert: string;
|
|
49
|
+
key: string;
|
|
50
|
+
ca?: string;
|
|
43
51
|
}
|
|
44
52
|
interface TransferOptions {
|
|
45
53
|
type: 'debit' | 'credit';
|
|
46
54
|
amount: string;
|
|
47
55
|
idempotencyKey: string;
|
|
56
|
+
/** Optional transaction category for settlement window determination */
|
|
57
|
+
category?: TransferCategory;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Options for verifying a transfer with OTP.
|
|
61
|
+
*/
|
|
62
|
+
interface VerifyTransferOptions {
|
|
63
|
+
/** SDK-reported geolocation for cross-referencing against IP-based geo */
|
|
64
|
+
sdkGeo?: SdkGeolocation;
|
|
48
65
|
}
|
|
49
66
|
|
|
50
67
|
/**
|
|
@@ -61,12 +78,23 @@ declare class EdgeUserClient {
|
|
|
61
78
|
verifyIdentity(options: VerifyIdentityOptions): Promise<VerifyIdentityResult>;
|
|
62
79
|
getBalance(): Promise<Balance>;
|
|
63
80
|
initiateTransfer(options: TransferOptions): Promise<Transfer>;
|
|
64
|
-
verifyTransfer(transferId: string, otp: string): Promise<Transfer>;
|
|
81
|
+
verifyTransfer(transferId: string, otp: string, options?: VerifyTransferOptions): Promise<Transfer>;
|
|
65
82
|
getTransfer(transferId: string): Promise<Transfer>;
|
|
66
83
|
listTransfers(params?: ListTransfersParams): Promise<TransferList>;
|
|
67
84
|
revokeConsent(): Promise<{
|
|
68
85
|
revoked: boolean;
|
|
69
86
|
}>;
|
|
87
|
+
/**
|
|
88
|
+
* Creates an EDGE-hosted transfer verification session.
|
|
89
|
+
* Returns a `verificationUrl` to open in an iframe or popup.
|
|
90
|
+
* The handoff token is single-use and expires in 120 seconds.
|
|
91
|
+
*/
|
|
92
|
+
createVerificationSession(transferId: string, options: CreateVerificationSessionRequest): Promise<VerificationSession>;
|
|
93
|
+
/**
|
|
94
|
+
* Polls the status of a verification session.
|
|
95
|
+
* Use as an alternative to postMessage events.
|
|
96
|
+
*/
|
|
97
|
+
getVerificationSessionStatus(transferId: string, sessionId: string): Promise<VerificationSessionStatusResponse>;
|
|
70
98
|
}
|
|
71
99
|
|
|
72
100
|
declare class EdgeConnectServer {
|
|
@@ -75,9 +103,16 @@ declare class EdgeConnectServer {
|
|
|
75
103
|
private readonly oauthBaseUrl;
|
|
76
104
|
private readonly timeout;
|
|
77
105
|
private readonly retryConfig;
|
|
106
|
+
private readonly httpsAgent;
|
|
107
|
+
private readonly dispatcher;
|
|
78
108
|
static getInstance(config: EdgeConnectServerConfig): EdgeConnectServer;
|
|
79
109
|
static clearInstances(): void;
|
|
80
110
|
constructor(config: EdgeConnectServerConfig);
|
|
111
|
+
/**
|
|
112
|
+
* Returns the `node:https.Agent` configured with mTLS client certificates.
|
|
113
|
+
* Use this with axios, got, or other HTTP clients. Returns `undefined` if mTLS is not configured.
|
|
114
|
+
*/
|
|
115
|
+
getHttpsAgent(): node_https.Agent | undefined;
|
|
81
116
|
/**
|
|
82
117
|
* Create a user-scoped client for making authenticated API calls.
|
|
83
118
|
*
|
|
@@ -97,4 +132,4 @@ declare class EdgeConnectServer {
|
|
|
97
132
|
private handleApiErrorFromBody;
|
|
98
133
|
}
|
|
99
134
|
|
|
100
|
-
export { EdgeConnectServer, type EdgeConnectServerConfig, EdgeUserClient, type RequestInfo, type ResponseInfo, type RetryConfig, type TransferOptions };
|
|
135
|
+
export { EdgeConnectServer, type EdgeConnectServerConfig, EdgeUserClient, type MtlsConfig, type RequestInfo, type ResponseInfo, type RetryConfig, type TransferOptions, type VerifyTransferOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import * as node_https from 'node:https';
|
|
2
|
+
import { EdgeEnvironment, TransferCategory, SdkGeolocation, User, VerifyIdentityOptions, VerifyIdentityResult, Balance, Transfer, ListTransfersParams, TransferList, CreateVerificationSessionRequest, VerificationSession, VerificationSessionStatusResponse, EdgeTokens } from '@edge-markets/connect';
|
|
3
|
+
export { Balance, CreateVerificationSessionRequest, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, EdgeEnvironment, EdgeError, EdgeIdentityVerificationError, EdgeInsufficientScopeError, EdgeNetworkError, EdgeNotFoundError, EdgeTokenExchangeError, EdgeTokens, ListTransfersParams, SdkGeolocation, TRANSFER_CATEGORIES, Transfer, TransferCategory, TransferList, TransferListItem, TransferStatus, TransferType, User, UserAddress, VerificationSession, VerificationSessionStatus, VerificationSessionStatusResponse, VerifyIdentityAddress, VerifyIdentityOptions, VerifyIdentityResult, VerifyIdentityScores, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isEdgeError, isIdentityVerificationError, isNetworkError, isProductionEnvironment } from '@edge-markets/connect';
|
|
3
4
|
|
|
4
5
|
interface RequestInfo {
|
|
5
6
|
method: string;
|
|
@@ -40,11 +41,27 @@ interface EdgeConnectServerConfig {
|
|
|
40
41
|
partnerKeyId: string;
|
|
41
42
|
strictResponseEncryption?: boolean;
|
|
42
43
|
};
|
|
44
|
+
mtls?: MtlsConfig;
|
|
45
|
+
}
|
|
46
|
+
interface MtlsConfig {
|
|
47
|
+
enabled: boolean;
|
|
48
|
+
cert: string;
|
|
49
|
+
key: string;
|
|
50
|
+
ca?: string;
|
|
43
51
|
}
|
|
44
52
|
interface TransferOptions {
|
|
45
53
|
type: 'debit' | 'credit';
|
|
46
54
|
amount: string;
|
|
47
55
|
idempotencyKey: string;
|
|
56
|
+
/** Optional transaction category for settlement window determination */
|
|
57
|
+
category?: TransferCategory;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Options for verifying a transfer with OTP.
|
|
61
|
+
*/
|
|
62
|
+
interface VerifyTransferOptions {
|
|
63
|
+
/** SDK-reported geolocation for cross-referencing against IP-based geo */
|
|
64
|
+
sdkGeo?: SdkGeolocation;
|
|
48
65
|
}
|
|
49
66
|
|
|
50
67
|
/**
|
|
@@ -61,12 +78,23 @@ declare class EdgeUserClient {
|
|
|
61
78
|
verifyIdentity(options: VerifyIdentityOptions): Promise<VerifyIdentityResult>;
|
|
62
79
|
getBalance(): Promise<Balance>;
|
|
63
80
|
initiateTransfer(options: TransferOptions): Promise<Transfer>;
|
|
64
|
-
verifyTransfer(transferId: string, otp: string): Promise<Transfer>;
|
|
81
|
+
verifyTransfer(transferId: string, otp: string, options?: VerifyTransferOptions): Promise<Transfer>;
|
|
65
82
|
getTransfer(transferId: string): Promise<Transfer>;
|
|
66
83
|
listTransfers(params?: ListTransfersParams): Promise<TransferList>;
|
|
67
84
|
revokeConsent(): Promise<{
|
|
68
85
|
revoked: boolean;
|
|
69
86
|
}>;
|
|
87
|
+
/**
|
|
88
|
+
* Creates an EDGE-hosted transfer verification session.
|
|
89
|
+
* Returns a `verificationUrl` to open in an iframe or popup.
|
|
90
|
+
* The handoff token is single-use and expires in 120 seconds.
|
|
91
|
+
*/
|
|
92
|
+
createVerificationSession(transferId: string, options: CreateVerificationSessionRequest): Promise<VerificationSession>;
|
|
93
|
+
/**
|
|
94
|
+
* Polls the status of a verification session.
|
|
95
|
+
* Use as an alternative to postMessage events.
|
|
96
|
+
*/
|
|
97
|
+
getVerificationSessionStatus(transferId: string, sessionId: string): Promise<VerificationSessionStatusResponse>;
|
|
70
98
|
}
|
|
71
99
|
|
|
72
100
|
declare class EdgeConnectServer {
|
|
@@ -75,9 +103,16 @@ declare class EdgeConnectServer {
|
|
|
75
103
|
private readonly oauthBaseUrl;
|
|
76
104
|
private readonly timeout;
|
|
77
105
|
private readonly retryConfig;
|
|
106
|
+
private readonly httpsAgent;
|
|
107
|
+
private readonly dispatcher;
|
|
78
108
|
static getInstance(config: EdgeConnectServerConfig): EdgeConnectServer;
|
|
79
109
|
static clearInstances(): void;
|
|
80
110
|
constructor(config: EdgeConnectServerConfig);
|
|
111
|
+
/**
|
|
112
|
+
* Returns the `node:https.Agent` configured with mTLS client certificates.
|
|
113
|
+
* Use this with axios, got, or other HTTP clients. Returns `undefined` if mTLS is not configured.
|
|
114
|
+
*/
|
|
115
|
+
getHttpsAgent(): node_https.Agent | undefined;
|
|
81
116
|
/**
|
|
82
117
|
* Create a user-scoped client for making authenticated API calls.
|
|
83
118
|
*
|
|
@@ -97,4 +132,4 @@ declare class EdgeConnectServer {
|
|
|
97
132
|
private handleApiErrorFromBody;
|
|
98
133
|
}
|
|
99
134
|
|
|
100
|
-
export { EdgeConnectServer, type EdgeConnectServerConfig, EdgeUserClient, type RequestInfo, type ResponseInfo, type RetryConfig, type TransferOptions };
|
|
135
|
+
export { EdgeConnectServer, type EdgeConnectServerConfig, EdgeUserClient, type MtlsConfig, type RequestInfo, type ResponseInfo, type RetryConfig, type TransferOptions, type VerifyTransferOptions };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -25,16 +35,19 @@ __export(index_exports, {
|
|
|
25
35
|
EdgeConnectServer: () => EdgeConnectServer,
|
|
26
36
|
EdgeConsentRequiredError: () => import_connect3.EdgeConsentRequiredError,
|
|
27
37
|
EdgeError: () => import_connect3.EdgeError,
|
|
38
|
+
EdgeIdentityVerificationError: () => import_connect3.EdgeIdentityVerificationError,
|
|
28
39
|
EdgeInsufficientScopeError: () => import_connect3.EdgeInsufficientScopeError,
|
|
29
40
|
EdgeNetworkError: () => import_connect3.EdgeNetworkError,
|
|
30
41
|
EdgeNotFoundError: () => import_connect3.EdgeNotFoundError,
|
|
31
42
|
EdgeTokenExchangeError: () => import_connect3.EdgeTokenExchangeError,
|
|
32
43
|
EdgeUserClient: () => EdgeUserClient,
|
|
44
|
+
TRANSFER_CATEGORIES: () => import_connect4.TRANSFER_CATEGORIES,
|
|
33
45
|
getEnvironmentConfig: () => import_connect4.getEnvironmentConfig,
|
|
34
46
|
isApiError: () => import_connect3.isApiError,
|
|
35
47
|
isAuthenticationError: () => import_connect3.isAuthenticationError,
|
|
36
48
|
isConsentRequiredError: () => import_connect3.isConsentRequiredError,
|
|
37
49
|
isEdgeError: () => import_connect3.isEdgeError,
|
|
50
|
+
isIdentityVerificationError: () => import_connect3.isIdentityVerificationError,
|
|
38
51
|
isNetworkError: () => import_connect3.isNetworkError,
|
|
39
52
|
isProductionEnvironment: () => import_connect4.isProductionEnvironment
|
|
40
53
|
});
|
|
@@ -85,6 +98,9 @@ function validateTransferOptions(options) {
|
|
|
85
98
|
} else if (options.idempotencyKey.length > 255) {
|
|
86
99
|
errors.idempotencyKey = ["Must be 255 characters or less"];
|
|
87
100
|
}
|
|
101
|
+
if (options.category && !["sportsbook", "casino", "dfs", "sweepstakes"].includes(options.category)) {
|
|
102
|
+
errors.category = ["Must be one of: sportsbook, casino, dfs, sweepstakes"];
|
|
103
|
+
}
|
|
88
104
|
if (Object.keys(errors).length > 0) {
|
|
89
105
|
throw new import_connect.EdgeValidationError("Invalid transfer options", errors);
|
|
90
106
|
}
|
|
@@ -113,14 +129,21 @@ var EdgeUserClient = class {
|
|
|
113
129
|
amount: options.amount,
|
|
114
130
|
idempotencyKey: options.idempotencyKey
|
|
115
131
|
};
|
|
132
|
+
if (options.category) {
|
|
133
|
+
body.category = options.category;
|
|
134
|
+
}
|
|
116
135
|
return this.server._apiRequest("POST", "/transfer", this.accessToken, body);
|
|
117
136
|
}
|
|
118
|
-
async verifyTransfer(transferId, otp) {
|
|
137
|
+
async verifyTransfer(transferId, otp, options) {
|
|
138
|
+
const body = { otp };
|
|
139
|
+
if (options?.sdkGeo) {
|
|
140
|
+
body.sdkGeo = options.sdkGeo;
|
|
141
|
+
}
|
|
119
142
|
return this.server._apiRequest(
|
|
120
143
|
"POST",
|
|
121
144
|
`/transfer/${encodeURIComponent(transferId)}/verify`,
|
|
122
145
|
this.accessToken,
|
|
123
|
-
|
|
146
|
+
body
|
|
124
147
|
);
|
|
125
148
|
}
|
|
126
149
|
async getTransfer(transferId) {
|
|
@@ -138,6 +161,30 @@ var EdgeUserClient = class {
|
|
|
138
161
|
async revokeConsent() {
|
|
139
162
|
return this.server._apiRequest("DELETE", "/consent", this.accessToken);
|
|
140
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* Creates an EDGE-hosted transfer verification session.
|
|
166
|
+
* Returns a `verificationUrl` to open in an iframe or popup.
|
|
167
|
+
* The handoff token is single-use and expires in 120 seconds.
|
|
168
|
+
*/
|
|
169
|
+
async createVerificationSession(transferId, options) {
|
|
170
|
+
return this.server._apiRequest(
|
|
171
|
+
"POST",
|
|
172
|
+
`/transfer/${encodeURIComponent(transferId)}/verification-session`,
|
|
173
|
+
this.accessToken,
|
|
174
|
+
{ origin: options.origin }
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Polls the status of a verification session.
|
|
179
|
+
* Use as an alternative to postMessage events.
|
|
180
|
+
*/
|
|
181
|
+
async getVerificationSessionStatus(transferId, sessionId) {
|
|
182
|
+
return this.server._apiRequest(
|
|
183
|
+
"GET",
|
|
184
|
+
`/transfer/${encodeURIComponent(transferId)}/verification-session/${encodeURIComponent(sessionId)}`,
|
|
185
|
+
this.accessToken
|
|
186
|
+
);
|
|
187
|
+
}
|
|
141
188
|
};
|
|
142
189
|
|
|
143
190
|
// src/mle.ts
|
|
@@ -215,6 +262,37 @@ function fromBase64Url(value) {
|
|
|
215
262
|
return Buffer.from(normalized, "base64");
|
|
216
263
|
}
|
|
217
264
|
|
|
265
|
+
// src/mtls.ts
|
|
266
|
+
var import_node_https = __toESM(require("https"));
|
|
267
|
+
function createHttpsAgent(config) {
|
|
268
|
+
return new import_node_https.default.Agent({
|
|
269
|
+
cert: config.cert,
|
|
270
|
+
key: config.key,
|
|
271
|
+
rejectUnauthorized: true,
|
|
272
|
+
...config.ca ? { ca: config.ca } : {}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function createUndiciDispatcher(config) {
|
|
276
|
+
const moduleName = "undici";
|
|
277
|
+
const { Agent } = require(moduleName);
|
|
278
|
+
return new Agent({
|
|
279
|
+
connect: {
|
|
280
|
+
cert: config.cert,
|
|
281
|
+
key: config.key,
|
|
282
|
+
rejectUnauthorized: true,
|
|
283
|
+
...config.ca ? { ca: config.ca } : {}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
function validateMtlsConfig(config) {
|
|
288
|
+
if (!config.cert?.trim()) {
|
|
289
|
+
throw new Error("EdgeConnectServer: mTLS cert is required when enabled");
|
|
290
|
+
}
|
|
291
|
+
if (!config.key?.trim()) {
|
|
292
|
+
throw new Error("EdgeConnectServer: mTLS key is required when enabled");
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
218
296
|
// src/types.ts
|
|
219
297
|
var DEFAULT_TIMEOUT = 3e4;
|
|
220
298
|
var USER_AGENT = "@edge-markets/connect-node/1.0.0";
|
|
@@ -261,6 +339,18 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
261
339
|
...DEFAULT_RETRY_CONFIG,
|
|
262
340
|
...config.retry
|
|
263
341
|
};
|
|
342
|
+
if (config.mtls?.enabled) {
|
|
343
|
+
validateMtlsConfig(config.mtls);
|
|
344
|
+
this.httpsAgent = createHttpsAgent(config.mtls);
|
|
345
|
+
this.dispatcher = createUndiciDispatcher(config.mtls);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Returns the `node:https.Agent` configured with mTLS client certificates.
|
|
350
|
+
* Use this with axios, got, or other HTTP clients. Returns `undefined` if mTLS is not configured.
|
|
351
|
+
*/
|
|
352
|
+
getHttpsAgent() {
|
|
353
|
+
return this.httpsAgent;
|
|
264
354
|
}
|
|
265
355
|
/**
|
|
266
356
|
* Create a user-scoped client for making authenticated API calls.
|
|
@@ -285,14 +375,18 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
285
375
|
redirect_uri: redirectUri || this.config.redirectUri || ""
|
|
286
376
|
};
|
|
287
377
|
try {
|
|
288
|
-
const response = await this.fetchWithTimeout(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
378
|
+
const response = await this.fetchWithTimeout(
|
|
379
|
+
tokenUrl,
|
|
380
|
+
{
|
|
381
|
+
method: "POST",
|
|
382
|
+
headers: {
|
|
383
|
+
"Content-Type": "application/json",
|
|
384
|
+
"User-Agent": USER_AGENT
|
|
385
|
+
},
|
|
386
|
+
body: JSON.stringify(body)
|
|
293
387
|
},
|
|
294
|
-
|
|
295
|
-
|
|
388
|
+
this.dispatcher
|
|
389
|
+
);
|
|
296
390
|
if (!response.ok) {
|
|
297
391
|
const error = await response.json().catch(() => ({}));
|
|
298
392
|
throw this.handleTokenError(error, response.status);
|
|
@@ -313,14 +407,18 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
313
407
|
client_secret: this.config.clientSecret
|
|
314
408
|
};
|
|
315
409
|
try {
|
|
316
|
-
const response = await this.fetchWithTimeout(
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
410
|
+
const response = await this.fetchWithTimeout(
|
|
411
|
+
tokenUrl,
|
|
412
|
+
{
|
|
413
|
+
method: "POST",
|
|
414
|
+
headers: {
|
|
415
|
+
"Content-Type": "application/json",
|
|
416
|
+
"User-Agent": USER_AGENT
|
|
417
|
+
},
|
|
418
|
+
body: JSON.stringify(body)
|
|
321
419
|
},
|
|
322
|
-
|
|
323
|
-
|
|
420
|
+
this.dispatcher
|
|
421
|
+
);
|
|
324
422
|
if (!response.ok) {
|
|
325
423
|
const error = await response.json().catch(() => ({}));
|
|
326
424
|
throw new import_connect2.EdgeAuthenticationError(
|
|
@@ -360,11 +458,15 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
360
458
|
requestBody = { jwe: encryptMle(body, this.config.clientId, mleConfig) };
|
|
361
459
|
}
|
|
362
460
|
}
|
|
363
|
-
const response = await this.fetchWithTimeout(
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
461
|
+
const response = await this.fetchWithTimeout(
|
|
462
|
+
url,
|
|
463
|
+
{
|
|
464
|
+
method,
|
|
465
|
+
headers: requestHeaders,
|
|
466
|
+
body: requestBody !== void 0 ? JSON.stringify(requestBody) : void 0
|
|
467
|
+
},
|
|
468
|
+
this.dispatcher
|
|
469
|
+
);
|
|
368
470
|
const rawResponseBody = await response.json().catch(() => ({}));
|
|
369
471
|
let responseBody = rawResponseBody;
|
|
370
472
|
if (mleEnabled && typeof rawResponseBody?.jwe === "string") {
|
|
@@ -423,14 +525,18 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
423
525
|
async sleep(ms) {
|
|
424
526
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
425
527
|
}
|
|
426
|
-
async fetchWithTimeout(url, options) {
|
|
528
|
+
async fetchWithTimeout(url, options, dispatcher) {
|
|
427
529
|
const controller = new AbortController();
|
|
428
530
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
429
531
|
try {
|
|
430
|
-
|
|
532
|
+
const fetchOptions = {
|
|
431
533
|
...options,
|
|
432
534
|
signal: controller.signal
|
|
433
|
-
}
|
|
535
|
+
};
|
|
536
|
+
if (dispatcher) {
|
|
537
|
+
fetchOptions.dispatcher = dispatcher;
|
|
538
|
+
}
|
|
539
|
+
return await fetch(url, fetchOptions);
|
|
434
540
|
} finally {
|
|
435
541
|
clearTimeout(timeoutId);
|
|
436
542
|
}
|
|
@@ -486,8 +592,21 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
486
592
|
}
|
|
487
593
|
}
|
|
488
594
|
if (status === 404) {
|
|
489
|
-
|
|
490
|
-
|
|
595
|
+
let resourceType = "Resource";
|
|
596
|
+
let resourceId = path.split("/").pop() || "unknown";
|
|
597
|
+
if (path.includes("/verification-session/")) {
|
|
598
|
+
resourceType = "VerificationSession";
|
|
599
|
+
const parts = path.split("/");
|
|
600
|
+
const vsIdx = parts.indexOf("verification-session");
|
|
601
|
+
resourceId = vsIdx >= 0 && parts[vsIdx + 1] ? parts[vsIdx + 1] : "unknown";
|
|
602
|
+
} else if (path.includes("/verification-session")) {
|
|
603
|
+
resourceType = "Transfer";
|
|
604
|
+
const parts = path.split("/");
|
|
605
|
+
const txIdx = parts.indexOf("transfer");
|
|
606
|
+
resourceId = txIdx >= 0 && parts[txIdx + 1] ? parts[txIdx + 1] : "unknown";
|
|
607
|
+
} else if (path.includes("/transfer")) {
|
|
608
|
+
resourceType = "Transfer";
|
|
609
|
+
}
|
|
491
610
|
return new import_connect2.EdgeNotFoundError(resourceType, resourceId);
|
|
492
611
|
}
|
|
493
612
|
if (status === 422 && error.error === "identity_verification_failed") {
|
|
@@ -515,16 +634,19 @@ var import_connect4 = require("@edge-markets/connect");
|
|
|
515
634
|
EdgeConnectServer,
|
|
516
635
|
EdgeConsentRequiredError,
|
|
517
636
|
EdgeError,
|
|
637
|
+
EdgeIdentityVerificationError,
|
|
518
638
|
EdgeInsufficientScopeError,
|
|
519
639
|
EdgeNetworkError,
|
|
520
640
|
EdgeNotFoundError,
|
|
521
641
|
EdgeTokenExchangeError,
|
|
522
642
|
EdgeUserClient,
|
|
643
|
+
TRANSFER_CATEGORIES,
|
|
523
644
|
getEnvironmentConfig,
|
|
524
645
|
isApiError,
|
|
525
646
|
isAuthenticationError,
|
|
526
647
|
isConsentRequiredError,
|
|
527
648
|
isEdgeError,
|
|
649
|
+
isIdentityVerificationError,
|
|
528
650
|
isNetworkError,
|
|
529
651
|
isProductionEnvironment
|
|
530
652
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// src/edge-connect-server.ts
|
|
2
9
|
import {
|
|
3
10
|
EdgeApiError,
|
|
@@ -54,6 +61,9 @@ function validateTransferOptions(options) {
|
|
|
54
61
|
} else if (options.idempotencyKey.length > 255) {
|
|
55
62
|
errors.idempotencyKey = ["Must be 255 characters or less"];
|
|
56
63
|
}
|
|
64
|
+
if (options.category && !["sportsbook", "casino", "dfs", "sweepstakes"].includes(options.category)) {
|
|
65
|
+
errors.category = ["Must be one of: sportsbook, casino, dfs, sweepstakes"];
|
|
66
|
+
}
|
|
57
67
|
if (Object.keys(errors).length > 0) {
|
|
58
68
|
throw new EdgeValidationError("Invalid transfer options", errors);
|
|
59
69
|
}
|
|
@@ -82,14 +92,21 @@ var EdgeUserClient = class {
|
|
|
82
92
|
amount: options.amount,
|
|
83
93
|
idempotencyKey: options.idempotencyKey
|
|
84
94
|
};
|
|
95
|
+
if (options.category) {
|
|
96
|
+
body.category = options.category;
|
|
97
|
+
}
|
|
85
98
|
return this.server._apiRequest("POST", "/transfer", this.accessToken, body);
|
|
86
99
|
}
|
|
87
|
-
async verifyTransfer(transferId, otp) {
|
|
100
|
+
async verifyTransfer(transferId, otp, options) {
|
|
101
|
+
const body = { otp };
|
|
102
|
+
if (options?.sdkGeo) {
|
|
103
|
+
body.sdkGeo = options.sdkGeo;
|
|
104
|
+
}
|
|
88
105
|
return this.server._apiRequest(
|
|
89
106
|
"POST",
|
|
90
107
|
`/transfer/${encodeURIComponent(transferId)}/verify`,
|
|
91
108
|
this.accessToken,
|
|
92
|
-
|
|
109
|
+
body
|
|
93
110
|
);
|
|
94
111
|
}
|
|
95
112
|
async getTransfer(transferId) {
|
|
@@ -107,6 +124,30 @@ var EdgeUserClient = class {
|
|
|
107
124
|
async revokeConsent() {
|
|
108
125
|
return this.server._apiRequest("DELETE", "/consent", this.accessToken);
|
|
109
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Creates an EDGE-hosted transfer verification session.
|
|
129
|
+
* Returns a `verificationUrl` to open in an iframe or popup.
|
|
130
|
+
* The handoff token is single-use and expires in 120 seconds.
|
|
131
|
+
*/
|
|
132
|
+
async createVerificationSession(transferId, options) {
|
|
133
|
+
return this.server._apiRequest(
|
|
134
|
+
"POST",
|
|
135
|
+
`/transfer/${encodeURIComponent(transferId)}/verification-session`,
|
|
136
|
+
this.accessToken,
|
|
137
|
+
{ origin: options.origin }
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Polls the status of a verification session.
|
|
142
|
+
* Use as an alternative to postMessage events.
|
|
143
|
+
*/
|
|
144
|
+
async getVerificationSessionStatus(transferId, sessionId) {
|
|
145
|
+
return this.server._apiRequest(
|
|
146
|
+
"GET",
|
|
147
|
+
`/transfer/${encodeURIComponent(transferId)}/verification-session/${encodeURIComponent(sessionId)}`,
|
|
148
|
+
this.accessToken
|
|
149
|
+
);
|
|
150
|
+
}
|
|
110
151
|
};
|
|
111
152
|
|
|
112
153
|
// src/mle.ts
|
|
@@ -184,6 +225,37 @@ function fromBase64Url(value) {
|
|
|
184
225
|
return Buffer.from(normalized, "base64");
|
|
185
226
|
}
|
|
186
227
|
|
|
228
|
+
// src/mtls.ts
|
|
229
|
+
import https from "https";
|
|
230
|
+
function createHttpsAgent(config) {
|
|
231
|
+
return new https.Agent({
|
|
232
|
+
cert: config.cert,
|
|
233
|
+
key: config.key,
|
|
234
|
+
rejectUnauthorized: true,
|
|
235
|
+
...config.ca ? { ca: config.ca } : {}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
function createUndiciDispatcher(config) {
|
|
239
|
+
const moduleName = "undici";
|
|
240
|
+
const { Agent } = __require(moduleName);
|
|
241
|
+
return new Agent({
|
|
242
|
+
connect: {
|
|
243
|
+
cert: config.cert,
|
|
244
|
+
key: config.key,
|
|
245
|
+
rejectUnauthorized: true,
|
|
246
|
+
...config.ca ? { ca: config.ca } : {}
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function validateMtlsConfig(config) {
|
|
251
|
+
if (!config.cert?.trim()) {
|
|
252
|
+
throw new Error("EdgeConnectServer: mTLS cert is required when enabled");
|
|
253
|
+
}
|
|
254
|
+
if (!config.key?.trim()) {
|
|
255
|
+
throw new Error("EdgeConnectServer: mTLS key is required when enabled");
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
187
259
|
// src/types.ts
|
|
188
260
|
var DEFAULT_TIMEOUT = 3e4;
|
|
189
261
|
var USER_AGENT = "@edge-markets/connect-node/1.0.0";
|
|
@@ -230,6 +302,18 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
230
302
|
...DEFAULT_RETRY_CONFIG,
|
|
231
303
|
...config.retry
|
|
232
304
|
};
|
|
305
|
+
if (config.mtls?.enabled) {
|
|
306
|
+
validateMtlsConfig(config.mtls);
|
|
307
|
+
this.httpsAgent = createHttpsAgent(config.mtls);
|
|
308
|
+
this.dispatcher = createUndiciDispatcher(config.mtls);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Returns the `node:https.Agent` configured with mTLS client certificates.
|
|
313
|
+
* Use this with axios, got, or other HTTP clients. Returns `undefined` if mTLS is not configured.
|
|
314
|
+
*/
|
|
315
|
+
getHttpsAgent() {
|
|
316
|
+
return this.httpsAgent;
|
|
233
317
|
}
|
|
234
318
|
/**
|
|
235
319
|
* Create a user-scoped client for making authenticated API calls.
|
|
@@ -254,14 +338,18 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
254
338
|
redirect_uri: redirectUri || this.config.redirectUri || ""
|
|
255
339
|
};
|
|
256
340
|
try {
|
|
257
|
-
const response = await this.fetchWithTimeout(
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
341
|
+
const response = await this.fetchWithTimeout(
|
|
342
|
+
tokenUrl,
|
|
343
|
+
{
|
|
344
|
+
method: "POST",
|
|
345
|
+
headers: {
|
|
346
|
+
"Content-Type": "application/json",
|
|
347
|
+
"User-Agent": USER_AGENT
|
|
348
|
+
},
|
|
349
|
+
body: JSON.stringify(body)
|
|
262
350
|
},
|
|
263
|
-
|
|
264
|
-
|
|
351
|
+
this.dispatcher
|
|
352
|
+
);
|
|
265
353
|
if (!response.ok) {
|
|
266
354
|
const error = await response.json().catch(() => ({}));
|
|
267
355
|
throw this.handleTokenError(error, response.status);
|
|
@@ -282,14 +370,18 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
282
370
|
client_secret: this.config.clientSecret
|
|
283
371
|
};
|
|
284
372
|
try {
|
|
285
|
-
const response = await this.fetchWithTimeout(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
373
|
+
const response = await this.fetchWithTimeout(
|
|
374
|
+
tokenUrl,
|
|
375
|
+
{
|
|
376
|
+
method: "POST",
|
|
377
|
+
headers: {
|
|
378
|
+
"Content-Type": "application/json",
|
|
379
|
+
"User-Agent": USER_AGENT
|
|
380
|
+
},
|
|
381
|
+
body: JSON.stringify(body)
|
|
290
382
|
},
|
|
291
|
-
|
|
292
|
-
|
|
383
|
+
this.dispatcher
|
|
384
|
+
);
|
|
293
385
|
if (!response.ok) {
|
|
294
386
|
const error = await response.json().catch(() => ({}));
|
|
295
387
|
throw new EdgeAuthenticationError(
|
|
@@ -329,11 +421,15 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
329
421
|
requestBody = { jwe: encryptMle(body, this.config.clientId, mleConfig) };
|
|
330
422
|
}
|
|
331
423
|
}
|
|
332
|
-
const response = await this.fetchWithTimeout(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
424
|
+
const response = await this.fetchWithTimeout(
|
|
425
|
+
url,
|
|
426
|
+
{
|
|
427
|
+
method,
|
|
428
|
+
headers: requestHeaders,
|
|
429
|
+
body: requestBody !== void 0 ? JSON.stringify(requestBody) : void 0
|
|
430
|
+
},
|
|
431
|
+
this.dispatcher
|
|
432
|
+
);
|
|
337
433
|
const rawResponseBody = await response.json().catch(() => ({}));
|
|
338
434
|
let responseBody = rawResponseBody;
|
|
339
435
|
if (mleEnabled && typeof rawResponseBody?.jwe === "string") {
|
|
@@ -392,14 +488,18 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
392
488
|
async sleep(ms) {
|
|
393
489
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
394
490
|
}
|
|
395
|
-
async fetchWithTimeout(url, options) {
|
|
491
|
+
async fetchWithTimeout(url, options, dispatcher) {
|
|
396
492
|
const controller = new AbortController();
|
|
397
493
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
398
494
|
try {
|
|
399
|
-
|
|
495
|
+
const fetchOptions = {
|
|
400
496
|
...options,
|
|
401
497
|
signal: controller.signal
|
|
402
|
-
}
|
|
498
|
+
};
|
|
499
|
+
if (dispatcher) {
|
|
500
|
+
fetchOptions.dispatcher = dispatcher;
|
|
501
|
+
}
|
|
502
|
+
return await fetch(url, fetchOptions);
|
|
403
503
|
} finally {
|
|
404
504
|
clearTimeout(timeoutId);
|
|
405
505
|
}
|
|
@@ -455,8 +555,21 @@ var EdgeConnectServer = class _EdgeConnectServer {
|
|
|
455
555
|
}
|
|
456
556
|
}
|
|
457
557
|
if (status === 404) {
|
|
458
|
-
|
|
459
|
-
|
|
558
|
+
let resourceType = "Resource";
|
|
559
|
+
let resourceId = path.split("/").pop() || "unknown";
|
|
560
|
+
if (path.includes("/verification-session/")) {
|
|
561
|
+
resourceType = "VerificationSession";
|
|
562
|
+
const parts = path.split("/");
|
|
563
|
+
const vsIdx = parts.indexOf("verification-session");
|
|
564
|
+
resourceId = vsIdx >= 0 && parts[vsIdx + 1] ? parts[vsIdx + 1] : "unknown";
|
|
565
|
+
} else if (path.includes("/verification-session")) {
|
|
566
|
+
resourceType = "Transfer";
|
|
567
|
+
const parts = path.split("/");
|
|
568
|
+
const txIdx = parts.indexOf("transfer");
|
|
569
|
+
resourceId = txIdx >= 0 && parts[txIdx + 1] ? parts[txIdx + 1] : "unknown";
|
|
570
|
+
} else if (path.includes("/transfer")) {
|
|
571
|
+
resourceType = "Transfer";
|
|
572
|
+
}
|
|
460
573
|
return new EdgeNotFoundError(resourceType, resourceId);
|
|
461
574
|
}
|
|
462
575
|
if (status === 422 && error.error === "identity_verification_failed") {
|
|
@@ -480,6 +593,7 @@ import {
|
|
|
480
593
|
EdgeAuthenticationError as EdgeAuthenticationError2,
|
|
481
594
|
EdgeConsentRequiredError as EdgeConsentRequiredError2,
|
|
482
595
|
EdgeError as EdgeError2,
|
|
596
|
+
EdgeIdentityVerificationError as EdgeIdentityVerificationError2,
|
|
483
597
|
EdgeInsufficientScopeError as EdgeInsufficientScopeError2,
|
|
484
598
|
EdgeNetworkError as EdgeNetworkError2,
|
|
485
599
|
EdgeNotFoundError as EdgeNotFoundError2,
|
|
@@ -488,25 +602,29 @@ import {
|
|
|
488
602
|
isAuthenticationError,
|
|
489
603
|
isConsentRequiredError,
|
|
490
604
|
isEdgeError,
|
|
605
|
+
isIdentityVerificationError,
|
|
491
606
|
isNetworkError
|
|
492
607
|
} from "@edge-markets/connect";
|
|
493
|
-
import { getEnvironmentConfig as getEnvironmentConfig2, isProductionEnvironment } from "@edge-markets/connect";
|
|
608
|
+
import { TRANSFER_CATEGORIES, getEnvironmentConfig as getEnvironmentConfig2, isProductionEnvironment } from "@edge-markets/connect";
|
|
494
609
|
export {
|
|
495
610
|
EdgeApiError2 as EdgeApiError,
|
|
496
611
|
EdgeAuthenticationError2 as EdgeAuthenticationError,
|
|
497
612
|
EdgeConnectServer,
|
|
498
613
|
EdgeConsentRequiredError2 as EdgeConsentRequiredError,
|
|
499
614
|
EdgeError2 as EdgeError,
|
|
615
|
+
EdgeIdentityVerificationError2 as EdgeIdentityVerificationError,
|
|
500
616
|
EdgeInsufficientScopeError2 as EdgeInsufficientScopeError,
|
|
501
617
|
EdgeNetworkError2 as EdgeNetworkError,
|
|
502
618
|
EdgeNotFoundError2 as EdgeNotFoundError,
|
|
503
619
|
EdgeTokenExchangeError2 as EdgeTokenExchangeError,
|
|
504
620
|
EdgeUserClient,
|
|
621
|
+
TRANSFER_CATEGORIES,
|
|
505
622
|
getEnvironmentConfig2 as getEnvironmentConfig,
|
|
506
623
|
isApiError,
|
|
507
624
|
isAuthenticationError,
|
|
508
625
|
isConsentRequiredError,
|
|
509
626
|
isEdgeError,
|
|
627
|
+
isIdentityVerificationError,
|
|
510
628
|
isNetworkError,
|
|
511
629
|
isProductionEnvironment
|
|
512
630
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edge-markets/connect-node",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Server SDK for EDGE Connect token exchange and API calls",
|
|
5
5
|
"author": "Edge Markets",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@edge-markets/connect": "^1.
|
|
24
|
+
"@edge-markets/connect": "^1.5.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"tsup": "^8.0.0",
|