@edge-markets/connect-react-native 1.2.0 → 1.4.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/dist/index.d.mts CHANGED
@@ -1,23 +1,10 @@
1
- import { EdgeEnvironment, EdgeLinkSuccess, EdgeLinkExit, EdgeScope } from '@edge-markets/connect';
2
- export { ALL_EDGE_SCOPES, Balance, EDGE_ENVIRONMENTS, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, EdgeEnvironment, EdgeError, EdgeLinkExit, EdgeLinkSuccess, EdgeNetworkError, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, EdgeTokens, SCOPE_DESCRIPTIONS, Transfer, User, formatScopesForEnvironment, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isNetworkError } from '@edge-markets/connect';
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';
3
3
 
4
- interface EdgeLinkConfig {
5
- clientId: string;
6
- environment: EdgeEnvironment;
4
+ interface EdgeLinkConfig extends EdgeLinkConfigBase {
7
5
  redirectUri: string;
8
- onSuccess: (result: EdgeLinkSuccess) => void;
9
- onExit?: (metadata: EdgeLinkExit) => void;
10
- onEvent?: (event: EdgeLinkEvent) => void;
11
- scopes?: EdgeScope[];
12
- linkUrl?: string;
13
6
  useExternalBrowser?: boolean;
14
7
  }
15
- interface EdgeLinkEvent {
16
- eventName: EdgeLinkEventName;
17
- timestamp: number;
18
- metadata?: Record<string, unknown>;
19
- }
20
- type EdgeLinkEventName = 'OPEN' | 'CLOSE' | 'HANDOFF' | 'SUCCESS' | 'ERROR' | 'REDIRECT';
21
8
  declare class EdgeLink {
22
9
  private readonly config;
23
10
  private pkce;
@@ -155,6 +142,8 @@ declare function useEdgeLink(config: UseEdgeLinkConfig): UseEdgeLinkReturn;
155
142
  interface UseEdgeLinkHandlerConfig {
156
143
  /** Your redirect URI prefix */
157
144
  redirectUri: string;
145
+ /** PKCE code verifier from the EdgeLink instance that initiated the flow */
146
+ codeVerifier: string;
158
147
  /** Called on successful auth */
159
148
  onSuccess: (result: EdgeLinkSuccess) => void;
160
149
  /** Called on error or user exit */
@@ -188,12 +177,41 @@ declare function useEdgeLinkHandler(config: UseEdgeLinkHandlerConfig): UseEdgeLi
188
177
  */
189
178
  declare function useEdgeLinkEvents(onEvent: (event: EdgeLinkEvent) => void, deps?: React.DependencyList): void;
190
179
 
191
- interface PKCEPair {
192
- verifier: string;
193
- challenge: string;
194
- }
180
+ /**
181
+ * React Native Geolocation Collector for EDGE Connect
182
+ *
183
+ * Collects the device's geolocation using available React Native geolocation
184
+ * libraries. Supports multiple libraries via dynamic import fallback chain:
185
+ *
186
+ * 1. `@react-native-community/geolocation` (most common)
187
+ * 2. `expo-location` (Expo projects)
188
+ * 3. Returns `null` if neither is available
189
+ *
190
+ * This function **never throws** — it returns `null` on permission denial,
191
+ * timeout, or library unavailability.
192
+ *
193
+ * @module @edge-markets/connect-react-native
194
+ */
195
+
196
+ /**
197
+ * Collects the device's geolocation using available React Native libraries.
198
+ *
199
+ * @returns The device's geolocation, or `null` if unavailable
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * import { collectGeolocation } from '@edge-markets/connect-react-native'
204
+ *
205
+ * const geo = await collectGeolocation()
206
+ * if (geo) {
207
+ * console.log(`Location: ${geo.latitude}, ${geo.longitude}`)
208
+ * }
209
+ * ```
210
+ */
211
+ declare function collectGeolocation(): Promise<SdkGeolocation | null>;
212
+
195
213
  declare function generatePKCE(): Promise<PKCEPair>;
196
- declare function generateState(): string;
214
+ declare function generateState(): Promise<string>;
197
215
  declare function isSecureCryptoAvailable(): Promise<boolean>;
198
216
 
199
- export { EdgeLink, type EdgeLinkConfig, type EdgeLinkEvent, type EdgeLinkEventName, type PKCEPair, type UseEdgeLinkConfig, type UseEdgeLinkHandlerConfig, type UseEdgeLinkHandlerReturn, type UseEdgeLinkReturn, generatePKCE, generateState, isSecureCryptoAvailable, useEdgeLink, useEdgeLinkEvents, useEdgeLinkHandler };
217
+ export { EdgeLink, type EdgeLinkConfig, type UseEdgeLinkConfig, type UseEdgeLinkHandlerConfig, type UseEdgeLinkHandlerReturn, type UseEdgeLinkReturn, collectGeolocation, generatePKCE, generateState, isSecureCryptoAvailable, useEdgeLink, useEdgeLinkEvents, useEdgeLinkHandler };
package/dist/index.d.ts CHANGED
@@ -1,23 +1,10 @@
1
- import { EdgeEnvironment, EdgeLinkSuccess, EdgeLinkExit, EdgeScope } from '@edge-markets/connect';
2
- export { ALL_EDGE_SCOPES, Balance, EDGE_ENVIRONMENTS, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, EdgeEnvironment, EdgeError, EdgeLinkExit, EdgeLinkSuccess, EdgeNetworkError, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, EdgeTokens, SCOPE_DESCRIPTIONS, Transfer, User, formatScopesForEnvironment, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isNetworkError } from '@edge-markets/connect';
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';
3
3
 
4
- interface EdgeLinkConfig {
5
- clientId: string;
6
- environment: EdgeEnvironment;
4
+ interface EdgeLinkConfig extends EdgeLinkConfigBase {
7
5
  redirectUri: string;
8
- onSuccess: (result: EdgeLinkSuccess) => void;
9
- onExit?: (metadata: EdgeLinkExit) => void;
10
- onEvent?: (event: EdgeLinkEvent) => void;
11
- scopes?: EdgeScope[];
12
- linkUrl?: string;
13
6
  useExternalBrowser?: boolean;
14
7
  }
15
- interface EdgeLinkEvent {
16
- eventName: EdgeLinkEventName;
17
- timestamp: number;
18
- metadata?: Record<string, unknown>;
19
- }
20
- type EdgeLinkEventName = 'OPEN' | 'CLOSE' | 'HANDOFF' | 'SUCCESS' | 'ERROR' | 'REDIRECT';
21
8
  declare class EdgeLink {
22
9
  private readonly config;
23
10
  private pkce;
@@ -155,6 +142,8 @@ declare function useEdgeLink(config: UseEdgeLinkConfig): UseEdgeLinkReturn;
155
142
  interface UseEdgeLinkHandlerConfig {
156
143
  /** Your redirect URI prefix */
157
144
  redirectUri: string;
145
+ /** PKCE code verifier from the EdgeLink instance that initiated the flow */
146
+ codeVerifier: string;
158
147
  /** Called on successful auth */
159
148
  onSuccess: (result: EdgeLinkSuccess) => void;
160
149
  /** Called on error or user exit */
@@ -188,12 +177,41 @@ declare function useEdgeLinkHandler(config: UseEdgeLinkHandlerConfig): UseEdgeLi
188
177
  */
189
178
  declare function useEdgeLinkEvents(onEvent: (event: EdgeLinkEvent) => void, deps?: React.DependencyList): void;
190
179
 
191
- interface PKCEPair {
192
- verifier: string;
193
- challenge: string;
194
- }
180
+ /**
181
+ * React Native Geolocation Collector for EDGE Connect
182
+ *
183
+ * Collects the device's geolocation using available React Native geolocation
184
+ * libraries. Supports multiple libraries via dynamic import fallback chain:
185
+ *
186
+ * 1. `@react-native-community/geolocation` (most common)
187
+ * 2. `expo-location` (Expo projects)
188
+ * 3. Returns `null` if neither is available
189
+ *
190
+ * This function **never throws** — it returns `null` on permission denial,
191
+ * timeout, or library unavailability.
192
+ *
193
+ * @module @edge-markets/connect-react-native
194
+ */
195
+
196
+ /**
197
+ * Collects the device's geolocation using available React Native libraries.
198
+ *
199
+ * @returns The device's geolocation, or `null` if unavailable
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * import { collectGeolocation } from '@edge-markets/connect-react-native'
204
+ *
205
+ * const geo = await collectGeolocation()
206
+ * if (geo) {
207
+ * console.log(`Location: ${geo.latitude}, ${geo.longitude}`)
208
+ * }
209
+ * ```
210
+ */
211
+ declare function collectGeolocation(): Promise<SdkGeolocation | null>;
212
+
195
213
  declare function generatePKCE(): Promise<PKCEPair>;
196
- declare function generateState(): string;
214
+ declare function generateState(): Promise<string>;
197
215
  declare function isSecureCryptoAvailable(): Promise<boolean>;
198
216
 
199
- export { EdgeLink, type EdgeLinkConfig, type EdgeLinkEvent, type EdgeLinkEventName, type PKCEPair, type UseEdgeLinkConfig, type UseEdgeLinkHandlerConfig, type UseEdgeLinkHandlerReturn, type UseEdgeLinkReturn, generatePKCE, generateState, isSecureCryptoAvailable, useEdgeLink, useEdgeLinkEvents, useEdgeLinkHandler };
217
+ export { EdgeLink, type EdgeLinkConfig, type UseEdgeLinkConfig, type UseEdgeLinkHandlerConfig, type UseEdgeLinkHandlerReturn, type UseEdgeLinkReturn, collectGeolocation, generatePKCE, generateState, isSecureCryptoAvailable, useEdgeLink, useEdgeLinkEvents, useEdgeLinkHandler };
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@ __export(index_exports, {
42
42
  EdgeStateMismatchError: () => import_connect2.EdgeStateMismatchError,
43
43
  EdgeTokenExchangeError: () => import_connect2.EdgeTokenExchangeError,
44
44
  SCOPE_DESCRIPTIONS: () => import_connect2.SCOPE_DESCRIPTIONS,
45
+ collectGeolocation: () => collectGeolocation,
45
46
  formatScopesForEnvironment: () => import_connect2.formatScopesForEnvironment,
46
47
  generatePKCE: () => generatePKCE,
47
48
  generateState: () => generateState,
@@ -233,13 +234,9 @@ async function getRandomBytes(byteLength) {
233
234
  return ExpoRandom.getRandomBytes(byteLength);
234
235
  } catch {
235
236
  }
236
- console.warn(
237
- "[EdgeLink] Using Math.random fallback - NOT CRYPTOGRAPHICALLY SECURE!\nInstall react-native-get-random-values or expo-random for production."
237
+ throw new Error(
238
+ "[EdgeLink] No cryptographically secure random source available. Install react-native-get-random-values (and import it before EdgeLink) or expo-random."
238
239
  );
239
- for (let i = 0; i < byteLength; i++) {
240
- array[i] = Math.floor(Math.random() * 256);
241
- }
242
- return array;
243
240
  }
244
241
  async function generateRandomHex(byteLength) {
245
242
  const bytes = await getRandomBytes(byteLength);
@@ -281,16 +278,9 @@ async function generatePKCE() {
281
278
  const challenge = base64UrlEncode(hash);
282
279
  return { verifier, challenge };
283
280
  }
284
- function generateState() {
285
- const array = new Uint8Array(32);
286
- if (typeof globalThis.crypto?.getRandomValues === "function") {
287
- globalThis.crypto.getRandomValues(array);
288
- } else {
289
- for (let i = 0; i < 32; i++) {
290
- array[i] = Math.floor(Math.random() * 256);
291
- }
292
- }
293
- return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("");
281
+ async function generateState() {
282
+ const bytes = await getRandomBytes(32);
283
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
294
284
  }
295
285
  async function isSecureCryptoAvailable() {
296
286
  if (typeof globalThis.crypto?.getRandomValues === "function") {
@@ -395,7 +385,7 @@ var EdgeLink = class {
395
385
  this.isOpen = true;
396
386
  try {
397
387
  this.pkce = await generatePKCE();
398
- this.state = generateState();
388
+ this.state = await generateState();
399
389
  this.setupLinkListener();
400
390
  const url = this.buildLinkUrl();
401
391
  this.emitEvent("HANDOFF", { url });
@@ -630,7 +620,6 @@ function useEdgeLinkHandler(config) {
630
620
  const state = parsed.searchParams.get("state");
631
621
  const error = parsed.searchParams.get("error");
632
622
  const errorDescription = parsed.searchParams.get("error_description");
633
- const codeVerifier = parsed.searchParams.get("code_verifier");
634
623
  if (error) {
635
624
  config.onError?.({
636
625
  code: error,
@@ -641,8 +630,7 @@ function useEdgeLinkHandler(config) {
641
630
  if (code && state) {
642
631
  config.onSuccess({
643
632
  code,
644
- codeVerifier: codeVerifier || "",
645
- // Might be empty if not passed in URL
633
+ codeVerifier: config.codeVerifier,
646
634
  state
647
635
  });
648
636
  return true;
@@ -668,6 +656,44 @@ function useEdgeLinkEvents(onEvent, deps = []) {
668
656
  (0, import_react.useEffect)(() => {
669
657
  }, [onEvent, ...deps]);
670
658
  }
659
+
660
+ // src/geolocation.ts
661
+ async function collectGeolocation() {
662
+ try {
663
+ const Geolocation = (await import("@react-native-community/geolocation")).default;
664
+ return new Promise((resolve) => {
665
+ Geolocation.getCurrentPosition(
666
+ (position) => {
667
+ resolve({
668
+ latitude: position.coords.latitude,
669
+ longitude: position.coords.longitude,
670
+ accuracy: position.coords.accuracy,
671
+ timestamp: new Date(position.timestamp).toISOString()
672
+ });
673
+ },
674
+ () => resolve(null),
675
+ { timeout: 1e4, maximumAge: 6e4, enableHighAccuracy: false }
676
+ );
677
+ });
678
+ } catch {
679
+ }
680
+ try {
681
+ const Location = await import("expo-location");
682
+ const { status } = await Location.requestForegroundPermissionsAsync();
683
+ if (status !== "granted") return null;
684
+ const position = await Location.getCurrentPositionAsync({
685
+ accuracy: Location.Accuracy?.Balanced
686
+ });
687
+ return {
688
+ latitude: position.coords.latitude,
689
+ longitude: position.coords.longitude,
690
+ accuracy: position.coords.accuracy,
691
+ timestamp: new Date(position.timestamp).toISOString()
692
+ };
693
+ } catch {
694
+ }
695
+ return null;
696
+ }
671
697
  // Annotate the CommonJS export names for ESM import in node:
672
698
  0 && (module.exports = {
673
699
  ALL_EDGE_SCOPES,
@@ -682,6 +708,7 @@ function useEdgeLinkEvents(onEvent, deps = []) {
682
708
  EdgeStateMismatchError,
683
709
  EdgeTokenExchangeError,
684
710
  SCOPE_DESCRIPTIONS,
711
+ collectGeolocation,
685
712
  formatScopesForEnvironment,
686
713
  generatePKCE,
687
714
  generateState,
package/dist/index.mjs CHANGED
@@ -1,21 +1,21 @@
1
1
  // src/index.ts
2
2
  import {
3
- getEnvironmentConfig as getEnvironmentConfig2,
4
- EDGE_ENVIRONMENTS,
5
3
  ALL_EDGE_SCOPES as ALL_EDGE_SCOPES2,
6
- SCOPE_DESCRIPTIONS,
7
- formatScopesForEnvironment as formatScopesForEnvironment2,
8
- EdgeError,
4
+ EDGE_ENVIRONMENTS,
5
+ EdgeApiError,
9
6
  EdgeAuthenticationError,
10
7
  EdgeConsentRequiredError,
11
- EdgeTokenExchangeError,
12
- EdgeApiError,
8
+ EdgeError,
13
9
  EdgeNetworkError,
14
10
  EdgePopupBlockedError,
15
11
  EdgeStateMismatchError,
12
+ EdgeTokenExchangeError,
13
+ SCOPE_DESCRIPTIONS,
14
+ formatScopesForEnvironment as formatScopesForEnvironment2,
15
+ getEnvironmentConfig as getEnvironmentConfig2,
16
+ isApiError,
16
17
  isAuthenticationError,
17
18
  isConsentRequiredError,
18
- isApiError,
19
19
  isNetworkError
20
20
  } from "@edge-markets/connect";
21
21
 
@@ -198,13 +198,9 @@ async function getRandomBytes(byteLength) {
198
198
  return ExpoRandom.getRandomBytes(byteLength);
199
199
  } catch {
200
200
  }
201
- console.warn(
202
- "[EdgeLink] Using Math.random fallback - NOT CRYPTOGRAPHICALLY SECURE!\nInstall react-native-get-random-values or expo-random for production."
201
+ throw new Error(
202
+ "[EdgeLink] No cryptographically secure random source available. Install react-native-get-random-values (and import it before EdgeLink) or expo-random."
203
203
  );
204
- for (let i = 0; i < byteLength; i++) {
205
- array[i] = Math.floor(Math.random() * 256);
206
- }
207
- return array;
208
204
  }
209
205
  async function generateRandomHex(byteLength) {
210
206
  const bytes = await getRandomBytes(byteLength);
@@ -246,16 +242,9 @@ async function generatePKCE() {
246
242
  const challenge = base64UrlEncode(hash);
247
243
  return { verifier, challenge };
248
244
  }
249
- function generateState() {
250
- const array = new Uint8Array(32);
251
- if (typeof globalThis.crypto?.getRandomValues === "function") {
252
- globalThis.crypto.getRandomValues(array);
253
- } else {
254
- for (let i = 0; i < 32; i++) {
255
- array[i] = Math.floor(Math.random() * 256);
256
- }
257
- }
258
- return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("");
245
+ async function generateState() {
246
+ const bytes = await getRandomBytes(32);
247
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
259
248
  }
260
249
  async function isSecureCryptoAvailable() {
261
250
  if (typeof globalThis.crypto?.getRandomValues === "function") {
@@ -360,7 +349,7 @@ var EdgeLink = class {
360
349
  this.isOpen = true;
361
350
  try {
362
351
  this.pkce = await generatePKCE();
363
- this.state = generateState();
352
+ this.state = await generateState();
364
353
  this.setupLinkListener();
365
354
  const url = this.buildLinkUrl();
366
355
  this.emitEvent("HANDOFF", { url });
@@ -595,7 +584,6 @@ function useEdgeLinkHandler(config) {
595
584
  const state = parsed.searchParams.get("state");
596
585
  const error = parsed.searchParams.get("error");
597
586
  const errorDescription = parsed.searchParams.get("error_description");
598
- const codeVerifier = parsed.searchParams.get("code_verifier");
599
587
  if (error) {
600
588
  config.onError?.({
601
589
  code: error,
@@ -606,8 +594,7 @@ function useEdgeLinkHandler(config) {
606
594
  if (code && state) {
607
595
  config.onSuccess({
608
596
  code,
609
- codeVerifier: codeVerifier || "",
610
- // Might be empty if not passed in URL
597
+ codeVerifier: config.codeVerifier,
611
598
  state
612
599
  });
613
600
  return true;
@@ -633,6 +620,44 @@ function useEdgeLinkEvents(onEvent, deps = []) {
633
620
  useEffect(() => {
634
621
  }, [onEvent, ...deps]);
635
622
  }
623
+
624
+ // src/geolocation.ts
625
+ async function collectGeolocation() {
626
+ try {
627
+ const Geolocation = (await import("@react-native-community/geolocation")).default;
628
+ return new Promise((resolve) => {
629
+ Geolocation.getCurrentPosition(
630
+ (position) => {
631
+ resolve({
632
+ latitude: position.coords.latitude,
633
+ longitude: position.coords.longitude,
634
+ accuracy: position.coords.accuracy,
635
+ timestamp: new Date(position.timestamp).toISOString()
636
+ });
637
+ },
638
+ () => resolve(null),
639
+ { timeout: 1e4, maximumAge: 6e4, enableHighAccuracy: false }
640
+ );
641
+ });
642
+ } catch {
643
+ }
644
+ try {
645
+ const Location = await import("expo-location");
646
+ const { status } = await Location.requestForegroundPermissionsAsync();
647
+ if (status !== "granted") return null;
648
+ const position = await Location.getCurrentPositionAsync({
649
+ accuracy: Location.Accuracy?.Balanced
650
+ });
651
+ return {
652
+ latitude: position.coords.latitude,
653
+ longitude: position.coords.longitude,
654
+ accuracy: position.coords.accuracy,
655
+ timestamp: new Date(position.timestamp).toISOString()
656
+ };
657
+ } catch {
658
+ }
659
+ return null;
660
+ }
636
661
  export {
637
662
  ALL_EDGE_SCOPES2 as ALL_EDGE_SCOPES,
638
663
  EDGE_ENVIRONMENTS,
@@ -646,6 +671,7 @@ export {
646
671
  EdgeStateMismatchError,
647
672
  EdgeTokenExchangeError,
648
673
  SCOPE_DESCRIPTIONS,
674
+ collectGeolocation,
649
675
  formatScopesForEnvironment2 as formatScopesForEnvironment,
650
676
  generatePKCE,
651
677
  generateState,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edge-markets/connect-react-native",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
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.0.0"
33
+ "@edge-markets/connect": "1.5.0"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "react": ">=18.0.0",