@frak-labs/core-sdk 1.0.0-beta.7f085fb7 → 1.0.0-beta.cb2a3a9a

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.
Files changed (55) hide show
  1. package/cdn/bundle.js +3 -3
  2. package/dist/actions-B-TIi011.cjs +1 -0
  3. package/dist/actions-IId7MAgk.js +1 -0
  4. package/dist/actions.cjs +1 -1
  5. package/dist/actions.d.cts +2 -2
  6. package/dist/actions.d.ts +2 -2
  7. package/dist/actions.js +1 -1
  8. package/dist/bundle.cjs +1 -1
  9. package/dist/bundle.d.cts +4 -4
  10. package/dist/bundle.d.ts +4 -4
  11. package/dist/bundle.js +1 -1
  12. package/dist/{index-Dwmo109y.d.cts → index-B1NOuCFq.d.ts} +158 -36
  13. package/dist/{index-BphwTmKA.d.cts → index-CGyEOo9J.d.cts} +1 -1
  14. package/dist/{index-_f8EuN_1.d.ts → index-Cdf5j2_W.d.ts} +1 -1
  15. package/dist/{index-BV5D9DsW.d.ts → index-CjEdFSJU.d.cts} +158 -36
  16. package/dist/index.cjs +1 -1
  17. package/dist/index.d.cts +3 -3
  18. package/dist/index.d.ts +3 -3
  19. package/dist/index.js +1 -1
  20. package/dist/{openSso-BwEK2M98.d.cts → openSso-B6pD2oA6.d.ts} +99 -4
  21. package/dist/{openSso-C1Wzl5-i.d.ts → openSso-qjaccFd0.d.cts} +98 -3
  22. package/dist/src-CePGcxy2.js +13 -0
  23. package/dist/src-D6ad7fS-.cjs +13 -0
  24. package/dist/trackEvent-DmZ8n4tR.js +1 -0
  25. package/dist/trackEvent-DsMwWkUv.cjs +1 -0
  26. package/package.json +2 -2
  27. package/src/actions/referral/processReferral.test.ts +4 -8
  28. package/src/actions/referral/processReferral.ts +5 -11
  29. package/src/clients/createIFrameFrakClient.ts +84 -3
  30. package/src/index.ts +8 -1
  31. package/src/types/config.ts +9 -0
  32. package/src/types/index.ts +2 -0
  33. package/src/types/lifecycle/client.ts +7 -0
  34. package/src/types/resolvedConfig.ts +10 -0
  35. package/src/types/rpc/displaySharingPage.ts +18 -0
  36. package/src/types/tracking.ts +36 -0
  37. package/src/utils/FrakContext.test.ts +151 -0
  38. package/src/utils/FrakContext.ts +67 -1
  39. package/src/utils/analytics/events/component.ts +58 -0
  40. package/src/utils/analytics/events/index.ts +20 -0
  41. package/src/utils/analytics/events/lifecycle.ts +26 -0
  42. package/src/utils/analytics/events/referral.ts +10 -0
  43. package/src/utils/analytics/index.ts +8 -0
  44. package/src/utils/{trackEvent.test.ts → analytics/trackEvent.test.ts} +19 -30
  45. package/src/utils/analytics/trackEvent.ts +34 -0
  46. package/src/utils/index.ts +5 -1
  47. package/src/utils/mergeAttribution.test.ts +153 -0
  48. package/src/utils/mergeAttribution.ts +75 -0
  49. package/dist/actions-D4aBXbdp.cjs +0 -1
  50. package/dist/actions-Dq_uN-wn.js +0 -1
  51. package/dist/src-BorHuT1g.cjs +0 -13
  52. package/dist/src-aPlQD0ZW.js +0 -13
  53. package/dist/trackEvent-BqJqRZ-u.cjs +0 -1
  54. package/dist/trackEvent-Bqq4jd6R.js +0 -1
  55. package/src/utils/trackEvent.ts +0 -41
@@ -1,8 +1,65 @@
1
- import { OpenPanel } from "@openpanel/web";
2
- import { LifecycleMessage, RpcClient } from "@frak-labs/frame-connector";
3
1
  import { Address, Hex } from "viem";
2
+ import { LifecycleMessage, RpcClient } from "@frak-labs/frame-connector";
3
+ import { OpenPanel } from "@openpanel/web";
4
4
  import { SiweMessage } from "viem/siwe";
5
5
 
6
+ //#region src/types/tracking.d.ts
7
+ type UtmParams = {
8
+ source?: string;
9
+ medium?: string;
10
+ campaign?: string;
11
+ term?: string;
12
+ content?: string;
13
+ };
14
+ /**
15
+ * Attribution parameters appended to outbound sharing URLs.
16
+ *
17
+ * Defaults are derived from the V2 Frak context when available:
18
+ * - `utmSource`: `"frak"`
19
+ * - `utmMedium`: `"referral"`
20
+ * - `utmCampaign`: merchantId (`context.m`)
21
+ * - `via`: `"frak"`
22
+ * - `ref`: clientId (`context.c`)
23
+ *
24
+ * Fields explicitly set here override the defaults. Existing params on the
25
+ * base URL are preserved (gap-fill policy) to respect merchant-provided UTMs.
26
+ */
27
+ type AttributionParams = {
28
+ utmSource?: string;
29
+ utmMedium?: string;
30
+ utmCampaign?: string;
31
+ utmContent?: string;
32
+ utmTerm?: string;
33
+ via?: string;
34
+ ref?: string;
35
+ };
36
+ /**
37
+ * Merchant-level attribution defaults.
38
+ *
39
+ * Same shape as {@link AttributionParams} minus `utmContent`, because
40
+ * `utm_content` describes the specific content/creative being shared and is
41
+ * inherently per-call or per-product (never a merchant-wide default).
42
+ *
43
+ * Used as the shape for both:
44
+ * - `FrakWalletSdkConfig.attribution` (SDK-side compile-time defaults)
45
+ * - Backend merchant-config attribution (dashboard-driven defaults)
46
+ */
47
+ type AttributionDefaults = Omit<AttributionParams, "utmContent">;
48
+ type TrackArrivalParams = {
49
+ /** @deprecated V1 legacy — use referrerClientId for v2 contexts */referrerWallet?: Address;
50
+ referrerClientId?: string;
51
+ referrerMerchantId?: string; /** Epoch seconds timestamp from the referral link creation */
52
+ referralTimestamp?: number;
53
+ landingUrl?: string;
54
+ utmParams?: UtmParams;
55
+ };
56
+ type TrackArrivalResult = {
57
+ success: boolean;
58
+ identityGroupId?: string;
59
+ touchpointId?: string;
60
+ error?: string;
61
+ };
62
+ //#endregion
6
63
  //#region src/types/config.d.ts
7
64
  /**
8
65
  * All the currencies available
@@ -82,6 +139,13 @@ type FrakWalletSdkConfig = {
82
139
  * @defaultValue true
83
140
  */
84
141
  waitForBackendConfig?: boolean;
142
+ /**
143
+ * Default attribution params (UTM / via / ref) appended to outbound
144
+ * sharing URLs. Per-call `displaySharingPage` overrides win, then backend
145
+ * config, then this SDK-level default. `utm_content` is intentionally
146
+ * excluded — it is per-content/per-product, never a merchant-wide default.
147
+ */
148
+ attribution?: AttributionDefaults;
85
149
  };
86
150
  /**
87
151
  * Custom i18n configuration for the modal
@@ -199,6 +263,12 @@ type ResolvedSdkConfig = {
199
263
  translations?: Record<string, string>;
200
264
  placements?: Record<string, ResolvedPlacement>; /** Global component defaults (used when no placement override exists) */
201
265
  components?: ResolvedPlacement["components"];
266
+ /**
267
+ * Default attribution params applied when building outbound sharing URLs.
268
+ * Per-call overrides win over these backend defaults; `utm_content` is
269
+ * intentionally excluded (per-content/per-product, never a merchant default).
270
+ */
271
+ attribution?: AttributionDefaults;
202
272
  };
203
273
  /**
204
274
  * Internal SDK config store state
@@ -221,7 +291,8 @@ type SdkResolvedConfig = {
221
291
  css?: string; /** Global translations (for reference / component fallback) */
222
292
  translations?: Record<string, string>; /** Named placements (keyed by placement ID) */
223
293
  placements?: Record<string, ResolvedPlacement>; /** Global component defaults (fallback for placement-level overrides) */
224
- components?: ResolvedPlacement["components"];
294
+ components?: ResolvedPlacement["components"]; /** Merged attribution defaults: backend > SDK static config */
295
+ attribution?: AttributionDefaults;
225
296
  };
226
297
  //#endregion
227
298
  //#region src/types/lifecycle/client.d.ts
@@ -276,6 +347,13 @@ type ResolvedConfigEvent = {
276
347
  * When present, listener should execute identity merge in background.
277
348
  */
278
349
  pendingMergeToken?: string;
350
+ /**
351
+ * Persistent per-origin anonymous id generated on the partner site
352
+ * (SDK-side localStorage). Propagated here so the listener can
353
+ * set it as an OpenPanel global property and stitch SDK events
354
+ * with listener events in the same funnel.
355
+ */
356
+ sdkAnonymousId?: string;
279
357
  sdkConfig?: ResolvedSdkConfig;
280
358
  };
281
359
  };
@@ -651,6 +729,11 @@ type SharingPageProduct = {
651
729
  * When provided and the product is selected, this link is used instead of the default sharing link
652
730
  */
653
731
  link?: string;
732
+ /**
733
+ * Optional `utm_content` value to apply when this product is selected.
734
+ * Falls back to the page-level `attribution.utmContent` when omitted.
735
+ */
736
+ utmContent?: string;
654
737
  };
655
738
  /**
656
739
  * Parameters to display the sharing page
@@ -668,6 +751,18 @@ type DisplaySharingPageParamsType = {
668
751
  * If not provided, the sharing link will be generated from the current page URL + merchant context
669
752
  */
670
753
  link?: string;
754
+ /**
755
+ * Optional attribution overrides for the outbound sharing URL.
756
+ *
757
+ * When provided (even as an empty object), Frak adds standard affiliation
758
+ * params (`utm_source=frak`, `utm_medium=referral`, `utm_campaign=<merchantId>`,
759
+ * `ref=<clientId>`, `via=frak`) alongside `fCtx`. Existing UTMs on the base
760
+ * URL are preserved (gap-fill). Set this to `null` to disable attribution
761
+ * params entirely (only `fCtx` is added).
762
+ *
763
+ * @default {} — defaults applied
764
+ */
765
+ attribution?: AttributionParams | null;
671
766
  /**
672
767
  * Optional metadata overrides for the sharing page
673
768
  */
@@ -1291,4 +1386,4 @@ declare const ssoPopupName = "frak-sso";
1291
1386
  */
1292
1387
  declare function openSso(client: FrakClient, args: OpenSsoParamsType): Promise<OpenSsoReturnType>;
1293
1388
  //#endregion
1294
- export { ResolvedPlacement as $, ModalRpcMetadata as A, LoginModalStepType as B, EmbeddedViewActionReferred as C, DisplaySharingPageResultType as D, DisplaySharingPageParamsType as E, SendTransactionReturnType as F, SsoMetadata as G, OpenSsoReturnType as H, SendTransactionTxType as I, ModalStepMetadata as J, FinalActionType as K, SiweAuthenticateModalStepType as L, ModalRpcStepsResultType as M, ModalStepTypes as N, SharingPageProduct as O, SendTransactionModalStepType as P, MerchantConfigResponse as Q, SiweAuthenticateReturnType as R, LoggedOutEmbeddedView as S, LoggedInEmbeddedView as T, PrepareSsoParamsType as U, OpenSsoParamsType as V, PrepareSsoReturnType as W, IFrameLifecycleEvent as X, InteractionTypeKey as Y, ClientLifecycleEvent as Z, RewardTier as _, FrakContextV1 as a, Language as at, DisplayEmbeddedWalletParamsType as b, isV2Context as c, IFrameTransport as d, ResolvedSdkConfig as et, IFrameRpcSchema as f, GetMerchantInformationReturnType as g, EstimatedReward as h, FrakContext as i, I18nConfig as it, ModalRpcStepsInput as j, DisplayModalParamsType as k, FrakClient as l, UserReferralStatusType as m, ssoPopupFeatures as n, Currency as nt, FrakContextV2 as o, LocalizedI18nConfig as ot, WalletStatusReturnType as p, FinalModalStepType as q, ssoPopupName as r, FrakWalletSdkConfig as rt, isV1Context as s, openSso as t, SdkResolvedConfig as tt, FrakLifecycleEvent as u, TokenAmountType as v, EmbeddedViewActionSharing as w, DisplayEmbeddedWalletResultType as x, SendInteractionParamsType as y, SiweAuthenticationParams as z };
1389
+ export { ResolvedPlacement as $, ModalRpcMetadata as A, LoginModalStepType as B, EmbeddedViewActionReferred as C, DisplaySharingPageResultType as D, DisplaySharingPageParamsType as E, SendTransactionReturnType as F, SsoMetadata as G, OpenSsoReturnType as H, SendTransactionTxType as I, ModalStepMetadata as J, FinalActionType as K, SiweAuthenticateModalStepType as L, ModalRpcStepsResultType as M, ModalStepTypes as N, SharingPageProduct as O, SendTransactionModalStepType as P, MerchantConfigResponse as Q, SiweAuthenticateReturnType as R, LoggedOutEmbeddedView as S, LoggedInEmbeddedView as T, PrepareSsoParamsType as U, OpenSsoParamsType as V, PrepareSsoReturnType as W, IFrameLifecycleEvent as X, InteractionTypeKey as Y, ClientLifecycleEvent as Z, RewardTier as _, FrakContextV1 as a, Language as at, DisplayEmbeddedWalletParamsType as b, isV2Context as c, AttributionParams as ct, IFrameTransport as d, UtmParams as dt, ResolvedSdkConfig as et, IFrameRpcSchema as f, GetMerchantInformationReturnType as g, EstimatedReward as h, FrakContext as i, I18nConfig as it, ModalRpcStepsInput as j, DisplayModalParamsType as k, FrakClient as l, TrackArrivalParams as lt, UserReferralStatusType as m, ssoPopupFeatures as n, Currency as nt, FrakContextV2 as o, LocalizedI18nConfig as ot, WalletStatusReturnType as p, FinalModalStepType as q, ssoPopupName as r, FrakWalletSdkConfig as rt, isV1Context as s, AttributionDefaults as st, openSso as t, SdkResolvedConfig as tt, FrakLifecycleEvent as u, TrackArrivalResult as ut, TokenAmountType as v, EmbeddedViewActionSharing as w, DisplayEmbeddedWalletResultType as x, SendInteractionParamsType as y, SiweAuthenticationParams as z };
@@ -1,8 +1,65 @@
1
+ import { OpenPanel } from "@openpanel/web";
1
2
  import { Address, Hex } from "viem";
2
3
  import { LifecycleMessage, RpcClient } from "@frak-labs/frame-connector";
3
- import { OpenPanel } from "@openpanel/web";
4
4
  import { SiweMessage } from "viem/siwe";
5
5
 
6
+ //#region src/types/tracking.d.ts
7
+ type UtmParams = {
8
+ source?: string;
9
+ medium?: string;
10
+ campaign?: string;
11
+ term?: string;
12
+ content?: string;
13
+ };
14
+ /**
15
+ * Attribution parameters appended to outbound sharing URLs.
16
+ *
17
+ * Defaults are derived from the V2 Frak context when available:
18
+ * - `utmSource`: `"frak"`
19
+ * - `utmMedium`: `"referral"`
20
+ * - `utmCampaign`: merchantId (`context.m`)
21
+ * - `via`: `"frak"`
22
+ * - `ref`: clientId (`context.c`)
23
+ *
24
+ * Fields explicitly set here override the defaults. Existing params on the
25
+ * base URL are preserved (gap-fill policy) to respect merchant-provided UTMs.
26
+ */
27
+ type AttributionParams = {
28
+ utmSource?: string;
29
+ utmMedium?: string;
30
+ utmCampaign?: string;
31
+ utmContent?: string;
32
+ utmTerm?: string;
33
+ via?: string;
34
+ ref?: string;
35
+ };
36
+ /**
37
+ * Merchant-level attribution defaults.
38
+ *
39
+ * Same shape as {@link AttributionParams} minus `utmContent`, because
40
+ * `utm_content` describes the specific content/creative being shared and is
41
+ * inherently per-call or per-product (never a merchant-wide default).
42
+ *
43
+ * Used as the shape for both:
44
+ * - `FrakWalletSdkConfig.attribution` (SDK-side compile-time defaults)
45
+ * - Backend merchant-config attribution (dashboard-driven defaults)
46
+ */
47
+ type AttributionDefaults = Omit<AttributionParams, "utmContent">;
48
+ type TrackArrivalParams = {
49
+ /** @deprecated V1 legacy — use referrerClientId for v2 contexts */referrerWallet?: Address;
50
+ referrerClientId?: string;
51
+ referrerMerchantId?: string; /** Epoch seconds timestamp from the referral link creation */
52
+ referralTimestamp?: number;
53
+ landingUrl?: string;
54
+ utmParams?: UtmParams;
55
+ };
56
+ type TrackArrivalResult = {
57
+ success: boolean;
58
+ identityGroupId?: string;
59
+ touchpointId?: string;
60
+ error?: string;
61
+ };
62
+ //#endregion
6
63
  //#region src/types/config.d.ts
7
64
  /**
8
65
  * All the currencies available
@@ -82,6 +139,13 @@ type FrakWalletSdkConfig = {
82
139
  * @defaultValue true
83
140
  */
84
141
  waitForBackendConfig?: boolean;
142
+ /**
143
+ * Default attribution params (UTM / via / ref) appended to outbound
144
+ * sharing URLs. Per-call `displaySharingPage` overrides win, then backend
145
+ * config, then this SDK-level default. `utm_content` is intentionally
146
+ * excluded — it is per-content/per-product, never a merchant-wide default.
147
+ */
148
+ attribution?: AttributionDefaults;
85
149
  };
86
150
  /**
87
151
  * Custom i18n configuration for the modal
@@ -199,6 +263,12 @@ type ResolvedSdkConfig = {
199
263
  translations?: Record<string, string>;
200
264
  placements?: Record<string, ResolvedPlacement>; /** Global component defaults (used when no placement override exists) */
201
265
  components?: ResolvedPlacement["components"];
266
+ /**
267
+ * Default attribution params applied when building outbound sharing URLs.
268
+ * Per-call overrides win over these backend defaults; `utm_content` is
269
+ * intentionally excluded (per-content/per-product, never a merchant default).
270
+ */
271
+ attribution?: AttributionDefaults;
202
272
  };
203
273
  /**
204
274
  * Internal SDK config store state
@@ -221,7 +291,8 @@ type SdkResolvedConfig = {
221
291
  css?: string; /** Global translations (for reference / component fallback) */
222
292
  translations?: Record<string, string>; /** Named placements (keyed by placement ID) */
223
293
  placements?: Record<string, ResolvedPlacement>; /** Global component defaults (fallback for placement-level overrides) */
224
- components?: ResolvedPlacement["components"];
294
+ components?: ResolvedPlacement["components"]; /** Merged attribution defaults: backend > SDK static config */
295
+ attribution?: AttributionDefaults;
225
296
  };
226
297
  //#endregion
227
298
  //#region src/types/lifecycle/client.d.ts
@@ -276,6 +347,13 @@ type ResolvedConfigEvent = {
276
347
  * When present, listener should execute identity merge in background.
277
348
  */
278
349
  pendingMergeToken?: string;
350
+ /**
351
+ * Persistent per-origin anonymous id generated on the partner site
352
+ * (SDK-side localStorage). Propagated here so the listener can
353
+ * set it as an OpenPanel global property and stitch SDK events
354
+ * with listener events in the same funnel.
355
+ */
356
+ sdkAnonymousId?: string;
279
357
  sdkConfig?: ResolvedSdkConfig;
280
358
  };
281
359
  };
@@ -651,6 +729,11 @@ type SharingPageProduct = {
651
729
  * When provided and the product is selected, this link is used instead of the default sharing link
652
730
  */
653
731
  link?: string;
732
+ /**
733
+ * Optional `utm_content` value to apply when this product is selected.
734
+ * Falls back to the page-level `attribution.utmContent` when omitted.
735
+ */
736
+ utmContent?: string;
654
737
  };
655
738
  /**
656
739
  * Parameters to display the sharing page
@@ -668,6 +751,18 @@ type DisplaySharingPageParamsType = {
668
751
  * If not provided, the sharing link will be generated from the current page URL + merchant context
669
752
  */
670
753
  link?: string;
754
+ /**
755
+ * Optional attribution overrides for the outbound sharing URL.
756
+ *
757
+ * When provided (even as an empty object), Frak adds standard affiliation
758
+ * params (`utm_source=frak`, `utm_medium=referral`, `utm_campaign=<merchantId>`,
759
+ * `ref=<clientId>`, `via=frak`) alongside `fCtx`. Existing UTMs on the base
760
+ * URL are preserved (gap-fill). Set this to `null` to disable attribution
761
+ * params entirely (only `fCtx` is added).
762
+ *
763
+ * @default {} — defaults applied
764
+ */
765
+ attribution?: AttributionParams | null;
671
766
  /**
672
767
  * Optional metadata overrides for the sharing page
673
768
  */
@@ -1291,4 +1386,4 @@ declare const ssoPopupName = "frak-sso";
1291
1386
  */
1292
1387
  declare function openSso(client: FrakClient, args: OpenSsoParamsType): Promise<OpenSsoReturnType>;
1293
1388
  //#endregion
1294
- export { ResolvedPlacement as $, ModalRpcMetadata as A, LoginModalStepType as B, EmbeddedViewActionReferred as C, DisplaySharingPageResultType as D, DisplaySharingPageParamsType as E, SendTransactionReturnType as F, SsoMetadata as G, OpenSsoReturnType as H, SendTransactionTxType as I, ModalStepMetadata as J, FinalActionType as K, SiweAuthenticateModalStepType as L, ModalRpcStepsResultType as M, ModalStepTypes as N, SharingPageProduct as O, SendTransactionModalStepType as P, MerchantConfigResponse as Q, SiweAuthenticateReturnType as R, LoggedOutEmbeddedView as S, LoggedInEmbeddedView as T, PrepareSsoParamsType as U, OpenSsoParamsType as V, PrepareSsoReturnType as W, IFrameLifecycleEvent as X, InteractionTypeKey as Y, ClientLifecycleEvent as Z, RewardTier as _, FrakContextV1 as a, Language as at, DisplayEmbeddedWalletParamsType as b, isV2Context as c, IFrameTransport as d, ResolvedSdkConfig as et, IFrameRpcSchema as f, GetMerchantInformationReturnType as g, EstimatedReward as h, FrakContext as i, I18nConfig as it, ModalRpcStepsInput as j, DisplayModalParamsType as k, FrakClient as l, UserReferralStatusType as m, ssoPopupFeatures as n, Currency as nt, FrakContextV2 as o, LocalizedI18nConfig as ot, WalletStatusReturnType as p, FinalModalStepType as q, ssoPopupName as r, FrakWalletSdkConfig as rt, isV1Context as s, openSso as t, SdkResolvedConfig as tt, FrakLifecycleEvent as u, TokenAmountType as v, EmbeddedViewActionSharing as w, DisplayEmbeddedWalletResultType as x, SendInteractionParamsType as y, SiweAuthenticationParams as z };
1389
+ export { ResolvedPlacement as $, ModalRpcMetadata as A, LoginModalStepType as B, EmbeddedViewActionReferred as C, DisplaySharingPageResultType as D, DisplaySharingPageParamsType as E, SendTransactionReturnType as F, SsoMetadata as G, OpenSsoReturnType as H, SendTransactionTxType as I, ModalStepMetadata as J, FinalActionType as K, SiweAuthenticateModalStepType as L, ModalRpcStepsResultType as M, ModalStepTypes as N, SharingPageProduct as O, SendTransactionModalStepType as P, MerchantConfigResponse as Q, SiweAuthenticateReturnType as R, LoggedOutEmbeddedView as S, LoggedInEmbeddedView as T, PrepareSsoParamsType as U, OpenSsoParamsType as V, PrepareSsoReturnType as W, IFrameLifecycleEvent as X, InteractionTypeKey as Y, ClientLifecycleEvent as Z, RewardTier as _, FrakContextV1 as a, Language as at, DisplayEmbeddedWalletParamsType as b, isV2Context as c, AttributionParams as ct, IFrameTransport as d, UtmParams as dt, ResolvedSdkConfig as et, IFrameRpcSchema as f, GetMerchantInformationReturnType as g, EstimatedReward as h, FrakContext as i, I18nConfig as it, ModalRpcStepsInput as j, DisplayModalParamsType as k, FrakClient as l, TrackArrivalParams as lt, UserReferralStatusType as m, ssoPopupFeatures as n, Currency as nt, FrakContextV2 as o, LocalizedI18nConfig as ot, WalletStatusReturnType as p, FinalModalStepType as q, ssoPopupName as r, FrakWalletSdkConfig as rt, isV1Context as s, AttributionDefaults as st, openSso as t, SdkResolvedConfig as tt, FrakLifecycleEvent as u, TrackArrivalResult as ut, TokenAmountType as v, EmbeddedViewActionSharing as w, DisplayEmbeddedWalletResultType as x, SendInteractionParamsType as y, SiweAuthenticationParams as z };
@@ -0,0 +1,13 @@
1
+ import{n as e,s as t,y as n}from"./trackEvent-DmZ8n4tR.js";import{Deferred as r,FrakRpcError as i,RpcErrorCodes as a,createRpcClient as o}from"@frak-labs/frame-connector";import{OpenPanel as s}from"@openpanel/web";const c=`nexus-wallet-backup`,l=`frakwallet://`;function u(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}function d(e){return`intent://${e.slice(13)}#Intent;scheme=frakwallet;end`}function f(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let a=u()&&p(e)?d(e):e;window.location.href=a,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function p(e){return e.startsWith(l)}const m={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function h(e){return e&&e in m?e:`eur`}function g(e){return e?m[e]??m.eur:m.eur}function _(e,t){let n=g(t),r=h(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function v(e){return e?`${e}Amount`:`eurAmount`}const y={id:`frak-wallet`,name:`frak-wallet`,title:`Frak Wallet`,allow:`publickey-credentials-get *; clipboard-write; web-share *`,style:{width:`0`,height:`0`,border:`0`,position:`absolute`,zIndex:2000001,top:`-1000px`,left:`-1000px`,colorScheme:`auto`}};function b({walletBaseUrl:e,config:t}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=y.id,i.name=y.name,i.allow=y.allow,i.style.zIndex=y.style.zIndex.toString(),x({iframe:i,isVisible:!1});let a=t?.walletUrl??e??`https://wallet.frak.id`,o=n();return i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}function x({iframe:e,isVisible:t}){if(!t){e.style.width=`0`,e.style.height=`0`,e.style.border=`0`,e.style.position=`fixed`,e.style.top=`-1000px`,e.style.left=`-1000px`;return}e.style.position=`fixed`,e.style.top=`0`,e.style.left=`0`,e.style.width=`100%`,e.style.height=`100%`,e.style.pointerEvents=`auto`}function S(e=`/listener`){if(!window.opener)return null;let t=t=>{try{return t.location.origin===window.location.origin&&t.location.pathname===e}catch{return!1}};if(t(window.opener))return window.opener;try{let e=window.opener.frames;for(let n=0;n<e.length;n++)if(t(e[n]))return e[n];return null}catch(t){return console.error(`[findIframeInOpener] Error finding iframe with pathname ${e}:`,t),null}}function C(){if(typeof navigator>`u`)return!1;let e=navigator.userAgent;return!!(/iPhone|iPad|iPod/i.test(e)||/Macintosh/i.test(e)&&navigator.maxTouchPoints>1)}const w=C();function T(){if(typeof navigator>`u`)return!1;let e=navigator.userAgent.toLowerCase();return e.includes(`instagram`)||e.includes(`fban`)||e.includes(`fbav`)||e.includes(`facebook`)}const E=T();function D(e){w&&e.startsWith(`https://`)?window.location.href=`x-safari-https://${e.slice(8)}`:w&&e.startsWith(`http://`)?window.location.href=`x-safari-http://${e.slice(7)}`:window.location.href=`https://backend.frak.id/common/social?u=${encodeURIComponent(e)}`}function O({perCall:e,defaults:t,productUtmContent:n}){if(e===null)return;let r=e!==void 0,i=t!==void 0&&Object.keys(t).length>0;if(!r&&!i&&!(n!==void 0&&n!==``))return;let a={...t,...e??{}},o=n??e?.utmContent;return o!==void 0&&o!==``?a.utmContent=o:delete a.utmContent,a}function k(e,t){if(typeof window>`u`)return;let n=new URL(window.location.href),r=n.searchParams.get(`sso`);r&&(t.then(()=>{e.sendLifecycle({clientLifecycle:`sso-redirect-complete`,data:{compressed:r}}),console.log(`[SSO URL Listener] Forwarded compressed SSO data to iframe`)}).catch(e=>{console.error(`[SSO URL Listener] Failed to forward SSO data:`,e)}),n.searchParams.delete(`sso`),window.history.replaceState({},``,n.toString()),console.log(`[SSO URL Listener] SSO parameter detected and URL cleaned`))}var A=class e{config;iframe;isSetupDone=!1;lastResponse=null;lastRequest=null;constructor(e,t){this.config=e,this.iframe=t,this.lastRequest=null,this.lastResponse=null}setLastResponse(e,t){this.lastResponse={message:e,response:t,timestamp:Date.now()}}setLastRequest(e){this.lastRequest={event:e,timestamp:Date.now()}}updateSetupStatus(e){this.isSetupDone=e}base64Encode(e){try{return btoa(JSON.stringify(e))}catch(e){return console.warn(`Failed to encode debug data`,e),btoa(`Failed to encode data`)}}getIframeStatus(){return this.iframe?{loading:this.iframe.hasAttribute(`loading`),url:this.iframe.src,readyState:this.iframe.contentDocument?.readyState?+(this.iframe.contentDocument.readyState===`complete`):-1,contentWindow:!!this.iframe.contentWindow,isConnected:this.iframe.isConnected}:null}getNavigatorInfo(){return navigator?{userAgent:navigator.userAgent,language:navigator.language,onLine:navigator.onLine,screenWidth:window.screen.width,screenHeight:window.screen.height,pixelRatio:window.devicePixelRatio}:null}gatherDebugInfo(e){let t=this.getIframeStatus(),n=this.getNavigatorInfo(),r=`Unknown`;return e instanceof i?r=`FrakRpcError: ${e.code} '${e.message}'`:e instanceof Error?r=e.message:typeof e==`string`&&(r=e),{timestamp:new Date().toISOString(),encodedUrl:btoa(window.location.href),encodedConfig:this.config?this.base64Encode(this.config):`no-config`,navigatorInfo:n?this.base64Encode(n):`no-navigator`,iframeStatus:t?this.base64Encode(t):`not-iframe`,lastRequest:this.lastRequest?this.base64Encode(this.lastRequest):`No Frak request logged`,lastResponse:this.lastResponse?this.base64Encode(this.lastResponse):`No Frak response logged`,clientStatus:this.isSetupDone?`setup`:`not-setup`,error:r}}static empty(){return new e}formatDebugInfo(e){let t=this.gatherDebugInfo(e);return`
2
+ Debug Information:
3
+ -----------------
4
+ Timestamp: ${t.timestamp}
5
+ URL: ${t.encodedUrl}
6
+ Config: ${t.encodedConfig}
7
+ Navigator Info: ${t.navigatorInfo}
8
+ IFrame Status: ${t.iframeStatus}
9
+ Last Request: ${t.lastRequest}
10
+ Last Response: ${t.lastResponse}
11
+ Client Status: ${t.clientStatus}
12
+ Error: ${t.error}
13
+ `.trim()}};const j=(()=>{if(typeof navigator>`u`)return!1;let e=navigator.userAgent;if(!(/iPhone|iPad|iPod/i.test(e)||/Macintosh/i.test(e)&&navigator.maxTouchPoints>1))return!1;let t=e.toLowerCase();return t.includes(`instagram`)||t.includes(`fban`)||t.includes(`fbav`)||t.includes(`facebook`)})();function M(e){e?localStorage.setItem(c,e):localStorage.removeItem(c)}function N(e,t){try{let n=new URL(e);if(!n.searchParams.has(`u`))return e;let r=I(window.location.href,t);return n.searchParams.delete(`u`),n.searchParams.append(`u`,r),n.toString()}catch{return e}}function P(e){let t=new URL(window.location.href);e&&t.searchParams.set(`fmt`,e);let n=t.protocol===`http:`?`x-safari-http`:`x-safari-https`;window.location.href=`${n}://${t.host}${t.pathname}${t.search}${t.hash}`}function F(e){return e.includes(`/common/social`)}function I(e,t){if(!t)return e;try{let n=new URL(e);return n.searchParams.set(`fmt`,t),n.toString()}catch{return`${e}${e.includes(`?`)?`&`:`?`}fmt=${encodeURIComponent(t)}`}}function L(e,t,n,r,i){if(i){let e=N(t,r);window.open(e,`_blank`);return}if(p(t)){let i=N(t,r);f(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(j&&F(t))P(r);else{let e=N(t,r);window.location.href=e}}function R({iframe:e,targetOrigin:t}){let n=new r;return{handleEvent:r=>{if(!(`iframeLifecycle`in r))return;let{iframeLifecycle:i,data:a}=r;switch(i){case`connected`:n.resolve(!0);break;case`do-backup`:M(a.backup);break;case`remove-backup`:localStorage.removeItem(c);break;case`show`:case`hide`:x({iframe:e,isVisible:i===`show`});break;case`redirect`:L(e,a.baseRedirectUrl,t,a.mergeToken,a.openInNewTab);break}},isConnected:n.promise}}function z({config:c,iframe:l}){let u=c?.walletUrl??`https://wallet.frak.id`,d=typeof navigator<`u`?navigator.language?.split(`-`)[0]:void 0,f=c.metadata.lang??(d===`en`||d===`fr`?d:void 0),p=c.domain??(typeof window<`u`?window.location.hostname:``);e.setCacheScope(p,f),e.reset();let m=e.isCacheFresh?void 0:e.resolve(c.domain,c.walletUrl,f),h=R({iframe:l,targetOrigin:u}),g=new r,_=Date.now(),v=new A(c,l);if(!l.contentWindow)throw new i(a.configError,`The iframe does not have a content window`);let y=o({emittingTransport:l.contentWindow,listeningTransport:window,targetOrigin:u,middleware:[{async onRequest(e,t){if(!await h.isConnected)throw new i(a.clientNotConnected,`The iframe provider isn't connected yet`);return await g.promise,t}},{onRequest(e,t){return v.setLastRequest(e),t},onResponse(e,t){return v.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:(e,t)=>{h.handleEvent(e)}}}),b=B(y,h),x=async()=>{b(),y.cleanup(),l.remove(),t(),e.clearCache(),e.reset()},S;{console.log(`[Frak SDK] Initializing OpenPanel`),S=new s({apiUrl:`https://op-api.gcp.frak.id`,clientId:`6eacc8d7-49ac-4936-95e9-81ef29449570`,trackScreenViews:!0,trackOutgoingLinks:!0,trackAttributes:!1,filter:({type:e,payload:t})=>(e!==`track`||!t?.properties||`sdkVersion`in t.properties||(t.properties={...t.properties,sdkVersion:`1.0.0`,userAnonymousClientId:n()}),!0)}),S.setGlobalProperties({sdkVersion:`1.0.0`,userAnonymousClientId:n()}),S.init(),S.track(`sdk_initialized`,{sdkVersion:`1.0.0`});let e=!1,t=setTimeout(()=>{e||(e=!0,S?.track(`sdk_iframe_handshake_failed`,{reason:`timeout`}))},3e4);h.isConnected.then(()=>{e||(e=!0,clearTimeout(t),S?.track(`sdk_iframe_connected`,{handshake_duration_ms:Date.now()-_}))}).catch(()=>{e||(e=!0,clearTimeout(t),S?.track(`sdk_iframe_handshake_failed`,{reason:`unknown`}))})}let C=V({config:c,rpcClient:y,lifecycleManager:h,configPromise:m,contextSent:g,openPanel:S}).then(()=>v.updateSetupStatus(!0)).catch(e=>{throw g.reject(e),e});return{config:c,debugInfo:v,waitForConnection:h.isConnected,waitForSetup:C,request:y.request,listenerRequest:y.listen,destroy:x,openPanel:S}}function B(e,t){let n,r,i=()=>e.sendLifecycle({clientLifecycle:`heartbeat`});async function a(){i(),n=setInterval(i,1e3),r=setTimeout(()=>{o(),console.log(`Heartbeat timeout: connection failed`)},3e4),await t.isConnected,o()}function o(){n&&clearInterval(n),r&&clearTimeout(r)}return a(),o}async function V({config:t,rpcClient:r,lifecycleManager:i,configPromise:a,contextSent:o,openPanel:s}){await i.isConnected,k(r,i.isConnected);let l=new URL(window.location.href),u=l.searchParams.get(`fmt`)??void 0;u&&(l.searchParams.delete(`fmt`),window.history.replaceState({},``,l.toString()));let d=n=>{let r=n?.merchantId??t.metadata.merchantId??``,i=n?.domain??``,a=n?.allowedDomains??[],o=n?.sdkConfig,s=o?.attribution||t.attribution?{...t.attribution,...o?.attribution}:void 0;e.setConfig(o?{isResolved:!0,merchantId:r,domain:i,allowedDomains:a,hasRawSdkConfig:!0,name:o.name??t.metadata.name,logoUrl:o.logoUrl??t.metadata.logoUrl,homepageLink:o.homepageLink??t.metadata.homepageLink,lang:o.lang??t.metadata.lang,currency:o.currency??t.metadata.currency,hidden:o.hidden,css:o.css,translations:o.translations,placements:o.placements,components:o.components,attribution:s}:{isResolved:!0,merchantId:r,domain:i,allowedDomains:a,name:t.metadata.name,logoUrl:t.metadata.logoUrl,homepageLink:t.metadata.homepageLink,lang:t.metadata.lang,currency:t.metadata.currency,attribution:s})},f=!1,p=e=>{let t=f?void 0:u;f=!0;let i=e.hasRawSdkConfig?{name:e.name,logoUrl:e.logoUrl,homepageLink:e.homepageLink,lang:e.lang,currency:e.currency,hidden:e.hidden,css:e.css,translations:e.translations,placements:e.placements,attribution:e.attribution}:e.attribution?{attribution:e.attribution}:void 0,a=n();if(s){let t=s.global??{};s.setGlobalProperties({...t,merchantId:e.merchantId,domain:e.domain??``})}r.sendLifecycle({clientLifecycle:`resolved-config`,data:{merchantId:e.merchantId,domain:e.domain??``,allowedDomains:e.allowedDomains??[],sourceUrl:window.location.href,...a&&{sdkAnonymousId:a},...t&&{pendingMergeToken:t},...i&&{sdkConfig:i}}})};e.isResolved&&(p(e.getConfig()),o.resolve()),a&&(d(await a),p(e.getConfig()),o.resolve());async function m(){let e=t.customizations?.css;e&&r.sendLifecycle({clientLifecycle:`modal-css`,data:{cssLink:e}})}async function h(){let e=t.customizations?.i18n;e&&r.sendLifecycle({clientLifecycle:`modal-i18n`,data:{i18n:e}})}async function g(){if(typeof window>`u`)return;let e=window.localStorage.getItem(c);e&&r.sendLifecycle({clientLifecycle:`restore-backup`,data:{backup:e}})}(await Promise.allSettled([m(),h(),g()])).some(e=>e.status===`rejected`)&&s?.track(`sdk_iframe_handshake_failed`,{reason:`asset_push`})}async function H({config:e}){let t=U(e),n=await b({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=z({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function U(e){let t=h(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}export{p as _,w as a,l as b,y as c,v as d,_ as f,u as g,m as h,O as i,b as l,h as m,z as n,E as o,g as p,A as r,D as s,H as t,S as u,d as v,f as y};
@@ -0,0 +1,13 @@
1
+ const e=require(`./trackEvent-DsMwWkUv.cjs`);let t=require(`@frak-labs/frame-connector`),n=require(`@openpanel/web`);const r=`nexus-wallet-backup`,i=`frakwallet://`;function a(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}function o(e){return`intent://${e.slice(13)}#Intent;scheme=frakwallet;end`}function s(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let s=a()&&c(e)?o(e):e;window.location.href=s,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function c(e){return e.startsWith(i)}const l={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function u(e){return e&&e in l?e:`eur`}function d(e){return e?l[e]??l.eur:l.eur}function f(e,t){let n=d(t),r=u(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function p(e){return e?`${e}Amount`:`eurAmount`}const m={id:`frak-wallet`,name:`frak-wallet`,title:`Frak Wallet`,allow:`publickey-credentials-get *; clipboard-write; web-share *`,style:{width:`0`,height:`0`,border:`0`,position:`absolute`,zIndex:2000001,top:`-1000px`,left:`-1000px`,colorScheme:`auto`}};function h({walletBaseUrl:t,config:n}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=m.id,i.name=m.name,i.allow=m.allow,i.style.zIndex=m.style.zIndex.toString(),g({iframe:i,isVisible:!1});let a=n?.walletUrl??t??`https://wallet.frak.id`,o=e.y();return i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}function g({iframe:e,isVisible:t}){if(!t){e.style.width=`0`,e.style.height=`0`,e.style.border=`0`,e.style.position=`fixed`,e.style.top=`-1000px`,e.style.left=`-1000px`;return}e.style.position=`fixed`,e.style.top=`0`,e.style.left=`0`,e.style.width=`100%`,e.style.height=`100%`,e.style.pointerEvents=`auto`}function _(e=`/listener`){if(!window.opener)return null;let t=t=>{try{return t.location.origin===window.location.origin&&t.location.pathname===e}catch{return!1}};if(t(window.opener))return window.opener;try{let e=window.opener.frames;for(let n=0;n<e.length;n++)if(t(e[n]))return e[n];return null}catch(t){return console.error(`[findIframeInOpener] Error finding iframe with pathname ${e}:`,t),null}}function v(){if(typeof navigator>`u`)return!1;let e=navigator.userAgent;return!!(/iPhone|iPad|iPod/i.test(e)||/Macintosh/i.test(e)&&navigator.maxTouchPoints>1)}const y=v();function b(){if(typeof navigator>`u`)return!1;let e=navigator.userAgent.toLowerCase();return e.includes(`instagram`)||e.includes(`fban`)||e.includes(`fbav`)||e.includes(`facebook`)}const x=b();function S(e){y&&e.startsWith(`https://`)?window.location.href=`x-safari-https://${e.slice(8)}`:y&&e.startsWith(`http://`)?window.location.href=`x-safari-http://${e.slice(7)}`:window.location.href=`https://backend.frak.id/common/social?u=${encodeURIComponent(e)}`}function C({perCall:e,defaults:t,productUtmContent:n}){if(e===null)return;let r=e!==void 0,i=t!==void 0&&Object.keys(t).length>0;if(!r&&!i&&!(n!==void 0&&n!==``))return;let a={...t,...e??{}},o=n??e?.utmContent;return o!==void 0&&o!==``?a.utmContent=o:delete a.utmContent,a}function w(e,t){if(typeof window>`u`)return;let n=new URL(window.location.href),r=n.searchParams.get(`sso`);r&&(t.then(()=>{e.sendLifecycle({clientLifecycle:`sso-redirect-complete`,data:{compressed:r}}),console.log(`[SSO URL Listener] Forwarded compressed SSO data to iframe`)}).catch(e=>{console.error(`[SSO URL Listener] Failed to forward SSO data:`,e)}),n.searchParams.delete(`sso`),window.history.replaceState({},``,n.toString()),console.log(`[SSO URL Listener] SSO parameter detected and URL cleaned`))}var T=class e{config;iframe;isSetupDone=!1;lastResponse=null;lastRequest=null;constructor(e,t){this.config=e,this.iframe=t,this.lastRequest=null,this.lastResponse=null}setLastResponse(e,t){this.lastResponse={message:e,response:t,timestamp:Date.now()}}setLastRequest(e){this.lastRequest={event:e,timestamp:Date.now()}}updateSetupStatus(e){this.isSetupDone=e}base64Encode(e){try{return btoa(JSON.stringify(e))}catch(e){return console.warn(`Failed to encode debug data`,e),btoa(`Failed to encode data`)}}getIframeStatus(){return this.iframe?{loading:this.iframe.hasAttribute(`loading`),url:this.iframe.src,readyState:this.iframe.contentDocument?.readyState?+(this.iframe.contentDocument.readyState===`complete`):-1,contentWindow:!!this.iframe.contentWindow,isConnected:this.iframe.isConnected}:null}getNavigatorInfo(){return navigator?{userAgent:navigator.userAgent,language:navigator.language,onLine:navigator.onLine,screenWidth:window.screen.width,screenHeight:window.screen.height,pixelRatio:window.devicePixelRatio}:null}gatherDebugInfo(e){let n=this.getIframeStatus(),r=this.getNavigatorInfo(),i=`Unknown`;return e instanceof t.FrakRpcError?i=`FrakRpcError: ${e.code} '${e.message}'`:e instanceof Error?i=e.message:typeof e==`string`&&(i=e),{timestamp:new Date().toISOString(),encodedUrl:btoa(window.location.href),encodedConfig:this.config?this.base64Encode(this.config):`no-config`,navigatorInfo:r?this.base64Encode(r):`no-navigator`,iframeStatus:n?this.base64Encode(n):`not-iframe`,lastRequest:this.lastRequest?this.base64Encode(this.lastRequest):`No Frak request logged`,lastResponse:this.lastResponse?this.base64Encode(this.lastResponse):`No Frak response logged`,clientStatus:this.isSetupDone?`setup`:`not-setup`,error:i}}static empty(){return new e}formatDebugInfo(e){let t=this.gatherDebugInfo(e);return`
2
+ Debug Information:
3
+ -----------------
4
+ Timestamp: ${t.timestamp}
5
+ URL: ${t.encodedUrl}
6
+ Config: ${t.encodedConfig}
7
+ Navigator Info: ${t.navigatorInfo}
8
+ IFrame Status: ${t.iframeStatus}
9
+ Last Request: ${t.lastRequest}
10
+ Last Response: ${t.lastResponse}
11
+ Client Status: ${t.clientStatus}
12
+ Error: ${t.error}
13
+ `.trim()}};const E=(()=>{if(typeof navigator>`u`)return!1;let e=navigator.userAgent;if(!(/iPhone|iPad|iPod/i.test(e)||/Macintosh/i.test(e)&&navigator.maxTouchPoints>1))return!1;let t=e.toLowerCase();return t.includes(`instagram`)||t.includes(`fban`)||t.includes(`fbav`)||t.includes(`facebook`)})();function D(e){e?localStorage.setItem(r,e):localStorage.removeItem(r)}function O(e,t){try{let n=new URL(e);if(!n.searchParams.has(`u`))return e;let r=j(window.location.href,t);return n.searchParams.delete(`u`),n.searchParams.append(`u`,r),n.toString()}catch{return e}}function k(e){let t=new URL(window.location.href);e&&t.searchParams.set(`fmt`,e);let n=t.protocol===`http:`?`x-safari-http`:`x-safari-https`;window.location.href=`${n}://${t.host}${t.pathname}${t.search}${t.hash}`}function A(e){return e.includes(`/common/social`)}function j(e,t){if(!t)return e;try{let n=new URL(e);return n.searchParams.set(`fmt`,t),n.toString()}catch{return`${e}${e.includes(`?`)?`&`:`?`}fmt=${encodeURIComponent(t)}`}}function M(e,t,n,r,i){if(i){let e=O(t,r);window.open(e,`_blank`);return}if(c(t)){let i=O(t,r);s(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(E&&A(t))k(r);else{let e=O(t,r);window.location.href=e}}function N({iframe:e,targetOrigin:n}){let i=new t.Deferred;return{handleEvent:t=>{if(!(`iframeLifecycle`in t))return;let{iframeLifecycle:a,data:o}=t;switch(a){case`connected`:i.resolve(!0);break;case`do-backup`:D(o.backup);break;case`remove-backup`:localStorage.removeItem(r);break;case`show`:case`hide`:g({iframe:e,isVisible:a===`show`});break;case`redirect`:M(e,o.baseRedirectUrl,n,o.mergeToken,o.openInNewTab);break}},isConnected:i.promise}}function P({config:r,iframe:i}){let a=r?.walletUrl??`https://wallet.frak.id`,o=typeof navigator<`u`?navigator.language?.split(`-`)[0]:void 0,s=r.metadata.lang??(o===`en`||o===`fr`?o:void 0),c=r.domain??(typeof window<`u`?window.location.hostname:``);e.n.setCacheScope(c,s),e.n.reset();let l=e.n.isCacheFresh?void 0:e.n.resolve(r.domain,r.walletUrl,s),u=N({iframe:i,targetOrigin:a}),d=new t.Deferred,f=Date.now(),p=new T(r,i);if(!i.contentWindow)throw new t.FrakRpcError(t.RpcErrorCodes.configError,`The iframe does not have a content window`);let m=(0,t.createRpcClient)({emittingTransport:i.contentWindow,listeningTransport:window,targetOrigin:a,middleware:[{async onRequest(e,n){if(!await u.isConnected)throw new t.FrakRpcError(t.RpcErrorCodes.clientNotConnected,`The iframe provider isn't connected yet`);return await d.promise,n}},{onRequest(e,t){return p.setLastRequest(e),t},onResponse(e,t){return p.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:(e,t)=>{u.handleEvent(e)}}}),h=F(m,u),g=async()=>{h(),m.cleanup(),i.remove(),e.s(),e.n.clearCache(),e.n.reset()},_;{console.log(`[Frak SDK] Initializing OpenPanel`),_=new n.OpenPanel({apiUrl:`https://op-api.gcp.frak.id`,clientId:`6eacc8d7-49ac-4936-95e9-81ef29449570`,trackScreenViews:!0,trackOutgoingLinks:!0,trackAttributes:!1,filter:({type:t,payload:n})=>(t!==`track`||!n?.properties||`sdkVersion`in n.properties||(n.properties={...n.properties,sdkVersion:`1.0.0`,userAnonymousClientId:e.y()}),!0)}),_.setGlobalProperties({sdkVersion:`1.0.0`,userAnonymousClientId:e.y()}),_.init(),_.track(`sdk_initialized`,{sdkVersion:`1.0.0`});let t=!1,r=setTimeout(()=>{t||(t=!0,_?.track(`sdk_iframe_handshake_failed`,{reason:`timeout`}))},3e4);u.isConnected.then(()=>{t||(t=!0,clearTimeout(r),_?.track(`sdk_iframe_connected`,{handshake_duration_ms:Date.now()-f}))}).catch(()=>{t||(t=!0,clearTimeout(r),_?.track(`sdk_iframe_handshake_failed`,{reason:`unknown`}))})}let v=I({config:r,rpcClient:m,lifecycleManager:u,configPromise:l,contextSent:d,openPanel:_}).then(()=>p.updateSetupStatus(!0)).catch(e=>{throw d.reject(e),e});return{config:r,debugInfo:p,waitForConnection:u.isConnected,waitForSetup:v,request:m.request,listenerRequest:m.listen,destroy:g,openPanel:_}}function F(e,t){let n,r,i=()=>e.sendLifecycle({clientLifecycle:`heartbeat`});async function a(){i(),n=setInterval(i,1e3),r=setTimeout(()=>{o(),console.log(`Heartbeat timeout: connection failed`)},3e4),await t.isConnected,o()}function o(){n&&clearInterval(n),r&&clearTimeout(r)}return a(),o}async function I({config:t,rpcClient:n,lifecycleManager:i,configPromise:a,contextSent:o,openPanel:s}){await i.isConnected,w(n,i.isConnected);let c=new URL(window.location.href),l=c.searchParams.get(`fmt`)??void 0;l&&(c.searchParams.delete(`fmt`),window.history.replaceState({},``,c.toString()));let u=n=>{let r=n?.merchantId??t.metadata.merchantId??``,i=n?.domain??``,a=n?.allowedDomains??[],o=n?.sdkConfig,s=o?.attribution||t.attribution?{...t.attribution,...o?.attribution}:void 0;e.n.setConfig(o?{isResolved:!0,merchantId:r,domain:i,allowedDomains:a,hasRawSdkConfig:!0,name:o.name??t.metadata.name,logoUrl:o.logoUrl??t.metadata.logoUrl,homepageLink:o.homepageLink??t.metadata.homepageLink,lang:o.lang??t.metadata.lang,currency:o.currency??t.metadata.currency,hidden:o.hidden,css:o.css,translations:o.translations,placements:o.placements,components:o.components,attribution:s}:{isResolved:!0,merchantId:r,domain:i,allowedDomains:a,name:t.metadata.name,logoUrl:t.metadata.logoUrl,homepageLink:t.metadata.homepageLink,lang:t.metadata.lang,currency:t.metadata.currency,attribution:s})},d=!1,f=t=>{let r=d?void 0:l;d=!0;let i=t.hasRawSdkConfig?{name:t.name,logoUrl:t.logoUrl,homepageLink:t.homepageLink,lang:t.lang,currency:t.currency,hidden:t.hidden,css:t.css,translations:t.translations,placements:t.placements,attribution:t.attribution}:t.attribution?{attribution:t.attribution}:void 0,a=e.y();if(s){let e=s.global??{};s.setGlobalProperties({...e,merchantId:t.merchantId,domain:t.domain??``})}n.sendLifecycle({clientLifecycle:`resolved-config`,data:{merchantId:t.merchantId,domain:t.domain??``,allowedDomains:t.allowedDomains??[],sourceUrl:window.location.href,...a&&{sdkAnonymousId:a},...r&&{pendingMergeToken:r},...i&&{sdkConfig:i}}})};e.n.isResolved&&(f(e.n.getConfig()),o.resolve()),a&&(u(await a),f(e.n.getConfig()),o.resolve());async function p(){let e=t.customizations?.css;e&&n.sendLifecycle({clientLifecycle:`modal-css`,data:{cssLink:e}})}async function m(){let e=t.customizations?.i18n;e&&n.sendLifecycle({clientLifecycle:`modal-i18n`,data:{i18n:e}})}async function h(){if(typeof window>`u`)return;let e=window.localStorage.getItem(r);e&&n.sendLifecycle({clientLifecycle:`restore-backup`,data:{backup:e}})}(await Promise.allSettled([p(),m(),h()])).some(e=>e.status===`rejected`)&&s?.track(`sdk_iframe_handshake_failed`,{reason:`asset_push`})}async function L({config:e}){let t=R(e),n=await h({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=P({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function R(e){let t=u(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return s}});
@@ -0,0 +1 @@
1
+ import{bytesToHex as e,hexToBytes as t,isAddress as n,keccak256 as r,toHex as i}from"viem";import{jsonDecode as a,jsonEncode as o}from"@frak-labs/frame-connector";const s=`frak-client-id`;function c(){return typeof crypto<`u`&&crypto.randomUUID?crypto.randomUUID():`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e===`x`?t:t&3|8).toString(16)})}function l(){if(typeof window>`u`||!window.localStorage)return console.warn(`[Frak SDK] No Window / localStorage available to save the clientId`),c();let e=localStorage.getItem(s);return e||(e=c(),localStorage.setItem(s,e)),e}function u({domain:e}={}){return r(i((e??window.location.host).replace(`www.`,``)))}function d(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join(``)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function f(e){let t=e.length%4;return Uint8Array.from(atob(e.replace(/-/g,`+`).replace(/_/g,`/`).padEnd(e.length+(t===0?0:4-t),`=`)),e=>e.charCodeAt(0))}function p(e){return d(o(e))}function m(e,t,n,r,i,a){let o=p(h({redirectUrl:t.redirectUrl,directExit:t.directExit,lang:t.lang,merchantId:n,metadata:{name:r,css:a,logoUrl:t.metadata?.logoUrl,homepageLink:t.metadata?.homepageLink},clientId:i})),s=new URL(e);return s.pathname=`/sso`,s.searchParams.set(`p`,o),s.toString()}function h(e){return{r:e.redirectUrl,cId:e.clientId,d:e.directExit,l:e.lang,m:e.merchantId,md:{n:e.metadata?.name,css:e.metadata?.css,l:e.metadata?.logoUrl,h:e.metadata?.homepageLink}}}const g=`menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800`,_=`frak-sso`;async function ee(e,t){let{metadata:n,customizations:r,walletUrl:i}=e.config;if(t.openInSameWindow??!!t.redirectUrl)return await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]});let a=t.ssoPopupUrl??m(i??`https://wallet.frak.id`,t,u(),n.name,l(),r?.css),o=window.open(a,_,g);if(!o)throw Error(`Popup was blocked. Please allow popups for this site.`);return o.focus(),await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]})??{}}const v=`https://backend.frak.id`;function te(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function y(e){return te(e)?`https://localhost:3030`:e.includes(`wallet-dev.frak.id`)||e.includes(`wallet.gcp-dev.frak.id`)?`https://backend.gcp-dev.frak.id`:v}function b(e){if(e)return y(e);if(typeof window<`u`){let e=window.FrakSetup?.client?.config?.walletUrl;if(e)return y(e)}return v}var x=class extends Map{maxSize;constructor(e){super(),this.maxSize=e}get(e){let t=super.get(e);return super.has(e)&&(super.delete(e),super.set(e,t)),t}set(e,t){if(super.has(e)&&super.delete(e),super.set(e,t),this.maxSize&&this.size>this.maxSize){let e=super.keys().next().value;e!==void 0&&super.delete(e)}return this}};const S=new x(1024),C=new x(1024),w=3e4,T=new x(1024);async function E(e,{cacheKey:t,cacheTime:n=w}){if(n>0){let e=C.get(t);if(e&&Date.now()-e.created<n)return e.data}let r=T.get(t);if(r&&Date.now()-r<1e3)throw Error(`Cache: ${t} recently failed, backing off`);let i=S.get(t);i||(i=e(),S.set(t,i));try{let e=await i;return C.set(t,{data:e,created:Date.now()}),T.delete(t),e}catch(e){throw T.set(t,Date.now()),e}finally{S.delete(t)}}function D(e){return{clear:()=>{S.delete(e),C.delete(e)},has:(t=w)=>{let n=C.get(e);return n?Date.now()-n.created<t:!1}}}function O(){S.clear(),C.clear(),T.clear()}function k(e){return a(f(e))}function A(e){return`r`in e&&!(`v`in e)}function j(e){return`v`in e&&e.v===2}const M=`fCtx`;function N(e){if(e)try{return j(e)?!e.c||!e.m||!e.t?void 0:p({v:2,c:e.c,m:e.m,t:e.t}):d(t(e.r))}catch(t){console.error(`Error compressing Frak context`,{e:t,context:e})}}function P(t){if(!(!t||t.length===0))try{let r=k(t);if(r&&typeof r==`object`&&r.v===2)return r.c&&r.m&&r.t?{v:2,c:r.c,m:r.m,t:r.t}:void 0;let i=e(f(t),{size:20});if(n(i))return{r:i}}catch(e){console.error(`Error decompressing Frak context`,{e,context:t})}}function ne({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(M);return t?P(t):null}const F=`frak`;function I(e,t){let n=j(e);return{utm_source:t.utmSource??F,utm_medium:t.utmMedium??`referral`,utm_campaign:t.utmCampaign??(n?e.m:void 0),utm_content:t.utmContent,utm_term:t.utmTerm,via:t.via??F,ref:t.ref??(n?e.c:void 0)}}function L(e,t,n){let r=I(t,n??{});for(let[t,n]of Object.entries(r))n===void 0||n===``||e.searchParams.has(t)||e.searchParams.set(t,n)}function R({url:e,context:t,attribution:n}){if(!e)return null;let r=N(t);if(!r)return null;let i=new URL(e);return i.searchParams.set(M,r),L(i,t,n),i.toString()}function z(e){let t=new URL(e);return t.searchParams.delete(M),t.toString()}function B({url:e,context:t}){if(!window.location?.href||typeof window>`u`){console.error(`No window found, can't update context`);return}let n=e??window.location.href,r;r=t===null?z(n):R({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const re={compress:N,decompress:P,parse:ne,update:R,remove:z,replaceUrl:B},V=`__frakSdkConfig`,H=`frak-config-cache`,U=`frak-merchant-id`,W={key:H},G=typeof window<`u`;function K(){return{isResolved:!1,merchantId:``}}let q=null;function J(){if(!G)return null;try{let e=localStorage.getItem(W.key);if(!e)return null;let t=JSON.parse(e);return t.config?.isResolved?(q=t,t):null}catch{return null}}function Y(){return(q??J())?.config}function ie(){let e=q??J();return e?Date.now()-e.timestamp<3e4:!1}function ae(e){if(!(!G||!e.isResolved))try{let t={config:e,timestamp:Date.now()};localStorage.setItem(W.key,JSON.stringify(t)),q=t}catch{}}function oe(){if(G){q=null;try{localStorage.removeItem(W.key)}catch{}}}function se(){G&&(window[V]||(window[V]=Y()??K()))}se();function X(){return G?window[V]??K():K()}function Z(e){G&&window.dispatchEvent(new CustomEvent(`frak:config`,{detail:e}))}function Q(e){return e??(G?window.location.hostname:``)}async function ce(e,t,n){try{let r=b(t),i=n?`&lang=${encodeURIComponent(n)}`:``,a=await fetch(`${r}/user/merchant/resolve?domain=${encodeURIComponent(e)}${i}`);if(!a.ok){console.warn(`[Frak SDK] Merchant lookup failed for domain ${e}: ${a.status}`);return}let o=await a.json();if(G)try{sessionStorage.setItem(U,o.merchantId)}catch{}return o}catch(e){console.warn(`[Frak SDK] Failed to fetch merchant config:`,e);return}}const $={getConfig:X,get isResolved(){return X().isResolved},get isCacheFresh(){return ie()},setCacheScope(e,t){W.key=`${H}:${`${e}:${t??``}`}`,q=null},setConfig(e){if(G&&(window[V]=e),ae(e),Z(e),G&&e.merchantId)try{sessionStorage.setItem(U,e.merchantId)}catch{}},reset(){let e=Y()??K();G&&(window[V]=e),Z(e)},clearCache(){if(oe(),O(),G)try{sessionStorage.removeItem(U)}catch{}},resolve(e,t,n){let r=Q(e);return r?E(async()=>{let e=await ce(r,t,n);if(!e)throw Error(`Config resolution returned empty`);return e},{cacheKey:`sdkConfig:${r}:${n??``}`,cacheTime:1/0}).catch(()=>void 0):Promise.resolve(void 0)},getMerchantId(){let e=X();if(e.isResolved&&e.merchantId)return e.merchantId;if(G)try{return sessionStorage.getItem(U)??void 0}catch{}},async resolveMerchantId(e,t){return $.getMerchantId()||(await $.resolve(e,t))?.merchantId}};function le(e,t,n){if(!e){console.debug(`[Frak] No client provided, skipping event tracking`);return}try{e.openPanel?.track(t,n)}catch(e){console.debug(`[Frak] Failed to track event:`,t,e)}}export{d as _,j as a,D as c,ee as d,g as f,f as g,p as h,A as i,E as l,m,$ as n,k as o,_ as p,re as r,O as s,le as t,b as u,u as v,l as y};
@@ -0,0 +1 @@
1
+ let e=require(`viem`),t=require(`@frak-labs/frame-connector`);const n=`frak-client-id`;function r(){return typeof crypto<`u`&&crypto.randomUUID?crypto.randomUUID():`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e===`x`?t:t&3|8).toString(16)})}function i(){if(typeof window>`u`||!window.localStorage)return console.warn(`[Frak SDK] No Window / localStorage available to save the clientId`),r();let e=localStorage.getItem(n);return e||(e=r(),localStorage.setItem(n,e)),e}function a({domain:t}={}){return(0,e.keccak256)((0,e.toHex)((t??window.location.host).replace(`www.`,``)))}function o(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join(``)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function s(e){let t=e.length%4;return Uint8Array.from(atob(e.replace(/-/g,`+`).replace(/_/g,`/`).padEnd(e.length+(t===0?0:4-t),`=`)),e=>e.charCodeAt(0))}function c(e){return o((0,t.jsonEncode)(e))}function l(e,t,n,r,i,a){let o=c(u({redirectUrl:t.redirectUrl,directExit:t.directExit,lang:t.lang,merchantId:n,metadata:{name:r,css:a,logoUrl:t.metadata?.logoUrl,homepageLink:t.metadata?.homepageLink},clientId:i})),s=new URL(e);return s.pathname=`/sso`,s.searchParams.set(`p`,o),s.toString()}function u(e){return{r:e.redirectUrl,cId:e.clientId,d:e.directExit,l:e.lang,m:e.merchantId,md:{n:e.metadata?.name,css:e.metadata?.css,l:e.metadata?.logoUrl,h:e.metadata?.homepageLink}}}const d=`menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800`,f=`frak-sso`;async function p(e,t){let{metadata:n,customizations:r,walletUrl:o}=e.config;if(t.openInSameWindow??!!t.redirectUrl)return await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]});let s=t.ssoPopupUrl??l(o??`https://wallet.frak.id`,t,a(),n.name,i(),r?.css),c=window.open(s,f,d);if(!c)throw Error(`Popup was blocked. Please allow popups for this site.`);return c.focus(),await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]})??{}}const m=`https://backend.frak.id`;function h(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function g(e){return h(e)?`https://localhost:3030`:e.includes(`wallet-dev.frak.id`)||e.includes(`wallet.gcp-dev.frak.id`)?`https://backend.gcp-dev.frak.id`:m}function _(e){if(e)return g(e);if(typeof window<`u`){let e=window.FrakSetup?.client?.config?.walletUrl;if(e)return g(e)}return m}var v=class extends Map{maxSize;constructor(e){super(),this.maxSize=e}get(e){let t=super.get(e);return super.has(e)&&(super.delete(e),super.set(e,t)),t}set(e,t){if(super.has(e)&&super.delete(e),super.set(e,t),this.maxSize&&this.size>this.maxSize){let e=super.keys().next().value;e!==void 0&&super.delete(e)}return this}};const y=new v(1024),b=new v(1024),x=3e4,S=new v(1024);async function C(e,{cacheKey:t,cacheTime:n=x}){if(n>0){let e=b.get(t);if(e&&Date.now()-e.created<n)return e.data}let r=S.get(t);if(r&&Date.now()-r<1e3)throw Error(`Cache: ${t} recently failed, backing off`);let i=y.get(t);i||(i=e(),y.set(t,i));try{let e=await i;return b.set(t,{data:e,created:Date.now()}),S.delete(t),e}catch(e){throw S.set(t,Date.now()),e}finally{y.delete(t)}}function ee(e){return{clear:()=>{y.delete(e),b.delete(e)},has:(t=x)=>{let n=b.get(e);return n?Date.now()-n.created<t:!1}}}function w(){y.clear(),b.clear(),S.clear()}function T(e){return(0,t.jsonDecode)(s(e))}function E(e){return`r`in e&&!(`v`in e)}function D(e){return`v`in e&&e.v===2}const O=`fCtx`;function k(t){if(t)try{return D(t)?!t.c||!t.m||!t.t?void 0:c({v:2,c:t.c,m:t.m,t:t.t}):o((0,e.hexToBytes)(t.r))}catch(e){console.error(`Error compressing Frak context`,{e,context:t})}}function A(t){if(!(!t||t.length===0))try{let n=T(t);if(n&&typeof n==`object`&&n.v===2)return n.c&&n.m&&n.t?{v:2,c:n.c,m:n.m,t:n.t}:void 0;let r=(0,e.bytesToHex)(s(t),{size:20});if((0,e.isAddress)(r))return{r}}catch(e){console.error(`Error decompressing Frak context`,{e,context:t})}}function j({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(O);return t?A(t):null}const M=`frak`;function N(e,t){let n=D(e);return{utm_source:t.utmSource??M,utm_medium:t.utmMedium??`referral`,utm_campaign:t.utmCampaign??(n?e.m:void 0),utm_content:t.utmContent,utm_term:t.utmTerm,via:t.via??M,ref:t.ref??(n?e.c:void 0)}}function te(e,t,n){let r=N(t,n??{});for(let[t,n]of Object.entries(r))n===void 0||n===``||e.searchParams.has(t)||e.searchParams.set(t,n)}function P({url:e,context:t,attribution:n}){if(!e)return null;let r=k(t);if(!r)return null;let i=new URL(e);return i.searchParams.set(O,r),te(i,t,n),i.toString()}function F(e){let t=new URL(e);return t.searchParams.delete(O),t.toString()}function I({url:e,context:t}){if(!window.location?.href||typeof window>`u`){console.error(`No window found, can't update context`);return}let n=e??window.location.href,r;r=t===null?F(n):P({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const L={compress:k,decompress:A,parse:j,update:P,remove:F,replaceUrl:I},R=`__frakSdkConfig`,z=`frak-config-cache`,B=`frak-merchant-id`,V={key:z},H=typeof window<`u`;function U(){return{isResolved:!1,merchantId:``}}let W=null;function G(){if(!H)return null;try{let e=localStorage.getItem(V.key);if(!e)return null;let t=JSON.parse(e);return t.config?.isResolved?(W=t,t):null}catch{return null}}function K(){return(W??G())?.config}function q(){let e=W??G();return e?Date.now()-e.timestamp<3e4:!1}function J(e){if(!(!H||!e.isResolved))try{let t={config:e,timestamp:Date.now()};localStorage.setItem(V.key,JSON.stringify(t)),W=t}catch{}}function Y(){if(H){W=null;try{localStorage.removeItem(V.key)}catch{}}}function X(){H&&(window[R]||(window[R]=K()??U()))}X();function Z(){return H?window[R]??U():U()}function Q(e){H&&window.dispatchEvent(new CustomEvent(`frak:config`,{detail:e}))}function ne(e){return e??(H?window.location.hostname:``)}async function re(e,t,n){try{let r=_(t),i=n?`&lang=${encodeURIComponent(n)}`:``,a=await fetch(`${r}/user/merchant/resolve?domain=${encodeURIComponent(e)}${i}`);if(!a.ok){console.warn(`[Frak SDK] Merchant lookup failed for domain ${e}: ${a.status}`);return}let o=await a.json();if(H)try{sessionStorage.setItem(B,o.merchantId)}catch{}return o}catch(e){console.warn(`[Frak SDK] Failed to fetch merchant config:`,e);return}}const $={getConfig:Z,get isResolved(){return Z().isResolved},get isCacheFresh(){return q()},setCacheScope(e,t){V.key=`${z}:${`${e}:${t??``}`}`,W=null},setConfig(e){if(H&&(window[R]=e),J(e),Q(e),H&&e.merchantId)try{sessionStorage.setItem(B,e.merchantId)}catch{}},reset(){let e=K()??U();H&&(window[R]=e),Q(e)},clearCache(){if(Y(),w(),H)try{sessionStorage.removeItem(B)}catch{}},resolve(e,t,n){let r=ne(e);return r?C(async()=>{let e=await re(r,t,n);if(!e)throw Error(`Config resolution returned empty`);return e},{cacheKey:`sdkConfig:${r}:${n??``}`,cacheTime:1/0}).catch(()=>void 0):Promise.resolve(void 0)},getMerchantId(){let e=Z();if(e.isResolved&&e.merchantId)return e.merchantId;if(H)try{return sessionStorage.getItem(B)??void 0}catch{}},async resolveMerchantId(e,t){return $.getMerchantId()||(await $.resolve(e,t))?.merchantId}};function ie(e,t,n){if(!e){console.debug(`[Frak] No client provided, skipping event tracking`);return}try{e.openPanel?.track(t,n)}catch(e){console.debug(`[Frak] Failed to track event:`,t,e)}}Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return ee}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return ie}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return i}});
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "url": "https://twitter.com/QNivelais"
12
12
  }
13
13
  ],
14
- "version": "1.0.0-beta.7f085fb7",
14
+ "version": "1.0.0-beta.cb2a3a9a",
15
15
  "description": "Core SDK of the Frak wallet, low level library to interact directly with the frak ecosystem.",
16
16
  "repository": {
17
17
  "url": "https://github.com/frak-id/wallet",
@@ -91,7 +91,7 @@
91
91
  "viem": "^2.x"
92
92
  },
93
93
  "dependencies": {
94
- "@frak-labs/frame-connector": "0.2.0-beta.7f085fb7",
94
+ "@frak-labs/frame-connector": "0.2.0-beta.cb2a3a9a",
95
95
  "@openpanel/web": "^1.2.0"
96
96
  },
97
97
  "devDependencies": {
@@ -100,10 +100,8 @@ describe("processReferral", () => {
100
100
  mockClient,
101
101
  "user_referred_started",
102
102
  {
103
- properties: {
104
- referrerClientId: "referrer-client-id",
105
- walletStatus: "connected",
106
- },
103
+ referrerClientId: "referrer-client-id",
104
+ walletStatus: "connected",
107
105
  }
108
106
  );
109
107
 
@@ -156,10 +154,8 @@ describe("processReferral", () => {
156
154
  mockClient,
157
155
  "user_referred_started",
158
156
  {
159
- properties: {
160
- referrer: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
161
- walletStatus: "connected",
162
- },
157
+ referrer: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
158
+ walletStatus: "connected",
163
159
  }
164
160
  );
165
161
  });
@@ -54,10 +54,8 @@ function trackArrivalIfValid(
54
54
 
55
55
  if (isV2Context(frakContext)) {
56
56
  trackEvent(client, "user_referred_started", {
57
- properties: {
58
- referrerClientId: frakContext.c,
59
- walletStatus: walletStatus?.key,
60
- },
57
+ referrerClientId: frakContext.c,
58
+ walletStatus: walletStatus?.key,
61
59
  });
62
60
  sendInteraction(client, {
63
61
  type: "arrival",
@@ -71,10 +69,8 @@ function trackArrivalIfValid(
71
69
 
72
70
  if (isV1Context(frakContext)) {
73
71
  trackEvent(client, "user_referred_started", {
74
- properties: {
75
- referrer: frakContext.r,
76
- walletStatus: walletStatus?.key,
77
- },
72
+ referrer: frakContext.r,
73
+ walletStatus: walletStatus?.key,
78
74
  });
79
75
  sendInteraction(client, {
80
76
  type: "arrival",
@@ -177,9 +173,7 @@ export function processReferral(
177
173
  });
178
174
 
179
175
  trackEvent(client, "user_referred_completed", {
180
- properties: {
181
- status: "success",
182
- },
176
+ status: "success",
183
177
  });
184
178
 
185
179
  return "success";