@edge-markets/connect 1.5.1 → 1.6.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
@@ -24,6 +24,7 @@ import type {
24
24
  Balance,
25
25
  Transfer,
26
26
  EdgeTokens,
27
+ EdgeWebhookEvent,
27
28
  } from '@edge-markets/connect'
28
29
 
29
30
  // Types are generated from the OpenAPI spec
@@ -36,6 +37,49 @@ const user: User = {
36
37
  }
37
38
  ```
38
39
 
40
+ ### Webhook events
41
+
42
+ `EdgeWebhookEvent` is a discriminated union over `event.type` covering every
43
+ event the producer emits. Switching narrows `event.data` to the matching
44
+ variant — no casts:
45
+
46
+ ```typescript
47
+ import type { EdgeWebhookEvent } from '@edge-markets/connect'
48
+
49
+ function handle(event: EdgeWebhookEvent) {
50
+ switch (event.type) {
51
+ case 'transfer.completed':
52
+ // event.data is { transferId, status: 'completed', type, amount }
53
+ console.log(`completed: ${event.data.transferId} for ${event.data.amount}`)
54
+ break
55
+ case 'transfer.failed':
56
+ // event.data.reason is `string | undefined`
57
+ console.log(`failed: ${event.data.reason ?? 'unknown'}`)
58
+ break
59
+ case 'transfer.expired':
60
+ console.log(`expired: ${event.data.transferId}`)
61
+ break
62
+ case 'transfer.processing':
63
+ // @experimental — reserved for ledger dual-write hand-off
64
+ break
65
+ case 'consent.revoked':
66
+ console.log(`consent revoked: ${event.data.userId}`)
67
+ break
68
+ default: {
69
+ const _exhaustive: never = event
70
+ return _exhaustive
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ > `event.data.amount` is intentionally typed as `string` (e.g. `'100.00'`) to
77
+ > preserve decimal precision. Parse with a decimal-aware library on your side.
78
+
79
+ For HMAC signature verification on the live HTTP delivery channel, use
80
+ `verifyWebhookSignature` from `@edge-markets/connect-node`. For
81
+ reconciliation polling, use `EdgeConnectServer.syncWebhookEvents`.
82
+
39
83
  ### Configuration
40
84
 
41
85
  Get environment-specific URLs:
@@ -43,12 +87,14 @@ Get environment-specific URLs:
43
87
  ```typescript
44
88
  import {
45
89
  getEnvironmentConfig,
90
+ getLinkUrl,
46
91
  EDGE_SCOPES,
47
92
  formatScopeForEnvironment,
48
93
  } from '@edge-markets/connect'
49
94
 
50
95
  const config = getEnvironmentConfig('staging')
51
96
  console.log(config.apiBaseUrl) // https://...
97
+ console.log(getLinkUrl('staging')) // https://oauth.staging-app.edgeboost.io/oauth/link
52
98
 
53
99
  // Format scopes for your environment
54
100
  const scopes = formatScopeForEnvironment(EDGE_SCOPES.BALANCE_READ, 'staging')
@@ -93,6 +139,12 @@ try {
93
139
  | `EdgeTokens` | OAuth tokens |
94
140
  | `EdgeLinkSuccess` | Successful link result |
95
141
  | `EdgeLinkExit` | Link exit metadata |
142
+ | `EdgeWebhookEvent` | Discriminated union over webhook event types |
143
+ | `TransferCompletedEventData` | Payload for `transfer.completed` |
144
+ | `TransferFailedEventData` | Payload for `transfer.failed` (includes optional `reason`) |
145
+ | `TransferExpiredEventData` | Payload for `transfer.expired` |
146
+ | `ConsentRevokedEventData` | Payload for `consent.revoked` |
147
+ | `EDGE_WEBHOOK_EVENT_TYPES` | Runtime tuple of all known event type strings |
96
148
 
97
149
  ### Configuration
98
150
 
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  type EdgeEnvironment = 'production' | 'staging' | 'sandbox' | 'development';
2
+ declare const EDGE_LINK_PATH = "/oauth/link";
2
3
  interface EdgeEnvironmentConfig {
3
4
  /**
4
5
  * @deprecated cognitoDomain is no longer used. Token exchange now goes through EdgeBoost API.
@@ -12,6 +13,14 @@ interface EdgeEnvironmentConfig {
12
13
  }
13
14
  declare const EDGE_ENVIRONMENTS: Readonly<Record<EdgeEnvironment, EdgeEnvironmentConfig>>;
14
15
  declare function getEnvironmentConfig(environment: EdgeEnvironment): EdgeEnvironmentConfig;
16
+ /**
17
+ * Resolves the hosted Link UI URL for an environment.
18
+ *
19
+ * `linkUrl` is an advanced override for nonstandard deployments. It accepts
20
+ * either the full Link URL (`https://oauth.example.com/oauth/link`) or just the
21
+ * hosted OAuth origin (`https://oauth.example.com`).
22
+ */
23
+ declare function getLinkUrl(environment: EdgeEnvironment, linkUrl?: string): string;
15
24
  declare function isProductionEnvironment(environment: EdgeEnvironment): boolean;
16
25
  declare function getAvailableEnvironments(): readonly EdgeEnvironment[];
17
26
 
@@ -2536,6 +2545,179 @@ declare const OTP_METHODS: readonly ["sms", "totp", "email"];
2536
2545
  */
2537
2546
  declare const TRANSFER_CATEGORIES: readonly ["sportsbook", "casino", "dfs", "sweepstakes"];
2538
2547
 
2548
+ /**
2549
+ * EDGE Connect Webhook Event Types (SDK-002)
2550
+ *
2551
+ * Discriminated union over `event.type` so partners get full type narrowing
2552
+ * inside `switch` blocks. Field shapes mirror the producer's enqueue calls
2553
+ * 1:1; see `edgeboost-api/src/nest/services/connect/`:
2554
+ * - `transfer-execution.service.ts:273` (transfer.completed)
2555
+ * - `verification-session.service.ts:468` (transfer.failed)
2556
+ * - `connect.service.ts:184` (transfer.expired)
2557
+ * - `oauth/consent.service.ts:125` (consent.revoked)
2558
+ *
2559
+ * **Decimal precision:** `data.amount` is intentionally a `string`, not a
2560
+ * `number`. The producer sends `String(transfer.amount)` so partner systems
2561
+ * can parse with arbitrary-precision libraries (e.g., decimal.js, big.js)
2562
+ * without losing the trailing cent.
2563
+ *
2564
+ * **Timestamps:** `created_at` is an ISO 8601 string, not a `Date` — webhook
2565
+ * payloads are JSON, parsing into `Date` is the partner's choice.
2566
+ */
2567
+
2568
+ /**
2569
+ * All EDGE Connect webhook event type strings.
2570
+ *
2571
+ * Use this with {@link EDGE_WEBHOOK_EVENT_TYPES} for runtime checks
2572
+ * and as the discriminator on {@link EdgeWebhookEvent}.
2573
+ */
2574
+ type EdgeWebhookEventType = 'transfer.completed' | 'transfer.failed' | 'transfer.expired' | 'transfer.processing' | 'consent.revoked';
2575
+ /**
2576
+ * Runtime tuple of every known event type.
2577
+ *
2578
+ * Use this when you need an array of strings (e.g., to filter incoming
2579
+ * events, validate config, or render a UI dropdown). Kept in sync with
2580
+ * {@link EdgeWebhookEventType} via `satisfies`.
2581
+ */
2582
+ declare const EDGE_WEBHOOK_EVENT_TYPES: readonly ["transfer.completed", "transfer.failed", "transfer.expired", "transfer.processing", "consent.revoked"];
2583
+ /**
2584
+ * Common envelope shared by every webhook event.
2585
+ *
2586
+ * @template T - The discriminator literal (event type)
2587
+ * @template D - The shape of the `data` payload for this event type
2588
+ */
2589
+ interface BaseWebhookEvent<T extends EdgeWebhookEventType, D> {
2590
+ /**
2591
+ * Globally unique event identifier (`evt_<base36-time><random>`).
2592
+ *
2593
+ * Use this for idempotency — webhook delivery is at-least-once.
2594
+ */
2595
+ id: string;
2596
+ /** Event discriminator. */
2597
+ type: T;
2598
+ /**
2599
+ * ISO 8601 timestamp of when EDGE created the event.
2600
+ *
2601
+ * Snake-case key matches the wire format — JSON payloads are not transformed.
2602
+ */
2603
+ created_at: string;
2604
+ /** Event-specific payload. Type narrows when you `switch` on `type`. */
2605
+ data: D;
2606
+ }
2607
+ /**
2608
+ * Payload for `transfer.completed`.
2609
+ *
2610
+ * Emitted when a transfer is verified and the user balance has been settled.
2611
+ */
2612
+ interface TransferCompletedEventData {
2613
+ /** UUID v4 of the transfer. */
2614
+ transferId: string;
2615
+ /** Always `'completed'` for this event. */
2616
+ status: 'completed';
2617
+ /** Direction of the transfer (debit = user → partner, credit = partner → user). */
2618
+ type: TransferType;
2619
+ /** Decimal amount as a string (e.g. `'100.00'`). NOT a number. */
2620
+ amount: string;
2621
+ }
2622
+ /**
2623
+ * Payload for `transfer.failed`.
2624
+ *
2625
+ * Emitted when OTP attempts are exhausted, the ledger rejects the transfer,
2626
+ * or a hard failure occurs after authorization.
2627
+ */
2628
+ interface TransferFailedEventData {
2629
+ transferId: string;
2630
+ status: 'failed';
2631
+ type: TransferType;
2632
+ amount: string;
2633
+ /**
2634
+ * Human-readable failure reason.
2635
+ *
2636
+ * Optional — older failures may not include this field. Always default-safe
2637
+ * with `event.data.reason ?? 'unknown'` rather than asserting.
2638
+ */
2639
+ reason?: string;
2640
+ }
2641
+ /**
2642
+ * Payload for `transfer.expired`.
2643
+ *
2644
+ * Emitted when the user did not verify their OTP within the 15-minute
2645
+ * verification window.
2646
+ */
2647
+ interface TransferExpiredEventData {
2648
+ transferId: string;
2649
+ status: 'expired';
2650
+ type: TransferType;
2651
+ amount: string;
2652
+ }
2653
+ /**
2654
+ * Payload for `transfer.processing`.
2655
+ *
2656
+ * @experimental Reserved for the EDGE-360 ledger dual-write hand-off and not
2657
+ * currently emitted by the production producer. The shape may change before
2658
+ * GA — do not rely on it in production code paths yet.
2659
+ */
2660
+ interface TransferProcessingEventData {
2661
+ transferId: string;
2662
+ status: 'processing';
2663
+ type: TransferType;
2664
+ amount: string;
2665
+ }
2666
+ /**
2667
+ * Payload for `consent.revoked`.
2668
+ *
2669
+ * Emitted when a user revokes the partner's access to their EDGE account.
2670
+ * The partner should mark the corresponding linked account as inactive and
2671
+ * stop calling user-scoped endpoints with the now-invalid access token.
2672
+ */
2673
+ interface ConsentRevokedEventData {
2674
+ /** EDGE user ID whose consent was revoked. */
2675
+ userId: string;
2676
+ /** OAuth client ID that lost consent (your partner client ID). */
2677
+ clientId: string;
2678
+ /** ISO 8601 timestamp of the revocation. */
2679
+ revokedAt: string;
2680
+ }
2681
+ /**
2682
+ * A fully-typed EDGE Connect webhook event.
2683
+ *
2684
+ * Switching on `event.type` narrows `event.data` to the matching variant —
2685
+ * no casts needed:
2686
+ *
2687
+ * @example
2688
+ * ```typescript
2689
+ * import type { EdgeWebhookEvent } from '@edge-markets/connect'
2690
+ *
2691
+ * function handle(event: EdgeWebhookEvent) {
2692
+ * switch (event.type) {
2693
+ * case 'transfer.completed':
2694
+ * // event.data is TransferCompletedEventData
2695
+ * creditWallet(event.data.transferId, event.data.amount)
2696
+ * break
2697
+ * case 'transfer.failed':
2698
+ * // event.data.reason is `string | undefined`
2699
+ * logFailure(event.data.transferId, event.data.reason)
2700
+ * break
2701
+ * case 'transfer.expired':
2702
+ * cancelPending(event.data.transferId)
2703
+ * break
2704
+ * case 'transfer.processing':
2705
+ * // experimental — no-op for now
2706
+ * break
2707
+ * case 'consent.revoked':
2708
+ * deactivateLink(event.data.userId, event.data.clientId)
2709
+ * break
2710
+ * default: {
2711
+ * // Compile error if a new event type is added without a handler
2712
+ * const _exhaustive: never = event
2713
+ * return _exhaustive
2714
+ * }
2715
+ * }
2716
+ * }
2717
+ * ```
2718
+ */
2719
+ type EdgeWebhookEvent = BaseWebhookEvent<'transfer.completed', TransferCompletedEventData> | BaseWebhookEvent<'transfer.failed', TransferFailedEventData> | BaseWebhookEvent<'transfer.expired', TransferExpiredEventData> | BaseWebhookEvent<'transfer.processing', TransferProcessingEventData> | BaseWebhookEvent<'consent.revoked', ConsentRevokedEventData>;
2720
+
2539
2721
  /**
2540
2722
  * EDGE Connect SDK Types
2541
2723
  *
@@ -3039,4 +3221,4 @@ declare const SDK_VERSION = "1.0.0";
3039
3221
  */
3040
3222
  declare const SDK_NAME = "@edge-markets/connect";
3041
3223
 
3042
- export { ALL_EDGE_SCOPES, type ApiError, type Balance, type ConsentRequiredError, type CreateVerificationSessionRequest, EDGE_ENVIRONMENTS, EDGE_SCOPES, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, type EdgeEnvironment, type EdgeEnvironmentConfig, EdgeError, EdgeIdentityVerificationError, EdgeInsufficientScopeError, type EdgeLinkConfigBase, type EdgeLinkEvent, type EdgeLinkEventName, type EdgeLinkExit, type EdgeLinkSuccess, EdgeNetworkError, EdgeNotFoundError, EdgePopupBlockedError, EdgePopupClosedError, type EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, type EdgeTokens, EdgeValidationError, type InitiateTransferRequest, type ListTransfersParams, OTP_METHODS, type OtpMethod, type PKCEPair, type RevokeConsentResponse, SCOPE_DESCRIPTIONS, SCOPE_ICONS, SDK_NAME, SDK_VERSION, type SdkGeolocation, TRANSFER_CATEGORIES, TRANSFER_STATUSES, TRANSFER_TYPES, type Transfer, type TransferCategory, type TransferList, type TransferListItem, type TransferStatus, type TransferType, type User, type UserAddress, type VerificationSession, type VerificationSessionStatus, type VerificationSessionStatusResponse, type VerifyIdentityAddress, type VerifyIdentityOptions, type VerifyIdentityResult, type VerifyIdentityScores, type components, formatScopeForEnvironment, formatScopesForEnvironment, getAvailableEnvironments, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isEdgeError, isIdentityVerificationError, isNetworkError, isProductionEnvironment, isValidScope, type operations, parseScope, type paths };
3224
+ export { ALL_EDGE_SCOPES, type ApiError, type Balance, type BaseWebhookEvent, type ConsentRequiredError, type ConsentRevokedEventData, type CreateVerificationSessionRequest, EDGE_ENVIRONMENTS, EDGE_LINK_PATH, EDGE_SCOPES, EDGE_WEBHOOK_EVENT_TYPES, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, type EdgeEnvironment, type EdgeEnvironmentConfig, EdgeError, EdgeIdentityVerificationError, EdgeInsufficientScopeError, type EdgeLinkConfigBase, type EdgeLinkEvent, type EdgeLinkEventName, type EdgeLinkExit, type EdgeLinkSuccess, EdgeNetworkError, EdgeNotFoundError, EdgePopupBlockedError, EdgePopupClosedError, type EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, type EdgeTokens, EdgeValidationError, type EdgeWebhookEvent, type EdgeWebhookEventType, type InitiateTransferRequest, type ListTransfersParams, OTP_METHODS, type OtpMethod, type PKCEPair, type RevokeConsentResponse, SCOPE_DESCRIPTIONS, SCOPE_ICONS, SDK_NAME, SDK_VERSION, type SdkGeolocation, TRANSFER_CATEGORIES, TRANSFER_STATUSES, TRANSFER_TYPES, type Transfer, type TransferCategory, type TransferCompletedEventData, type TransferExpiredEventData, type TransferFailedEventData, type TransferList, type TransferListItem, type TransferProcessingEventData, type TransferStatus, type TransferType, type User, type UserAddress, type VerificationSession, type VerificationSessionStatus, type VerificationSessionStatusResponse, type VerifyIdentityAddress, type VerifyIdentityOptions, type VerifyIdentityResult, type VerifyIdentityScores, type components, formatScopeForEnvironment, formatScopesForEnvironment, getAvailableEnvironments, getEnvironmentConfig, getLinkUrl, isApiError, isAuthenticationError, isConsentRequiredError, isEdgeError, isIdentityVerificationError, isNetworkError, isProductionEnvironment, isValidScope, type operations, parseScope, type paths };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  type EdgeEnvironment = 'production' | 'staging' | 'sandbox' | 'development';
2
+ declare const EDGE_LINK_PATH = "/oauth/link";
2
3
  interface EdgeEnvironmentConfig {
3
4
  /**
4
5
  * @deprecated cognitoDomain is no longer used. Token exchange now goes through EdgeBoost API.
@@ -12,6 +13,14 @@ interface EdgeEnvironmentConfig {
12
13
  }
13
14
  declare const EDGE_ENVIRONMENTS: Readonly<Record<EdgeEnvironment, EdgeEnvironmentConfig>>;
14
15
  declare function getEnvironmentConfig(environment: EdgeEnvironment): EdgeEnvironmentConfig;
16
+ /**
17
+ * Resolves the hosted Link UI URL for an environment.
18
+ *
19
+ * `linkUrl` is an advanced override for nonstandard deployments. It accepts
20
+ * either the full Link URL (`https://oauth.example.com/oauth/link`) or just the
21
+ * hosted OAuth origin (`https://oauth.example.com`).
22
+ */
23
+ declare function getLinkUrl(environment: EdgeEnvironment, linkUrl?: string): string;
15
24
  declare function isProductionEnvironment(environment: EdgeEnvironment): boolean;
16
25
  declare function getAvailableEnvironments(): readonly EdgeEnvironment[];
17
26
 
@@ -2536,6 +2545,179 @@ declare const OTP_METHODS: readonly ["sms", "totp", "email"];
2536
2545
  */
2537
2546
  declare const TRANSFER_CATEGORIES: readonly ["sportsbook", "casino", "dfs", "sweepstakes"];
2538
2547
 
2548
+ /**
2549
+ * EDGE Connect Webhook Event Types (SDK-002)
2550
+ *
2551
+ * Discriminated union over `event.type` so partners get full type narrowing
2552
+ * inside `switch` blocks. Field shapes mirror the producer's enqueue calls
2553
+ * 1:1; see `edgeboost-api/src/nest/services/connect/`:
2554
+ * - `transfer-execution.service.ts:273` (transfer.completed)
2555
+ * - `verification-session.service.ts:468` (transfer.failed)
2556
+ * - `connect.service.ts:184` (transfer.expired)
2557
+ * - `oauth/consent.service.ts:125` (consent.revoked)
2558
+ *
2559
+ * **Decimal precision:** `data.amount` is intentionally a `string`, not a
2560
+ * `number`. The producer sends `String(transfer.amount)` so partner systems
2561
+ * can parse with arbitrary-precision libraries (e.g., decimal.js, big.js)
2562
+ * without losing the trailing cent.
2563
+ *
2564
+ * **Timestamps:** `created_at` is an ISO 8601 string, not a `Date` — webhook
2565
+ * payloads are JSON, parsing into `Date` is the partner's choice.
2566
+ */
2567
+
2568
+ /**
2569
+ * All EDGE Connect webhook event type strings.
2570
+ *
2571
+ * Use this with {@link EDGE_WEBHOOK_EVENT_TYPES} for runtime checks
2572
+ * and as the discriminator on {@link EdgeWebhookEvent}.
2573
+ */
2574
+ type EdgeWebhookEventType = 'transfer.completed' | 'transfer.failed' | 'transfer.expired' | 'transfer.processing' | 'consent.revoked';
2575
+ /**
2576
+ * Runtime tuple of every known event type.
2577
+ *
2578
+ * Use this when you need an array of strings (e.g., to filter incoming
2579
+ * events, validate config, or render a UI dropdown). Kept in sync with
2580
+ * {@link EdgeWebhookEventType} via `satisfies`.
2581
+ */
2582
+ declare const EDGE_WEBHOOK_EVENT_TYPES: readonly ["transfer.completed", "transfer.failed", "transfer.expired", "transfer.processing", "consent.revoked"];
2583
+ /**
2584
+ * Common envelope shared by every webhook event.
2585
+ *
2586
+ * @template T - The discriminator literal (event type)
2587
+ * @template D - The shape of the `data` payload for this event type
2588
+ */
2589
+ interface BaseWebhookEvent<T extends EdgeWebhookEventType, D> {
2590
+ /**
2591
+ * Globally unique event identifier (`evt_<base36-time><random>`).
2592
+ *
2593
+ * Use this for idempotency — webhook delivery is at-least-once.
2594
+ */
2595
+ id: string;
2596
+ /** Event discriminator. */
2597
+ type: T;
2598
+ /**
2599
+ * ISO 8601 timestamp of when EDGE created the event.
2600
+ *
2601
+ * Snake-case key matches the wire format — JSON payloads are not transformed.
2602
+ */
2603
+ created_at: string;
2604
+ /** Event-specific payload. Type narrows when you `switch` on `type`. */
2605
+ data: D;
2606
+ }
2607
+ /**
2608
+ * Payload for `transfer.completed`.
2609
+ *
2610
+ * Emitted when a transfer is verified and the user balance has been settled.
2611
+ */
2612
+ interface TransferCompletedEventData {
2613
+ /** UUID v4 of the transfer. */
2614
+ transferId: string;
2615
+ /** Always `'completed'` for this event. */
2616
+ status: 'completed';
2617
+ /** Direction of the transfer (debit = user → partner, credit = partner → user). */
2618
+ type: TransferType;
2619
+ /** Decimal amount as a string (e.g. `'100.00'`). NOT a number. */
2620
+ amount: string;
2621
+ }
2622
+ /**
2623
+ * Payload for `transfer.failed`.
2624
+ *
2625
+ * Emitted when OTP attempts are exhausted, the ledger rejects the transfer,
2626
+ * or a hard failure occurs after authorization.
2627
+ */
2628
+ interface TransferFailedEventData {
2629
+ transferId: string;
2630
+ status: 'failed';
2631
+ type: TransferType;
2632
+ amount: string;
2633
+ /**
2634
+ * Human-readable failure reason.
2635
+ *
2636
+ * Optional — older failures may not include this field. Always default-safe
2637
+ * with `event.data.reason ?? 'unknown'` rather than asserting.
2638
+ */
2639
+ reason?: string;
2640
+ }
2641
+ /**
2642
+ * Payload for `transfer.expired`.
2643
+ *
2644
+ * Emitted when the user did not verify their OTP within the 15-minute
2645
+ * verification window.
2646
+ */
2647
+ interface TransferExpiredEventData {
2648
+ transferId: string;
2649
+ status: 'expired';
2650
+ type: TransferType;
2651
+ amount: string;
2652
+ }
2653
+ /**
2654
+ * Payload for `transfer.processing`.
2655
+ *
2656
+ * @experimental Reserved for the EDGE-360 ledger dual-write hand-off and not
2657
+ * currently emitted by the production producer. The shape may change before
2658
+ * GA — do not rely on it in production code paths yet.
2659
+ */
2660
+ interface TransferProcessingEventData {
2661
+ transferId: string;
2662
+ status: 'processing';
2663
+ type: TransferType;
2664
+ amount: string;
2665
+ }
2666
+ /**
2667
+ * Payload for `consent.revoked`.
2668
+ *
2669
+ * Emitted when a user revokes the partner's access to their EDGE account.
2670
+ * The partner should mark the corresponding linked account as inactive and
2671
+ * stop calling user-scoped endpoints with the now-invalid access token.
2672
+ */
2673
+ interface ConsentRevokedEventData {
2674
+ /** EDGE user ID whose consent was revoked. */
2675
+ userId: string;
2676
+ /** OAuth client ID that lost consent (your partner client ID). */
2677
+ clientId: string;
2678
+ /** ISO 8601 timestamp of the revocation. */
2679
+ revokedAt: string;
2680
+ }
2681
+ /**
2682
+ * A fully-typed EDGE Connect webhook event.
2683
+ *
2684
+ * Switching on `event.type` narrows `event.data` to the matching variant —
2685
+ * no casts needed:
2686
+ *
2687
+ * @example
2688
+ * ```typescript
2689
+ * import type { EdgeWebhookEvent } from '@edge-markets/connect'
2690
+ *
2691
+ * function handle(event: EdgeWebhookEvent) {
2692
+ * switch (event.type) {
2693
+ * case 'transfer.completed':
2694
+ * // event.data is TransferCompletedEventData
2695
+ * creditWallet(event.data.transferId, event.data.amount)
2696
+ * break
2697
+ * case 'transfer.failed':
2698
+ * // event.data.reason is `string | undefined`
2699
+ * logFailure(event.data.transferId, event.data.reason)
2700
+ * break
2701
+ * case 'transfer.expired':
2702
+ * cancelPending(event.data.transferId)
2703
+ * break
2704
+ * case 'transfer.processing':
2705
+ * // experimental — no-op for now
2706
+ * break
2707
+ * case 'consent.revoked':
2708
+ * deactivateLink(event.data.userId, event.data.clientId)
2709
+ * break
2710
+ * default: {
2711
+ * // Compile error if a new event type is added without a handler
2712
+ * const _exhaustive: never = event
2713
+ * return _exhaustive
2714
+ * }
2715
+ * }
2716
+ * }
2717
+ * ```
2718
+ */
2719
+ type EdgeWebhookEvent = BaseWebhookEvent<'transfer.completed', TransferCompletedEventData> | BaseWebhookEvent<'transfer.failed', TransferFailedEventData> | BaseWebhookEvent<'transfer.expired', TransferExpiredEventData> | BaseWebhookEvent<'transfer.processing', TransferProcessingEventData> | BaseWebhookEvent<'consent.revoked', ConsentRevokedEventData>;
2720
+
2539
2721
  /**
2540
2722
  * EDGE Connect SDK Types
2541
2723
  *
@@ -3039,4 +3221,4 @@ declare const SDK_VERSION = "1.0.0";
3039
3221
  */
3040
3222
  declare const SDK_NAME = "@edge-markets/connect";
3041
3223
 
3042
- export { ALL_EDGE_SCOPES, type ApiError, type Balance, type ConsentRequiredError, type CreateVerificationSessionRequest, EDGE_ENVIRONMENTS, EDGE_SCOPES, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, type EdgeEnvironment, type EdgeEnvironmentConfig, EdgeError, EdgeIdentityVerificationError, EdgeInsufficientScopeError, type EdgeLinkConfigBase, type EdgeLinkEvent, type EdgeLinkEventName, type EdgeLinkExit, type EdgeLinkSuccess, EdgeNetworkError, EdgeNotFoundError, EdgePopupBlockedError, EdgePopupClosedError, type EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, type EdgeTokens, EdgeValidationError, type InitiateTransferRequest, type ListTransfersParams, OTP_METHODS, type OtpMethod, type PKCEPair, type RevokeConsentResponse, SCOPE_DESCRIPTIONS, SCOPE_ICONS, SDK_NAME, SDK_VERSION, type SdkGeolocation, TRANSFER_CATEGORIES, TRANSFER_STATUSES, TRANSFER_TYPES, type Transfer, type TransferCategory, type TransferList, type TransferListItem, type TransferStatus, type TransferType, type User, type UserAddress, type VerificationSession, type VerificationSessionStatus, type VerificationSessionStatusResponse, type VerifyIdentityAddress, type VerifyIdentityOptions, type VerifyIdentityResult, type VerifyIdentityScores, type components, formatScopeForEnvironment, formatScopesForEnvironment, getAvailableEnvironments, getEnvironmentConfig, isApiError, isAuthenticationError, isConsentRequiredError, isEdgeError, isIdentityVerificationError, isNetworkError, isProductionEnvironment, isValidScope, type operations, parseScope, type paths };
3224
+ export { ALL_EDGE_SCOPES, type ApiError, type Balance, type BaseWebhookEvent, type ConsentRequiredError, type ConsentRevokedEventData, type CreateVerificationSessionRequest, EDGE_ENVIRONMENTS, EDGE_LINK_PATH, EDGE_SCOPES, EDGE_WEBHOOK_EVENT_TYPES, EdgeApiError, EdgeAuthenticationError, EdgeConsentRequiredError, type EdgeEnvironment, type EdgeEnvironmentConfig, EdgeError, EdgeIdentityVerificationError, EdgeInsufficientScopeError, type EdgeLinkConfigBase, type EdgeLinkEvent, type EdgeLinkEventName, type EdgeLinkExit, type EdgeLinkSuccess, EdgeNetworkError, EdgeNotFoundError, EdgePopupBlockedError, EdgePopupClosedError, type EdgeScope, EdgeStateMismatchError, EdgeTokenExchangeError, type EdgeTokens, EdgeValidationError, type EdgeWebhookEvent, type EdgeWebhookEventType, type InitiateTransferRequest, type ListTransfersParams, OTP_METHODS, type OtpMethod, type PKCEPair, type RevokeConsentResponse, SCOPE_DESCRIPTIONS, SCOPE_ICONS, SDK_NAME, SDK_VERSION, type SdkGeolocation, TRANSFER_CATEGORIES, TRANSFER_STATUSES, TRANSFER_TYPES, type Transfer, type TransferCategory, type TransferCompletedEventData, type TransferExpiredEventData, type TransferFailedEventData, type TransferList, type TransferListItem, type TransferProcessingEventData, type TransferStatus, type TransferType, type User, type UserAddress, type VerificationSession, type VerificationSessionStatus, type VerificationSessionStatusResponse, type VerifyIdentityAddress, type VerifyIdentityOptions, type VerifyIdentityResult, type VerifyIdentityScores, type components, formatScopeForEnvironment, formatScopesForEnvironment, getAvailableEnvironments, getEnvironmentConfig, getLinkUrl, isApiError, isAuthenticationError, isConsentRequiredError, isEdgeError, isIdentityVerificationError, isNetworkError, isProductionEnvironment, isValidScope, type operations, parseScope, type paths };
package/dist/index.js CHANGED
@@ -22,7 +22,9 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  ALL_EDGE_SCOPES: () => ALL_EDGE_SCOPES,
24
24
  EDGE_ENVIRONMENTS: () => EDGE_ENVIRONMENTS,
25
+ EDGE_LINK_PATH: () => EDGE_LINK_PATH,
25
26
  EDGE_SCOPES: () => EDGE_SCOPES,
27
+ EDGE_WEBHOOK_EVENT_TYPES: () => EDGE_WEBHOOK_EVENT_TYPES,
26
28
  EdgeApiError: () => EdgeApiError,
27
29
  EdgeAuthenticationError: () => EdgeAuthenticationError,
28
30
  EdgeConsentRequiredError: () => EdgeConsentRequiredError,
@@ -48,6 +50,7 @@ __export(index_exports, {
48
50
  formatScopesForEnvironment: () => formatScopesForEnvironment,
49
51
  getAvailableEnvironments: () => getAvailableEnvironments,
50
52
  getEnvironmentConfig: () => getEnvironmentConfig,
53
+ getLinkUrl: () => getLinkUrl,
51
54
  isApiError: () => isApiError,
52
55
  isAuthenticationError: () => isAuthenticationError,
53
56
  isConsentRequiredError: () => isConsentRequiredError,
@@ -77,13 +80,23 @@ var TRANSFER_CATEGORIES = [
77
80
  "sweepstakes"
78
81
  ];
79
82
 
83
+ // src/types/webhooks.ts
84
+ var EDGE_WEBHOOK_EVENT_TYPES = [
85
+ "transfer.completed",
86
+ "transfer.failed",
87
+ "transfer.expired",
88
+ "transfer.processing",
89
+ "consent.revoked"
90
+ ];
91
+
80
92
  // src/config/environments.ts
93
+ var EDGE_LINK_PATH = "/oauth/link";
81
94
  var EDGE_ENVIRONMENTS = {
82
95
  production: {
83
96
  cognitoDomain: "https://edge-connect.auth.us-east-1.amazoncognito.com",
84
- apiBaseUrl: "https://api.edgeboost.com/connect/v1",
85
- oauthBaseUrl: "https://api.edgeboost.com/api/v3/oauth",
86
- userClientUrl: "https://app.edgeboost.com",
97
+ apiBaseUrl: "https://connect.edgeboost.io/connect/v1",
98
+ oauthBaseUrl: "https://connect.edgeboost.io/connect/oauth",
99
+ userClientUrl: "https://oauth.edgeboost.io",
87
100
  displayName: "Production",
88
101
  isProduction: true
89
102
  },
@@ -99,15 +112,15 @@ var EDGE_ENVIRONMENTS = {
99
112
  // User-facing captive frame for the Link SDK enrollment and transfer
100
113
  // verification flows. Served from the edge-connect-oauth Vite app
101
114
  // deployed on Amplify. No mTLS — browser traffic.
102
- userClientUrl: "https://oauth.staging-app.edgeboost.bet",
115
+ userClientUrl: "https://oauth.staging-app.edgeboost.io",
103
116
  displayName: "Staging",
104
117
  isProduction: false
105
118
  },
106
119
  sandbox: {
107
120
  cognitoDomain: "https://edge-connect-sandbox.auth.us-east-1.amazoncognito.com",
108
- apiBaseUrl: "https://sandbox-api.edgeboost.com/connect/v1",
109
- oauthBaseUrl: "https://sandbox-api.edgeboost.com/api/v3/oauth",
110
- userClientUrl: "https://sandbox.edgeboost.com",
121
+ apiBaseUrl: "https://api-sandbox.staging.edgeboost.io/connect/v1",
122
+ oauthBaseUrl: "https://api-sandbox.staging.edgeboost.io/api/v3/oauth",
123
+ userClientUrl: "https://oauth.staging-app.edgeboost.io",
111
124
  displayName: "Sandbox",
112
125
  isProduction: false
113
126
  },
@@ -133,6 +146,17 @@ var EDGE_ENVIRONMENTS = {
133
146
  function getEnvironmentConfig(environment) {
134
147
  return EDGE_ENVIRONMENTS[environment];
135
148
  }
149
+ function getLinkUrl(environment, linkUrl) {
150
+ const configuredUrl = linkUrl?.trim();
151
+ const url = new URL(configuredUrl || `${EDGE_ENVIRONMENTS[environment].userClientUrl}${EDGE_LINK_PATH}`);
152
+ const normalizedPath = url.pathname.replace(/\/+$/, "");
153
+ if (!normalizedPath || normalizedPath === "/" || normalizedPath === "/oauth") {
154
+ url.pathname = EDGE_LINK_PATH;
155
+ } else {
156
+ url.pathname = normalizedPath;
157
+ }
158
+ return url.toString();
159
+ }
136
160
  function isProductionEnvironment(environment) {
137
161
  return EDGE_ENVIRONMENTS[environment].isProduction;
138
162
  }
@@ -332,7 +356,9 @@ var SDK_NAME = "@edge-markets/connect";
332
356
  0 && (module.exports = {
333
357
  ALL_EDGE_SCOPES,
334
358
  EDGE_ENVIRONMENTS,
359
+ EDGE_LINK_PATH,
335
360
  EDGE_SCOPES,
361
+ EDGE_WEBHOOK_EVENT_TYPES,
336
362
  EdgeApiError,
337
363
  EdgeAuthenticationError,
338
364
  EdgeConsentRequiredError,
@@ -358,6 +384,7 @@ var SDK_NAME = "@edge-markets/connect";
358
384
  formatScopesForEnvironment,
359
385
  getAvailableEnvironments,
360
386
  getEnvironmentConfig,
387
+ getLinkUrl,
361
388
  isApiError,
362
389
  isAuthenticationError,
363
390
  isConsentRequiredError,
package/dist/index.mjs CHANGED
@@ -15,13 +15,23 @@ var TRANSFER_CATEGORIES = [
15
15
  "sweepstakes"
16
16
  ];
17
17
 
18
+ // src/types/webhooks.ts
19
+ var EDGE_WEBHOOK_EVENT_TYPES = [
20
+ "transfer.completed",
21
+ "transfer.failed",
22
+ "transfer.expired",
23
+ "transfer.processing",
24
+ "consent.revoked"
25
+ ];
26
+
18
27
  // src/config/environments.ts
28
+ var EDGE_LINK_PATH = "/oauth/link";
19
29
  var EDGE_ENVIRONMENTS = {
20
30
  production: {
21
31
  cognitoDomain: "https://edge-connect.auth.us-east-1.amazoncognito.com",
22
- apiBaseUrl: "https://api.edgeboost.com/connect/v1",
23
- oauthBaseUrl: "https://api.edgeboost.com/api/v3/oauth",
24
- userClientUrl: "https://app.edgeboost.com",
32
+ apiBaseUrl: "https://connect.edgeboost.io/connect/v1",
33
+ oauthBaseUrl: "https://connect.edgeboost.io/connect/oauth",
34
+ userClientUrl: "https://oauth.edgeboost.io",
25
35
  displayName: "Production",
26
36
  isProduction: true
27
37
  },
@@ -37,15 +47,15 @@ var EDGE_ENVIRONMENTS = {
37
47
  // User-facing captive frame for the Link SDK enrollment and transfer
38
48
  // verification flows. Served from the edge-connect-oauth Vite app
39
49
  // deployed on Amplify. No mTLS — browser traffic.
40
- userClientUrl: "https://oauth.staging-app.edgeboost.bet",
50
+ userClientUrl: "https://oauth.staging-app.edgeboost.io",
41
51
  displayName: "Staging",
42
52
  isProduction: false
43
53
  },
44
54
  sandbox: {
45
55
  cognitoDomain: "https://edge-connect-sandbox.auth.us-east-1.amazoncognito.com",
46
- apiBaseUrl: "https://sandbox-api.edgeboost.com/connect/v1",
47
- oauthBaseUrl: "https://sandbox-api.edgeboost.com/api/v3/oauth",
48
- userClientUrl: "https://sandbox.edgeboost.com",
56
+ apiBaseUrl: "https://api-sandbox.staging.edgeboost.io/connect/v1",
57
+ oauthBaseUrl: "https://api-sandbox.staging.edgeboost.io/api/v3/oauth",
58
+ userClientUrl: "https://oauth.staging-app.edgeboost.io",
49
59
  displayName: "Sandbox",
50
60
  isProduction: false
51
61
  },
@@ -71,6 +81,17 @@ var EDGE_ENVIRONMENTS = {
71
81
  function getEnvironmentConfig(environment) {
72
82
  return EDGE_ENVIRONMENTS[environment];
73
83
  }
84
+ function getLinkUrl(environment, linkUrl) {
85
+ const configuredUrl = linkUrl?.trim();
86
+ const url = new URL(configuredUrl || `${EDGE_ENVIRONMENTS[environment].userClientUrl}${EDGE_LINK_PATH}`);
87
+ const normalizedPath = url.pathname.replace(/\/+$/, "");
88
+ if (!normalizedPath || normalizedPath === "/" || normalizedPath === "/oauth") {
89
+ url.pathname = EDGE_LINK_PATH;
90
+ } else {
91
+ url.pathname = normalizedPath;
92
+ }
93
+ return url.toString();
94
+ }
74
95
  function isProductionEnvironment(environment) {
75
96
  return EDGE_ENVIRONMENTS[environment].isProduction;
76
97
  }
@@ -269,7 +290,9 @@ var SDK_NAME = "@edge-markets/connect";
269
290
  export {
270
291
  ALL_EDGE_SCOPES,
271
292
  EDGE_ENVIRONMENTS,
293
+ EDGE_LINK_PATH,
272
294
  EDGE_SCOPES,
295
+ EDGE_WEBHOOK_EVENT_TYPES,
273
296
  EdgeApiError,
274
297
  EdgeAuthenticationError,
275
298
  EdgeConsentRequiredError,
@@ -295,6 +318,7 @@ export {
295
318
  formatScopesForEnvironment,
296
319
  getAvailableEnvironments,
297
320
  getEnvironmentConfig,
321
+ getLinkUrl,
298
322
  isApiError,
299
323
  isAuthenticationError,
300
324
  isConsentRequiredError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edge-markets/connect",
3
- "version": "1.5.1",
3
+ "version": "1.6.1",
4
4
  "description": "Core types, configuration, and utilities for EDGE Connect SDK",
5
5
  "author": "EdgeBoost",
6
6
  "license": "MIT",