@edge-markets/connect-react-native 1.4.2 → 1.5.1

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 CHANGED
@@ -74,7 +74,7 @@ import { Button, Alert } from 'react-native'
74
74
  function ConnectEdgeButton() {
75
75
  const { open, isOpen, isSuccess, result, error, reset } = useEdgeLink({
76
76
  clientId: 'your-client-id',
77
- environment: 'staging',
77
+ environment: 'sandbox',
78
78
  redirectUri: 'myapp://oauth/callback',
79
79
  })
80
80
 
@@ -130,14 +130,14 @@ React hook for EdgeLink integration.
130
130
  | Property | Type | Required | Description |
131
131
  |----------|------|----------|-------------|
132
132
  | `clientId` | `string` | ✅ | Your OAuth client ID |
133
- | `environment` | `'production' \| 'staging' \| 'sandbox'` | ✅ | Environment |
133
+ | `environment` | `'production' \| 'sandbox'` | ✅ | Environment |
134
134
  | `redirectUri` | `string` | ✅ | Deep link URI for callback |
135
135
  | `scopes` | `EdgeScope[]` | ❌ | Requested permissions |
136
136
  | `linkUrl` | `string` | ❌ | Custom Link URL/origin (dev only) |
137
137
  | `useExternalBrowser` | `boolean` | ❌ | Use external browser |
138
138
 
139
- The SDK derives the hosted Link URL from `environment`; staging defaults to
140
- `https://oauth.staging-app.edgeboost.io/oauth/link`. `linkUrl` is only needed for
139
+ The SDK derives the hosted Link URL from `environment`; sandbox defaults to
140
+ `https://sandbox-oauth.staging-app.edgeboost.io/oauth/link`. `linkUrl` is only needed for
141
141
  nonstandard deployments. If provided as an origin, for example
142
142
  `https://oauth.example.com`, the SDK appends `/oauth/link`.
143
143
 
@@ -162,7 +162,7 @@ import { EdgeLink } from '@edge-markets/connect-react-native'
162
162
 
163
163
  const link = new EdgeLink({
164
164
  clientId: 'your-client-id',
165
- environment: 'staging',
165
+ environment: 'sandbox',
166
166
  redirectUri: 'myapp://oauth/callback',
167
167
  onSuccess: (result) => {
168
168
  console.log('Auth code:', result.code)
@@ -262,7 +262,7 @@ import { EdgeConnectServer } from '@edge-markets/connect-node'
262
262
  const server = new EdgeConnectServer({
263
263
  clientId: 'your-client-id',
264
264
  clientSecret: 'your-client-secret',
265
- environment: 'staging',
265
+ environment: 'sandbox',
266
266
  })
267
267
 
268
268
  // In your API endpoint
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EdgeLinkConfigBase, EdgeEnvironment, EdgeScope, EdgeLinkSuccess, EdgeLinkEvent, SdkGeolocation, PKCEPair } from '@edge-markets/connect';
2
- export { ALL_EDGE_SCOPES, Balance, EDGE_ENVIRONMENTS, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, EdgeEnvironment, EdgeError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgeNetworkError, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, EdgeTokens, PKCEPair, SCOPE_DESCRIPTIONS, SdkGeolocation, Transfer, User, formatScopesForEnvironment, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isNetworkError } from '@edge-markets/connect';
2
+ export { ACTIVE_EDGE_SCOPES, ALL_EDGE_SCOPES, Balance, EDGE_CONNECT_FEATURE_UNAVAILABLE_MESSAGE, EDGE_ENVIRONMENTS, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, EdgeEnvironment, EdgeError, EdgeFeatureUnavailableError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgeNetworkError, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, EdgeTokens, PKCEPair, RESERVED_EDGE_SCOPES, SCOPE_DESCRIPTIONS, SdkGeolocation, Transfer, User, formatScopesForEnvironment, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isFeatureUnavailableError, isNetworkError } from '@edge-markets/connect';
3
3
 
4
4
  interface EdgeLinkConfig extends EdgeLinkConfigBase {
5
5
  redirectUri: string;
@@ -18,6 +18,8 @@ declare class EdgeLink {
18
18
  close(): Promise<void>;
19
19
  destroy(): void;
20
20
  private buildLinkUrl;
21
+ private getScopes;
22
+ private assertActiveScopes;
21
23
  private setupLinkListener;
22
24
  private removeLinkListener;
23
25
  private processCallback;
@@ -85,7 +87,7 @@ interface UseEdgeLinkReturn {
85
87
  * function ConnectButton() {
86
88
  * const { open, isOpen, isSuccess, result, error } = useEdgeLink({
87
89
  * clientId: 'your-client-id',
88
- * environment: 'staging',
90
+ * environment: 'sandbox',
89
91
  * redirectUri: 'myapp://oauth/callback',
90
92
  * })
91
93
  *
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EdgeLinkConfigBase, EdgeEnvironment, EdgeScope, EdgeLinkSuccess, EdgeLinkEvent, SdkGeolocation, PKCEPair } from '@edge-markets/connect';
2
- export { ALL_EDGE_SCOPES, Balance, EDGE_ENVIRONMENTS, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, EdgeEnvironment, EdgeError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgeNetworkError, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, EdgeTokens, PKCEPair, SCOPE_DESCRIPTIONS, SdkGeolocation, Transfer, User, formatScopesForEnvironment, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isNetworkError } from '@edge-markets/connect';
2
+ export { ACTIVE_EDGE_SCOPES, ALL_EDGE_SCOPES, Balance, EDGE_CONNECT_FEATURE_UNAVAILABLE_MESSAGE, EDGE_ENVIRONMENTS, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, EdgeEnvironment, EdgeError, EdgeFeatureUnavailableError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgeNetworkError, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, EdgeTokens, PKCEPair, RESERVED_EDGE_SCOPES, SCOPE_DESCRIPTIONS, SdkGeolocation, Transfer, User, formatScopesForEnvironment, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isFeatureUnavailableError, isNetworkError } from '@edge-markets/connect';
3
3
 
4
4
  interface EdgeLinkConfig extends EdgeLinkConfigBase {
5
5
  redirectUri: string;
@@ -18,6 +18,8 @@ declare class EdgeLink {
18
18
  close(): Promise<void>;
19
19
  destroy(): void;
20
20
  private buildLinkUrl;
21
+ private getScopes;
22
+ private assertActiveScopes;
21
23
  private setupLinkListener;
22
24
  private removeLinkListener;
23
25
  private processCallback;
@@ -85,7 +87,7 @@ interface UseEdgeLinkReturn {
85
87
  * function ConnectButton() {
86
88
  * const { open, isOpen, isSuccess, result, error } = useEdgeLink({
87
89
  * clientId: 'your-client-id',
88
- * environment: 'staging',
90
+ * environment: 'sandbox',
89
91
  * redirectUri: 'myapp://oauth/callback',
90
92
  * })
91
93
  *
package/dist/index.js CHANGED
@@ -30,17 +30,21 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ ACTIVE_EDGE_SCOPES: () => import_connect2.ACTIVE_EDGE_SCOPES,
33
34
  ALL_EDGE_SCOPES: () => import_connect2.ALL_EDGE_SCOPES,
35
+ EDGE_CONNECT_FEATURE_UNAVAILABLE_MESSAGE: () => import_connect2.EDGE_CONNECT_FEATURE_UNAVAILABLE_MESSAGE,
34
36
  EDGE_ENVIRONMENTS: () => import_connect2.EDGE_ENVIRONMENTS,
35
37
  EdgeApiError: () => import_connect2.EdgeApiError,
36
38
  EdgeAuthenticationError: () => import_connect2.EdgeAuthenticationError,
37
39
  EdgeConsentRequiredError: () => import_connect2.EdgeConsentRequiredError,
38
40
  EdgeError: () => import_connect2.EdgeError,
41
+ EdgeFeatureUnavailableError: () => import_connect2.EdgeFeatureUnavailableError,
39
42
  EdgeLink: () => EdgeLink,
40
43
  EdgeNetworkError: () => import_connect2.EdgeNetworkError,
41
44
  EdgePopupBlockedError: () => import_connect2.EdgePopupBlockedError,
42
45
  EdgeStateMismatchError: () => import_connect2.EdgeStateMismatchError,
43
46
  EdgeTokenExchangeError: () => import_connect2.EdgeTokenExchangeError,
47
+ RESERVED_EDGE_SCOPES: () => import_connect2.RESERVED_EDGE_SCOPES,
44
48
  SCOPE_DESCRIPTIONS: () => import_connect2.SCOPE_DESCRIPTIONS,
45
49
  collectGeolocation: () => collectGeolocation,
46
50
  formatScopesForEnvironment: () => import_connect2.formatScopesForEnvironment,
@@ -50,6 +54,7 @@ __export(index_exports, {
50
54
  isApiError: () => import_connect2.isApiError,
51
55
  isAuthenticationError: () => import_connect2.isAuthenticationError,
52
56
  isConsentRequiredError: () => import_connect2.isConsentRequiredError,
57
+ isFeatureUnavailableError: () => import_connect2.isFeatureUnavailableError,
53
58
  isNetworkError: () => import_connect2.isNetworkError,
54
59
  isSecureCryptoAvailable: () => isSecureCryptoAvailable,
55
60
  useEdgeLink: () => useEdgeLink,
@@ -381,6 +386,8 @@ var EdgeLink = class {
381
386
  console.warn("[EdgeLink] Already open");
382
387
  return;
383
388
  }
389
+ const scopes = this.getScopes();
390
+ this.assertActiveScopes(scopes);
384
391
  this.emitEvent("OPEN");
385
392
  this.isOpen = true;
386
393
  try {
@@ -424,7 +431,7 @@ var EdgeLink = class {
424
431
  }
425
432
  buildLinkUrl() {
426
433
  const url = new URL((0, import_connect.getLinkUrl)(this.config.environment, this.config.linkUrl));
427
- const scopes = this.config.scopes || import_connect.ALL_EDGE_SCOPES;
434
+ const scopes = this.getScopes();
428
435
  url.searchParams.set("client_id", this.config.clientId);
429
436
  url.searchParams.set("state", this.state);
430
437
  url.searchParams.set("code_challenge", this.pkce.challenge);
@@ -436,6 +443,14 @@ var EdgeLink = class {
436
443
  url.searchParams.set("flow", "redirect");
437
444
  return url.toString();
438
445
  }
446
+ getScopes() {
447
+ return this.config.scopes || import_connect.ACTIVE_EDGE_SCOPES;
448
+ }
449
+ assertActiveScopes(scopes) {
450
+ if (scopes.some((scope) => (0, import_connect.isTransferWriteScope)(scope))) {
451
+ throw new import_connect.EdgeFeatureUnavailableError();
452
+ }
453
+ }
439
454
  setupLinkListener() {
440
455
  this.removeLinkListener();
441
456
  this.linkListener = import_react_native.Linking.addEventListener("url", ({ url }) => {
@@ -568,21 +583,23 @@ function useEdgeLink(config) {
568
583
  linkRef.current?.destroy();
569
584
  linkRef.current = null;
570
585
  };
571
- }, [
572
- config.clientId,
573
- config.environment,
574
- config.redirectUri,
575
- config.scopes,
576
- config.linkUrl,
577
- config.useExternalBrowser
578
- ]);
586
+ }, [config.clientId, config.environment, config.redirectUri, config.scopes, config.linkUrl, config.useExternalBrowser]);
579
587
  const open = (0, import_react.useCallback)(async () => {
580
588
  if (!linkRef.current) return;
581
589
  setIsOpen(true);
582
590
  setIsSuccess(false);
583
591
  setIsError(false);
584
592
  setError(null);
585
- await linkRef.current.open();
593
+ try {
594
+ await linkRef.current.open();
595
+ } catch (err) {
596
+ setIsOpen(false);
597
+ setIsError(true);
598
+ setError({
599
+ code: err instanceof Error && "code" in err ? String(err.code) : "open_failed",
600
+ message: err instanceof Error ? err.message : "Failed to open EdgeLink"
601
+ });
602
+ }
586
603
  }, []);
587
604
  const close = (0, import_react.useCallback)(async () => {
588
605
  if (!linkRef.current) return;
@@ -694,17 +711,21 @@ async function collectGeolocation() {
694
711
  }
695
712
  // Annotate the CommonJS export names for ESM import in node:
696
713
  0 && (module.exports = {
714
+ ACTIVE_EDGE_SCOPES,
697
715
  ALL_EDGE_SCOPES,
716
+ EDGE_CONNECT_FEATURE_UNAVAILABLE_MESSAGE,
698
717
  EDGE_ENVIRONMENTS,
699
718
  EdgeApiError,
700
719
  EdgeAuthenticationError,
701
720
  EdgeConsentRequiredError,
702
721
  EdgeError,
722
+ EdgeFeatureUnavailableError,
703
723
  EdgeLink,
704
724
  EdgeNetworkError,
705
725
  EdgePopupBlockedError,
706
726
  EdgeStateMismatchError,
707
727
  EdgeTokenExchangeError,
728
+ RESERVED_EDGE_SCOPES,
708
729
  SCOPE_DESCRIPTIONS,
709
730
  collectGeolocation,
710
731
  formatScopesForEnvironment,
@@ -714,6 +735,7 @@ async function collectGeolocation() {
714
735
  isApiError,
715
736
  isAuthenticationError,
716
737
  isConsentRequiredError,
738
+ isFeatureUnavailableError,
717
739
  isNetworkError,
718
740
  isSecureCryptoAvailable,
719
741
  useEdgeLink,
package/dist/index.mjs CHANGED
@@ -1,11 +1,15 @@
1
1
  // src/index.ts
2
2
  import {
3
- ALL_EDGE_SCOPES as ALL_EDGE_SCOPES2,
3
+ ACTIVE_EDGE_SCOPES as ACTIVE_EDGE_SCOPES2,
4
+ ALL_EDGE_SCOPES,
5
+ RESERVED_EDGE_SCOPES,
6
+ EDGE_CONNECT_FEATURE_UNAVAILABLE_MESSAGE,
4
7
  EDGE_ENVIRONMENTS,
5
8
  EdgeApiError,
6
9
  EdgeAuthenticationError,
7
10
  EdgeConsentRequiredError,
8
11
  EdgeError,
12
+ EdgeFeatureUnavailableError as EdgeFeatureUnavailableError2,
9
13
  EdgeNetworkError,
10
14
  EdgePopupBlockedError,
11
15
  EdgeStateMismatchError,
@@ -16,14 +20,17 @@ import {
16
20
  isApiError,
17
21
  isAuthenticationError,
18
22
  isConsentRequiredError,
23
+ isFeatureUnavailableError,
19
24
  isNetworkError
20
25
  } from "@edge-markets/connect";
21
26
 
22
27
  // src/edge-link.ts
23
28
  import {
24
- ALL_EDGE_SCOPES,
29
+ ACTIVE_EDGE_SCOPES,
30
+ EdgeFeatureUnavailableError,
25
31
  formatScopesForEnvironment,
26
- getLinkUrl
32
+ getLinkUrl,
33
+ isTransferWriteScope
27
34
  } from "@edge-markets/connect";
28
35
  import { Linking, Platform } from "react-native";
29
36
 
@@ -345,6 +352,8 @@ var EdgeLink = class {
345
352
  console.warn("[EdgeLink] Already open");
346
353
  return;
347
354
  }
355
+ const scopes = this.getScopes();
356
+ this.assertActiveScopes(scopes);
348
357
  this.emitEvent("OPEN");
349
358
  this.isOpen = true;
350
359
  try {
@@ -388,7 +397,7 @@ var EdgeLink = class {
388
397
  }
389
398
  buildLinkUrl() {
390
399
  const url = new URL(getLinkUrl(this.config.environment, this.config.linkUrl));
391
- const scopes = this.config.scopes || ALL_EDGE_SCOPES;
400
+ const scopes = this.getScopes();
392
401
  url.searchParams.set("client_id", this.config.clientId);
393
402
  url.searchParams.set("state", this.state);
394
403
  url.searchParams.set("code_challenge", this.pkce.challenge);
@@ -400,6 +409,14 @@ var EdgeLink = class {
400
409
  url.searchParams.set("flow", "redirect");
401
410
  return url.toString();
402
411
  }
412
+ getScopes() {
413
+ return this.config.scopes || ACTIVE_EDGE_SCOPES;
414
+ }
415
+ assertActiveScopes(scopes) {
416
+ if (scopes.some((scope) => isTransferWriteScope(scope))) {
417
+ throw new EdgeFeatureUnavailableError();
418
+ }
419
+ }
403
420
  setupLinkListener() {
404
421
  this.removeLinkListener();
405
422
  this.linkListener = Linking.addEventListener("url", ({ url }) => {
@@ -532,21 +549,23 @@ function useEdgeLink(config) {
532
549
  linkRef.current?.destroy();
533
550
  linkRef.current = null;
534
551
  };
535
- }, [
536
- config.clientId,
537
- config.environment,
538
- config.redirectUri,
539
- config.scopes,
540
- config.linkUrl,
541
- config.useExternalBrowser
542
- ]);
552
+ }, [config.clientId, config.environment, config.redirectUri, config.scopes, config.linkUrl, config.useExternalBrowser]);
543
553
  const open = useCallback(async () => {
544
554
  if (!linkRef.current) return;
545
555
  setIsOpen(true);
546
556
  setIsSuccess(false);
547
557
  setIsError(false);
548
558
  setError(null);
549
- await linkRef.current.open();
559
+ try {
560
+ await linkRef.current.open();
561
+ } catch (err) {
562
+ setIsOpen(false);
563
+ setIsError(true);
564
+ setError({
565
+ code: err instanceof Error && "code" in err ? String(err.code) : "open_failed",
566
+ message: err instanceof Error ? err.message : "Failed to open EdgeLink"
567
+ });
568
+ }
550
569
  }, []);
551
570
  const close = useCallback(async () => {
552
571
  if (!linkRef.current) return;
@@ -657,17 +676,21 @@ async function collectGeolocation() {
657
676
  return null;
658
677
  }
659
678
  export {
660
- ALL_EDGE_SCOPES2 as ALL_EDGE_SCOPES,
679
+ ACTIVE_EDGE_SCOPES2 as ACTIVE_EDGE_SCOPES,
680
+ ALL_EDGE_SCOPES,
681
+ EDGE_CONNECT_FEATURE_UNAVAILABLE_MESSAGE,
661
682
  EDGE_ENVIRONMENTS,
662
683
  EdgeApiError,
663
684
  EdgeAuthenticationError,
664
685
  EdgeConsentRequiredError,
665
686
  EdgeError,
687
+ EdgeFeatureUnavailableError2 as EdgeFeatureUnavailableError,
666
688
  EdgeLink,
667
689
  EdgeNetworkError,
668
690
  EdgePopupBlockedError,
669
691
  EdgeStateMismatchError,
670
692
  EdgeTokenExchangeError,
693
+ RESERVED_EDGE_SCOPES,
671
694
  SCOPE_DESCRIPTIONS,
672
695
  collectGeolocation,
673
696
  formatScopesForEnvironment2 as formatScopesForEnvironment,
@@ -677,6 +700,7 @@ export {
677
700
  isApiError,
678
701
  isAuthenticationError,
679
702
  isConsentRequiredError,
703
+ isFeatureUnavailableError,
680
704
  isNetworkError,
681
705
  isSecureCryptoAvailable,
682
706
  useEdgeLink,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edge-markets/connect-react-native",
3
- "version": "1.4.2",
3
+ "version": "1.5.1",
4
4
  "description": "React Native SDK for EDGE Connect authentication flow for mobile apps",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -30,7 +30,7 @@
30
30
  "author": "EdgeBoost",
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
- "@edge-markets/connect": "^1.6.1"
33
+ "@edge-markets/connect": "^1.9.1"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "react": ">=18.0.0",