@edge-markets/connect-link 1.5.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 CHANGED
@@ -93,11 +93,16 @@ interface EdgeLinkConfig {
93
93
  onExit?: (metadata) => void // Called when user exits
94
94
  onEvent?: (event) => void // Called for analytics events
95
95
  scopes?: EdgeScope[] // Scopes to request (default: all)
96
- linkUrl?: string // Custom Link URL (dev only)
96
+ linkUrl?: string // Custom Link URL/origin (dev only)
97
97
  redirectUri?: string // Legacy popup callback URI (migration only)
98
98
  }
99
99
  ```
100
100
 
101
+ The SDK derives the hosted Link URL from `environment`; staging defaults to
102
+ `https://oauth.staging-app.edgeboost.io/oauth/link`. `linkUrl` is only needed for
103
+ nonstandard deployments. If provided as an origin, for example
104
+ `https://oauth.example.com`, the SDK appends `/oauth/link`.
105
+
101
106
  Popup integrations are origin-based. Register your frontend origin with EDGE
102
107
  for `postMessage` validation, for example:
103
108
 
@@ -325,9 +330,3 @@ function ConnectButton() {
325
330
 
326
331
  MIT
327
332
 
328
-
329
-
330
-
331
-
332
-
333
-
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { EdgeLinkConfigBase, EdgeScope, EdgeLinkSuccess, EdgeLinkExit, SdkGeolocation, PKCEPair } from '@edge-markets/connect';
1
+ import { EdgeLinkConfigBase, EdgeScope, SdkGeolocation, EdgeLinkSuccess, EdgeLinkExit, PKCEPair } from '@edge-markets/connect';
2
2
  export { ALL_EDGE_SCOPES, EDGE_SCOPES, EdgeEnvironment, EdgeError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, PKCEPair, SdkGeolocation, isEdgeError } from '@edge-markets/connect';
3
3
 
4
4
  /**
@@ -200,18 +200,6 @@ declare class EdgeLink {
200
200
  private cleanup;
201
201
  }
202
202
 
203
- interface UseEdgeLinkConfig extends Omit<EdgeLinkConfig, 'onSuccess' | 'onExit'> {
204
- onSuccess?: (result: EdgeLinkSuccess) => void | Promise<void>;
205
- onExit?: (metadata: EdgeLinkExit) => void;
206
- }
207
- interface UseEdgeLinkReturn {
208
- open: (options?: EdgeLinkOpenOptions) => void;
209
- ready: boolean;
210
- error: Error | null;
211
- isOpen: boolean;
212
- }
213
- declare function useEdgeLink(config: UseEdgeLinkConfig): UseEdgeLinkReturn;
214
-
215
203
  /**
216
204
  * EdgeTransferVerify - Transfer Verification Launcher for EDGE Connect
217
205
  *
@@ -634,6 +622,37 @@ declare class EdgeTransferVerify {
634
622
  private handleUserClose;
635
623
  }
636
624
 
625
+ interface UseEdgeLinkConfig extends Omit<EdgeLinkConfig, 'onSuccess' | 'onExit'> {
626
+ onSuccess?: (result: EdgeLinkSuccess) => void | Promise<void>;
627
+ onExit?: (metadata: EdgeLinkExit) => void;
628
+ }
629
+ interface UseEdgeLinkReturn {
630
+ open: (options?: EdgeLinkOpenOptions) => void;
631
+ ready: boolean;
632
+ error: Error | null;
633
+ isOpen: boolean;
634
+ }
635
+ declare function useEdgeLink(config: UseEdgeLinkConfig): UseEdgeLinkReturn;
636
+ interface UseEdgeTransferVerifyConfig extends Omit<EdgeTransferVerifyConfig, 'onSuccess' | 'onError' | 'onCancel' | 'onExpired' | 'onLoaded' | 'onEvent'> {
637
+ onSuccess?: (event: TransferVerifyEvent) => void | Promise<void>;
638
+ onError?: (event: TransferVerifyEvent) => void | Promise<void>;
639
+ onCancel?: (event: TransferVerifyEvent) => void | Promise<void>;
640
+ onExpired?: (event: TransferVerifyEvent) => void | Promise<void>;
641
+ onLoaded?: (event: TransferVerifyEvent) => void | Promise<void>;
642
+ onEvent?: (event: TransferVerifyEvent) => void | Promise<void>;
643
+ }
644
+ interface UseEdgeTransferVerifyReturn {
645
+ open: () => void;
646
+ close: () => void;
647
+ destroy: () => void;
648
+ ready: boolean;
649
+ isOpen: boolean;
650
+ isLoaded: boolean;
651
+ lastEvent: TransferVerifyEvent | null;
652
+ error: Error | null;
653
+ }
654
+ declare function useEdgeTransferVerify(config: UseEdgeTransferVerifyConfig): UseEdgeTransferVerifyReturn;
655
+
637
656
  /**
638
657
  * Iframe Manager
639
658
  *
@@ -879,4 +898,4 @@ declare function generateState(): string;
879
898
  */
880
899
  declare function assertCryptoAvailable(): void;
881
900
 
882
- export { EdgeLink, type EdgeLinkConfig, type EdgeLinkOpenOptions, EdgeTransferVerify, type EdgeTransferVerifyConfig, type GeolocationOptions, type IframeCallbacks, type IframeConfig, IframeManager, type TransferVerifyEvent, type TransferVerifyEventType, type TransferVerifyMode, type UseEdgeLinkConfig, type UseEdgeLinkReturn, assertCryptoAvailable, collectGeolocation, generatePKCE, generateState, useEdgeLink };
901
+ export { EdgeLink, type EdgeLinkConfig, type EdgeLinkOpenOptions, EdgeTransferVerify, type EdgeTransferVerifyConfig, type GeolocationOptions, type IframeCallbacks, type IframeConfig, IframeManager, type TransferVerifyEvent, type TransferVerifyEventType, type TransferVerifyMode, type UseEdgeLinkConfig, type UseEdgeLinkReturn, type UseEdgeTransferVerifyConfig, type UseEdgeTransferVerifyReturn, assertCryptoAvailable, collectGeolocation, generatePKCE, generateState, useEdgeLink, useEdgeTransferVerify };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { EdgeLinkConfigBase, EdgeScope, EdgeLinkSuccess, EdgeLinkExit, SdkGeolocation, PKCEPair } from '@edge-markets/connect';
1
+ import { EdgeLinkConfigBase, EdgeScope, SdkGeolocation, EdgeLinkSuccess, EdgeLinkExit, PKCEPair } from '@edge-markets/connect';
2
2
  export { ALL_EDGE_SCOPES, EDGE_SCOPES, EdgeEnvironment, EdgeError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, PKCEPair, SdkGeolocation, isEdgeError } from '@edge-markets/connect';
3
3
 
4
4
  /**
@@ -200,18 +200,6 @@ declare class EdgeLink {
200
200
  private cleanup;
201
201
  }
202
202
 
203
- interface UseEdgeLinkConfig extends Omit<EdgeLinkConfig, 'onSuccess' | 'onExit'> {
204
- onSuccess?: (result: EdgeLinkSuccess) => void | Promise<void>;
205
- onExit?: (metadata: EdgeLinkExit) => void;
206
- }
207
- interface UseEdgeLinkReturn {
208
- open: (options?: EdgeLinkOpenOptions) => void;
209
- ready: boolean;
210
- error: Error | null;
211
- isOpen: boolean;
212
- }
213
- declare function useEdgeLink(config: UseEdgeLinkConfig): UseEdgeLinkReturn;
214
-
215
203
  /**
216
204
  * EdgeTransferVerify - Transfer Verification Launcher for EDGE Connect
217
205
  *
@@ -634,6 +622,37 @@ declare class EdgeTransferVerify {
634
622
  private handleUserClose;
635
623
  }
636
624
 
625
+ interface UseEdgeLinkConfig extends Omit<EdgeLinkConfig, 'onSuccess' | 'onExit'> {
626
+ onSuccess?: (result: EdgeLinkSuccess) => void | Promise<void>;
627
+ onExit?: (metadata: EdgeLinkExit) => void;
628
+ }
629
+ interface UseEdgeLinkReturn {
630
+ open: (options?: EdgeLinkOpenOptions) => void;
631
+ ready: boolean;
632
+ error: Error | null;
633
+ isOpen: boolean;
634
+ }
635
+ declare function useEdgeLink(config: UseEdgeLinkConfig): UseEdgeLinkReturn;
636
+ interface UseEdgeTransferVerifyConfig extends Omit<EdgeTransferVerifyConfig, 'onSuccess' | 'onError' | 'onCancel' | 'onExpired' | 'onLoaded' | 'onEvent'> {
637
+ onSuccess?: (event: TransferVerifyEvent) => void | Promise<void>;
638
+ onError?: (event: TransferVerifyEvent) => void | Promise<void>;
639
+ onCancel?: (event: TransferVerifyEvent) => void | Promise<void>;
640
+ onExpired?: (event: TransferVerifyEvent) => void | Promise<void>;
641
+ onLoaded?: (event: TransferVerifyEvent) => void | Promise<void>;
642
+ onEvent?: (event: TransferVerifyEvent) => void | Promise<void>;
643
+ }
644
+ interface UseEdgeTransferVerifyReturn {
645
+ open: () => void;
646
+ close: () => void;
647
+ destroy: () => void;
648
+ ready: boolean;
649
+ isOpen: boolean;
650
+ isLoaded: boolean;
651
+ lastEvent: TransferVerifyEvent | null;
652
+ error: Error | null;
653
+ }
654
+ declare function useEdgeTransferVerify(config: UseEdgeTransferVerifyConfig): UseEdgeTransferVerifyReturn;
655
+
637
656
  /**
638
657
  * Iframe Manager
639
658
  *
@@ -879,4 +898,4 @@ declare function generateState(): string;
879
898
  */
880
899
  declare function assertCryptoAvailable(): void;
881
900
 
882
- export { EdgeLink, type EdgeLinkConfig, type EdgeLinkOpenOptions, EdgeTransferVerify, type EdgeTransferVerifyConfig, type GeolocationOptions, type IframeCallbacks, type IframeConfig, IframeManager, type TransferVerifyEvent, type TransferVerifyEventType, type TransferVerifyMode, type UseEdgeLinkConfig, type UseEdgeLinkReturn, assertCryptoAvailable, collectGeolocation, generatePKCE, generateState, useEdgeLink };
901
+ export { EdgeLink, type EdgeLinkConfig, type EdgeLinkOpenOptions, EdgeTransferVerify, type EdgeTransferVerifyConfig, type GeolocationOptions, type IframeCallbacks, type IframeConfig, IframeManager, type TransferVerifyEvent, type TransferVerifyEventType, type TransferVerifyMode, type UseEdgeLinkConfig, type UseEdgeLinkReturn, type UseEdgeTransferVerifyConfig, type UseEdgeTransferVerifyReturn, assertCryptoAvailable, collectGeolocation, generatePKCE, generateState, useEdgeLink, useEdgeTransferVerify };
package/dist/index.js CHANGED
@@ -33,7 +33,8 @@ __export(index_exports, {
33
33
  generatePKCE: () => generatePKCE,
34
34
  generateState: () => generateState,
35
35
  isEdgeError: () => import_connect3.isEdgeError,
36
- useEdgeLink: () => useEdgeLink
36
+ useEdgeLink: () => useEdgeLink,
37
+ useEdgeTransferVerify: () => useEdgeTransferVerify
37
38
  });
38
39
  module.exports = __toCommonJS(index_exports);
39
40
 
@@ -356,8 +357,7 @@ var EdgeLink = class {
356
357
  assertCryptoAvailable();
357
358
  this.config = config;
358
359
  this.popup = new PopupManager();
359
- const envConfig = (0, import_connect.getEnvironmentConfig)(config.environment);
360
- this.expectedOrigin = config.linkUrl ? new URL(config.linkUrl).origin : new URL(envConfig.userClientUrl).origin;
360
+ this.expectedOrigin = new URL((0, import_connect.getLinkUrl)(config.environment, config.linkUrl)).origin;
361
361
  this.setupMessageListener();
362
362
  }
363
363
  // ===========================================================================
@@ -482,9 +482,7 @@ var EdgeLink = class {
482
482
  * - Returning code via postMessage
483
483
  */
484
484
  buildLinkUrl(scopes) {
485
- const envConfig = (0, import_connect.getEnvironmentConfig)(this.config.environment);
486
- const baseUrl = this.config.linkUrl || `${envConfig.userClientUrl}/oauth/link`;
487
- const url = new URL(baseUrl);
485
+ const url = new URL((0, import_connect.getLinkUrl)(this.config.environment, this.config.linkUrl));
488
486
  url.searchParams.set("client_id", this.config.clientId);
489
487
  url.searchParams.set("state", this.state);
490
488
  url.searchParams.set("code_challenge", this.pkce.challenge);
@@ -615,56 +613,6 @@ var EdgeLink = class {
615
613
 
616
614
  // src/hooks.ts
617
615
  var import_react = require("react");
618
- function useEdgeLink(config) {
619
- const linkRef = (0, import_react.useRef)(null);
620
- const [ready, setReady] = (0, import_react.useState)(false);
621
- const [error, setError] = (0, import_react.useState)(null);
622
- const [isOpen, setIsOpen] = (0, import_react.useState)(false);
623
- const configRef = (0, import_react.useRef)(config);
624
- configRef.current = config;
625
- (0, import_react.useEffect)(() => {
626
- try {
627
- linkRef.current = new EdgeLink({
628
- ...configRef.current,
629
- onSuccess: (result) => {
630
- setIsOpen(false);
631
- configRef.current.onSuccess?.(result);
632
- },
633
- onExit: (metadata) => {
634
- setIsOpen(false);
635
- configRef.current.onExit?.(metadata);
636
- },
637
- onEvent: (event) => {
638
- if (event.eventName === "OPEN") setIsOpen(true);
639
- if (event.eventName === "CLOSE") setIsOpen(false);
640
- configRef.current.onEvent?.(event);
641
- }
642
- });
643
- setReady(true);
644
- setError(null);
645
- } catch (err) {
646
- setError(err instanceof Error ? err : new Error("Failed to initialize EdgeLink"));
647
- setReady(false);
648
- }
649
- return () => {
650
- linkRef.current?.destroy();
651
- linkRef.current = null;
652
- setReady(false);
653
- };
654
- }, [config.clientId, config.environment]);
655
- const open = (0, import_react.useCallback)((options) => {
656
- if (!linkRef.current) {
657
- setError(new Error("EdgeLink not initialized"));
658
- return;
659
- }
660
- try {
661
- linkRef.current.open(options);
662
- } catch (err) {
663
- setError(err instanceof Error ? err : new Error("Failed to open EdgeLink"));
664
- }
665
- }, []);
666
- return { open, ready, error, isOpen };
667
- }
668
616
 
669
617
  // src/edge-transfer-verify.ts
670
618
  var import_connect2 = require("@edge-markets/connect");
@@ -1221,6 +1169,153 @@ var EdgeTransferVerify = class {
1221
1169
  }
1222
1170
  };
1223
1171
 
1172
+ // src/hooks.ts
1173
+ function useEdgeLink(config) {
1174
+ const linkRef = (0, import_react.useRef)(null);
1175
+ const [ready, setReady] = (0, import_react.useState)(false);
1176
+ const [error, setError] = (0, import_react.useState)(null);
1177
+ const [isOpen, setIsOpen] = (0, import_react.useState)(false);
1178
+ const configRef = (0, import_react.useRef)(config);
1179
+ configRef.current = config;
1180
+ (0, import_react.useEffect)(() => {
1181
+ try {
1182
+ linkRef.current = new EdgeLink({
1183
+ ...configRef.current,
1184
+ onSuccess: (result) => {
1185
+ setIsOpen(false);
1186
+ configRef.current.onSuccess?.(result);
1187
+ },
1188
+ onExit: (metadata) => {
1189
+ setIsOpen(false);
1190
+ configRef.current.onExit?.(metadata);
1191
+ },
1192
+ onEvent: (event) => {
1193
+ if (event.eventName === "OPEN") setIsOpen(true);
1194
+ if (event.eventName === "CLOSE") setIsOpen(false);
1195
+ configRef.current.onEvent?.(event);
1196
+ }
1197
+ });
1198
+ setReady(true);
1199
+ setError(null);
1200
+ } catch (err) {
1201
+ setError(err instanceof Error ? err : new Error("Failed to initialize EdgeLink"));
1202
+ setReady(false);
1203
+ }
1204
+ return () => {
1205
+ linkRef.current?.destroy();
1206
+ linkRef.current = null;
1207
+ setReady(false);
1208
+ };
1209
+ }, [config.clientId, config.environment]);
1210
+ const open = (0, import_react.useCallback)((options) => {
1211
+ if (!linkRef.current) {
1212
+ setError(new Error("EdgeLink not initialized"));
1213
+ return;
1214
+ }
1215
+ try {
1216
+ linkRef.current.open(options);
1217
+ } catch (err) {
1218
+ setError(err instanceof Error ? err : new Error("Failed to open EdgeLink"));
1219
+ }
1220
+ }, []);
1221
+ return { open, ready, error, isOpen };
1222
+ }
1223
+ function useEdgeTransferVerify(config) {
1224
+ const verifyRef = (0, import_react.useRef)(null);
1225
+ const [ready, setReady] = (0, import_react.useState)(false);
1226
+ const [isOpen, setIsOpen] = (0, import_react.useState)(false);
1227
+ const [isLoaded, setIsLoaded] = (0, import_react.useState)(false);
1228
+ const [lastEvent, setLastEvent] = (0, import_react.useState)(null);
1229
+ const [error, setError] = (0, import_react.useState)(null);
1230
+ const configRef = (0, import_react.useRef)(config);
1231
+ configRef.current = config;
1232
+ (0, import_react.useEffect)(() => {
1233
+ if ((configRef.current.mode || "iframe") === "iframe" && !configRef.current.container) {
1234
+ verifyRef.current = null;
1235
+ setReady(false);
1236
+ setError(null);
1237
+ setIsLoaded(false);
1238
+ setLastEvent(null);
1239
+ return;
1240
+ }
1241
+ try {
1242
+ verifyRef.current = new EdgeTransferVerify({
1243
+ ...configRef.current,
1244
+ onSuccess: (event) => {
1245
+ setIsOpen(false);
1246
+ setLastEvent(event);
1247
+ void configRef.current.onSuccess?.(event);
1248
+ },
1249
+ onError: (event) => {
1250
+ setIsOpen(false);
1251
+ setLastEvent(event);
1252
+ setError(new Error(event.error || "EDGE transfer verification failed"));
1253
+ void configRef.current.onError?.(event);
1254
+ },
1255
+ onCancel: (event) => {
1256
+ setIsOpen(false);
1257
+ setLastEvent(event);
1258
+ void configRef.current.onCancel?.(event);
1259
+ },
1260
+ onExpired: (event) => {
1261
+ setIsOpen(false);
1262
+ setLastEvent(event);
1263
+ void configRef.current.onExpired?.(event);
1264
+ },
1265
+ onLoaded: (event) => {
1266
+ setIsLoaded(true);
1267
+ setLastEvent(event);
1268
+ void configRef.current.onLoaded?.(event);
1269
+ },
1270
+ onEvent: (event) => {
1271
+ setLastEvent(event);
1272
+ void configRef.current.onEvent?.(event);
1273
+ }
1274
+ });
1275
+ setReady(true);
1276
+ setError(null);
1277
+ setIsLoaded(false);
1278
+ setLastEvent(null);
1279
+ } catch (err) {
1280
+ setError(err instanceof Error ? err : new Error("Failed to initialize EdgeTransferVerify"));
1281
+ setReady(false);
1282
+ }
1283
+ return () => {
1284
+ verifyRef.current?.destroy();
1285
+ verifyRef.current = null;
1286
+ setReady(false);
1287
+ setIsOpen(false);
1288
+ setIsLoaded(false);
1289
+ };
1290
+ }, [config.verificationUrl, config.sessionId, config.nonce, config.mode, config.container]);
1291
+ const open = (0, import_react.useCallback)(() => {
1292
+ if (!verifyRef.current) {
1293
+ setError(new Error("EdgeTransferVerify not initialized"));
1294
+ return;
1295
+ }
1296
+ try {
1297
+ verifyRef.current.open();
1298
+ setIsOpen(true);
1299
+ setError(null);
1300
+ } catch (err) {
1301
+ setError(err instanceof Error ? err : new Error("Failed to open EdgeTransferVerify"));
1302
+ setIsOpen(false);
1303
+ }
1304
+ }, []);
1305
+ const close = (0, import_react.useCallback)(() => {
1306
+ verifyRef.current?.close();
1307
+ setIsOpen(false);
1308
+ }, []);
1309
+ const destroy = (0, import_react.useCallback)(() => {
1310
+ verifyRef.current?.destroy();
1311
+ verifyRef.current = null;
1312
+ setReady(false);
1313
+ setIsOpen(false);
1314
+ setIsLoaded(false);
1315
+ }, []);
1316
+ return { open, close, destroy, ready, isOpen, isLoaded, lastEvent, error };
1317
+ }
1318
+
1224
1319
  // src/geolocation.ts
1225
1320
  async function collectGeolocation(options) {
1226
1321
  if (typeof navigator === "undefined" || !navigator.geolocation) {
@@ -1263,5 +1358,6 @@ var import_connect4 = require("@edge-markets/connect");
1263
1358
  generatePKCE,
1264
1359
  generateState,
1265
1360
  isEdgeError,
1266
- useEdgeLink
1361
+ useEdgeLink,
1362
+ useEdgeTransferVerify
1267
1363
  });
package/dist/index.mjs CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  ALL_EDGE_SCOPES,
4
4
  EdgePopupBlockedError,
5
5
  formatScopesForEnvironment,
6
- getEnvironmentConfig
6
+ getLinkUrl
7
7
  } from "@edge-markets/connect";
8
8
 
9
9
  // src/pkce.ts
@@ -322,8 +322,7 @@ var EdgeLink = class {
322
322
  assertCryptoAvailable();
323
323
  this.config = config;
324
324
  this.popup = new PopupManager();
325
- const envConfig = getEnvironmentConfig(config.environment);
326
- this.expectedOrigin = config.linkUrl ? new URL(config.linkUrl).origin : new URL(envConfig.userClientUrl).origin;
325
+ this.expectedOrigin = new URL(getLinkUrl(config.environment, config.linkUrl)).origin;
327
326
  this.setupMessageListener();
328
327
  }
329
328
  // ===========================================================================
@@ -448,9 +447,7 @@ var EdgeLink = class {
448
447
  * - Returning code via postMessage
449
448
  */
450
449
  buildLinkUrl(scopes) {
451
- const envConfig = getEnvironmentConfig(this.config.environment);
452
- const baseUrl = this.config.linkUrl || `${envConfig.userClientUrl}/oauth/link`;
453
- const url = new URL(baseUrl);
450
+ const url = new URL(getLinkUrl(this.config.environment, this.config.linkUrl));
454
451
  url.searchParams.set("client_id", this.config.clientId);
455
452
  url.searchParams.set("state", this.state);
456
453
  url.searchParams.set("code_challenge", this.pkce.challenge);
@@ -580,57 +577,7 @@ var EdgeLink = class {
580
577
  };
581
578
 
582
579
  // src/hooks.ts
583
- import { useEffect, useRef, useCallback, useState } from "react";
584
- function useEdgeLink(config) {
585
- const linkRef = useRef(null);
586
- const [ready, setReady] = useState(false);
587
- const [error, setError] = useState(null);
588
- const [isOpen, setIsOpen] = useState(false);
589
- const configRef = useRef(config);
590
- configRef.current = config;
591
- useEffect(() => {
592
- try {
593
- linkRef.current = new EdgeLink({
594
- ...configRef.current,
595
- onSuccess: (result) => {
596
- setIsOpen(false);
597
- configRef.current.onSuccess?.(result);
598
- },
599
- onExit: (metadata) => {
600
- setIsOpen(false);
601
- configRef.current.onExit?.(metadata);
602
- },
603
- onEvent: (event) => {
604
- if (event.eventName === "OPEN") setIsOpen(true);
605
- if (event.eventName === "CLOSE") setIsOpen(false);
606
- configRef.current.onEvent?.(event);
607
- }
608
- });
609
- setReady(true);
610
- setError(null);
611
- } catch (err) {
612
- setError(err instanceof Error ? err : new Error("Failed to initialize EdgeLink"));
613
- setReady(false);
614
- }
615
- return () => {
616
- linkRef.current?.destroy();
617
- linkRef.current = null;
618
- setReady(false);
619
- };
620
- }, [config.clientId, config.environment]);
621
- const open = useCallback((options) => {
622
- if (!linkRef.current) {
623
- setError(new Error("EdgeLink not initialized"));
624
- return;
625
- }
626
- try {
627
- linkRef.current.open(options);
628
- } catch (err) {
629
- setError(err instanceof Error ? err : new Error("Failed to open EdgeLink"));
630
- }
631
- }, []);
632
- return { open, ready, error, isOpen };
633
- }
580
+ import { useCallback, useEffect, useRef, useState } from "react";
634
581
 
635
582
  // src/edge-transfer-verify.ts
636
583
  import { EdgePopupBlockedError as EdgePopupBlockedError2 } from "@edge-markets/connect";
@@ -1187,6 +1134,153 @@ var EdgeTransferVerify = class {
1187
1134
  }
1188
1135
  };
1189
1136
 
1137
+ // src/hooks.ts
1138
+ function useEdgeLink(config) {
1139
+ const linkRef = useRef(null);
1140
+ const [ready, setReady] = useState(false);
1141
+ const [error, setError] = useState(null);
1142
+ const [isOpen, setIsOpen] = useState(false);
1143
+ const configRef = useRef(config);
1144
+ configRef.current = config;
1145
+ useEffect(() => {
1146
+ try {
1147
+ linkRef.current = new EdgeLink({
1148
+ ...configRef.current,
1149
+ onSuccess: (result) => {
1150
+ setIsOpen(false);
1151
+ configRef.current.onSuccess?.(result);
1152
+ },
1153
+ onExit: (metadata) => {
1154
+ setIsOpen(false);
1155
+ configRef.current.onExit?.(metadata);
1156
+ },
1157
+ onEvent: (event) => {
1158
+ if (event.eventName === "OPEN") setIsOpen(true);
1159
+ if (event.eventName === "CLOSE") setIsOpen(false);
1160
+ configRef.current.onEvent?.(event);
1161
+ }
1162
+ });
1163
+ setReady(true);
1164
+ setError(null);
1165
+ } catch (err) {
1166
+ setError(err instanceof Error ? err : new Error("Failed to initialize EdgeLink"));
1167
+ setReady(false);
1168
+ }
1169
+ return () => {
1170
+ linkRef.current?.destroy();
1171
+ linkRef.current = null;
1172
+ setReady(false);
1173
+ };
1174
+ }, [config.clientId, config.environment]);
1175
+ const open = useCallback((options) => {
1176
+ if (!linkRef.current) {
1177
+ setError(new Error("EdgeLink not initialized"));
1178
+ return;
1179
+ }
1180
+ try {
1181
+ linkRef.current.open(options);
1182
+ } catch (err) {
1183
+ setError(err instanceof Error ? err : new Error("Failed to open EdgeLink"));
1184
+ }
1185
+ }, []);
1186
+ return { open, ready, error, isOpen };
1187
+ }
1188
+ function useEdgeTransferVerify(config) {
1189
+ const verifyRef = useRef(null);
1190
+ const [ready, setReady] = useState(false);
1191
+ const [isOpen, setIsOpen] = useState(false);
1192
+ const [isLoaded, setIsLoaded] = useState(false);
1193
+ const [lastEvent, setLastEvent] = useState(null);
1194
+ const [error, setError] = useState(null);
1195
+ const configRef = useRef(config);
1196
+ configRef.current = config;
1197
+ useEffect(() => {
1198
+ if ((configRef.current.mode || "iframe") === "iframe" && !configRef.current.container) {
1199
+ verifyRef.current = null;
1200
+ setReady(false);
1201
+ setError(null);
1202
+ setIsLoaded(false);
1203
+ setLastEvent(null);
1204
+ return;
1205
+ }
1206
+ try {
1207
+ verifyRef.current = new EdgeTransferVerify({
1208
+ ...configRef.current,
1209
+ onSuccess: (event) => {
1210
+ setIsOpen(false);
1211
+ setLastEvent(event);
1212
+ void configRef.current.onSuccess?.(event);
1213
+ },
1214
+ onError: (event) => {
1215
+ setIsOpen(false);
1216
+ setLastEvent(event);
1217
+ setError(new Error(event.error || "EDGE transfer verification failed"));
1218
+ void configRef.current.onError?.(event);
1219
+ },
1220
+ onCancel: (event) => {
1221
+ setIsOpen(false);
1222
+ setLastEvent(event);
1223
+ void configRef.current.onCancel?.(event);
1224
+ },
1225
+ onExpired: (event) => {
1226
+ setIsOpen(false);
1227
+ setLastEvent(event);
1228
+ void configRef.current.onExpired?.(event);
1229
+ },
1230
+ onLoaded: (event) => {
1231
+ setIsLoaded(true);
1232
+ setLastEvent(event);
1233
+ void configRef.current.onLoaded?.(event);
1234
+ },
1235
+ onEvent: (event) => {
1236
+ setLastEvent(event);
1237
+ void configRef.current.onEvent?.(event);
1238
+ }
1239
+ });
1240
+ setReady(true);
1241
+ setError(null);
1242
+ setIsLoaded(false);
1243
+ setLastEvent(null);
1244
+ } catch (err) {
1245
+ setError(err instanceof Error ? err : new Error("Failed to initialize EdgeTransferVerify"));
1246
+ setReady(false);
1247
+ }
1248
+ return () => {
1249
+ verifyRef.current?.destroy();
1250
+ verifyRef.current = null;
1251
+ setReady(false);
1252
+ setIsOpen(false);
1253
+ setIsLoaded(false);
1254
+ };
1255
+ }, [config.verificationUrl, config.sessionId, config.nonce, config.mode, config.container]);
1256
+ const open = useCallback(() => {
1257
+ if (!verifyRef.current) {
1258
+ setError(new Error("EdgeTransferVerify not initialized"));
1259
+ return;
1260
+ }
1261
+ try {
1262
+ verifyRef.current.open();
1263
+ setIsOpen(true);
1264
+ setError(null);
1265
+ } catch (err) {
1266
+ setError(err instanceof Error ? err : new Error("Failed to open EdgeTransferVerify"));
1267
+ setIsOpen(false);
1268
+ }
1269
+ }, []);
1270
+ const close = useCallback(() => {
1271
+ verifyRef.current?.close();
1272
+ setIsOpen(false);
1273
+ }, []);
1274
+ const destroy = useCallback(() => {
1275
+ verifyRef.current?.destroy();
1276
+ verifyRef.current = null;
1277
+ setReady(false);
1278
+ setIsOpen(false);
1279
+ setIsLoaded(false);
1280
+ }, []);
1281
+ return { open, close, destroy, ready, isOpen, isLoaded, lastEvent, error };
1282
+ }
1283
+
1190
1284
  // src/geolocation.ts
1191
1285
  async function collectGeolocation(options) {
1192
1286
  if (typeof navigator === "undefined" || !navigator.geolocation) {
@@ -1228,5 +1322,6 @@ export {
1228
1322
  generatePKCE,
1229
1323
  generateState,
1230
1324
  isEdgeError,
1231
- useEdgeLink
1325
+ useEdgeLink,
1326
+ useEdgeTransferVerify
1232
1327
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edge-markets/connect-link",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Browser SDK for EDGE Connect popup authentication",
5
5
  "author": "EdgeBoost",
6
6
  "license": "MIT",
@@ -21,7 +21,7 @@
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
- "@edge-markets/connect": "^1.5.1"
24
+ "@edge-markets/connect": "^1.7.0"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "react": ">=17.0.0"