@frak-labs/core-sdk 1.0.0-beta.0cd79998 → 1.0.0-beta.10dada3f

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 (49) hide show
  1. package/cdn/bundle.js +3 -3
  2. package/dist/actions-Bsl5ub7_.js +1 -0
  3. package/dist/actions-C_B0fn1P.cjs +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-BCwGNRmk.d.cts → index-BSGP3dbi.d.ts} +113 -22
  13. package/dist/{index-DZuYiI2M.d.ts → index-Bh0TuKYS.d.ts} +1 -1
  14. package/dist/{index-CVnwk1E_.d.cts → index-DW8xes2o.d.cts} +1 -1
  15. package/dist/{index-BfmJnxzo.d.ts → index-TRJNS6B5.d.cts} +113 -22
  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-BQ-q-_Y9.d.ts → openSso-Bvhy_urG.d.cts} +24 -6
  21. package/dist/{openSso-CMBCbhvP.d.cts → openSso-D2kTUv0-.d.ts} +24 -6
  22. package/dist/sdkConfigStore-B6CkorsU.cjs +1 -0
  23. package/dist/sdkConfigStore-Dx0oAVEO.js +1 -0
  24. package/dist/src-CLF8o8WB.cjs +13 -0
  25. package/dist/src-al3X6r-n.js +13 -0
  26. package/package.json +2 -2
  27. package/src/actions/referral/processReferral.test.ts +73 -8
  28. package/src/actions/referral/processReferral.ts +15 -12
  29. package/src/clients/createIFrameFrakClient.ts +72 -2
  30. package/src/index.ts +4 -1
  31. package/src/types/context.ts +16 -4
  32. package/src/types/lifecycle/client.ts +7 -0
  33. package/src/utils/FrakContext.test.ts +41 -7
  34. package/src/utils/FrakContext.ts +24 -15
  35. package/src/utils/analytics/events/component.ts +58 -0
  36. package/src/utils/analytics/events/index.ts +20 -0
  37. package/src/utils/analytics/events/lifecycle.ts +26 -0
  38. package/src/utils/analytics/events/referral.ts +11 -0
  39. package/src/utils/analytics/index.ts +8 -0
  40. package/src/utils/{trackEvent.test.ts → analytics/trackEvent.test.ts} +22 -30
  41. package/src/utils/analytics/trackEvent.ts +34 -0
  42. package/src/utils/index.ts +1 -1
  43. package/dist/actions-BMTVobuH.js +0 -1
  44. package/dist/actions-ukNCM0d7.cjs +0 -1
  45. package/dist/src-Cx0RZEA3.js +0 -13
  46. package/dist/src-DmYZ4ZLk.cjs +0 -13
  47. package/dist/trackEvent-B5xo_5K3.cjs +0 -1
  48. package/dist/trackEvent-DdykyX0U.js +0 -1
  49. package/src/utils/trackEvent.ts +0 -41
@@ -1,4 +1,4 @@
1
- import { G as SsoMetadata, Q as MerchantConfigResponse, U as PrepareSsoParamsType, a as FrakContextV1, at as Language, ct as AttributionParams, i as FrakContext, l as FrakClient, nt as Currency, o as FrakContextV2, rt as FrakWalletSdkConfig, st as AttributionDefaults, tt as SdkResolvedConfig, v as TokenAmountType } from "./openSso-BQ-q-_Y9.js";
1
+ import { G as SsoMetadata, Q as MerchantConfigResponse, U as PrepareSsoParamsType, a as FrakContextV1, at as Language, ct as AttributionParams, i as FrakContext, l as FrakClient, nt as Currency, o as FrakContextV2, rt as FrakWalletSdkConfig, st as AttributionDefaults, tt as SdkResolvedConfig, v as TokenAmountType } from "./openSso-Bvhy_urG.cjs";
2
2
  import { Hex } from "viem";
3
3
  import { RpcMessage, RpcResponse } from "@frak-labs/frame-connector";
4
4
 
@@ -111,6 +111,112 @@ declare const locales: {
111
111
  readonly gbp: "en-GB";
112
112
  };
113
113
  //#endregion
114
+ //#region src/utils/analytics/events/component.d.ts
115
+ type ButtonBaseProps = {
116
+ placement?: string;
117
+ target_interaction?: string;
118
+ has_reward?: boolean;
119
+ };
120
+ type BannerVariant = "referral" | "inapp";
121
+ type BannerOutcome = "clicked" | "dismissed";
122
+ type PostPurchaseVariant = "referrer" | "referee";
123
+ type ShareClickAction = "share-modal" | "embedded-wallet" | "sharing-page";
124
+ type SdkComponentEventMap = {
125
+ share_button_clicked: ButtonBaseProps & {
126
+ click_action: ShareClickAction;
127
+ };
128
+ share_modal_error: ButtonBaseProps & {
129
+ error?: string;
130
+ };
131
+ open_in_app_clicked: {
132
+ placement?: string;
133
+ path: string;
134
+ };
135
+ app_not_installed: {
136
+ placement?: string;
137
+ path: string;
138
+ };
139
+ banner_impression: {
140
+ placement?: string;
141
+ variant: BannerVariant;
142
+ has_reward?: boolean;
143
+ };
144
+ banner_resolved: {
145
+ placement?: string;
146
+ variant: BannerVariant;
147
+ outcome: BannerOutcome;
148
+ };
149
+ post_purchase_impression: {
150
+ placement?: string;
151
+ variant: PostPurchaseVariant;
152
+ has_reward?: boolean;
153
+ };
154
+ post_purchase_clicked: {
155
+ placement?: string;
156
+ variant: PostPurchaseVariant;
157
+ };
158
+ };
159
+ //#endregion
160
+ //#region src/utils/analytics/events/lifecycle.d.ts
161
+ type SdkHandshakeFailureReason = "timeout" | "origin" | "asset_push" | "unknown";
162
+ type SdkLifecycleEventMap = {
163
+ sdk_initialized: {
164
+ sdkVersion?: string;
165
+ };
166
+ sdk_iframe_connected: {
167
+ handshake_duration_ms: number;
168
+ };
169
+ sdk_iframe_handshake_failed: {
170
+ reason: SdkHandshakeFailureReason;
171
+ };
172
+ /**
173
+ * Emitted by the CDN bootstrap when `initFrakSdk()` throws before a
174
+ * client is available. Uses a transient OpenPanel instance so broken
175
+ * partner integrations are still captured.
176
+ */
177
+ sdk_init_failed: {
178
+ reason: string;
179
+ config_missing?: boolean;
180
+ };
181
+ };
182
+ //#endregion
183
+ //#region src/utils/analytics/events/referral.d.ts
184
+ type SdkReferralEventMap = {
185
+ user_referred_started: {
186
+ referrer?: string;
187
+ referrerClientId?: string;
188
+ referrerWallet?: string;
189
+ walletStatus?: string;
190
+ };
191
+ user_referred_completed: {
192
+ status: "success";
193
+ };
194
+ };
195
+ //#endregion
196
+ //#region src/utils/analytics/events/index.d.ts
197
+ /**
198
+ * Merged SDK event map. Consumed by the SDK's typed `trackEvent`.
199
+ * Stays isolated from wallet-shared because the SDK ships in partner
200
+ * bundles (different OpenPanel client id, no wallet-shared dependency
201
+ * allowed — see `packages/wallet-shared/AGENTS.md`).
202
+ */
203
+ type SdkEventMap = SdkLifecycleEventMap & SdkComponentEventMap & SdkReferralEventMap;
204
+ //#endregion
205
+ //#region src/utils/analytics/trackEvent.d.ts
206
+ /**
207
+ * Track an analytics event via the SDK's OpenPanel instance.
208
+ * Fire-and-forget — silently catches errors so analytics never break a
209
+ * partner integration.
210
+ *
211
+ * The client must be passed explicitly because the OpenPanel instance is
212
+ * scoped to each `FrakClient` (a partner site may hold multiple iframes).
213
+ *
214
+ * @param client - The Frak client instance (no-op if undefined)
215
+ * @param event - Typed event name from the SDK event map
216
+ * @param properties - Typed properties for the given event
217
+ */
218
+ declare function trackEvent<K extends keyof SdkEventMap>(client: FrakClient | undefined, event: K, properties?: SdkEventMap[K]): void;
219
+ //#endregion
114
220
  //#region src/utils/backendUrl.d.ts
115
221
  /**
116
222
  * Get the backend URL for API calls
@@ -297,15 +403,15 @@ declare function parse({
297
403
  /**
298
404
  * Add or replace the `fCtx` query parameter in a URL with the given context.
299
405
  *
300
- * When `attribution` is provided (even as an empty object), standard affiliation
301
- * params (`utm_source`, `utm_medium`, `utm_campaign`, `ref`, `via`, ...) are
302
- * also appended using gap-fill semantics: pre-existing params on the URL are
303
- * preserved, and defaults are derived from the context when applicable.
406
+ * Standard affiliation params (`utm_source`, `utm_medium`, `utm_campaign`,
407
+ * `ref`, `via`, ...) are always appended using gap-fill semantics: pre-existing
408
+ * params on the URL are preserved, defaults are derived from the context when
409
+ * applicable, and `attribution` overrides take precedence when provided.
304
410
  *
305
411
  * @param args
306
412
  * @param args.url - The URL to update
307
413
  * @param args.context - The context to embed (V1 or V2)
308
- * @param args.attribution - Optional attribution overrides. Omit to skip UTM/ref params.
414
+ * @param args.attribution - Optional attribution overrides. Defaults are applied even when omitted.
309
415
  * @returns The updated URL string, or null on failure
310
416
  */
311
417
  declare function update({
@@ -594,21 +700,6 @@ type CompressedSsoData = {
594
700
  };
595
701
  };
596
702
  //#endregion
597
- //#region src/utils/trackEvent.d.ts
598
- /**
599
- * Analytics event names emitted by the SDK
600
- */
601
- type FrakEvent = "share_button_clicked" | "wallet_button_clicked" | "open_in_app_clicked" | "open_in_app_login_clicked" | "app_not_installed" | "share_modal_error" | "user_referred_started" | "user_referred_completed" | "user_referred_error";
602
- type EventProps = Record<string, unknown>;
603
- /**
604
- * Track an analytics event via OpenPanel.
605
- * Fire-and-forget: silently catches errors.
606
- * @param client - The Frak client instance (no-op if undefined)
607
- * @param event - The event name to track
608
- * @param props - Optional event properties
609
- */
610
- declare function trackEvent(client: FrakClient | undefined, event: FrakEvent, props?: EventProps): void;
611
- //#endregion
612
703
  //#region src/utils/computeLegacyProductId.d.ts
613
704
  /**
614
705
  * Compute the legacy product id from a domain
@@ -620,4 +711,4 @@ declare function computeLegacyProductId({
620
711
  domain?: string;
621
712
  }): `0x${string}`;
622
713
  //#endregion
623
- export { base64urlDecode as A, DebugInfoGatherer as B, isChromiumAndroid as C, DEEP_LINK_SCHEME as D, triggerDeepLinkWithFallback as E, withCache as F, CompressedData as H, getBackendUrl as I, LocalesKey as L, getClientId as M, clearAllCache as N, decompressJsonFromB64 as O, getCache as P, locales as R, DeepLinkFallbackOptions as S, toAndroidIntentUrl as T, HashProtectedData as U, createIFrameFrakClient as V, KeyProvider as W, getSupportedLocale as _, CompressedSsoData as a, formatAmount as b, sdkConfigStore as c, isIOS as d, isInAppBrowser as f, findIframeInOpener as g, createIframe as h, AppSpecificSsoMetadata as i, base64urlEncode as j, compressJsonToB64 as k, MergeAttributionInput as l, baseIframeProps as m, FrakEvent as n, FullSsoParams as o, redirectToExternalBrowser as p, trackEvent as r, generateSsoUrl as s, computeLegacyProductId as t, mergeAttribution as u, getSupportedCurrency as v, isFrakDeepLink as w, FrakContextManager as x, getCurrencyAmountKey as y, setupClient as z };
714
+ export { getClientId as A, setupClient as B, toAndroidIntentUrl as C, compressJsonToB64 as D, decompressJsonFromB64 as E, trackEvent as F, KeyProvider as G, createIFrameFrakClient as H, SdkEventMap as I, SdkHandshakeFailureReason as L, getCache as M, withCache as N, base64urlDecode as O, getBackendUrl as P, LocalesKey as R, isFrakDeepLink as S, DEEP_LINK_SCHEME as T, CompressedData as U, DebugInfoGatherer as V, HashProtectedData as W, getCurrencyAmountKey as _, generateSsoUrl as a, DeepLinkFallbackOptions as b, mergeAttribution as c, redirectToExternalBrowser as d, baseIframeProps as f, getSupportedCurrency as g, getSupportedLocale as h, FullSsoParams as i, clearAllCache as j, base64urlEncode as k, isIOS as l, findIframeInOpener as m, AppSpecificSsoMetadata as n, sdkConfigStore as o, createIframe as p, CompressedSsoData as r, MergeAttributionInput as s, computeLegacyProductId as t, isInAppBrowser as u, formatAmount as v, triggerDeepLinkWithFallback as w, isChromiumAndroid as x, FrakContextManager as y, locales as z };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./trackEvent-B5xo_5K3.cjs`),t=require(`./src-DmYZ4ZLk.cjs`);exports.DEEP_LINK_SCHEME=t.b,exports.DebugInfoGatherer=t.r,exports.FrakContextManager=e.r,exports.base64urlDecode=e.g,exports.base64urlEncode=e._,exports.baseIframeProps=t.c,exports.clearAllCache=e.s,exports.compressJsonToB64=e.h,exports.computeLegacyProductId=e.v,exports.createIFrameFrakClient=t.n,exports.createIframe=t.l,exports.decompressJsonFromB64=e.o,exports.findIframeInOpener=t.u,exports.formatAmount=t.f,exports.generateSsoUrl=e.m,exports.getBackendUrl=e.u,exports.getCache=e.c,exports.getClientId=e.y,exports.getCurrencyAmountKey=t.d,exports.getSupportedCurrency=t.m,exports.getSupportedLocale=t.p,exports.isChromiumAndroid=t.g,exports.isFrakDeepLink=t._,exports.isIOS=t.a,exports.isInAppBrowser=t.o,exports.isV1Context=e.i,exports.isV2Context=e.a,exports.locales=t.h,exports.mergeAttribution=t.i,exports.redirectToExternalBrowser=t.s,exports.sdkConfigStore=e.n,exports.setupClient=t.t,exports.ssoPopupFeatures=e.f,exports.ssoPopupName=e.p,exports.toAndroidIntentUrl=t.v,exports.trackEvent=e.t,exports.triggerDeepLinkWithFallback=t.y,exports.withCache=e.l;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./sdkConfigStore-B6CkorsU.cjs`),t=require(`./src-CLF8o8WB.cjs`);exports.DEEP_LINK_SCHEME=t.b,exports.DebugInfoGatherer=t.r,exports.FrakContextManager=e.n,exports.base64urlDecode=e.g,exports.base64urlEncode=e._,exports.baseIframeProps=t.c,exports.clearAllCache=e.o,exports.compressJsonToB64=e.h,exports.computeLegacyProductId=e.v,exports.createIFrameFrakClient=t.n,exports.createIframe=t.l,exports.decompressJsonFromB64=e.a,exports.findIframeInOpener=t.u,exports.formatAmount=t.f,exports.generateSsoUrl=e.m,exports.getBackendUrl=e.l,exports.getCache=e.s,exports.getClientId=e.y,exports.getCurrencyAmountKey=t.d,exports.getSupportedCurrency=t.m,exports.getSupportedLocale=t.p,exports.isChromiumAndroid=t.g,exports.isFrakDeepLink=t._,exports.isIOS=t.a,exports.isInAppBrowser=t.o,exports.isV1Context=e.r,exports.isV2Context=e.i,exports.locales=t.h,exports.mergeAttribution=t.i,exports.redirectToExternalBrowser=t.s,exports.sdkConfigStore=e.t,exports.setupClient=t.t,exports.ssoPopupFeatures=e.f,exports.ssoPopupName=e.p,exports.toAndroidIntentUrl=t.v,exports.trackEvent=e.u,exports.triggerDeepLinkWithFallback=t.y,exports.withCache=e.c;
package/dist/index.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- import { $ as ResolvedPlacement, A as ModalRpcMetadata, B as LoginModalStepType, C as EmbeddedViewActionReferred, D as DisplaySharingPageResultType, E as DisplaySharingPageParamsType, F as SendTransactionReturnType, G as SsoMetadata, H as OpenSsoReturnType, I as SendTransactionTxType, J as ModalStepMetadata, K as FinalActionType, L as SiweAuthenticateModalStepType, M as ModalRpcStepsResultType, N as ModalStepTypes, O as SharingPageProduct, P as SendTransactionModalStepType, Q as MerchantConfigResponse, R as SiweAuthenticateReturnType, S as LoggedOutEmbeddedView, T as LoggedInEmbeddedView, U as PrepareSsoParamsType, V as OpenSsoParamsType, W as PrepareSsoReturnType, X as IFrameLifecycleEvent, Y as InteractionTypeKey, Z as ClientLifecycleEvent, _ as RewardTier, a as FrakContextV1, at as Language, b as DisplayEmbeddedWalletParamsType, c as isV2Context, ct as AttributionParams, d as IFrameTransport, dt as UtmParams, et as ResolvedSdkConfig, f as IFrameRpcSchema, g as GetMerchantInformationReturnType, h as EstimatedReward, i as FrakContext, it as I18nConfig, j as ModalRpcStepsInput, k as DisplayModalParamsType, l as FrakClient, lt as TrackArrivalParams, m as UserReferralStatusType, n as ssoPopupFeatures, nt as Currency, o as FrakContextV2, ot as LocalizedI18nConfig, p as WalletStatusReturnType, q as FinalModalStepType, r as ssoPopupName, rt as FrakWalletSdkConfig, s as isV1Context, st as AttributionDefaults, tt as SdkResolvedConfig, u as FrakLifecycleEvent, ut as TrackArrivalResult, v as TokenAmountType, w as EmbeddedViewActionSharing, x as DisplayEmbeddedWalletResultType, y as SendInteractionParamsType, z as SiweAuthenticationParams } from "./openSso-CMBCbhvP.cjs";
2
- import { A as base64urlDecode, B as DebugInfoGatherer, C as isChromiumAndroid, D as DEEP_LINK_SCHEME, E as triggerDeepLinkWithFallback, F as withCache, H as CompressedData, I as getBackendUrl, L as LocalesKey, M as getClientId, N as clearAllCache, O as decompressJsonFromB64, P as getCache, R as locales, S as DeepLinkFallbackOptions, T as toAndroidIntentUrl, U as HashProtectedData, V as createIFrameFrakClient, W as KeyProvider, _ as getSupportedLocale, a as CompressedSsoData, b as formatAmount, c as sdkConfigStore, d as isIOS, f as isInAppBrowser, g as findIframeInOpener, h as createIframe, i as AppSpecificSsoMetadata, j as base64urlEncode, k as compressJsonToB64, l as MergeAttributionInput, m as baseIframeProps, n as FrakEvent, o as FullSsoParams, p as redirectToExternalBrowser, r as trackEvent, s as generateSsoUrl, t as computeLegacyProductId, u as mergeAttribution, v as getSupportedCurrency, w as isFrakDeepLink, x as FrakContextManager, y as getCurrencyAmountKey, z as setupClient } from "./index-BCwGNRmk.cjs";
3
- export { AppSpecificSsoMetadata, AttributionDefaults, AttributionParams, ClientLifecycleEvent, CompressedData, CompressedSsoData, Currency, DEEP_LINK_SCHEME, DebugInfoGatherer, DeepLinkFallbackOptions, DisplayEmbeddedWalletParamsType, DisplayEmbeddedWalletResultType, DisplayModalParamsType, DisplaySharingPageParamsType, DisplaySharingPageResultType, EmbeddedViewActionReferred, EmbeddedViewActionSharing, EstimatedReward, FinalActionType, FinalModalStepType, FrakClient, FrakContext, FrakContextManager, FrakContextV1, FrakContextV2, FrakEvent, FrakLifecycleEvent, FrakWalletSdkConfig, FullSsoParams, GetMerchantInformationReturnType, HashProtectedData, I18nConfig, IFrameLifecycleEvent, IFrameRpcSchema, IFrameTransport, InteractionTypeKey, KeyProvider, Language, LocalesKey, LocalizedI18nConfig, LoggedInEmbeddedView, LoggedOutEmbeddedView, LoginModalStepType, MerchantConfigResponse, MergeAttributionInput, ModalRpcMetadata, ModalRpcStepsInput, ModalRpcStepsResultType, ModalStepMetadata, ModalStepTypes, OpenSsoParamsType, OpenSsoReturnType, PrepareSsoParamsType, PrepareSsoReturnType, ResolvedPlacement, ResolvedSdkConfig, RewardTier, SdkResolvedConfig, SendInteractionParamsType, SendTransactionModalStepType, SendTransactionReturnType, SendTransactionTxType, SharingPageProduct, SiweAuthenticateModalStepType, SiweAuthenticateReturnType, SiweAuthenticationParams, SsoMetadata, TokenAmountType, TrackArrivalParams, TrackArrivalResult, UserReferralStatusType, UtmParams, WalletStatusReturnType, base64urlDecode, base64urlEncode, baseIframeProps, clearAllCache, compressJsonToB64, computeLegacyProductId, createIFrameFrakClient, createIframe, decompressJsonFromB64, findIframeInOpener, formatAmount, generateSsoUrl, getBackendUrl, getCache, getClientId, getCurrencyAmountKey, getSupportedCurrency, getSupportedLocale, isChromiumAndroid, isFrakDeepLink, isIOS, isInAppBrowser, isV1Context, isV2Context, locales, mergeAttribution, redirectToExternalBrowser, sdkConfigStore, setupClient, ssoPopupFeatures, ssoPopupName, toAndroidIntentUrl, trackEvent, triggerDeepLinkWithFallback, withCache };
1
+ import { $ as ResolvedPlacement, A as ModalRpcMetadata, B as LoginModalStepType, C as EmbeddedViewActionReferred, D as DisplaySharingPageResultType, E as DisplaySharingPageParamsType, F as SendTransactionReturnType, G as SsoMetadata, H as OpenSsoReturnType, I as SendTransactionTxType, J as ModalStepMetadata, K as FinalActionType, L as SiweAuthenticateModalStepType, M as ModalRpcStepsResultType, N as ModalStepTypes, O as SharingPageProduct, P as SendTransactionModalStepType, Q as MerchantConfigResponse, R as SiweAuthenticateReturnType, S as LoggedOutEmbeddedView, T as LoggedInEmbeddedView, U as PrepareSsoParamsType, V as OpenSsoParamsType, W as PrepareSsoReturnType, X as IFrameLifecycleEvent, Y as InteractionTypeKey, Z as ClientLifecycleEvent, _ as RewardTier, a as FrakContextV1, at as Language, b as DisplayEmbeddedWalletParamsType, c as isV2Context, ct as AttributionParams, d as IFrameTransport, dt as UtmParams, et as ResolvedSdkConfig, f as IFrameRpcSchema, g as GetMerchantInformationReturnType, h as EstimatedReward, i as FrakContext, it as I18nConfig, j as ModalRpcStepsInput, k as DisplayModalParamsType, l as FrakClient, lt as TrackArrivalParams, m as UserReferralStatusType, n as ssoPopupFeatures, nt as Currency, o as FrakContextV2, ot as LocalizedI18nConfig, p as WalletStatusReturnType, q as FinalModalStepType, r as ssoPopupName, rt as FrakWalletSdkConfig, s as isV1Context, st as AttributionDefaults, tt as SdkResolvedConfig, u as FrakLifecycleEvent, ut as TrackArrivalResult, v as TokenAmountType, w as EmbeddedViewActionSharing, x as DisplayEmbeddedWalletResultType, y as SendInteractionParamsType, z as SiweAuthenticationParams } from "./openSso-Bvhy_urG.cjs";
2
+ import { A as getClientId, B as setupClient, C as toAndroidIntentUrl, D as compressJsonToB64, E as decompressJsonFromB64, F as trackEvent, G as KeyProvider, H as createIFrameFrakClient, I as SdkEventMap, L as SdkHandshakeFailureReason, M as getCache, N as withCache, O as base64urlDecode, P as getBackendUrl, R as LocalesKey, S as isFrakDeepLink, T as DEEP_LINK_SCHEME, U as CompressedData, V as DebugInfoGatherer, W as HashProtectedData, _ as getCurrencyAmountKey, a as generateSsoUrl, b as DeepLinkFallbackOptions, c as mergeAttribution, d as redirectToExternalBrowser, f as baseIframeProps, g as getSupportedCurrency, h as getSupportedLocale, i as FullSsoParams, j as clearAllCache, k as base64urlEncode, l as isIOS, m as findIframeInOpener, n as AppSpecificSsoMetadata, o as sdkConfigStore, p as createIframe, r as CompressedSsoData, s as MergeAttributionInput, t as computeLegacyProductId, u as isInAppBrowser, v as formatAmount, w as triggerDeepLinkWithFallback, x as isChromiumAndroid, y as FrakContextManager, z as locales } from "./index-TRJNS6B5.cjs";
3
+ export { AppSpecificSsoMetadata, AttributionDefaults, AttributionParams, ClientLifecycleEvent, CompressedData, CompressedSsoData, Currency, DEEP_LINK_SCHEME, DebugInfoGatherer, DeepLinkFallbackOptions, DisplayEmbeddedWalletParamsType, DisplayEmbeddedWalletResultType, DisplayModalParamsType, DisplaySharingPageParamsType, DisplaySharingPageResultType, EmbeddedViewActionReferred, EmbeddedViewActionSharing, EstimatedReward, FinalActionType, FinalModalStepType, FrakClient, FrakContext, FrakContextManager, FrakContextV1, FrakContextV2, FrakLifecycleEvent, FrakWalletSdkConfig, FullSsoParams, GetMerchantInformationReturnType, HashProtectedData, I18nConfig, IFrameLifecycleEvent, IFrameRpcSchema, IFrameTransport, InteractionTypeKey, KeyProvider, Language, LocalesKey, LocalizedI18nConfig, LoggedInEmbeddedView, LoggedOutEmbeddedView, LoginModalStepType, MerchantConfigResponse, MergeAttributionInput, ModalRpcMetadata, ModalRpcStepsInput, ModalRpcStepsResultType, ModalStepMetadata, ModalStepTypes, OpenSsoParamsType, OpenSsoReturnType, PrepareSsoParamsType, PrepareSsoReturnType, ResolvedPlacement, ResolvedSdkConfig, RewardTier, SdkEventMap, SdkHandshakeFailureReason, SdkResolvedConfig, SendInteractionParamsType, SendTransactionModalStepType, SendTransactionReturnType, SendTransactionTxType, SharingPageProduct, SiweAuthenticateModalStepType, SiweAuthenticateReturnType, SiweAuthenticationParams, SsoMetadata, TokenAmountType, TrackArrivalParams, TrackArrivalResult, UserReferralStatusType, UtmParams, WalletStatusReturnType, base64urlDecode, base64urlEncode, baseIframeProps, clearAllCache, compressJsonToB64, computeLegacyProductId, createIFrameFrakClient, createIframe, decompressJsonFromB64, findIframeInOpener, formatAmount, generateSsoUrl, getBackendUrl, getCache, getClientId, getCurrencyAmountKey, getSupportedCurrency, getSupportedLocale, isChromiumAndroid, isFrakDeepLink, isIOS, isInAppBrowser, isV1Context, isV2Context, locales, mergeAttribution, redirectToExternalBrowser, sdkConfigStore, setupClient, ssoPopupFeatures, ssoPopupName, toAndroidIntentUrl, trackEvent, triggerDeepLinkWithFallback, withCache };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { $ as ResolvedPlacement, A as ModalRpcMetadata, B as LoginModalStepType, C as EmbeddedViewActionReferred, D as DisplaySharingPageResultType, E as DisplaySharingPageParamsType, F as SendTransactionReturnType, G as SsoMetadata, H as OpenSsoReturnType, I as SendTransactionTxType, J as ModalStepMetadata, K as FinalActionType, L as SiweAuthenticateModalStepType, M as ModalRpcStepsResultType, N as ModalStepTypes, O as SharingPageProduct, P as SendTransactionModalStepType, Q as MerchantConfigResponse, R as SiweAuthenticateReturnType, S as LoggedOutEmbeddedView, T as LoggedInEmbeddedView, U as PrepareSsoParamsType, V as OpenSsoParamsType, W as PrepareSsoReturnType, X as IFrameLifecycleEvent, Y as InteractionTypeKey, Z as ClientLifecycleEvent, _ as RewardTier, a as FrakContextV1, at as Language, b as DisplayEmbeddedWalletParamsType, c as isV2Context, ct as AttributionParams, d as IFrameTransport, dt as UtmParams, et as ResolvedSdkConfig, f as IFrameRpcSchema, g as GetMerchantInformationReturnType, h as EstimatedReward, i as FrakContext, it as I18nConfig, j as ModalRpcStepsInput, k as DisplayModalParamsType, l as FrakClient, lt as TrackArrivalParams, m as UserReferralStatusType, n as ssoPopupFeatures, nt as Currency, o as FrakContextV2, ot as LocalizedI18nConfig, p as WalletStatusReturnType, q as FinalModalStepType, r as ssoPopupName, rt as FrakWalletSdkConfig, s as isV1Context, st as AttributionDefaults, tt as SdkResolvedConfig, u as FrakLifecycleEvent, ut as TrackArrivalResult, v as TokenAmountType, w as EmbeddedViewActionSharing, x as DisplayEmbeddedWalletResultType, y as SendInteractionParamsType, z as SiweAuthenticationParams } from "./openSso-BQ-q-_Y9.js";
2
- import { A as base64urlDecode, B as DebugInfoGatherer, C as isChromiumAndroid, D as DEEP_LINK_SCHEME, E as triggerDeepLinkWithFallback, F as withCache, H as CompressedData, I as getBackendUrl, L as LocalesKey, M as getClientId, N as clearAllCache, O as decompressJsonFromB64, P as getCache, R as locales, S as DeepLinkFallbackOptions, T as toAndroidIntentUrl, U as HashProtectedData, V as createIFrameFrakClient, W as KeyProvider, _ as getSupportedLocale, a as CompressedSsoData, b as formatAmount, c as sdkConfigStore, d as isIOS, f as isInAppBrowser, g as findIframeInOpener, h as createIframe, i as AppSpecificSsoMetadata, j as base64urlEncode, k as compressJsonToB64, l as MergeAttributionInput, m as baseIframeProps, n as FrakEvent, o as FullSsoParams, p as redirectToExternalBrowser, r as trackEvent, s as generateSsoUrl, t as computeLegacyProductId, u as mergeAttribution, v as getSupportedCurrency, w as isFrakDeepLink, x as FrakContextManager, y as getCurrencyAmountKey, z as setupClient } from "./index-BfmJnxzo.js";
3
- export { AppSpecificSsoMetadata, AttributionDefaults, AttributionParams, ClientLifecycleEvent, CompressedData, CompressedSsoData, Currency, DEEP_LINK_SCHEME, DebugInfoGatherer, DeepLinkFallbackOptions, DisplayEmbeddedWalletParamsType, DisplayEmbeddedWalletResultType, DisplayModalParamsType, DisplaySharingPageParamsType, DisplaySharingPageResultType, EmbeddedViewActionReferred, EmbeddedViewActionSharing, EstimatedReward, FinalActionType, FinalModalStepType, FrakClient, FrakContext, FrakContextManager, FrakContextV1, FrakContextV2, FrakEvent, FrakLifecycleEvent, FrakWalletSdkConfig, FullSsoParams, GetMerchantInformationReturnType, HashProtectedData, I18nConfig, IFrameLifecycleEvent, IFrameRpcSchema, IFrameTransport, InteractionTypeKey, KeyProvider, Language, LocalesKey, LocalizedI18nConfig, LoggedInEmbeddedView, LoggedOutEmbeddedView, LoginModalStepType, MerchantConfigResponse, MergeAttributionInput, ModalRpcMetadata, ModalRpcStepsInput, ModalRpcStepsResultType, ModalStepMetadata, ModalStepTypes, OpenSsoParamsType, OpenSsoReturnType, PrepareSsoParamsType, PrepareSsoReturnType, ResolvedPlacement, ResolvedSdkConfig, RewardTier, SdkResolvedConfig, SendInteractionParamsType, SendTransactionModalStepType, SendTransactionReturnType, SendTransactionTxType, SharingPageProduct, SiweAuthenticateModalStepType, SiweAuthenticateReturnType, SiweAuthenticationParams, SsoMetadata, TokenAmountType, TrackArrivalParams, TrackArrivalResult, UserReferralStatusType, UtmParams, WalletStatusReturnType, base64urlDecode, base64urlEncode, baseIframeProps, clearAllCache, compressJsonToB64, computeLegacyProductId, createIFrameFrakClient, createIframe, decompressJsonFromB64, findIframeInOpener, formatAmount, generateSsoUrl, getBackendUrl, getCache, getClientId, getCurrencyAmountKey, getSupportedCurrency, getSupportedLocale, isChromiumAndroid, isFrakDeepLink, isIOS, isInAppBrowser, isV1Context, isV2Context, locales, mergeAttribution, redirectToExternalBrowser, sdkConfigStore, setupClient, ssoPopupFeatures, ssoPopupName, toAndroidIntentUrl, trackEvent, triggerDeepLinkWithFallback, withCache };
1
+ import { $ as ResolvedPlacement, A as ModalRpcMetadata, B as LoginModalStepType, C as EmbeddedViewActionReferred, D as DisplaySharingPageResultType, E as DisplaySharingPageParamsType, F as SendTransactionReturnType, G as SsoMetadata, H as OpenSsoReturnType, I as SendTransactionTxType, J as ModalStepMetadata, K as FinalActionType, L as SiweAuthenticateModalStepType, M as ModalRpcStepsResultType, N as ModalStepTypes, O as SharingPageProduct, P as SendTransactionModalStepType, Q as MerchantConfigResponse, R as SiweAuthenticateReturnType, S as LoggedOutEmbeddedView, T as LoggedInEmbeddedView, U as PrepareSsoParamsType, V as OpenSsoParamsType, W as PrepareSsoReturnType, X as IFrameLifecycleEvent, Y as InteractionTypeKey, Z as ClientLifecycleEvent, _ as RewardTier, a as FrakContextV1, at as Language, b as DisplayEmbeddedWalletParamsType, c as isV2Context, ct as AttributionParams, d as IFrameTransport, dt as UtmParams, et as ResolvedSdkConfig, f as IFrameRpcSchema, g as GetMerchantInformationReturnType, h as EstimatedReward, i as FrakContext, it as I18nConfig, j as ModalRpcStepsInput, k as DisplayModalParamsType, l as FrakClient, lt as TrackArrivalParams, m as UserReferralStatusType, n as ssoPopupFeatures, nt as Currency, o as FrakContextV2, ot as LocalizedI18nConfig, p as WalletStatusReturnType, q as FinalModalStepType, r as ssoPopupName, rt as FrakWalletSdkConfig, s as isV1Context, st as AttributionDefaults, tt as SdkResolvedConfig, u as FrakLifecycleEvent, ut as TrackArrivalResult, v as TokenAmountType, w as EmbeddedViewActionSharing, x as DisplayEmbeddedWalletResultType, y as SendInteractionParamsType, z as SiweAuthenticationParams } from "./openSso-D2kTUv0-.js";
2
+ import { A as getClientId, B as setupClient, C as toAndroidIntentUrl, D as compressJsonToB64, E as decompressJsonFromB64, F as trackEvent, G as KeyProvider, H as createIFrameFrakClient, I as SdkEventMap, L as SdkHandshakeFailureReason, M as getCache, N as withCache, O as base64urlDecode, P as getBackendUrl, R as LocalesKey, S as isFrakDeepLink, T as DEEP_LINK_SCHEME, U as CompressedData, V as DebugInfoGatherer, W as HashProtectedData, _ as getCurrencyAmountKey, a as generateSsoUrl, b as DeepLinkFallbackOptions, c as mergeAttribution, d as redirectToExternalBrowser, f as baseIframeProps, g as getSupportedCurrency, h as getSupportedLocale, i as FullSsoParams, j as clearAllCache, k as base64urlEncode, l as isIOS, m as findIframeInOpener, n as AppSpecificSsoMetadata, o as sdkConfigStore, p as createIframe, r as CompressedSsoData, s as MergeAttributionInput, t as computeLegacyProductId, u as isInAppBrowser, v as formatAmount, w as triggerDeepLinkWithFallback, x as isChromiumAndroid, y as FrakContextManager, z as locales } from "./index-BSGP3dbi.js";
3
+ export { AppSpecificSsoMetadata, AttributionDefaults, AttributionParams, ClientLifecycleEvent, CompressedData, CompressedSsoData, Currency, DEEP_LINK_SCHEME, DebugInfoGatherer, DeepLinkFallbackOptions, DisplayEmbeddedWalletParamsType, DisplayEmbeddedWalletResultType, DisplayModalParamsType, DisplaySharingPageParamsType, DisplaySharingPageResultType, EmbeddedViewActionReferred, EmbeddedViewActionSharing, EstimatedReward, FinalActionType, FinalModalStepType, FrakClient, FrakContext, FrakContextManager, FrakContextV1, FrakContextV2, FrakLifecycleEvent, FrakWalletSdkConfig, FullSsoParams, GetMerchantInformationReturnType, HashProtectedData, I18nConfig, IFrameLifecycleEvent, IFrameRpcSchema, IFrameTransport, InteractionTypeKey, KeyProvider, Language, LocalesKey, LocalizedI18nConfig, LoggedInEmbeddedView, LoggedOutEmbeddedView, LoginModalStepType, MerchantConfigResponse, MergeAttributionInput, ModalRpcMetadata, ModalRpcStepsInput, ModalRpcStepsResultType, ModalStepMetadata, ModalStepTypes, OpenSsoParamsType, OpenSsoReturnType, PrepareSsoParamsType, PrepareSsoReturnType, ResolvedPlacement, ResolvedSdkConfig, RewardTier, SdkEventMap, SdkHandshakeFailureReason, SdkResolvedConfig, SendInteractionParamsType, SendTransactionModalStepType, SendTransactionReturnType, SendTransactionTxType, SharingPageProduct, SiweAuthenticateModalStepType, SiweAuthenticateReturnType, SiweAuthenticationParams, SsoMetadata, TokenAmountType, TrackArrivalParams, TrackArrivalResult, UserReferralStatusType, UtmParams, WalletStatusReturnType, base64urlDecode, base64urlEncode, baseIframeProps, clearAllCache, compressJsonToB64, computeLegacyProductId, createIFrameFrakClient, createIframe, decompressJsonFromB64, findIframeInOpener, formatAmount, generateSsoUrl, getBackendUrl, getCache, getClientId, getCurrencyAmountKey, getSupportedCurrency, getSupportedLocale, isChromiumAndroid, isFrakDeepLink, isIOS, isInAppBrowser, isV1Context, isV2Context, locales, mergeAttribution, redirectToExternalBrowser, sdkConfigStore, setupClient, ssoPopupFeatures, ssoPopupName, toAndroidIntentUrl, trackEvent, triggerDeepLinkWithFallback, withCache };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{_ as e,a as t,c as n,f as r,g as i,h as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,s as p,t as m,u as h,v as g,y as _}from"./trackEvent-DdykyX0U.js";import{_ as v,a as y,b,c as x,d as S,f as C,g as w,h as T,i as E,l as D,m as O,n as k,o as A,p as j,r as M,s as N,t as P,u as F,v as I,y as L}from"./src-Cx0RZEA3.js";export{b as DEEP_LINK_SCHEME,M as DebugInfoGatherer,f as FrakContextManager,i as base64urlDecode,e as base64urlEncode,x as baseIframeProps,p as clearAllCache,a as compressJsonToB64,g as computeLegacyProductId,k as createIFrameFrakClient,D as createIframe,u as decompressJsonFromB64,F as findIframeInOpener,C as formatAmount,c as generateSsoUrl,h as getBackendUrl,n as getCache,_ as getClientId,S as getCurrencyAmountKey,O as getSupportedCurrency,j as getSupportedLocale,w as isChromiumAndroid,v as isFrakDeepLink,y as isIOS,A as isInAppBrowser,o as isV1Context,t as isV2Context,T as locales,E as mergeAttribution,N as redirectToExternalBrowser,l as sdkConfigStore,P as setupClient,r as ssoPopupFeatures,d as ssoPopupName,I as toAndroidIntentUrl,m as trackEvent,L as triggerDeepLinkWithFallback,s as withCache};
1
+ import{_ as e,a as t,c as n,f as r,g as i,h as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,s as p,t as m,u as h,v as g,y as _}from"./sdkConfigStore-Dx0oAVEO.js";import{_ as v,a as y,b,c as x,d as S,f as C,g as w,h as T,i as E,l as D,m as O,n as k,o as A,p as j,r as M,s as N,t as P,u as F,v as I,y as L}from"./src-al3X6r-n.js";export{b as DEEP_LINK_SCHEME,M as DebugInfoGatherer,l as FrakContextManager,i as base64urlDecode,e as base64urlEncode,x as baseIframeProps,u as clearAllCache,a as compressJsonToB64,g as computeLegacyProductId,k as createIFrameFrakClient,D as createIframe,t as decompressJsonFromB64,F as findIframeInOpener,C as formatAmount,c as generateSsoUrl,s as getBackendUrl,p as getCache,_ as getClientId,S as getCurrencyAmountKey,O as getSupportedCurrency,j as getSupportedLocale,w as isChromiumAndroid,v as isFrakDeepLink,y as isIOS,A as isInAppBrowser,f as isV1Context,o as isV2Context,T as locales,E as mergeAttribution,N as redirectToExternalBrowser,m as sdkConfigStore,P as setupClient,r as ssoPopupFeatures,d as ssoPopupName,I as toAndroidIntentUrl,h as trackEvent,L as triggerDeepLinkWithFallback,n as withCache};
@@ -1,6 +1,6 @@
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
6
  //#region src/types/tracking.d.ts
@@ -347,6 +347,13 @@ type ResolvedConfigEvent = {
347
347
  * When present, listener should execute identity merge in background.
348
348
  */
349
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;
350
357
  sdkConfig?: ResolvedSdkConfig;
351
358
  };
352
359
  };
@@ -1289,15 +1296,26 @@ type FrakContextV1 = {
1289
1296
  /** Referrer wallet address */r: Address;
1290
1297
  };
1291
1298
  /**
1292
- * V2 Frak Context — anonymous-first referral context.
1293
- * Contains the sharer's clientId, merchantId, and link creation timestamp.
1299
+ * V2 Frak Context — anonymous-first referral context with optional wallet.
1300
+ *
1301
+ * Carries merchant context (`m`) and creation timestamp (`t`) unconditionally.
1302
+ * Identifies the sharer via either the anonymous clientId (`c`) or, when the
1303
+ * sharer is authenticated, the stronger wallet identifier (`w`). A valid V2
1304
+ * context MUST contain at least one of `c` or `w`; both may be present when
1305
+ * a logged-in user shares a link (best attribution signal).
1306
+ *
1307
+ * `w` takes precedence as the source of truth because the wallet is bound to
1308
+ * the user's WebAuthn credential, survives localStorage clears, and is global
1309
+ * across merchants — unlike `c`, which is a per-browser UUID.
1310
+ *
1294
1311
  * @ignore
1295
1312
  */
1296
1313
  type FrakContextV2 = {
1297
- /** Version discriminator */v: 2; /** Sharer's anonymous clientId (UUID from localStorage) */
1298
- c: string; /** Merchant ID (UUID) */
1314
+ /** Version discriminator */v: 2; /** Merchant ID (UUID) */
1299
1315
  m: string; /** Link creation timestamp (epoch seconds) */
1300
- t: number;
1316
+ t: number; /** Sharer's anonymous clientId (UUID from localStorage). Optional when `w` is provided. */
1317
+ c?: string; /** Sharer's wallet address. Preferred source of truth when the sharer is authenticated. Optional when `c` is provided. */
1318
+ w?: Address;
1301
1319
  };
1302
1320
  /**
1303
1321
  * The current Frak Context — union of all versions.
@@ -1,6 +1,6 @@
1
- import { OpenPanel } from "@openpanel/web";
2
1
  import { Address, Hex } from "viem";
3
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
6
  //#region src/types/tracking.d.ts
@@ -347,6 +347,13 @@ type ResolvedConfigEvent = {
347
347
  * When present, listener should execute identity merge in background.
348
348
  */
349
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;
350
357
  sdkConfig?: ResolvedSdkConfig;
351
358
  };
352
359
  };
@@ -1289,15 +1296,26 @@ type FrakContextV1 = {
1289
1296
  /** Referrer wallet address */r: Address;
1290
1297
  };
1291
1298
  /**
1292
- * V2 Frak Context — anonymous-first referral context.
1293
- * Contains the sharer's clientId, merchantId, and link creation timestamp.
1299
+ * V2 Frak Context — anonymous-first referral context with optional wallet.
1300
+ *
1301
+ * Carries merchant context (`m`) and creation timestamp (`t`) unconditionally.
1302
+ * Identifies the sharer via either the anonymous clientId (`c`) or, when the
1303
+ * sharer is authenticated, the stronger wallet identifier (`w`). A valid V2
1304
+ * context MUST contain at least one of `c` or `w`; both may be present when
1305
+ * a logged-in user shares a link (best attribution signal).
1306
+ *
1307
+ * `w` takes precedence as the source of truth because the wallet is bound to
1308
+ * the user's WebAuthn credential, survives localStorage clears, and is global
1309
+ * across merchants — unlike `c`, which is a per-browser UUID.
1310
+ *
1294
1311
  * @ignore
1295
1312
  */
1296
1313
  type FrakContextV2 = {
1297
- /** Version discriminator */v: 2; /** Sharer's anonymous clientId (UUID from localStorage) */
1298
- c: string; /** Merchant ID (UUID) */
1314
+ /** Version discriminator */v: 2; /** Merchant ID (UUID) */
1299
1315
  m: string; /** Link creation timestamp (epoch seconds) */
1300
- t: number;
1316
+ t: number; /** Sharer's anonymous clientId (UUID from localStorage). Optional when `w` is provided. */
1317
+ c?: string; /** Sharer's wallet address. Preferred source of truth when the sharer is authenticated. Optional when `c` is provided. */
1318
+ w?: Address;
1301
1319
  };
1302
1320
  /**
1303
1321
  * The current Frak Context — union of all versions.
@@ -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]})??{}}function ee(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)}}const m=`https://backend.frak.id`;function te(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function h(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`:m}function g(e){if(e)return h(e);if(typeof window<`u`){let e=window.FrakSetup?.client?.config?.walletUrl;if(e)return h(e)}return m}var _=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 v=new _(1024),y=new _(1024),b=3e4,x=new _(1024);async function S(e,{cacheKey:t,cacheTime:n=b}){if(n>0){let e=y.get(t);if(e&&Date.now()-e.created<n)return e.data}let r=x.get(t);if(r&&Date.now()-r<1e3)throw Error(`Cache: ${t} recently failed, backing off`);let i=v.get(t);i||(i=e(),v.set(t,i));try{let e=await i;return y.set(t,{data:e,created:Date.now()}),x.delete(t),e}catch(e){throw x.set(t,Date.now()),e}finally{v.delete(t)}}function C(e){return{clear:()=>{v.delete(e),y.delete(e)},has:(t=b)=>{let n=y.get(e);return n?Date.now()-n.created<t:!1}}}function w(){v.clear(),y.clear(),x.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.m||!t.t||!t.c&&!t.w?void 0:c({v:2,m:t.m,t:t.t,...t.c?{c:t.c}:{},...t.w?{w:t.w}:{}}):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.m||!n.t||!n.c&&!n.w?void 0:{v:2,m:n.m,t:n.t,...n.c?{c:n.c}:{},...n.w?{w:n.w}:{}};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 ne({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(O);return t?A(t):null}const j=`frak`;function M(e,t){let n=D(e);return{utm_source:t.utmSource??j,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??j,ref:t.ref??(n?e.c:void 0)}}function N(e,t,n){let r=M(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),N(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:ne,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 re(e){return e??(H?window.location.hostname:``)}async function ie(e,t,n){try{let r=g(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=re(e);return r?S(async()=>{let e=await ie(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}};Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return S}}),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 D}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return ee}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return i}});
@@ -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(ee({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 ee(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 h=`menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800`,g=`frak-sso`;async function _(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,h);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]})??{}}function v(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)}}const y=`https://backend.frak.id`;function b(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function x(e){return b(e)?`https://localhost:3030`:e.includes(`wallet-dev.frak.id`)||e.includes(`wallet.gcp-dev.frak.id`)?`https://backend.gcp-dev.frak.id`:y}function S(e){if(e)return x(e);if(typeof window<`u`){let e=window.FrakSetup?.client?.config?.walletUrl;if(e)return x(e)}return y}var C=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 w=new C(1024),T=new C(1024),E=3e4,D=new C(1024);async function O(e,{cacheKey:t,cacheTime:n=E}){if(n>0){let e=T.get(t);if(e&&Date.now()-e.created<n)return e.data}let r=D.get(t);if(r&&Date.now()-r<1e3)throw Error(`Cache: ${t} recently failed, backing off`);let i=w.get(t);i||(i=e(),w.set(t,i));try{let e=await i;return T.set(t,{data:e,created:Date.now()}),D.delete(t),e}catch(e){throw D.set(t,Date.now()),e}finally{w.delete(t)}}function k(e){return{clear:()=>{w.delete(e),T.delete(e)},has:(t=E)=>{let n=T.get(e);return n?Date.now()-n.created<t:!1}}}function A(){w.clear(),T.clear(),D.clear()}function j(e){return a(f(e))}function M(e){return`r`in e&&!(`v`in e)}function N(e){return`v`in e&&e.v===2}const P=`fCtx`;function F(e){if(e)try{return N(e)?!e.m||!e.t||!e.c&&!e.w?void 0:p({v:2,m:e.m,t:e.t,...e.c?{c:e.c}:{},...e.w?{w:e.w}:{}}):d(t(e.r))}catch(t){console.error(`Error compressing Frak context`,{e:t,context:e})}}function I(t){if(!(!t||t.length===0))try{let r=j(t);if(r&&typeof r==`object`&&r.v===2)return!r.m||!r.t||!r.c&&!r.w?void 0:{v:2,m:r.m,t:r.t,...r.c?{c:r.c}:{},...r.w?{w:r.w}:{}};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 te({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(P);return t?I(t):null}const L=`frak`;function R(e,t){let n=N(e);return{utm_source:t.utmSource??L,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??L,ref:t.ref??(n?e.c:void 0)}}function z(e,t,n){let r=R(t,n??{});for(let[t,n]of Object.entries(r))n===void 0||n===``||e.searchParams.has(t)||e.searchParams.set(t,n)}function B({url:e,context:t,attribution:n}){if(!e)return null;let r=F(t);if(!r)return null;let i=new URL(e);return i.searchParams.set(P,r),z(i,t,n),i.toString()}function V(e){let t=new URL(e);return t.searchParams.delete(P),t.toString()}function ne({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?V(n):B({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const re={compress:F,decompress:I,parse:te,update:B,remove:V,replaceUrl:ne},H=`__frakSdkConfig`,U=`frak-config-cache`,W=`frak-merchant-id`,G={key:U},K=typeof window<`u`;function q(){return{isResolved:!1,merchantId:``}}let J=null;function Y(){if(!K)return null;try{let e=localStorage.getItem(G.key);if(!e)return null;let t=JSON.parse(e);return t.config?.isResolved?(J=t,t):null}catch{return null}}function X(){return(J??Y())?.config}function ie(){let e=J??Y();return e?Date.now()-e.timestamp<3e4:!1}function ae(e){if(!(!K||!e.isResolved))try{let t={config:e,timestamp:Date.now()};localStorage.setItem(G.key,JSON.stringify(t)),J=t}catch{}}function oe(){if(K){J=null;try{localStorage.removeItem(G.key)}catch{}}}function se(){K&&(window[H]||(window[H]=X()??q()))}se();function Z(){return K?window[H]??q():q()}function Q(e){K&&window.dispatchEvent(new CustomEvent(`frak:config`,{detail:e}))}function ce(e){return e??(K?window.location.hostname:``)}async function le(e,t,n){try{let r=S(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(K)try{sessionStorage.setItem(W,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 ie()},setCacheScope(e,t){G.key=`${U}:${`${e}:${t??``}`}`,J=null},setConfig(e){if(K&&(window[H]=e),ae(e),Q(e),K&&e.merchantId)try{sessionStorage.setItem(W,e.merchantId)}catch{}},reset(){let e=X()??q();K&&(window[H]=e),Q(e)},clearCache(){if(oe(),A(),K)try{sessionStorage.removeItem(W)}catch{}},resolve(e,t,n){let r=ce(e);return r?O(async()=>{let e=await le(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(K)try{return sessionStorage.getItem(W)??void 0}catch{}},async resolveMerchantId(e,t){return $.getMerchantId()||(await $.resolve(e,t))?.merchantId}};export{d as _,j as a,O as c,_ as d,h as f,f as g,p as h,N as i,S as l,m,re as n,A as o,g as p,M as r,k as s,$ as t,v as u,u as v,l as y};
@@ -0,0 +1,13 @@
1
+ const e=require(`./sdkConfigStore-B6CkorsU.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.t.setCacheScope(c,s),e.t.reset();let l=e.t.isCacheFresh?void 0:e.t.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.o(),e.t.clearCache(),e.t.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.t.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.t.isResolved&&(f(e.t.getConfig()),o.resolve()),a&&(u(await a),f(e.t.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,13 @@
1
+ import{o as e,t,y as n}from"./sdkConfigStore-Dx0oAVEO.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:``);t.setCacheScope(p,f),t.reset();let m=t.isCacheFresh?void 0:t.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(),e(),t.clearCache(),t.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:e,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??e.metadata.merchantId??``,i=n?.domain??``,a=n?.allowedDomains??[],o=n?.sdkConfig,s=o?.attribution||e.attribution?{...e.attribution,...o?.attribution}:void 0;t.setConfig(o?{isResolved:!0,merchantId:r,domain:i,allowedDomains:a,hasRawSdkConfig:!0,name:o.name??e.metadata.name,logoUrl:o.logoUrl??e.metadata.logoUrl,homepageLink:o.homepageLink??e.metadata.homepageLink,lang:o.lang??e.metadata.lang,currency:o.currency??e.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:e.metadata.name,logoUrl:e.metadata.logoUrl,homepageLink:e.metadata.homepageLink,lang:e.metadata.lang,currency:e.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}}})};t.isResolved&&(p(t.getConfig()),o.resolve()),a&&(d(await a),p(t.getConfig()),o.resolve());async function m(){let t=e.customizations?.css;t&&r.sendLifecycle({clientLifecycle:`modal-css`,data:{cssLink:t}})}async function h(){let t=e.customizations?.i18n;t&&r.sendLifecycle({clientLifecycle:`modal-i18n`,data:{i18n:t}})}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};
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.0cd79998",
14
+ "version": "1.0.0-beta.10dada3f",
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.0cd79998",
94
+ "@frak-labs/frame-connector": "0.2.0-beta.10dada3f",
95
95
  "@openpanel/web": "^1.2.0"
96
96
  },
97
97
  "devDependencies": {
@@ -100,10 +100,9 @@ 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
+ referrerWallet: undefined,
105
+ walletStatus: "connected",
107
106
  }
108
107
  );
109
108
 
@@ -111,6 +110,7 @@ describe("processReferral", () => {
111
110
  type: "arrival",
112
111
  referrerClientId: "referrer-client-id",
113
112
  referrerMerchantId: "merchant-uuid",
113
+ referrerWallet: undefined,
114
114
  referralTimestamp: 1709654400,
115
115
  landingUrl: "https://example.com/test",
116
116
  });
@@ -135,6 +135,73 @@ describe("processReferral", () => {
135
135
  expect(result).toBe("self-referral");
136
136
  vi.mocked(utils.getClientId).mockReturnValue("test-client-id");
137
137
  });
138
+
139
+ it("should successfully process v2 referral with wallet only (no clientId)", async () => {
140
+ await import("../../utils");
141
+ const { sendInteraction } = await import("../sendInteraction");
142
+
143
+ const referrerWallet =
144
+ "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" as Address;
145
+ const v2WithWalletOnly: FrakContextV2 = {
146
+ v: 2,
147
+ m: "merchant-uuid",
148
+ t: 1709654400,
149
+ w: referrerWallet,
150
+ };
151
+
152
+ const result = await processReferral(mockClient, {
153
+ walletStatus: mockWalletStatus,
154
+ frakContext: v2WithWalletOnly,
155
+ });
156
+
157
+ expect(result).toBe("success");
158
+ expect(sendInteraction).toHaveBeenCalledWith(mockClient, {
159
+ type: "arrival",
160
+ referrerClientId: undefined,
161
+ referrerMerchantId: "merchant-uuid",
162
+ referrerWallet,
163
+ referralTimestamp: 1709654400,
164
+ landingUrl: "https://example.com/test",
165
+ });
166
+ });
167
+
168
+ it("should return 'self-referral' when v2 wallet matches current wallet", async () => {
169
+ const v2SelfReferralByWallet: FrakContextV2 = {
170
+ v: 2,
171
+ m: "merchant-uuid",
172
+ t: 1709654400,
173
+ w: mockAddress,
174
+ };
175
+
176
+ const result = await processReferral(mockClient, {
177
+ walletStatus: mockWalletStatus,
178
+ frakContext: v2SelfReferralByWallet,
179
+ });
180
+
181
+ expect(result).toBe("self-referral");
182
+ });
183
+
184
+ it("should prefer wallet over clientId for self-referral when both are present", async () => {
185
+ const utils = await import("../../utils");
186
+ // clientId does NOT match current user, but wallet does → still self-referral
187
+ vi.mocked(utils.getClientId).mockReturnValue("some-other-client");
188
+
189
+ const v2Hybrid: FrakContextV2 = {
190
+ v: 2,
191
+ c: "referrer-client-id",
192
+ m: "merchant-uuid",
193
+ t: 1709654400,
194
+ w: mockAddress,
195
+ };
196
+
197
+ const result = await processReferral(mockClient, {
198
+ walletStatus: mockWalletStatus,
199
+ frakContext: v2Hybrid,
200
+ });
201
+
202
+ expect(result).toBe("self-referral");
203
+ vi.mocked(utils.getClientId).mockReturnValue("test-client-id");
204
+ });
138
205
  });
139
206
 
140
207
  describe("V1 context (backward compat)", () => {
@@ -156,10 +223,8 @@ describe("processReferral", () => {
156
223
  mockClient,
157
224
  "user_referred_started",
158
225
  {
159
- properties: {
160
- referrer: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
161
- walletStatus: "connected",
162
- },
226
+ referrer: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
227
+ walletStatus: "connected",
163
228
  }
164
229
  );
165
230
  });